LeetCode - 双指针(Two Pointers) 算法集合 [对撞指针、快慢指针、滑动窗口、双链遍历]

欢迎关注我的CSDN:https://spike.blog.csdn.net/
本文地址:https://spike.blog.csdn.net/article/details/139270999

Two Sum

双指针算法是一种常见且灵活的技巧,通过使用两个指针协同完成任务。这些指针可以指向不同的元素,具体应用取决于问题的性质。双指针算法的常见用法:

  1. 对撞指针:一左一右向中间逼近。例如,反转字符串中的元音字母问题,可以使用对撞指针。
  2. 快慢指针:一快一慢,步长不同。例如,判断链表中是否有环问题,可以使用快慢指针,看慢指针是否能追上快指针。单链表找中间节点问题也可以用快慢指针,快指针到链表结尾,慢指针到一半。
  3. 滑动窗口:类似计算机网络中的滑动窗口。一般是右端向右扩充,达到停止条件后右端不动,左端向右端逼近,逼近达到停止条件后,左端不动,右端继续扩充。

双指针算法包括:对撞指针快慢指针滑动窗口双链遍历

  1. 167. 两数之和 II - 输入有序数组 - 对撞指针
  2. 633. 平方数之和 - 对撞指针,题目167变种
  3. 680. 验证回文串 II - 对撞指针,需要判断去除1个字符 l+1 或 r-1
  4. 15. 三数之和 - 两数之和的进阶版,先排序,逐步修改序列
  5. 142. 环形链表 II - 快慢指针
  6. 76. 最小覆盖子串 - 滑动窗口,Counter类的使用
  7. 88. 合并两个有序数组 - 双链遍历
  8. 524. 通过删除字母匹配到字典里最长单词 - 双链遍历,优先排序,再依次比较。

1. 对撞指针

167. 两数之和 II - 输入有序数组 - 对撞指针

class Solution:def twoSum(self, numbers: List[int], target: int) -> List[int]:"""时间复杂度O(n),空间复杂度O(1)"""# 输入的已经排序n=len(numbers)  # 数量l,r=0,n-1  # 左右指针while l<r:v=numbers[l]+numbers[r]  # 两数之和if v>target: # 移动指针r-=1elif v<target:l+=1else:return [l+1,r+1]

633. 平方数之和 - 对撞指针,167变种

class Solution:def judgeSquareSum(self, c: int) -> bool:"""时间复杂度 O(n),空间复杂度 O(1)"""# 左右指针l, r = 0, int(sqrt(c))while l <= r:  # 遍历条件需要相等# 计算值v = pow(l, 2) + pow(r, 2)if v > c:  # 移动右指针r -= 1elif v < c:  # 移动左指针l += 1else:return Truereturn False

680. 验证回文串 II - 对撞指针,需要判断去除1个字符 l+1 或 r-1

class Solution:def validPalindrome(self, s: str) -> bool:"""时间复杂度 O(n), 空间复杂度 O(1)"""def check(l, r):"""检查s是否是回文"""while l < r:if s[l] == s[r]:l += 1r -= 1else:return Falsereturn Truen = len(s)l, r = 0, n-1  # 左右指针while l < r:if s[l] == s[r]:  # 回文l += 1r -= 1else:# 越过1个值,最多可以从中删除一个字符return check(l+1, r) or check(l, r-1)return True

15. 三数之和 - 两数之和的进阶版,先排序,逐步修改序列

class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:"""时间O(N^2),空间O(logN) -> 排序"""def two_sum(nums, t):"""经典的两数之和,同时,避免重复添加"""n = len(nums)l, r = 0, n-1res = []while l < r:x = nums[l] + nums[r]if x > t:r -= 1elif x < t:l += 1else:sr = [nums[l], nums[r], -t]if sr not in res:  # 避免重复添加res.append(sr)l += 1return resnums.sort()  # 排序n = len(nums)  # 序列长度res = []  # 输出结果for i in range(n):# 避免重复数字if i > 0 and nums[i-1] == nums[i]:continuet = nums[i]  # 依次遍历res += two_sum(nums[i+1:], -t)return res

2. 快慢指针

142. 环形链表 II - 快慢指针

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution:def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]:"""时间复杂度O(n),空间复杂度O(1)"""if not head:return None# 快慢指针先指向headslow=fast=head# 判断是否运行到结尾while fast.next and fast.next.next:slow=slow.next  # 移动1步fast=fast.next.next  # 移动2步if slow==fast:fast=head # fast从head开始重新计数while slow!=fast:  # 移动到位置slow=slow.nextfast=fast.nextreturn fast # 相等即返回return None

3. 滑动窗口

76. 最小覆盖子串 - 滑动窗口

