【LeetCode】3. 无重复字符的最长子串

链接:

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;
    }
}
posted @ 2020-06-07 19:18  CrazyBlogs  阅读(69)  评论(0编辑  收藏  举报