[leetcode] 面试经典 150 题——篇3:滑动窗口

[leetcode] 面试经典 150 题——篇3:滑动窗口

    • 方法概述
      • 基本原理
      • 适用场景
      • 示例说明
    • 1. [中等] 长度最小的子数组(leetcode 209题)
      • 题目描述
      • 解题思路
      • python代码
    • 2. [中等] 无重复字符的最长子串(leetcode 5题)
      • 题目描述
      • 解题思路
      • python代码

方法概述

滑动窗口是一种常用的算法技巧,特别适用于需要在数组或序列上找到满足某些条件的子数组(或子串)的问题。它通过维护一个动态大小的“窗口”来遍历整个序列,并根据问题的要求调整这个窗口的大小和位置,从而高效地解决问题。以下是滑动窗口的基本原理:

基本原理

  • 定义窗口:窗口通常由**两个指针(也称为边界)定义,这两个指针可以指向数组中的任意两个元素,形成一个范围。窗口内的元素是当前正在处理的数据集。
  • 扩展窗口:通过移动右指针(通常是向右),逐步增加窗口的大小,将更多的元素包含进窗口内。在这个过程中,可以根据需要更新窗口内的状态(例如,总和、乘积等)。
  • 收缩窗口:当窗口满足某个条件时(比如窗口内的元素总和超过了目标值),可以通过移动左指针来缩小窗口,移除一些不再需要的元素。这样可以在保持窗口内满足条件的同时,尝试找到更优解(如最小长度的子数组)。
  • 重复上述过程:直到右指针遍历完整个数组或序列。在此过程中,不断根据题目要求更新最优解。

适用场景

滑动窗口技术非常适合于以下几类问题:

  • 寻找满足某些条件的连续子数组或子串
  • 需要在序列中寻找最大/最小的连续部分,比如最大和子数组、最小和子数组长度等。
  • 涉及到固定大小或可变大小的窗口操作,比如限制窗口内的唯一字符数、元素之和等。

示例说明

以寻找和大于等于给定目标值的最小长度子数组为例:

  • 初始化窗口为数组的第一个元素,左右指针均指向数组的起始位置。
  • 不断移动右指针扩大窗口,直到窗口内所有元素的和首次大于或等于目标值。
  • 然后尝试移动左指针缩小窗口,同时检查是否仍然满足条件。如果满足,则记录当前窗口的长度并继续尝试缩小窗口;如果不满足,则停止缩小窗口,再次移动右指针。
  • 重复上述步骤直到右指针到达数组末尾。

这种方法能有效地减少不必要的计算,时间复杂度通常为 O(n),因为每个元素最多只会被访问两次(一次通过右指针,另一次通过左指针)。这使得滑动窗口成为解决这类问题的一种非常有效的方法。


1. [中等] 长度最小的子数组(leetcode 209题)

题目描述

给定一个含有 n 个正整数的数组和一个正整数 target
找出该数组中满足其总和大于等于target 的长度最小的 子数组 [nums_l, nums_l+1, ..., nums_r-1, nums_r] ,并返回其长度。如果不存在符合条件的子数组,返回 0

示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:
输入:target = 4, nums = [1,4,4]
输出:1
示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

解题思路

要解决这个问题,我们可以使用滑动窗口(双指针)的技术。这个方法可以有效地找到满足条件的最小子数组长度,而不需要对每个可能的子数组进行两两比较。下面是具体步骤:

  • 初始化两个指针 left 和 right 来表示当前处理的子数组的左右边界,同时初始化一个变量来记录当前窗口内的元素总和以及另一个变量来保存满足条件的最小子数组长度
  • 移动右指针扩展窗口,并将新加入的元素加到当前窗口的总和中。
  • 当窗口内元素的总和大于或等于目标值时,尝试收缩窗口(通过移动左指针),并在此过程中更新最小子数组长度。

重复上述过程直到遍历完整个数组。

python代码

def minSubArrayLen(target, nums):n = len(nums)left = 0current_sum = 0min_length = float('inf')  # 初始化最小长度为无穷大for right in range(n):current_sum += nums[right]  # 扩展窗口 while current_sum >= target:# 更新最小长度min_length = min(min_length, right - left + 1)# 收缩窗口current_sum -= nums[left]left += 1return min_length if min_length != float('inf') else 0
# 示例用法:
print(minSubArrayLen(7, [2,3,1,2,4,3]))  # 应输出 2

