链接:
https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
描述:
给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是子串的长度,"pwke" 是一个子序列,不是子串。
int lengthOfLongestSubstring(string s) {}
思路:滑动窗口
使用两个指针表示滑动窗口 ([) (left) , (right) ())
开始位置 (left) 遍历整个字符串的过程中,
结束位置 (right) 从开始位置依次向后滑动,
滑动过程中,用哈希表检查窗口中是否存在重复字符,
如存在,就停止滑动,看是否更新最长滑动窗口的大小
C++
展开后查看
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int result = 0;
unordered_set<char> set;
int left, right;
for(left = 0; left < s.size(); left++){
for(right = left; right < s.size(); right++){
if(set.count(s[right]) == 0){
set.insert(s[right]);
}else{
break;
}
}
result = max(result, right - left);
set.clear();
}
return result;
}
};
Java
展开后查看
class Solution {
public int lengthOfLongestSubstring(String s) {
int result = 0;
Set<Character> set = new HashSet<Character>();
int left, right;
for(left = 0; left < s.length(); left++){
for(right = left; right < s.length(); right++){
if(!set.contains(s.charAt(right))){
set.add(s.charAt(right));
}else{
break;
}
}
result = Math.max(result, right - left);
set.clear();
}
return result;
}
}
优化:
例如,字符串为 abcabcbb。
第一步,开始位置为字符串的第一个字符,
不断滑动结束位置,当遇到重复字符就停止滑动。
此时,子字符串为 (abc)abcbb。
之后,开始位置会指向下一个字符, a(bc)abcbb。
此时,不必对结束位置调到开始位置,
因为,滑动窗口内的字符是不会存在重复字符的。
因此,调整开始位置后,结束位置继续从原来的位置开始滑动即可。
注意,调整开始位置前,不必清空哈希表,
从哈希表中删除原来开始位置的字符即可。
C++
展开后查看
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int result = 0;
unordered_set<char> set;
for(int left = 0, right = 0; left < s.size(); left++){
while(right < s.size() && set.count(s[right]) == 0){
set.insert(s[right]);
right++;
}
result = max(result, right - left);
set.erase(s[left]);
}
return result;
}
};
Java
展开后查看
class Solution {
public int lengthOfLongestSubstring(String s) {
int result = 0;
Set<Character> set = new HashSet<Character>();
for(int left = 0, right = 0; left < s.length(); left++){
while(right < s.length() && !set.contains(s.charAt(right))){
set.add(s.charAt(right));
right++;
}
result = Math.max(result, right - left);
set.remove(s.charAt(left));
}
return result;
}
}