双指针详解

article/2025/10/21 17:59:45

1、定义

顾名思义,双指针即用两个不同速度不同方向的指针对数组或对象进行访问,通过两个不同指针的碰撞从而达到特定的目的。

2、解决问题

在时间或空间条件有限的情况下使用单向遍历需要消耗大量的时间或者根本无法解决问题,这时候就需要我们使用双指针,通过指针的碰撞判断是否达到条件,从而解决问题。

双指针分为快慢指针和左右指针,左右指针通常在数组有序的情况下使用,快慢指针通常在单向遍历需要消耗大量时间,或者有特定要求限制的情况下使用。

首先介绍一下左右指针

左右指针通常在数组有序的情况下,从最小和最大端同时对数组进行处理,对满足特定条件的数组元素进行成对处理,快慢指针逐渐靠拢直至发生碰撞,则遍历完所有数组。

举个例子:

一个孤岛上有7个人重量54kg,55kg,56kg,57kg,58kg,59kg,70kg。她们需要逃生到安全的地方。现在有足够的救生艇,但是每个救生艇只能坐两个人,而且每个救生艇最大能承受113kg的重量,那她们最少需要多少救生艇才能全部逃生。

现在我们来分析,如果最重的人可以与最轻的人共用一艘船,那么就这样安排。否则,最重的人无法与任何人配对,那么他们将自己独自乘一艘船。这么做的原因是,如果最轻的人可以与任何人配对,那么他们也可以与最重的人配对。

那我们首先让她们按照体重排好队
在这里插入图片描述

那我们首先看最瘦的和最胖的,连个加起来有124斤,是坐不了一条船的

在这里插入图片描述
那我们只能让最胖的自己坐一条船,然后看第二胖的能不能和最瘦的一起坐船走,这时候用了一条船。
在这里插入图片描述
可以发现最瘦的果然和第二胖的人体重一共为113kg,她们是可以一起坐船走的,这时候一共占用了两条船,接下来继续看第二瘦和第三胖的人。。。。。。。

在这里插入图片描述

最后组队情况为:

54kg - 59kg,55kg - 58kg,56kg - 57kg,70kg

从上我们可以看到双指针即是在有序数组的情况下,我们通过两个指针在遍历的过程中进行标记,对满足条件的进行处理,直至遍历完整个数组。

下面看几个例题:

881. 救生艇

第 i 个人的体重为 people[i],每艘船可以承载的最大重量为 limit

每艘船最多可同时载两人,但条件是这些人的重量之和最多为 limit

返回载到每一个人所需的最小船数。(保证每个人都能被船载)。

示例 1:输入:[2,1,4,7,3,2,5]
输出:5
解释:最长的 “山脉” 是 [1,4,7,3,2],长度为 5。
示例 2:输入:[2,2,2]
输出:0
解释:不含 “山脉”。提示:
0 <= A.length <= 10000
0 <= A[i] <= 10000

如上所述:如果最重的人可以与最轻的人共用一艘船,那么就这样安排。否则,最重的人无法与任何人配对,那么他们将自己独自乘一艘船。

这么做的原因是,如果最轻的人可以与任何人配对,那么他们也可以与最重的人配对。

代码如下:

class Solution {public int numRescueBoats(int[] people, int limit) {Arrays.sort(people);int i = 0, j = people.length - 1;int ans = 0;while (i <= j) {ans++;if (people[i] + people[j] <= limit)i++;j--;}return ans;}
}

快慢指针

快慢指针中的快慢即两个指针移动的快慢不同,通过两个指针移动速度的不同,判断数组或链表的长度、是否有环、特定位置的数值等。

举个例子:

假如有一条跑道,假如有环,会沿着环一直跑,乌龟每次走一步,兔子每次走两步,那么如果有环,那么他们必定会相遇,过程如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

环形链表问题:

141. 环形链表
142. 环形链表 II

回文链表问题:

对于回文链表问题,使用快慢指针解决,快指针步长为2,慢指针步长为1,则当快指针移动到链表末尾的时候,满指针正好移动到链表的中点。我们可以将链表的后半部分反转(修改链表结构),然后将前半部分和后半部分进行比较。