2. [中等] 无重复字符的最长子串(leetcode 5题)

题目描述

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

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

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

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

解题思路

  • 首先分辨子串和子序列的区别
    • 子串:s中出现的连续的一段
    • 子序列:s中出现的,不要求连续,但是相对位置关系不能变
  • 求满足某些条件的子串问题,考虑用双指针方法求解。需要考虑以下问题:
    • 如何维护 "子串内容不重复"这个条件
    • 左右指针分别指向哪里
    • 左指针移动的条件是什么,右指针移动的条件是什么
    • 程序终止的条件是什么
  • 考虑使用一个字典维护子串信息,key不可重复,根据元素有无在dict的key中判断元素是否出现过。左指针指向目标子串的左索引,右指针指向右索引;使用一个变量max_len表示最大子串;右指针取元素后,判断是否在dict中,不管是否存在,右指针都移动到下一个位置;如果右指针取元素后,不在dict中,则左指针不动,将元素保存到dict中,当右指针取到重复元素后,左指针移动到下一个位置,同样将元素保存到dict中;更新左右指针后,更新max_len值,max_len和(right - left + 1)相比取较大的值,当right遍历完毕s后,最后返回max_len

python代码

def length_of_longest_substring(s: str) -> int:char_map = {}  # 用来存储字符及其最新位置left = 0  # 窗口的左边界max_length = 0  # 记录最大长度for right in range(len(s)):if s[right] in char_map:  # 如果当前字符已经存在于char_map中,移动左指针left = max(left, char_map[s[right]] + 1) #更新左指针信息char_map[s[right]] = right  # 更新右指针信息max_length = max(max_length, right - left + 1)  # 更新最大长度return max_length# 示例调用
s = "abcabdcbb"
print(length_of_longest_substring(s))  # 输出应该是3,因为"abc"是不含重复字符的最长子串

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/36042.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++图论(二)之图的存储图解

在 C 中实现图的存储时,常用的方法包括 邻接矩阵(Adjacency Matrix)、邻接表(Adjacency List) 和 边列表(Edge List)。以下是具体实现方法、优缺点分析及代码示例: 1. 邻接矩阵&…

ABAP PDF预览

画个屏幕 PDF JPG TXT都可以参考预览,把二进制流传递给标准函数就行 *&---------------------------------------------------------------------* *& Report YDEMO2 *&---------------------------------------------------------------------* *&am…

Compose 的产生和原理

引言 compose 出现的目的: 重新定义android 上ui 的编写方式。为了提高android 原生ui开发效率。让android 的UI开发方式跟上时代。 正文 compose 是什么? 就是一套ui框架 和flutter 一样是一套ui框架 Flutter:跨平台开发趋势与企业应用的…

单口路由器多拨号ADSL实现方法

条件是多拨号场景,公司路由器接口不够用

H3C SecPath SysScan-AK 系列漏洞扫描系统

H3C SecPath SysScan-AK 系列是一款专业的漏洞扫描系统,旨在帮助组织和企业快速、准确地发现网络和系统中存在的安全漏洞。该系统具有以下特点: 1. 多样化的扫描能力:支持对各类网络设备、服务器、应用程序等进行漏洞扫描,能够全面…

[蓝桥杯 2023 省 B] 飞机降落

[蓝桥杯 2023 省 B] 飞机降落 题目描述 N N N 架飞机准备降落到某个只有一条跑道的机场。其中第 i i i 架飞机在 T i T_{i} Ti​ 时刻到达机场上空,到达时它的剩余油料还可以继续盘旋 D i D_{i} Di​ 个单位时间,即它最早可以于 T i T_{i} Ti​ 时刻…

Kafka详解——介绍与部署

1. 什么是 Kafka? Kafka 是一个分布式的消息队列系统,最初由 LinkedIn 开发,后来成为 Apache 开源项目。它的主要用途包括实时数据处理、日志收集、数据流管道构建等。Kafka 具备高吞吐量、可扩展性、持久性和容错性,广泛应用于大…

win10搭建opengl环境搭建并测试--输出立方体球体和碗型并在球体上贴图

参照本文档可以完成环境搭建和测试,如果想要快速完成环境的搭建可以获取本人的工程,包括所用到的工具链和测试工程源码获取(非免费介意务下载):链接: https://pan.baidu.com/s/1H2ejbT7kLM9ore5MqyomgA 提取码: 8s1b …

