思路二:巢狀for,逐個排除
思路三:滑動視窗+hash
給定乙個字串,請你找出其中不含有重複字元的 最長子串 的長度剛開始的想法是:逐個檢查字串中的字元,並且在hash陣列中建立對映,與字元的ascii碼一一對應,通過檢查hash陣列中的標誌來判斷相同的字元是否出現過,如果已經出現,則記錄重複的字元並再次初始化hash,以重複的字元為起點重新檢查。
**:
但是會遇到提交錯誤如下:int
lengthoflongestsubstring
(char
* s)
else
// i++;}if
( count>count_max ) count_max = count;
return count_max;
}
原因是:我判斷重複之後,是直接以當前重複的字元為起點來進行計數的,實際中遇到
"***f"
這種情況,就會誤判為最長為"df"
,沒有從第乙個重複的字元處重新判斷!!!然後,我新增了乙個變數,用來記錄最近的重複字元的位置資訊,**如下:
然鵝,又出錯了。。。int
lengthoflongestsubstring
(char
* s)
;//memset( hash, 0, 150 );//初始化hash,全部為0
i=0;
for( i=
0; i<
strlen
(s); i++)if
( count>count_max ) count_max = count;
//記錄新的最大長度
count = i+
1- last;
hash[
*(s+i)]=
(1+i);
//更新位置
last = i+1;
//更新最近的重複字元的位置
}/* 不重複 */
else}if
( count>count_max ) count_max = count;
return count_max;
}
分析原因是,在連續兩次遇到重複字元的之後,如果兩次的重複字元不一樣,可以把當前遇到的重複字元算進去,這樣新**就如下:
實際上就是加了一行**:int
lengthoflongestsubstring
(char
* s)
;//memset( hash, 0, 150 );//初始化hash,全部為0
i=0;
for( i=
0; i<
strlen
(s); i++)if
( count>count_max ) count_max = count;
//記錄新的最大長度
count = i+
1- last;if(
*(s+i)!=*
(s+last-1)
) count++
; hash[
*(s+i)]=
(1+i);
//更新位置
last = i+1;
//更新最近的重複字元的位置
}/* 不重複 */
else}if
( count>count_max ) count_max = count;
return count_max;
}
if( *(s+i)!=*(s+last-1) ) count++;
,用來判斷當前重複字元是否是前乙個重複的字元,如果不同則可以計數。結果顯而易見,又錯了。。。
幸運的是,每一次改**,都是在不斷通過新的測試用例。
通過270個
放棄了,發現我的想法和滑動視窗的思想差不多,嘗試用滑動視窗演算法結合hash解題。int
lengthoflongestsubstring
(char
* s)
;//memset( hash, 0, 150 );//初始化hash,全部為0
i=0;
for( i=
0; i<
strlen
(s); i++)if
( count>count_max ) count_max = count;
//記錄新的最大長度
count = i+
1- last;if(
*(s+i)!=*
(s+last-1)
&&( hash[
*(s+i)
]< last )
) count++
;//當前重複字元是否和前乙個重複字元相同,如果不同則可以計數!前提是當前重複字元在上乙個重複字元之前
hash[
*(s+i)]=
(1+i);
//更新位置
last = i+1;
//更新最近的重複字元的位置
}/* 不重複 */
else}if
( count>count_max ) count_max = count;
return count_max;
}
這個演算法太莽了,不到萬不得已不採用!
視窗滑動演算法經常原來解決一些查詢滿足一定條件的連續區間的性質(長度)問題,類似於==「請找到滿足xx條件的最xx的區間(可以是子串、子陣列)的xx」==。所以,視窗滑動演算法是在乙個特定大小的字串上或者是乙個陣列上進行的操作,而不是對整個字串或者陣列進行操作,這樣就極大的降低了時間複雜度,降低了迴圈巢狀的深度。
**如下:
執行結果:int
lengthoflongestsubstring
(char
* s)
;//hash中存放字元的位置,hash的下標對應字元的ascii碼
if( s[0]
=='\0'
)for
( i=
0;s[i]
!='\0'
;i++
) hash[s[i]
]= i+1;
//更新位置
} count = i-start;
max_length = count>max_length?count:max_length;
return max_length;
}
(ps:為什麼相同的**,提交多次會有不一樣的結果?)
變數的意義:
思路:首先根據滑動視窗的思想,要遍歷字串,從最左端開始,逐個向右進行排查,每遇到乙個字元就在hash中查詢當前字元的上乙個位置,如果當前字元的上乙個位置在當前子串起始位置之前,就代表當前子串中沒有重複的字元(當前字元不重複),然後更新當前字元在hash中的位置。如果當前字元的上乙個位置在當前子串起始位置之後,就代表當前字元已經在子串中存在,意味著字元重複,終結不重複子串,所以要更新count,更新max_length,並且最重要的:將子串的起始位置移動到重複字元的上乙個位置上,開始下一輪子串計數。最後在遍歷完字串之後,再進行一次子串長度更新!
leetcode 3 無重複的字串
給定乙個字串,請你找出其中不含有重複字元的 最長子串 的長度。示例 1 輸入 abcabcbb 輸出 3 解釋 因為無重複字元的最長子串是 abc 所以其長度為 3。示例 2 輸入 bbbbb 輸出 1 解釋 因為無重複字元的最長子串是 b 所以其長度為 1。示例 3 輸入 pwwkew 輸出 3 ...
leetcode 3 無重複字元的最長字元子串
堅持打卡!題目 給定乙個字串,請你找出其中不含有重複字元的 最長子串 的長度。示例 1 輸入 abcabcbb 輸出 3 解釋 因為無重複字元的最長子串是 abc 所以其長度為 3。示例 2 輸入 bbbbb 輸出 1 解釋 因為無重複字元的最長子串是 b 所以其長度為 1。示例 3 輸入 pwwk...
leetcode 3 最長無重複字串
3.longest substring without repeating characters 題面 given a string,find the length of the longest substring without repeating characters.給定字串,找到最長無重複字...