如下题:

234. 回文链表

回文链表问题可以分为5个步骤:

  1. 找到前半部分链表的尾节点。
  2. 反转后半部分链表。
  3. 判断是否回文。
  4. 恢复链表。
  5. 返回结果。
class Solution {public boolean isPalindrome(ListNode head) {if (head == null) {return true;}// 找到前半部分链表的尾节点并反转后半部分链表ListNode firstHalfEnd = endOfFirstHalf(head);ListNode secondHalfStart = reverseList(firstHalfEnd.next);// 判断是否回文ListNode p1 = head;ListNode p2 = secondHalfStart;boolean result = true;while (result && p2 != null) {if (p1.val != p2.val) {result = false;}p1 = p1.next;p2 = p2.next;}        // 还原链表并返回结果firstHalfEnd.next = reverseList(secondHalfStart);return result;}private ListNode reverseList(ListNode head) {ListNode prev = null;ListNode curr = head;while (curr != null) {ListNode nextTemp = curr.next;curr.next = prev;prev = curr;curr = nextTemp;}return prev;}private ListNode endOfFirstHalf(ListNode head) {ListNode fast = head;ListNode slow = head;while (fast.next != null && fast.next.next != null) {fast = fast.next.next;slow = slow.next;}return slow;}
}

链表中倒数第K个节点问题

  1. 初始化: 前指针 former 、后指针 latter ,双指针都指向头节点 head​ 。
  2. 构建双指针距离: 前指针 former 先向前走 kk 步(结束后,双指针 former 和 latter 间相距 kk 步)。
  3. 双指针共同移动: 循环中,双指针 former 和 latter 每轮都向前走一步,直至 former 走过链表 尾节点 时跳出(跳出后, latter 与尾节点距离为 k-1k−1,即 latter 指向倒数第 kk 个节点)。
  4. 返回值: 返回 latter 即可

如下图所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
代码如下:

class Solution {public ListNode getKthFromEnd(ListNode head, int k) {ListNode former = head, latter = head;for(int i = 0; i < k; i++)former = former.next;while(former != null) {former = former.next;latter = latter.next;}return latter;}
}

寻找两个链表交点问题

160. 相交链表

编写一个程序,找到两个单链表相交的起始节点。

如下面的两个链表:
在这里插入图片描述

