今天突然发现leetcode有中文版了,名字叫领扣,牛逼牛逼,中文版最大的好处在于题目理解更快,并且页面载入的速度会快很多,并且中文版和英文版的数据库还没有合并,楼主相当于重新刷一遍,因此之后的都以中文为主,废话少说,上题目与解答
给定一个字符串,找出不含有重复字符的最长子串的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 无重复字符的最长子串是 "abc",其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 无重复字符的最长子串是 "b",其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 无重复字符的最长子串是 "wke",其长度为 3。
请注意,答案必须是一个子串,"pwke" 是一个子序列 而不是子串。
这道题目题意说的很清楚了,很粗暴的想法使用变化大小的滑窗去做,遍历滑窗的大小,对于某个大小的滑窗,使用hashmap或者set看是否存在重复的元素,这样的复杂度是O(n^2)。
显然这种做法不是我们想要的,这道题和楼主前几天一个面试中的问题类似,题目是找寻一个数组中,最大的连续子数组,要求子数组的和大于某个数。输入是数组与大于的数,输出是数组,那道题目的解法是两个指针,这里也类似,使用两个指针。
方法:
- 设立两个指针l与r,或者不叫指针叫index
- 维护一个unordered_map<char, int>中包含[l,r]之间的元素出现的次数
- 一旦l等于r或者r指向的元素次数为0,unordered_map中的计数增加,并且r右移
- 一旦r指向的元素次数不为0,unordered_map相应元素计数减少,l右移
O(n)复杂度即可
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_map<char, int> m;
for(int i = 0; i < s.size(); ++i){
m[s[i]] = 0;
}
int l = 0, r = 0, res = 0;
while(r < s.size() && l < s.size()){
if(l == r || m[s[r]] == 0){
m[s[r]]++;
++r;
}else if(m[s[r]] >= 0){
m[s[l]]--;
++l;
}
res = max(res, r - l);
}
return res;
}
};
欢迎小伙伴投票?,欢迎留言讨论
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。