c 求字串內無重複字元的最長子串
阿新 • • 發佈:2019-02-01
題目描述
分析
根據題意,最直接暴力的一種方法就是把所有子串都遍歷一遍,選出沒有重複字元且最長的子串即為結果。注意,本題只需要輸出最長子串的長度即可,無需內容。初版程式碼
int lengthOfLongestSubstring(char* s) {
int len=strlen(s);
int count=0;
bool isOk=true;
char *tempS;
tempS=(char *)malloc(len);
int longLastIndex=0; //用來輸出最長子串的,但本題中無需用到它
int longLenth=0 ;
for(int i=0;i<len;){
isOk=true;
for(int j=0;j<count;j++){
if(tempS[j]==s[i]){
isOk=false;
break;
}
}
if(isOk){
tempS[count++]=s[i++];
if(i==len&&longLenth<count){
longLastIndex=i;
longLenth=count ;
}
}
else{
if(longLenth<count){
longLastIndex=i;
longLenth=count;
}
i=i-count+1;
count=0;
}
}
return longLenth;
}
- 改進優化
上述程式碼的實現就如分析裡所說,遍歷了所有子串來找結果。事實上,做了很多重複性的工作,比如說字串“abcabcbb”,當第四位‘a’字元不符合時,又從第2位(i-count+1)字元‘b’開始找,但其實我們在上一輪的時候,就已經比較過‘b’和‘c’了。針對此,我們可以得到更高效的程式碼,如下:
int lengthOfLongestSubstring(char* s) {
int len=strlen(s);
int count=0;
int start=0; //記錄新子串的起始位置
bool isOk=true;
//char *tempS;
//tempS=(char *)malloc(len); 無需額外的陣列來儲存
int longLastIndex=0;
int longLenth=0;
for(int i=0;i<len;i++){
isOk=true;
for(int j=0;j<count;j++){
if(s[j+start]==s[i]){ //改動處
isOk=false;
start=j+start+1; //改動處
break;
}
}
if(isOk){
count++;
if(i==len-1&&longLenth<count){
longLenth=count;
}
}
else{
if(longLenth<count){
longLenth=count;
}
count=i-start+1; //改動處
}
}
return longLenth;
}
該優化的核心思想是用一個start變數記錄下發生不滿足條件(即子符相同的)位置,那麼從start位置到達當前i變數所在的位置之間的子符,便是上一輪匹配中,滿足條件的子符,無需再回溯,直接記下其個數再接著匹配就好。