  • 创建两个指针 pA 和 pB,分别初始化为链表 A 和 B 的头结点。然后让它们向后逐结点遍历。
  • 当 pA 到达链表的尾部时,将它重定位到链表 B 的头结点 (你没看错,就是链表 B); 类似的,当pB 到达链表的尾部时,将它重定位到链表 A 的头结点。 若在某一时刻 pA 和 pB 相遇,则 pA/pB 为相交结点。
  • 想弄清楚为什么这样可行, 可以考虑以下两个链表: A={1,3,5,7,9,11} 和 B={2,4,9,11},相交于结点 9。 由于 B.length (=4) < A.length (=6),pB 比pA 少经过 22 个结点,会先到达尾部。将 pB 重定向到 A 的头结点,pA 重定向到 B 的头结点后,pB 要比pA 多走 2 个结点。因此,它们会同时到达交点。
  • 如果两个链表存在相交,它们末尾的结点必然相同。因此当 pA/pB 到达链表结尾时,记录下链表 A/B对应的元素。若最后元素不相同,则两个链表不相交。

代码如下:

public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {/**定义两个指针, 第一轮让两个到达末尾的节点指向另一个链表的头部, 最后如果相遇则为交点(在第一轮移动中恰好抹除了长度差)两个指针等于移动了相同的距离, 有交点就返回, 无交点就是各走了两条指针的长度**/if(headA == null || headB == null) return null;ListNode pA = headA, pB = headB;// 在这里第一轮体现在pA和pB第一次到达尾部会移向另一链表的表头, 而第二轮体现在如果pA或pB相交就返回交点, 不相交最后就是null==nullwhile(pA != pB) {pA = pA == null ? headB : pA.next;pB = pB == null ? headA : pB.next;}return pA;}
}

http://chatgpt.dhexx.cn/article/9Wa6srfF.shtml

相关文章

指针基本认识

指针 一、指针是什么&#xff1f;二、指针和指针类型1.指针-整数2.指针的解引用 三、野指针四、指针运算1.指针-指针2.指针关系运算 五、指针和数组六、二级指针七、指针数组 一、指针是什么&#xff1f; 在计算机科学中&#xff0c;指针&#xff08;Pointer&#xff09;是编程…

c++ 指针详解

文章目录 指针1、 使用指针遍历[数组](https://blog.csdn.net/m0_62870588/article/details/123787052)2、指针的概念与理解3、指针的创建与初始化4、指针的基本操作5、指针的算数操作6、[const](https://blog.csdn.net/m0_62870588/article/details/123399735)指针7、指针的[数…

深入理解C语言指针

一、指针的概念 要知道指针的概念&#xff0c;要先了解变量在内存中如何存储的。在存储时&#xff0c;内存被分为一块一块的。每一块都有一个特有的编号。而这个编号可以暂时理解为指针&#xff0c;就像酒店的门牌号一样。 1.1、变量和地址 先写一段简单的代码&#xff1a; …

c语言指针的指针

1、情况 c语言指针的指针&#xff0c;还是比较常用的一个功能&#xff1b;当然&#xff0c;我也相信&#xff0c;一些用C语言很长时间的人&#xff0c;也没大用过&#xff0c;因为用不到&#xff0c;这是工作需求决定的&#xff0c;但总体来说&#xff0c;还是经常用的。 理解…

十四、C指针详解(四):指针的指针

文章目录 一、指针的指针 一、指针的指针 指针用来存放变量的地址&#xff0c;同时&#xff0c;指针也有自己的地址&#xff0c;因此&#xff0c;就可以设置一个指针变量&#xff0c;用来存放指针的地址&#xff0c;也就是指针的指针&#xff0c;他存放的是一个地址&#xff0…

指针的指针、字符串和指针、数组指针(详)

一、指针的指针 指针的指针&#xff0c;即指针的地址 定义了一个指针变量&#xff0c;指针变量本身占4个字节&#xff0c;指针变量也有地址编号 例&#xff1a; int a0x12345678; 假设a的地址为&#xff1a;0x0000 2000 int *p; p&a; 则p中存放的是a的地址编号为0x0000 20…

指针的指针(简单易懂)

int a 12&#xff1b; int *b &a; 内存的分配如下 这时再来一个变量 c &b; 问题来了? c 是什么类型? b 是指向整型的指针 ,c 是指向整形指针的指针&#xff1f; 是的 c 是指向指针的指针 声明如下 int ** c; int a 12; int *b &a; int **c &b…

Nginx Rewrite规则详解

Nginx Rewrite 规则相关指令 相关指令有if,rewrite,set,return,break等&#xff0c;其中最关键的就是rewrite.一个简单的Nginx Rewrite规则语法如下&#xff1a;rewrite ^/b/(.*)\.html /play.php?video$1 break; 1.break指令 默认值&#xff1a;none ;使用环境&#xff1a…

nginx配置文件rewrite规则

nginx配置文件rewrite规则 文章目录 nginx配置文件rewrite规则[toc]ifRewite 规则介绍flag标志位配置rewrite规则last二次转发 if 语法&#xff1a;if (condition) {…} 应用场景&#xff1a; server段 location段 常见的condition 变量名&#xff08;变量值为空串&#xf…

nginx Rewrite 规则

一&#xff1a;nginx Rewrite 规则 1&#xff1a;rewrite的概念&#xff1a; Nginx Rewrite功能是使用nginx提供的全局变量或自己设置的变量&#xff0c;结合正则表达式和标志位实现URL重写以及重定向功能。Rewrite指令只能放在server {}&#xff0c;location {}&#xff0c;…

Nginx高级之Rewrite规则

进阶阶段的回顾: Nginx进阶之静态Web资源服务 Nginx进阶之代理服务 Nginx进阶之负载均衡服务 Nginx进阶之缓存服务和动静分离 作用及应用场景 作用: 实现对URL的重写以及对匹配(正则表达式)的url的重定向 场景: 1. URL访问跳转, 支持开发设计 ① 页面跳转 ② 兼容…

Nginx配置请求转发location及rewrite规则

location / {# 精确匹配 / &#xff0c;主机名后面不能带任何字符串[ configuration A ] }location / {# 因为所有的地址都以 / 开头&#xff0c;所以这条规则将匹配到所有请求# 但是正则和最长字符串会优先匹配[ configuration B ] }location /documents/ {# 匹配任何以 …

Rewrite规则简介

Rewirte主要的功能就是实现URL的跳转&#xff0c;它的正则表达式是基于Perl语言。可基于服务器级的(httpd.conf)和目录级的(.htaccess)两种方式。如果要想用到rewrite模块&#xff0c;必须先安装或加载rewrite模块。方法有两种一种是编译apache的时候就直接安装rewrite模块&…

rewrite详解

rewrite模块 URI跟URL介绍 什么是uri&#xff1f;统一标识符&#xff0c;拿www.abc.com/aw/wd/举例&#xff0c;那么rui就是/aw/wd/这部分数据(也有可能是图片&#xff0c;html网页,如果是伪静态的话,那就得看配置是啥玩意了 什么是url? 统一定位符&#xff…

Nginx基础——Rewrite规则

点击上方“芋道源码”&#xff0c;选择“置顶公众号” 技术文章第一时间送达&#xff01; 源码精品专栏 精尽 Dubbo 原理与源码专栏( 已经完成 69 篇&#xff0c;预计总共 75 篇 )中文详细注释的开源项目Java 并发源码合集RocketMQ 源码合集Sharding-JDBC 源码解析合集Spring …

F280049C Crossbar X-BAR

文章目录 X-BAR9.1 输入X-BAR9.2 ePWM、CLB和GPIO输出X-BAR9.2.1 ePWM X-BAR9.2.1.1 ePWM X-BAR架构 9.2.2 CLB X-BAR9.2.2.1 CLB X-BAR架构 9.2.3 GPIO输出X-BAR9.2.3.1 GPIO输出X-BAR架构9.2.4 X-BAR标志 总结 X-BAR 交叉开关&#xff08;在本章中称为X-BAR&#xff09;提供…

BCGControlBar Pro 31.2 正式版-Key

什么是 MFC 的 BCGControlBar Pro&#xff1f; BCGControlBar&#xff08;“Business Components Gallery ControlBar”&#xff09;是一个 MFC 扩展库&#xff0c;企鹅180846090允许您创建具有完全自定义选项&#xff08;功能区、可自定义工具栏、菜单等&#xff09;和一组丰富…

BCGControlBar Library for .NET 7.1.1 Crack

什么是 BCGControlBar Library for .NET&#xff1f; BCGControlBar Library for .NET 是 100% 托管代码工具包&#xff0c;用 C/CLI 编写&#xff0c;面向 Microsoft .NET Framework 2.0 或更高版本。该库包含许多高度可定制、完全可设计的组件&#xff0c;使您能够创建最复杂…

BCGControlBar v12的向导使用图解

BCGControlBar专业版是MFC的一个扩展库&#xff0c;您可以用来构建类似于Microsoft Office 2000/XP/2003/2007/2010、Microsoft Visual Studio&#xff08;打印、用户定制工具栏、菜单等&#xff09;和其他一些知名产品的高级用户界面。 首先从网上下载BCGControlBar v12资源 &…

MFC界面控件BCGControlBar v33.4 - 日历、属性网格组件升级

BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。 我们的组件可以轻松地集成到您的应用程序中&#xff0c;并为您节省数百个开发和调试时间。 BCGControlBar专业版和BCGSuite for MFC v33.4已正式发布了&#xff0c;该版本包含了对Windows 11 Mica materi…