LeetCode:3 无重复字符的最长子串 哈希表+双指针 O(n)

题目描述

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。

示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。

示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。

请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

用双指针指定一个区间[l, r],表示潜在的无重复字符的最长子串,用一个哈希表记录区间内字符的出现情况

每次循环,取区间右端点的字符,查询哈希表,查看其是否在区间[l, r-1]内(因为随着右端点的推进,哈希表储存的是之前的[l, r-1]的元素)

  • 如果不在,那么就加进哈希表,尝试更新答案,然后右指针r++
  • 如果在,那么就不断将左指针右移l++ 直到遇到与右端点相同的字符为止,并且每次右移时,在哈希表中删除左指针指向的元素(因为区间左端点移动了,那么必然有元素会被排除区间),最后区间右端点r++

代码

class Solution {
public:
    int lengthOfLongestSubstring(string s)
    {
        if(s.size()==0)
            return 0;
        unordered_set<char> hash;
        int l=0; int r=0; int ans=0;
        while(r<s.length())
        {
            auto it = hash.find(s[r]);
            if(it==hash.end())
            {
                hash.insert(s[r]);
                if(r-l+1>ans)
                    ans = r-l+1;
                r++;
            }
            else
            {
                while(s[l]!=s[r])
                {
                    l++;
                    hash.erase(s[l-1]);
                }
                l++;
                r++;
            }
        }
        return ans;
    }
};
发布了171 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44176696/article/details/104497673