当前位置: 首页 > news >正文

双指针常用方法

1.双指针介绍

双指针是解题时一种常见的思路,一般有两种用法。

1)两个指针反方向,分别从数组开头和结尾开始移动,例如对有序数组的搜索。

2)两个指针同方向移动,例如快慢指针,都是从数组开头开始遍历,只是速度不一样。

除了用于数组,也可以用于链表,树,图。

2.反向的双指针

力扣icon-default.png?t=N2N8https://leetcode.cn/problems/two-sum-ii-input-array-is-sorted/

因为数组是非递减的,所以可以数组首尾各置一个指针,若值相加大于目标值,则尾指针自减,若值相加小于目标值,则头指针自增,这样就一步步逼近了目标值。

class Solution {
public:vector<int> twoSum(vector<int>& numbers, int target) {int i = 0, j = numbers.size()-1;while(i<j){int t = numbers[i] + numbers[j];if(target==t) return vector<int>({i+1,j+1});else if(target>t){i++;}else{j--;}}return vector<int>();}
};

3.同向的双指针

力扣icon-default.png?t=N2N8https://leetcode.cn/problems/linked-list-cycle-ii/这题有两个要点,先是要判断链表中是否有环,接着是找到环的入口。

判断是否有环,可以用快慢指针。

两个指针同时从起点出发,快指针一次两步,慢指针一次一步。

如果链表中有环,则快慢指针一定会相遇,就像在操场上一直跑圈,速度快的人一定会在某一刻比速度慢的人多跑一圈,所以二人相遇了。

若是快慢指针没有相遇,且快指针指向了NULL,那很明显,就是没有环。

确定链表有环后,就是寻找环的入口了。

可以用题目中的示例来简单理解一下。

下图使用快慢指针,从起点[3]出发,慢指针一次一步,快指针一次两步,很快这两个指针会在节点[-4]相遇。

相遇后,将慢指针移回链表起点[3],快慢指针都一次走一步,两个指针再次相遇的节点[2],就是环的入口。

 一个简单易懂的解释就是:

慢指针路径:起点--环的入口--快慢指针相遇的节点

快指针路径:起点--环的入口--快慢指针相遇的节点--环的入口--快慢指针相遇的节点

因为快指针路径==慢指针路径*2

所以【快慢指针相遇的节点--环的入口--快慢指针相遇的节点】== 【 起点--环的入口--快慢指针相遇的节点】

同时减去【环的入口--快慢指针相遇的节点】

所以【快慢指针相遇的节点--环的入口】== 【 起点--环的入口】

所以找到环得到入口就是将慢指针移到起点,与快指针都是一次一步,直到相遇,相遇节点就是环的入口。

如果还是没有理解的,可以直接搜索【Floyd 判圈法】找动画视频直观理解一下。

代码:

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode(int x) : val(x), next(NULL) {}* };*/
class Solution {
public:ListNode *detectCycle(ListNode *head) {if(!head) return NULL;ListNode* slow = head, *fast = head;while(slow->next && fast->next && fast->next->next){slow = slow->next;fast = fast->next->next;if(slow==fast){slow = head;while(slow!=fast){slow = slow->next;fast = fast->next;}return slow;}}return NULL;}
};

http://www.lryc.cn/news/43436.html

相关文章:

  • 人工智能大模型之ChatGPT原理解析
  • 傅里叶谱方法-傅里叶谱方法的原理、快速傅里叶变换及其Matlab程序实现
  • 11万字数字政府智慧政务大数据建设平台(大数据底座、数据治理)
  • Node.js学习笔记——Node.js模块化
  • 【洛谷刷题】蓝桥杯专题突破-广度优先搜索-bfs(12)
  • 【数据结构】堆(堆的实现 堆向下调整算法 堆的创建 堆的插入 堆的删除 堆的代码实现 堆的应用)
  • JDBC数据库驱动的下载与安装与连接
  • 如何更改 PDF 背景颜色?
  • room数据库使用以及增加表的使用
  • WiFi-交互过程分析
  • 基于ZYNQ+linux+xenomai 的多轴运动控制平台关键技术研发-测试系统搭建(四)
  • 初识操作系统
  • #详细介绍!!!线程池
  • 【嵌入式Linux学习笔记】基于Linux官方库的标准外设驱动
  • 网络爬虫抓包工具
  • 蓝桥杯倒计时 | 倒计时17天
  • 【Spring Cloud Alibaba】7.Sentinel熔断器仪表盘监控
  • 个人博客系统项目测试报告
  • flutter安装自用笔记
  • tomcat线程池以及在SpringBoot中的启动过程
  • 第十四届中国大学生创新创业大赛
  • LeetCode:322. 零钱兑换——动态规划从案例入门
  • 【lwIP(第四章)】网络接口
  • Vue3 pinia入门篇(一)
  • python面向对象编程解释
  • ARM(IMX6U)嵌入式软件裸机开发之环境搭建与配置
  • Java文件复制多种方法
  • Java语言-----封装、继承、抽象、多态、接口
  • 基于深度学习的瓶子检测软件(UI界面+YOLOv5+训练数据集)
  • 仿网易云小程序(一)