每日一题——无重复字符的最长子串

321 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

题目描述

给定一个字符串 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 由英文字母、数字、符号和空格组成

思路

这道题我们可以使用滑动窗口的思想来解决,通读题目出现了重复字符,一旦涉及出现次数,需要用到散列表,在每次构造字串时,我们都将其存入HashSet中;涉及到字串问题,我们就可以考虑使用滑动窗口。

从前往后遍历每一个字符,在每次循环中将其加入到HashSet中,这里存储的是值本身,如果右指针的值没在set中出现,那么窗口开始移动知道出现重复字符,此时,整个窗口的长度就等于right - i + 1

image.png

代码

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int length = s.size();
        unordered_set<char> ans;
        if(length == 0) return 0;
        int right = -1, result = 0;
        for(int i = 0 ;i < length;i ++)
        {
            // 左指针向右移动一格,移除一个字符
            if(i != 0) ans.erase(s[i - 1]);
            
            while(right + 1 < length && !ans.count(s[right + 1]))
            {
                ans.insert(s[++ right]);// 不断移动右指针
                
            }
            result = max(result,right - i + 1);
        }
        return result;
    }
};