Leetcode - longest-substring-without-repeating-characters
題目
<https://leetcode.com/problems/longest-substring-without-repeating-characters>
題意
給出一個字符串,求每個字符都不相同的最長子串長度。
現在題目要求我們求出這兩個數的和。
Example 1:
Input: "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.
思路
錯誤的思路
二分 + Hash
1、既然要找每個字符都不相同的最長子串長度,那麽便可以使用二分思想。首先取中值,假如當前中值是存在每個字符都不相同的子串的,說明應該搜索右邊的區間。否則,搜索左邊區間。這個二分答案的時間復雜度大概是O(log n)。
2、這裏還涉及如何判斷是否存在長度為K的不相同子串。我的想法是,拿出每一個子串,然後對每個子串使用Hash思想,對字符出現次數進行統計,若有出現2次的字符,那麽說明該子串不成立。若遇到一個全部只出現1次的,那麽就終止搜索。這一步的時間復雜度是O(n^2)
很可惜,一共900多個樣例,最後一個超時了!
正確的思路
滑動窗口
看了題解,才發現大佬的做法真牛P。他的時間復雜度是O(n)。
大概思路是:維護一個字符串不相同的區間,下面把它稱為一個窗口。這個窗口只包含互不相同的連續字符。
具體的做法是:設定該區間的左右區間分別是i,j。然後從左到右遍歷字符串,對於每一個新來的字符,先判斷該字符是否在區間內出現了。
(1)若出現了,說明區間+新字符
形成的新字符串
是存在重復字符的。那麽不應該將字符加入該區間(窗口不應該向右擴增),而且應該將區間的左邊界收縮(窗口左邊往右收縮),直到對於新字符來說,區間內不存在重復字符。(該區間要時刻保證,只包含互不相同的連續字符)
(2)若沒在區間內出現過,說明當前存在更長的不相同的子串。故將該字符加入區間(窗口向右擴增),並且更新最大值。
正確的代碼
該代碼是參考題解寫的。
class Solution { public: int lengthOfLongestSubstring(string s) { int a[256]; int n = s.length(); memset(a, 0, sizeof(int)*256); int i = 0;//“不相同子串”的左區間 int j = 0;//“不相同子串”的右區間 int ans = 0; while(i<n && j<n){ //如果新的字符沒有在“不相同子串”中出現,說明有更大的不相同子串。 if(a[s[j]] == 0){ a[s[j]] = 1; j++; ans = max(ans, j-i); } else{ a[s[i]] = 0; i++; } } return ans; } };
錯誤的代碼
該代碼是辣雞我寫的,有1個樣例超時了。
class Solution {//toulanboy
public:
int lengthOfLongestSubstring(string s) {
long long left = 0;
int right = s.length();
long long a[300];
while(left < right){
int mid = ceil((left + right)/2.0);
bool isExist = false;
//判斷是否存在長度為mid的互不相同的子串
for(int i=0; i+mid-1<s.length();++i){
if(isExist){
break;
}
memset(a, 0, sizeof(long long)*300);
for(int j=0; j<mid; ++j){
a[s[i+j]]++;
}
int sum = 0;
for(int j=0; j<300; ++j){
if(a[j] == 1)
sum += 1;
}
if(sum == mid)
isExist = true;
}
if(isExist){
left = mid;
}
else{
right = mid - 1;
}
}
return left;
}
};
運行結果
Runtime: 12 ms, faster than 99.84% of C++ online submissions for Longest Substring Without Repeating Characters.
Memory Usage: 9.2 MB, less than 99.68% of C++ online submissions for Longest Substring Without Repeating Characters.
Leetcode - longest-substring-without-repeating-characters