题意:给你一个字符串,找到里面不包含相同字符的最长子串。
解题思路:
思路一:暴力,(loop1)从第一个字符开始,(loop2)字符数量从1到n,(loop3)判断每个子串是否符合条件。时间复杂度为O(n * n * n)。
思路二:sliding window,滑动窗口。(loop1)从第一个字符开始,依次处理每个字符,(loop2)判断当前子串是否包含该字符,若包含,则将子串中该字符及前面的去掉,然后在尾部插入该字符;若不包含,直接在尾部插入该字符。时间复杂度为O(n * n)
思路三:sliding window optimal,优化的滑动窗口。使用map容器或者vector容器,由于容器对查找操作十分友好,set.count(key)与map[key]查找key的操作时间复杂度都是O(1),所以选用map存储字符串与位置信息,map[char] = int.
class Solution {
public:
int lengthOfLongestSubstring(string s) {
map<char, int> imap;
int i = 0, j = 0, n = s.size(), ans = 0;
while(i < n && j < n){
if(imap.count(s[j]))
i = max(i, imap[s[j]] + 1);
imap[s[j]] = j++;
ans = max(ans, j - i);
}
return ans;
}
};
值得注意的地方是,当imap中存在s[j]字符时,坐标位置有可能在窗口开始位置i之前,那么此时imap中存在该字符,对窗口长度没影响,直接给imap[s[j]]重新赋值新的位置即可。
窗口起始位置 i = max(i, imap[s[j]] + 1);