TCP、UDP协议的应用、ServerSocket和Socket、DatagramSocket和DatagramPacket

DAY13.1 Java核心基础 TCP协议 TCP 协议是面向连接的运算层协议,比较复杂,应用程序在使用TCP协议之前必须建立连接,才能传输数据,数据传输完毕之后需要释放连接 就好比现实生活中的打电话,首先确保电话打通了才能进…

如何在 GoLand 中设置默认项目文件夹

在使用 GoLand 进行开发时,设置一个默认的项目文件夹可以大大提高工作效率。默认项目文件夹会在你打开或新建项目时自动预选,避免每次都需要手动导航到目标目录。本文将详细介绍如何在 GoLand 中设置默认项目文件夹。 步骤一:打开系统设置 …

SvelteKit 最新中文文档教程(5)—— 页面选项

前言 Svelte,一个语法简洁、入门容易,面向未来的前端框架。 从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1: Svelte …

Mac下Ollama安装全攻略:开启本地大模型之旅

文章目录 Mac下Ollama安装全攻略:开启本地大模型之旅一、Ollama 是什么功能特点优势应用场景 二、安装前准备(一)系统要求(二)硬件要求 三、下载安装包(一)官网下载(二)其…

华为营销流程落地方案:MTC=MTL+LTC

目录 简介 MTC流程 作者简介 简介 只讲最本质的底层逻辑,交付可落地的方案。 作为一个主打实践的产品老炮,接下来我将结合自己的经验, 以华为系的这套流程为基准, 将涉及业务层次的流程全部重构一套本地化、落地化的方案。 …

vscode使用ssh同时连接主机CentOS:user和ubuntu20.04:docker

主机为CentOS docker为Ubuntu20.04 两者可以使用一个vscode远程链接 1.使用已拉取好的Ubuntu镜像建立docker容器 2.进入容器内,下载一些关于ssh的安装包 apt-get install vim apt-get install openssh-client apt-get install openssh-server apt-get install ssh passwd …

NFS网络文件共享服务

文章目录 1. NFS工作原理1.1 挂载结构介绍1.2 NFS的工作原理 2. NFS服务安装2.1 NFS软件列表2.2 启动NFS相关服务2.3 NFS服务常见进程2.4 实战配置NFS服务器端 3. NFS服务配置3.1 在NFS Server端执行的操作3.1.1 查看部署环境3.1.2 启动rpcbind及NFS服务,然后加入开…

《多语言实时交流辅助系统前端的设计与实现》开题报告

个人主页:大数据蟒行探索者 目录 一、选题目的与意义 1.选题目的 2选题意义 2.1技术挑战与创新 2.2市场需求 2.3促进文化交流 2.4教育应用 2.5社会影响 二、研究现状与文献综述 1.研究现状 2.文献综述 2.1 前端技术的发展与应用 2.2 自然语言处理技术…

SpringCloud网关:Gateway路由配置与过滤器链

文章目录 引言一、Gateway基本架构二、路由配置方式2.1 配置文件方式2.2 Java代码方式 三、内置断言工厂四、内置过滤器工厂4.1 请求路径相关过滤器4.2 请求和响应头过滤器4.3 功能性过滤器 五、自定义过滤器5.1 自定义GatewayFilter5.2 自定义过滤器工厂 六、全局过滤器总结 引…

咖啡点单小程序毕业设计(JAVA+SpringBoot+微信小程序+完整源码+论文)

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、项目背景介绍: 随着社会的快速发展和…

Excel(函数进阶篇):Vlookup函数进阶、TAKE嵌套SORE函数、SUBTOTAL函数、INDIRECT函数

目录 Vlookup函数返回多列结果Vlookup函数多条件匹配Vlookup函数部分匹配TAKE函数嵌套SORT函数,提取排序数据SUBTOTAL函数:制作动态报表SUBTOTAL函数:创建连续编号INDIRECT函数Vlookup跨多表抓取数据INDIRECT函数常见跨表的错误Vloopup函数联…

大模型 VS 传统算法:人工智能时代的“新老对话“

大模型 VS 传统算法:人工智能时代的"新老对话" 在AlphaGo击败李世石、ChatGPT掀起全民AI热潮的今天,人们往往将"大模型"与"算法"混为一谈。但当我们深入技术内核时会发现,这二者恰似人工智能发展的两个平行宇…