【测评中的编程题】最长不重复子串
题目:
给定一个字符串,求没有重复字母的最长连续子串。
思路:
一般求连续子串会想到双指针、滑动窗口,时间复杂度为O(2n)。
进一步优化,可将时间复杂度降到O(n)。当遇到重复字母时,需滑动左窗口,也就是要找到第一个重复字母,将左窗口设置为第一个重复字母右边的那个位置。优化办法就是记录每个字母的位置,遍历过程中保持子串不含重复字符,处理办法是根据重复字母来倒推左窗口将要移到的位置。
步骤如下:
1. 初始化recorde[],初始值为-1,表示所有26个字母均未出现
2. 初始化low,maxlen
3. 遍历字符串中的每个字母
1)判断每个字母是否与当前子串重复,如果重复则调整左窗口位置并更新maxlen
2)更新每个字母在字符串中的位置记录
1 size_t longest_unique_substr_len(const string& s) { 2 vector<size_t> recorde(26, -1); 3 size_t left = 0, maxlen = 0; 4 for (size_t i = 0;i != s.size();++i) { 5 size_t letter = s[i] - 'a'; 6 if (recorde[letter] != -1 && recorde[letter]>=left) { //字母letter已出现,且在当前子串范围内 7 maxlen = max(maxlen, i - left); 8 left = recorde[letter] + 1; //更新子串起始位置 9 } 10 recorde[letter] = i; //记录字母对应给定字符串的位置 11 } 12 return max(maxlen, s.size() - left); 13 }
源文件: