給定一個字串,找出不含有重複字元的最長子串的長度。
示例: 給定 "abcabcbb" ,沒有重複字元的最長子串是 "abc" ,那麼長度就是3。
給定 "bbbbb" ,最長的子串就是 "b" ,長度是1。
給定 "pwwkew" ,最長子串是 "wke" ,長度是3。請注意答案必須是一個子串,"pwke" 是 子序列 而不是子串。
思路:
- 從字串第一個元素起,從左到右獲取子串。
- 每前進一個字元(下標為j),就在當前子串中查詢是否存在與當前字元重複的字元,如果存在(重複字元的下標為i),那麼能確定一個包含不重複字元的子串,其長度為j - i 對比已儲存的最大長度並把兩者的最大值儲存。
- 現在下一個子串的起點為當前重複的字元下標j.重複執行2、3操作,直到最後一個字元。
其實這是滑動視窗的思路。左閉右開。
int lengthOfLongestSubstring(char* s) {
int len = strlen(s);
//長度為0 的情況的處理
if(len == 0) return 0;
int max = 1;
int statrIndex = 0;
for (int i = 1; i < len; i ++) {
char subStr = s[i];
for(int j = statrIndex; j <i; j ++)
{
char ssubStr = s[j];
//如果找到重複字串
if (subStr == ssubStr ) {
if (max < i - statrIndex) {
max = i - statrIndex;
}
statrIndex = j + 1;
break;
}
}
//長度沒新增一位,更新最大值
if (max < i + 1 - statrIndex) {
max = i + 1 - statrIndex;
}
}
return max;
}
複製程式碼
其他解法:
//每個字元都有唯一字串ASCII的作為唯一標識,這是個技巧性問題。最多256個
int lengthOfLongestSubstring(char* s) {
//演算法:用book標記出現過的字元的index,用max標記最大長度,用start標記當前不重複開始的index,用num表示當前不重複的個數
//遍歷陣列,若book[]大於start,說明遇到相同元素,則從其相同處重新計算長度和起始位置
if(NULL == s)
return NULL;
int len=strlen(s);
int book[255]={0};
//memset(book,0xff,255*sizeof(int));//將book初始化為-1
if (0==len)
return 0;
int start=0,max=0;//max_start=0;
int num=0;
for (int i=0;i<len;i++)
{
if(book[s[i]]==0 || book[s[i]]<start+1)
{
num++;
if(num>max)
{
//max_start=start;
max=num;
}
book[s[i]]=i+1;
}
else
{
start=book[s[i]];
num=i-start+1;
book[s[i]]=i+1;
}
}
return max;
}
複製程式碼
//寫得好屌啊
int lengthOfLongestSubstring(char* s) {
int len=0;
char *end=s,*temp;
char* addressTable[128]={NULL};
while(*end){
temp = addressTable[*end];
addressTable[*end]=end;
if(temp>=s){
len=end-s>len?end-s:len;
s = temp+1;
}end++;
}
len=end-s>len?end-s:len;
return len;
}
複製程式碼
小結:這裡又存在查詢問題,可以考慮使用雜湊Map提高效率。
待完善....