三、滑动窗口问题

news/2024/5/20 9:45:19 标签: python, 算法, leetcode, 滑动窗口

leetcode.cn/problems/longest-substring-without-repeating-characters/?envType=study-plan-v2&envId=top-100-liked" rel="nofollow">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 由英文字母、数字、符号和空格组成

题目思路

对于这道题,要求是找到最长连续的、不包含重复字符的字符子串。

经过观察思考我们可以得知,可以通过滑动窗口的方法来寻找这样的答案。

这里,子串的条件是不能包含重复的字符,因此首先在遍历时,我们可以定义一个哈希表来保存对应字符所处位置,方便查看当前字符是否在子串中。

同时,定义leftright指针,分别作为滑动窗口的左右两端,因此子串长度就是right - left

right从左到右遍历时,对于s[right]

  • 如果该字符未曾出现、或出现的位置在当前子串左边,那么该字符可以作为
  • 否则,就对left指针进行更新——即更新到对应已重复字符的下一个位置,将重复排除掉;
  • 最后,每轮循环都需要记录或刷新当前字符的位置;

算法代码

python3">class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        letter_index_map = {}
        left, right = 0, 0
        max_length = 0
        while right < len(s):
            curr_letter_index = letter_index_map.get(s[right])
            # 说明当前字符要么从未出现、要么在当前子序列之前出现
            if curr_letter_index is None or curr_letter_index < left:
                max_length = max(max_length, right - left + 1)
            else:
                left = curr_letter_index + 1
            # 记录/刷新当前字符所在位置
            letter_index_map[s[right]] = right
            right += 1
        return max_length

leetcode.cn/problems/find-all-anagrams-in-a-string/?envType=study-plan-v2&envId=top-100-liked" rel="nofollow">438、找到字符串中所有字母异位词(中等)

题目描述

给定两个字符串 sp,找到 s 中所有 p异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

异位词 指由相同字母重排列形成的字符串(包括相同的字符串)。

示例 1:

输入: s = “cbaebabacd”, p = “abc”
输出: [0,6]
解释:
起始索引等于 0 的子串是 “cba”, 它是 “abc” 的异位词。
起始索引等于 6 的子串是 “bac”, 它是 “abc” 的异位词。

示例 2:

输入: s = “abab”, p = “ab”
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 “ab”, 它是 “ab” 的异位词。
起始索引等于 1 的子串是 “ba”, 它是 “ab” 的异位词。
起始索引等于 2 的子串是 “ab”, 它是 “ab” 的异位词。

提示:

  • 1 <= s.length, p.length <= 3 * 104
  • s 和 p 仅包含小写字母

题目思路

所谓的异位词,在哈希问题中已有说明: 49、字母异位词分组
在该问题中,既可以直接对单词进行排序来判断。

在这道题中,这里如果直接去排序的话,需要排序的次数就太多了,例如如果s长度是10,p长度是3,那么至少要排序7+1次,更不用说s和p的长度可能会非常大。

因此,另一种方法则是字母计数,只需要使用ASCII码作为索引构造哈希表,然后统计字母出现次数,最后对比两个哈希表是否相同,就可以知道两个单词是否是字母异位词了。

在这道题中,本质上就是以p的长度划定一个滑动窗口,每向右移动一位时:

  • 窗口最左侧字符去掉,因此该字符的计数-1;
  • 窗口最右侧字符新增,因此该字符的计数+1;
  • 如果此时的s_counterp_counter是否相同,就将对应索引加入结果中;

需要注意的是,在滑动前,我们自然是要有已经构造好的窗口,因此定义两个字母哈希表s_counterp_counter

  • s_counter,记录滑动过程中,s字符子串字符出现次数;
  • p_counter,不变量,记录p的字符出现次数,相当于模板;

同时,因为所谓遍历,本质上就是开始滑动窗口,因此构造完s_counterp_counter后,需要首先做一下判断,看下第一个滑动区间是否满足条件。

算法代码

