字符串————滑动窗口

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

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

示例 1:

输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

代码:

class Solution {

public:

    int lengthOfLongestSubstring(string s) {

        unordered_set<char> str;//创建一个set容器,方便查找已在字串中的元素

        int n=s.size();

        int length=0;

        int left=0;//作为左游标,当前i与left之间的元素个数就是字串的长度,移动左游标直到字串无重复元素

        for(int i=0;i<n;i++)

        {

            while(str.find(s[i])!=str.end())//查找str[i],若容器中不存在与s[i]相同的元素,返回end()

            {

                str.erase(s[left]);//容器中存在与s[i]相同的,left+1窗口缩小一个单位

                left++;

            }

            length=max(length,i-left+1);

            str.insert(s[i]);

        }

        return length;

        //核心思想,利用一个可变大小的窗口,窗口储存当前子串,从左至右,当出现相同元素时,说明窗口已经不能继续增长,改变窗口左端,继续检测,直到窗口内无重复元素

    }

};

思路:

这道题主要用到思路是:滑动窗口

什么是滑动窗口?

其实就是一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列!

如何移动?

我们只要把队列的左边的元素移出就行了,直到满足题目要求!

一直维持这样的队列,找出队列出现最长的长度时候,求出解!

时间复杂度:O(n)

下面介绍关于滑动窗口的万能模板,可以解决相关问题,相信一定可以对滑动窗口有一定了解!

模板虽好,还是少套为好!多思考!更重要!

还有类似题目有:

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

class Solution:
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        from collections import defaultdict
        lookup = defaultdict(int)
        start = 0
        end = 0
        max_len = 0
        counter = 0
        while end < len(s):
            if lookup[s[end]] > 0:
                counter += 1
            lookup[s[end]] += 1
            end += 1
            while counter > 0:
                if lookup[s[start]] > 1:
                    counter -= 1
                lookup[s[start]] -= 1
                start += 1
            max_len = max(max_len, end - start)
        return max_len

76. 最小覆盖子串

class Solution:
    def minWindow(self, s: 'str', t: 'str') -> 'str':
        from collections import defaultdict
        lookup = defaultdict(int)
        for c in t:
            lookup[c] += 1
        start = 0
        end = 0
        min_len = float("inf")
        counter = len(t)
        res = ""
        while end < len(s):
            if lookup[s[end]] > 0:
                counter -= 1
            lookup[s[end]] -= 1
            end += 1
            while counter == 0:
                if min_len > end - start:
                    min_len = end - start
                    res = s[start:end]
                if lookup[s[start]] == 0:
                    counter += 1
                lookup[s[start]] += 1
                start += 1
        return res

159. 至多包含两个不同字符的最长子串

class Solution:
    def lengthOfLongestSubstringTwoDistinct(self, s: str) -> int:
        from collections import defaultdict
        lookup = defaultdict(int)
        start = 0
        end = 0
        max_len = 0
        counter = 0
        while end < len(s):
            if lookup[s[end]] == 0:
                counter += 1
            lookup[s[end]] += 1
            end +=1
            while counter > 2:
                if lookup[s[start]] == 1:
                    counter -= 1
                lookup[s[start]] -= 1
                start += 1
            max_len = max(max_len, end - start)
        return max_len

340. 至多包含 K 个不同字符的最长子串

class Solution:
    def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int:
        from collections import defaultdict
        lookup = defaultdict(int)
        start = 0
        end = 0
        max_len = 0
        counter = 0
        while end < len(s):
            if lookup[s[end]] == 0:
                counter += 1
            lookup[s[end]] += 1
            end += 1
            while counter > k:
                if lookup[s[start]] == 1:
                    counter -= 1
                lookup[s[start]] -= 1
                start += 1
            max_len = max(max_len, end - start)
        return max_len

滑动窗口题目:

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

30. 串联所有单词的子串

76. 最小覆盖子串

159. 至多包含两个不同字符的最长子串

209. 长度最小的子数组

239. 滑动窗口最大值

567. 字符串的排列

632. 最小区间

727. 最小窗口子序列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
字符串哈希滑动窗口是一种用于处理字符串的算法。它主要用于在给定的字符串中找到满足特定条件的子串。 在字符串哈希滑动窗口算法中,我们首先计算原始字符串的哈希值。然后,我们使用一个滑动窗口来遍历字符串,每次滑动一个固定长度的窗口。我们可以通过比较每个窗口内的子串的哈希值来判断是否满足条件。 具体而言,我们可以使用BKDRHash等哈希函数来计算字符串的哈希值。然后,我们枚举每个可能的起点,并使用滑动窗口来计算窗口内的子串的哈希值。通过比较窗口内的子串的哈希值,我们可以判断是否满足条件。 对于滑动窗口的移动,如果窗口内的子串满足条件,我们可以继续将窗口往右移动一个固定的长度。如果窗口内的子串不满足条件,我们将窗口的右边界移到最右端,并依次比较新窗口内的子串的哈希值。 综上所述,字符串哈希滑动窗口算法是通过计算字符串的哈希值,并使用滑动窗口来遍历字符串,以找到满足特定条件的子串。这个算法可以高效地处理字符串,并且能够应用于各种字符串相关的问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [String (字符串哈希+滑动窗口)](https://blog.csdn.net/weixin_43872264/article/details/107571742)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [【字符串hash+滑动窗口】String HDU - 4821](https://blog.csdn.net/qq_45599865/article/details/111143633)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值