CareerCup之1.3字符串去重
【題目】
原文:
1.3 Design an algorithm and write code to remove the duplicate characters in a string without using any additional buffer. NOTE: One or two additional variables are fine. An
extra copy of the array is not.
FOLLOW UP
Write the test cases for this method.
譯文:
設計算法並寫出代碼移除字符串中重複的字符,不能使用額外的緩存空間。注意: 可以使用額外的一個或兩個變量,但不允許額外再開一個數組拷貝。
【分析】
這道題目其實是要你就地(in place)將字符串中重複字符移除。你可以向麵試官問清楚, 不能使用額外的一份數組拷貝是指根本就不允許開一個數組,還是說可以開一個固定大小, 與問題規模(即字符串長度)無關的數組。
根據麵試官的回答,製定相應的解題策略。
【思路一】
如果根本就不允許你再開一個數組,隻能用額外的一到兩個變量。那麼,最先想到的方法就是暴力求解法了。
你可以依次訪問這個數組的每個元素,每訪問一個,就將該元素與前麵的元素進行比較,如果相同就去掉,如果不相同就添加到前麵序列中。
時間複雜度為O(n^2)
相應代碼為代碼一
【思路二】
如果根本就不允許你再開一個數組,隻能用額外的一到兩個變量。第二種方法就是先排序,再去重。
排序之後重複元素必定是相鄰的,這樣去重就簡單多了。
排序時間複雜度最快為快速排序為O(nlogn)
去重時間複雜度為O(n)
最終為O(nlogn)
相應代碼為代碼二
【思路三】
1 如果可以開一個固定大小,與問題規模(即字符串長度)無關的數組,那麼可以用一個數組來 表征每個字符的出現(假設是ASCII字符,則數組大小為256),這樣的話隻需要遍曆一遍字符 串即可,時間複雜度O(n)。
相應代碼為代碼三
2 如果字符集更小一些,比如隻是a-z,即字符串裏隻包含小寫字母,那麼使用一個int變量中 的每一位來表征每個字符的出現,用位運算來實現。也可以在O(n)的時間裏移除重複字符,而且還不需要額 外開一個數組。
相應代碼為代碼四
【代碼一】
/********************************* * 日期:2014-5-6 * 作者:SJF0115 * 題目: 字符串中字符去重 * 來源:CareerCup **********************************/ #include <iostream> #include <algorithm> #include <string.h> using namespace std; //刪除一個字符串中重複字符 void RemoveDuplicates(char str[]){ int i,j; if(str == NULL){ return; } int len = strlen(str); //去重 int index = 0; for(i = 0;i < len;i++){ //str[i]為待考察的元素 與前麵元素比較看是否重複 for(j = 0;j < i;j++){ //有重複的元素 if(str[i] == str[j]){ break; } } //str[i] 前麵沒有與之重複的元素 if(j >= i){ str[index++] = str[i]; } } str[index] = '\0'; } int main() { char str[] = "abababa"; RemoveDuplicates(str); cout<<str<<endl; return 0; }
【代碼二】
//刪除一個字符串中重複字符 void RemoveDuplicates(char str[]){ if(str == NULL){ return; } int len = strlen(str); //排序 sort(str,str+len); int index = 1; //去重 for(int i = 1;i < len;i++){ if(str[i] != str[i-1]){ str[index++] = str[i]; } } str[index] = '\0'; }
【代碼三】
//刪除一個字符串中重複字符 void RemoveDuplicates(char str[]){ bool vis[256]; //初始化 memset(vis,false,sizeof(vis)); int len = strlen(str); int index = 0; for(int i = 0;i < len;i++){ if(!vis[str[i]]){ str[index++] = str[i]; vis[str[i]] = true; } } str[index] = '\0'; }
【代碼四】
void RemoveDuplicates(char str[]){ int len = strlen(str); if(len < 2) return; int check = 0; int index = 0; //去重 for(int i=0; i<len; ++i){ int v = (int)(str[i]-'a'); if((check & (1<<v))==0){ str[index++] = str[i]; check |= (1<<v); } } str[index] = '\0'; }
最後更新:2017-04-03 12:56:33