python3">class Solution:
    def findAnagrams(self, s: str, p: str) -> List[int]:
        s_len, p_len = len(s), len(p)
        if s_len < p_len:
            return []

        s_counter = [0] * 26
        p_counter = [0] * 26

        total_anagrams_idx = []
        for i in range(p_len):
            s_counter[ord(s[i]) - ord('a')] += 1
            p_counter[ord(p[i]) - ord('a')] += 1

        # 第一个滑动区间单独判断
        if s_counter == p_counter:
            total_anagrams_idx.append(0)

        for i in range(s_len - p_len):
            # 滑动一位,去掉左侧字符,新增右侧字符
            s_counter[ord(s[i]) - ord('a')] -= 1
            s_counter[ord(s[i + p_len]) - ord('a')] += 1

            if s_counter == p_counter:
                total_anagrams_idx.append(i + 1)

        return total_anagrams_idx

补充说明

所谓滑动窗口法,又称为“寸取法”,一般用来解决查找满足依一定条件的连续区间的特殊性质(长度等) 等一类问题

由于区间是连续的,因此当整个区间发生变化时,可以通过对旧有的计算结果对搜索空间的剪枝(一般就是滑动窗口最左侧滑出的部分),从而减少了重复计算、降低了时间复杂度、避免了暴力的搜索。

往往类似于“请找到满足xx条件的最x区间/子串/子数组”这一类问题都可以使用滑动窗口法来进行解决。


http://www.niftyadmin.cn/n/5384659.html

相关文章

网贷大数据查询多了对征信有影响吗?

网贷大数据在日常的金融借贷中起到很重要的风控作用&#xff0c;不少银行已经将大数据检测作为重要的风控环节。很多人在申贷之前都会提前了解自己的大数据信用情况&#xff0c;那网贷大数据查询多了对征信有影响吗?本文带你一起去看看。 首先要说结论&#xff1a;那就是查询网…

【初始RabbitMQ】死信队列的实现

死信的概念 死信&#xff0c;顾名思义就是无法被消费的消息&#xff0c;字面意思可以这样理解&#xff0c;一般来说&#xff0c;producer 将消息投递到 broker 或者直接到 queue 里了&#xff0c;consumer 从 queue 取出消息 进行消费&#xff0c;但某些时候由于特定的原因导致…

python opencv比较图片相似度

目录 一:均值哈希算法 二:三直方图算法 三:单通道直方图 一:均值哈希算法 均值哈希算法是一种快速比较图像相似度的方法。它首先将图像转化为灰度图像,然后计算图像的均值,接着将每个像素的

QT常用事件

鼠标事件&#xff08;QMouseEvent&#xff09;&#xff0c;如点击、移动、释放等。 键盘事件&#xff08;QKeyEvent&#xff09;&#xff0c;如按键按下和释放。 窗口事件&#xff08;QResizeEvent, QMoveEvent&#xff09;&#xff0c;当窗口大小或位置改变时。 绘制事件&…

Spring Cloud Gateway 中文文档

Spring Cloud Gateway 中文文档 官方文档 该项目提供了一个建立在Spring Ecosystem之上的API网关&#xff0c;包括&#xff1a;Spring 5&#xff0c;Spring Boot 2和Project Reactor。 Spring Cloud Gateway旨在提供一种简单而有效的方式来对API进行路由&#xff0c;并为他们提…

Unity摄像机跟随

Unity摄像机跟随 方法一&#xff1a;摄像机子物体 将摄像机直接拖拽到被跟随的目标下面即可&#xff0c;这样摄像机永远在目标的后面 缺点&#xff1a; 屏幕旋转太平滑了目标物体在屏幕上的位置永远不变目标物体被销毁时总不能把摄像机也销毁了吧 方法二&#xff1a;子物体…

laravel-admin的3个开发细节调整

在使用laravel-admin开发的过程中&#xff0c;根据官方开发文档Laravel admin | laravel-admin基本都能实现想要的效果&#xff0c;这里补充3个文档上没有描述的细节 Laravel8命令行创建控制器调整 在laravel-admin中可以使用php artisan admin:make UserController --modelAp…

攻防世界-web-Training-WWW-Robots

题目信息 In this little training challenge, you are going to learn about the Robots_exclusion_standard. The robots.txt file is used by web crawlers to check if they are allowed to crawl and index your website or only parts of it. Sometimes these files rev…