力扣:3. 无重复字符的最长子串(滑动窗口)


3. 无重复字符的最长子串 - 力扣(LeetCode)3. 无重复字符的最长子串 - 给定一个字符串 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 由英文字母、数字、符号和空格组成https://leetcode.cn/problems/longest-substring-without-repeating-characters/

 思路:

1.定义一个右指针right= 一1,且right只遍历字符串一次

2.定义set集合,定义外层for循环,for循环的 就相当于左指针(左右指针之间就是一个窗口)

3.内层while循环,只要右边的字符在set集合没有出现过,就继续while循环(右指针right右移),扩大窗口

4.更新Max

注意:for循环里面要先把 左边的字符从set集合移除,因为每循环一次,i会加1(左指针右移),缩小窗口

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        // set集合,记录每个字符是否出现过
        unordered_set set;
        int n = s.size();
        // 右指针,初始值为 -1,相当于在字符串的左边界的左侧
        int right = -1, Max = 0;
        for (int i = 0; i < n; i++) {
            if (i != 0) {
                // 左指针向右移动一格(就是for循环的i++),把左指针指向的字符从set集合移除
                set.erase(s[i - 1]);
            }
            // 如果不越界且右边字符不在set里面,就移动右指针
            while (right + 1 < n && !set.count(s[right + 1])) {
                set.insert(s[right + 1]);
                right++;
            }
            //更新Max
            Max = max(Max, right - i + 1);
        }
        return Max;
    }
};

你可能感兴趣的:(力扣刷题,leetcode,算法)