无重复字符的最长子串(leetcode-3)
题目
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。请注意,你的答案必须是子串的长度,"pwke" 是一个子序列,不是子串。
思路
双指针法。看到这种“连续”、“最大”、“最长”的就应该想到双指针。双指针是专门用来解决最长的序列的一系列问题的。
双指针其实也是一种贪心。主要思想是:用一个指针(左指针)指向最左边,另一个指针(右指针)从第一个元素开始遍历。两个指针夹起来的部分就是一个子串。只要这个子串没有相同字符,那么右指针就一直右移。直到,右指针的字符重复了,那么左指针右移。这就相当于,将左边的长度缩短。然后重复上述操作。
这种贪心是对的,因为如果最短的子串都不满足要求,那么更大的子串一定不满足(仔细想想应该能想出来)。
代码
# include <iostream>
# include <string>
# include <algorithm>
# include <unordered_set>
using namespace std;
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int lp = 0, rp = 0;
int ans = 0;
unordered_set <char> unique_set;
// 左指针指向
while (lp < s.size())
{
// 右边能走就一直走
while (unique_set.find(s[rp]) == unique_set.end() && rp < s.size())
unique_set.insert(s[rp++]);
// 不能就删除左边一个
ans = max(ans, (int)unique_set.size());
unique_set.erase(s[lp++]);
}
return ans;
}
};
int main() {
Solution a = Solution();
printf("%d\n", a.lengthOfLongestSubstring("abcabcbc"));
printf("%d\n", a.lengthOfLongestSubstring("bbbbbb"));
printf("%d\n", a.lengthOfLongestSubstring("pwwkew"));
}

浙公网安备 33010602011771号