class Solution:def minWindow(self, s: str, t: str) -> str:"""时间复杂度 O(m+n),空间复杂度 O(1)"""rl,rr=-1,len(s) # 目标的最大窗口l=0  # 左指针cnt_s=Counter()  # 计数器字典cnt_t=Counter(t) # 目标计数器字典less=len(cnt_t)  # 不重复的t字母数量for r,c in enumerate(s):cnt_s[c]+=1  # s计数器if cnt_s[c]==cnt_t[c]:  # 数量相等less-=1  # 数量减一while less==0:  # 满足条件if r-l < rr-rl:  # 区间更小rl,rr=l,r  # 更新左右指针# -----# 如果数量相等,之后数量需要减一,所以less需要提前+1x=s[l]  # 左指针当前字母if cnt_s[x]==cnt_t[x]:  less+=1  # 不重复+1cnt_s[x]-=1  # 指针减1l+=1  # 已经更新,所以需要移动左指针# -----return "" if rl<0 else s[rl:rr+1]

4. 双链遍历

88. 合并两个有序数组 - 双链指针

class Solution:def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:"""Do not return anything, modify nums1 in-place instead.时间复杂度 O(n),空间复杂度 O(1)"""pos=(m-1)+(n-1)+1  # 最远位置m-=1  # 最后位置n-=1  # 最后位置while m>=0 and n>=0:  # 遍历两个数组# 注意: 大于等于确保,优先移动mif nums1[m]>=nums2[n]:nums1[pos]=nums1[m]  # 赋值大值m-=1else:nums1[pos]=nums2[n]n-=1pos-=1  # 移动指针while n>=0: # 优先移动m,所以剩下的就是nnums1[pos]=nums2[n]pos-=1n-=1

524. 通过删除字母匹配到字典里最长单词 - 双链指针,优先排序,再依次比较。

class Solution:def findLongestWord(self, s: str, dictionary: List[str]) -> str:"""d 是字典长度,m 是s长度时间复杂度 O(d x (m+n)),空间复杂度 O(d x m)"""# 按目标结果排序,优先做前面的words = sorted(dictionary, key=lambda x: (-len(x), x))for t in words:i = j = 0  # 双指针while i < len(t) and j < len(s): # 双指针遍历if t[i] == s[j]:  # 相同i += 1  # t指针+1,满足条件j+=1  # s指针默认都+1if i == len(t):  # 长度满足return t  # 直接返回return ""

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

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

相关文章

Java中的异常处理策略:编写健壮的软件

异常处理是Java编程中一个重要的方面&#xff0c;正确的异常处理策略可以使软件更加健壮和易于维护。本文将详细探讨Java中的异常处理机制&#xff0c;介绍常见的异常类&#xff0c;以及提供有效的异常处理技巧和最佳实践。 #### 1. Java异常类别 Java中的异常分为两大类&…

Clickhouse 字符串函数使用总结—— Clickhouse基础篇(七)

文章目录 判空非空判断字符串长度左补齐字符串右补齐字符串字符串转小写字符串转大写重复字符串拼接字符串函数计算子串base64编码base64解码判断开头字符串判断结尾字符串删除空白字符从HTML提取纯文本字符串部分替换字符串全部替换字符串正则部分替换字符串正则全部替换计算子…

Spring Boot 与 OpenJ9 的 Docker 集成:提升 Java 应用性能的新选择

## 引言 随着 Docker 的普及&#xff0c;越来越多的开发者开始使用 Docker 来部署和管理他们的应用。在这种趋势下&#xff0c;将 Spring Boot 与 OpenJ9 结合使用&#xff0c;可以为 Java 应用带来更高的性能和更低的资源占用。本文将介绍如何在 Docker 环境中使用 Spring Bo…

回顾封装、继承和多态的概念,并给出相关示例

封装、继承和多态是面向对象编程&#xff08;OOP&#xff09;的三个核心概念。下面我将分别解释这些概念&#xff0c;并给出相应的示例。 封装 概念&#xff1a;封装是将数据&#xff08;变量&#xff09;和操作数据的方法&#xff08;函数&#xff09;组合到一个类中&#x…

pytest断言与Selenium模拟操作的规划案例

pytest断言与Selenium模拟操作的规划案例 在使用pytest进行自动化测试时&#xff0c;断言是验证测试结果是否符合预期的关键步骤。pytest提供了简洁的断言语法&#xff0c;使得编写测试用例更加直观和易于维护。以下是一个简单的规划案例&#xff0c;展示了如何在pytest中使用…

202309青少年软件编程(Python)等级考试试卷(四级)

第 1 题 【单选题】 用枚举算法求解“100 以内既能被 3 整除又能被 4 整除的元素”时, 在下列数值范围内,算法执行效率最高的是? ( ) A :1~101 B :4~100 C :12~100 D :12~96 正确答案:D 试题解析: 在选取循环控制变量时, 枚举范围应尽可能小, 但又不能遗漏。 第 …

掌握Python循环:从基础到应用的完整指南

循环语句是编程中常用的一种结构&#xff0c;用于重复执行特定的代码块。Python3 提供了几种类型的循环语句&#xff0c;包括for循环和while循环。接下来&#xff0c;我会详细解释循环语句的基本语法、常用命令、示例、应用场景、注意事项和总结。 基本语法 for 循环 for 变…

什么是勒索软件

