题目:无重复字符的最长子串
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
提示:
0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成
暴力解法思路
用一个string对象保存从下标 j 开始的不重复元素,当遇到重复元素则停止并记录不重复元素个数到maxSubLength中。
遍历字符串的第一个元素到最后一个元素重复上述操作,最终maxSubLength中保存了最大不重复子串的长度。
暴力解法代码:击败8.99%
class Solution {
public:
int lengthOfLongestSubstring(string s) {
string tailStr;
int maxSubLength = 0;
for (int i = 0; i < s.length(); i++) {
int j = i;
for (; j < s.length(); j++) {
size_t nLoc = tailStr.find(s[j]);
if (nLoc != string::npos) {
if (maxSubLength < j - i) {
maxSubLength = j - i;
}
break;
} else {
tailStr += s[j];
}
}
if (maxSubLength < j - i) {
maxSubLength = j - i;
}
tailStr.clear();
}
return maxSubLength;
}
};
优化:滑动窗口思想
采用滑动窗口思想,右指针向右滑动直到出现重复,左指针在出现重复时向右滑动直到不出现重复,继续右指针向右滑动…
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int left = 0;
int right = 0;
int curentLength = 0;
int maxLength = 0;
set<char> subString;
while (right < s.length()) {
if (subString.count(s[right]) == 0) {
subString.insert(s[right]);
curentLength++;
if (curentLength > maxLength) {
maxLength = curentLength;
}
right++;
} else {
while(subString.count(s[right]) != 0) {
subString.erase(s[left]);
left++;
curentLength--;
}
subString.insert(s[right]);
curentLength++;
right++;
}
}
return maxLength;
}
};
总结
暴力解法是双重遍历 + 记录不重复元素
滑动窗口是左右指针滑动,滑动规则是右指针向右滑动直到出现重复,左指针在出现重复时向右滑动直到不出现重复。
谢谢观看,祝顺利!