什么是勒索软件 勒索软件又称勒索病毒&#xff0c;是一种特殊的恶意软件&#xff0c;又被归类为“阻断访问式攻击”&#xff08;denial-of-access attack&#xff09;&#xff0c;与其他病毒最大的不同在于攻击手法以及中毒方式。勒索软件的攻击方式是将受害者的电脑锁起来或者…

mysql-增量备份流程详细流程

3.增量备份流程 原理&#xff1a;每次备份上一次备份到现在产生的新数据 1.在数据库上面创建一个测试的库 增量备份流程&#xff08;重要) 增量备份跟上一次相比 我增加了啥--incremental //放到何处 --incremental-basedir //上一级//第一次增量备份 innobackupex --user…

Spring Boot中如何查询PGSQL分表后的数据

数据库用的pgsql&#xff0c;在表数据超过100w条的时候执行定时任务进行了分表&#xff0c;分表后表名命名为原的表名后面拼接时间&#xff0c;如原表名是card_device_trajectory_info&#xff0c;分表后拼接时间后得到card_device_trajectory_info_20240503&#xff0c;然后分…

ubuntu使用oh my zsh美化终端

ubuntu使用oh my zsh美化终端 文章目录 ubuntu使用oh my zsh美化终端1. 安装zsh和oh my zsh2. 修改zsh主题3. 安装zsh插件4. 将.bashrc移植到.zshrcReference 1. 安装zsh和oh my zsh 首先安装zsh sudo apt install zsh然后查看本地有哪些shell可以使用 cat /etc/shells 将默…

使用nexus搭建的nodejs私库,定期清理无用的npm组件,彻底释放磁盘空间

一、背景 昨天我们整理了一篇关于docker私库&#xff0c;如何定期清理以释放磁盘空间的文章。 虽然也提及了npm前端应用的组件该如何定期清理的&#xff0c;本文是对它作一个补充说明。 前文也看到了&#xff0c;npm组件占用的blob空间为180多GB&#xff0c;急需清理。 二、…

Flutter 中的 MouseRegion 小部件:全面指南

Flutter 中的 MouseRegion 小部件&#xff1a;全面指南 在 Flutter 中&#xff0c;MouseRegion 是一个非常有用的小部件&#xff0c;它允许你为部件添加鼠标事件&#xff08;如点击、悬停、离开等&#xff09;。这在开发需要处理鼠标交互的应用时尤为重要。本文将详细介绍 Mou…

100个 Unity小游戏系列三 -Unity 抽奖游戏专题一 转盘抽奖游戏

一 、效果展示 二、知识点 2.1 布局需要实现功能 1、转动的根目录为itemSpinRoot 2、创建对应的item 3、每个item转动的角度 2.2 代码 public class WheelDialog : UIBase{[SerializeField] Button btnClick;[SerializeField] Button btnClose;[SerializeField] Sprite[] ite…

微信小程序(路由传参)

微信小程序的路由系统和其他Web应用类似&#xff0c;主要通过页面路径和URL参数进行页面导航和数据传递。下面详细介绍微信小程序路由的基本使用方法和相关技巧。 1. 基本页面导航 1.1 配置页面路径 在微信小程序的 app.json 文件中&#xff0c;需要配置小程序的页面路径。这…

哪有异地组网的工具?

不同地区的电脑与电脑、设备与设备、电脑与设备之间的信息远程通信&#xff0c;一直是企业和个人面临的难题。通过使用天联组网的解决方案&#xff0c;这个问题将迎刃而解。 天联组网解决方案 天联组网是一种可以实现不同地区之间电脑、设备及其之间的信息远程通信的解决方案。…

Trie字符串统计-java

Trie&#xff0c;又称前缀树或字典树&#xff0c;是一种有序树&#xff0c;用于保存关联数组&#xff0c;其中的键通常是字符串。 目录 前言☀ 一、Trie字符串统计☀ 二、算法思路☀ 1.Trie树定义&#x1f319; 2.变量解释&#x1f319; 3.插入操作&#x1f319; 4.Trie树查找操…

vim文本编辑器相关用法

1. 引言 Vim&#xff0c;一个功能强大的文本编辑器&#xff0c;它在程序员和系统管理员中广受欢迎。Vim是Vi的增强版&#xff0c;提供了一系列高级功能&#xff0c;包括语法高亮、代码补全、多窗口编辑等。 2. Vim的安装 Vim的安装过程在不同的Linux发行版中略有不同。以下是…

MapStruct高级用法

MapStruct高级用法 依赖注入&#xff08;Using dependency injection&#xff09; Mapper(componentModel SPRING) public interface SpringMapper {SpringMapper MAPPER Mappers.getMapper(SpringMapper.class);PersonDTO personDoToDTO(Person person); }public static fin…

【class18】人工智能初步----语音识别(4)

【class17】 上节课&#xff0c;我们学习了: 语音端点检测的相关概念&#xff0c;并通过代码切分和保存了音频。 本节课&#xff0c;我们将学习这些知识点&#xff1a;1. 序列到序列模型2. 循环神经网络3. 调用短语音识别接口 知其然&#xff0c;知其所以然 在调用语…