算法——双指针

一、背景知识 

  • 双指针(Two Pointers):指的是在遍历元素的过程中,不是使用单个指针进行访问,而是使用两个指针进行访问,从而达到相应的目的。
  • 对撞时针
    • 两个指针方向相反
    • 对撞指针一般用来解决有序数组或者字符串问题
  • 快慢指针:
    • 两个指针方向相同,速度不同。移动快的指针被称为 「快指针(fast)」,移动慢的指针被称为「慢指针(slow)」
    • 快慢指针一般用于处理数组中的移动、删除元素问题,或者链表中的判断是否有环、长度问题。
  • 分离双指针:
    • 两个指针分别属于不同的数组 / 链表
    • 分离双指针一般用于处理有序数组合并,求交集、并集问题。
  • 滑动窗口法:

    • 两个指针,一前一后组成滑动窗口,并计算滑动窗口中的元素的问题。一般是右端向右扩充,达到停止条件后右端不动,左端向右端逼近,逼近达到停止条件后,左端不动,右端继续扩充。

    • 滑动窗口法一般用于处理字符串匹配问题和子数组问题
  • 时间复杂度O(n)

二、例题

总结:

  • 要移动多个指针的情况可以分解成双指针的情况(1+n)
  • 关键是什么条件下移动哪个指针,分开思考,一起走就容易乱 

 1、移动零(快慢指针)

突破点:右指针是贴着左指针开始往右移的,不是从数组右端往左移,因为那样会搅乱数组元素的相对顺序 

class Solution {public void moveZeroes(int[] nums) {int l=0;//左指针int r=0;//右指针int count=0;//计算0的个数while(r<nums.length){if(nums[r]!=0 && nums[l]==0){//找到0,交换后,左右指针都往右移nums[l]=nums[r];nums[r]=0;count++;l++;}if(nums[l]!=0){//没找到0,左右指针都往右移l++;}//前两种情况都有r++; 所以把它提到外面,大家都能用r++;//如果只有左指针找到0,右指针继续往右移}}
}

 代码优化:封装方法

class Solution {public void moveZeroes(int[] nums) {int n = nums.length, left = 0, right = 0;while (right < n) {if (nums[right] != 0) {swap(nums, left, right);left++;}right++;}}public void swap(int[] nums, int left, int right) {int temp = nums[left];nums[left] = nums[right];nums[right] = temp;}
}

2、盛最多水的容器(对撞指针)

突破点:不是同时移动两个指针,而是只移动较小的那个,因为较小的值改变会影响整体面积 

public class Solution {public int maxArea(int[] height) {int l = 0, r = height.length - 1;//左右指针分别指向数组的头尾int ans = 0;//维护一个最大值while (l < r) {int area = Math.min(height[l], height[r]) * (r - l);//当前面积,不一定是最大值ans = Math.max(ans, area);//移动数字较小的那个指针,整体面积才会发生变化 if (height[l] <= height[r]) {++l;}else {--r;}}return ans;}
}

3、三数之和(对撞指针)

突破点:三个指针的相对方位不会改变,一左一中一右,
        它们也不会走对方走过的路,因为它们三个实际上是相同的
        如果改变了方位,就会出现重复的三元组 

class Solution {public List<List<Integer>> threeSum(int[] nums) {int n = nums.length;Arrays.sort(nums);List<List<Integer>> ans = new ArrayList<List<Integer>>();// 枚举 afor (int first = 0; first < n; ++first) {// 需要和上一次枚举的数不相同if (first > 0 && nums[first] == nums[first - 1]) {continue;}// c 对应的指针初始指向数组的最右端int third = n - 1;int target = -nums[first];// 枚举 bfor (int second = first + 1; second < n; ++second) {// 需要和上一次枚举的数不相同if (second > first + 1 && nums[second] == nums[second - 1]) {continue;}// 需要保证 b 的指针在 c 的指针的左侧// 因为当b走到c的右边时,相当于原来的c,会有重复的三元组产生while (second < third && nums[second] + nums[third] > target) {//b和c之和大于target,b是往右走值是增大的,所以要移动c指针往左走--third;}// 如果指针重合,随着 b 后续的增加// 就不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环if (second == third) {break;}//找到了 if (nums[second] + nums[third] == target) {List<Integer> list = new ArrayList<Integer>();list.add(nums[first]);list.add(nums[second]);list.add(nums[third]);ans.add(list);}}}return ans;}
}

4、接雨水(对撞指针)

突破点:是从两边向中间逼近,而非从左到右 

class Solution {public int trap(int[] height) {int ans=0;int left=0,right=height.length-1;//左右指针分别指向数组的头尾端int leftMax=0,rightMax=0;while(left<right){//指针未相撞leftMax=Math.max(leftMax,height[left]);rightMax=Math.max(rightMax,height[right]);if(height[left]<height[right]){ans+=leftMax-height[left];//当前height[left]夹在leftMax和rightMax中间,所以它的存水量受制于最小值++left;//移动最小值,才会改变可存水量}else{ans+=rightMax-height[right];--right;}}}
}

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

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

相关文章

SecureCRT -- 使用说明

【概念解释】什么是SSH&#xff1f; SSH的英文全称是Secure Shell 传统的网络服务程序&#xff0c;如&#xff1a;ftp和telnet在本质上都是不安全的&#xff0c;因为它们在网络上用明文传送口令和数据&#xff0c;别有用心的人非常容易就可以截获这些口令和数据。而通过使用SS…

《Deep learning for fine-grained image analysis: A survey》阅读笔记

论文标题 《Deep learning for fine-grained image analysis: A survey》 作者 魏秀参&#xff0c;旷世研究院 初读 摘要 细粒度图像分析&#xff08;FGIA&#xff09;的任务是分析从属类别的视觉对象。 细粒度性质引起的类间小变化和类内大变化使其成为一个具有挑战性的…

筒仓料位监测|敢不敢对“精度”下狠手!您家筒仓料位测得准吗?

您家是不是还在人工敲仓估算&#xff1f; 您能精确知道料位和库存吗&#xff1f; 您能实时看到库存盈亏吗&#xff1f; 筒仓里装了什么&#xff1f;用了多少&#xff1f; 什么时候进料最划算&#xff1f; 您家的筒仓管理方式可靠吗&#xff1f; 上海思伟筒仓料位监测方案 看…

UE5制作场景时的小技巧和注意事项

UE5制作场景时的小技巧和注意事项 一、场景相关 1.1灯光 1.1.1构建完光照,发现场景都是黑的 可能是所有灯光是静态灯光,把skylight改为动态,如果改完之后还是黑色的,那就在构建一次,就应该没问题了 1.1.2场景中有多个动态光会造成阴影闪烁 需要将skylight变为固定 1…

并行与分布式 第7章 体系结构 上

文章目录 并行与分布式 第7章 体系结构 上7.1 多处理器结构7.1.1 多处理器存储结构分类7.1.2 非共享存储多处理器7.1.3 共享存储多处理器7.1.4 多核结构 7.2 Cache一致性问题7.2.1数据共享引发的问题7.2.2 Cache一致性协议7.2.3 监听协议的实现7.2.4目录式协议 并行与分布式 第…

数据结构~~~~ [队列] ~~~~

文章目录 队列队列的概念与结构队列的接口实现***队列的初始化******队列的销毁******队列的插入与创建节点******队列的删除******队列的队头数据******队列的队尾数据******队列的判空*** 队列 队列的概念与结构 队列的插入数据在队尾出数据在队头&#xff08;尾入头出&…

pytorch下载离线包的网址

下载地址&#xff1a;https://download.pytorch.org/whl/torch_stable.html 安装GPU版本需要安装&#xff1a;torch、torchvision、 注意版本需要对应上 格式&#xff1a;适用cuda版本&#xff0c;torch版本 或者 orchvision版本&#xff0c;cp38就是适用python 3.8版本 下…

PGFNet

方法 MFRM means ‘multi-modal feature refinement mechanism’&#xff0c;MMAFM means ‘multi-modal and multi-scale attention fusion model’&#xff0c;RPM means ‘residual prediction module’ scale attention weights U R S _R^S RS​,U D S _D^S DS​ enhan…

【操作系统】文件系统的逻辑结构与目录结构

文章目录 文件的概念定义属性基本操作 文件的结构文件的逻辑结构文件的目录结构文件控制块&#xff08;FCB&#xff09;索引节点目录结构 文件的概念 定义 在操作系统中&#xff0c;文件被定义为&#xff1a;以计算机硬盘为载体的存储在计算机上的信息集合。 属性 描述文件…

【Redis使用】一年多来redis使用笔记md文档,第(2)篇:命令和数据库操作

Redis 是一个高性能的key-value数据库。本文会让你知道&#xff1a;什么是 nosql、Redis 的特点、如何修改常用Redis配置、写出Redis中string类型数据的增删改查操作命令、写出Redis中hash类型数据的增删改查相关命令、说出Redis中 list 保存的数据类型、使用StrictRedis对象对…

Vue3+Vite实现工程化,插值表达式和v-text以及v-html

1、插值表达式 插值表达式最基本的数据绑定形式是文本插值&#xff0c;它使用的是"Mustache"语法&#xff0c;即 双大括号{{}} 插值表达式是将数据 渲染 到元素的指定位置的手段之一插值表达式 不绝对依赖标签&#xff0c;其位置相对自由插值表达式中支持javascript的…

[uni-app] uni.showToast 一闪而过问题/设定时间无效/1秒即逝

toast一闪就消失 1.猜测频繁点击导致 – 排除 2.猜测再定时器内导致-- 排除 3.和封装的接口调用一起导致 - 是改原因 深挖发现: axios封装中, 对loading/hindloading进行了配置, 看来是 showToast 与 loading等冲突导致的 wx.hideLoading(Object object) 解决办法 再封装的…

【计算机毕业设计】Node.js商城APP-97200,免费送源码,【开题选题+程序定制+论文书写+答辩ppt书写-原创定制程序】

Node.js商城APP的开发 摘 要 在传统的商业模式中&#xff0c;对于日常各类商品&#xff0c;人们习惯于到各种商家店铺购买。然而在快节奏的新时代中&#xff0c;人们不一定能为购买各类商品腾出时间&#xff0c;更不会耐心挑选自己想要的商品。所以设计一个商城APP&#xff0c…

Notpad-- ubuntu下载安装

Notpad-- ubuntu下载安装 下载 Gitee链接&#xff1a; https://gitee.com/cxasm/notepad– 安装 sudo apt install *.deb运行 /opt/apps/com.hmja.notepad/files/Notepad--出错 需要安装qt5 sudo apt-get install qt5-default

米诺地尔行业分析:预计2029年将达到14亿美元

米诺地尔市场规模庞大&#xff0c;不仅包括消费品市场和服务行业&#xff0c;还涵盖了创新科技领域。随着经济的发展和市场需求的不断增长&#xff0c;米诺地尔市场的规模将继续扩大&#xff0c;各行各业都将面临更多机遇和挑战。 随着社会经济发展和城市化进程的推进&#xff…

【JavaEE初阶】计算机是如何工作的

一、计算机发展史 计算的需求在⼈类的历史中是广泛存在的&#xff0c;发展大体经历了从⼀般计算⼯具到机械计算机到目前的电子计算机的发展历程。 人类对计算的需求&#xff0c;驱动我们不断的发明、改善计算机。目前这个时代是“电子计算机”的时代&#xff0c;发展的潮流是…

竞赛 题目:基于机器视觉opencv的手势检测 手势识别 算法 - 深度学习 卷积神经网络 opencv python

文章目录 1 简介2 传统机器视觉的手势检测2.1 轮廓检测法2.2 算法结果2.3 整体代码实现2.3.1 算法流程 3 深度学习方法做手势识别3.1 经典的卷积神经网络3.2 YOLO系列3.3 SSD3.4 实现步骤3.4.1 数据集3.4.2 图像预处理3.4.3 构建卷积神经网络结构3.4.4 实验训练过程及结果 3.5 …

【C++百宝箱】语法总结:引用 | 内联函数 | auto | 范围for循环

&#x1f6a9;纸上得来终觉浅&#xff0c; 绝知此事要躬行。 &#x1f31f;主页&#xff1a;June-Frost &#x1f680;专栏&#xff1a;C入门宝典 &#x1f525;本文主要探讨C的语法&#xff0c;并深入了解C如何针对C语言中存在的不合理之处进行优化改进。 目录&#xff1a; ⌛…

麒麟KYSEC使用方法02-开启及关闭exectl

原文链接&#xff1a;麒麟KYSEC使用方法02-开启及关闭exectl hello&#xff0c;大家好啊&#xff0c;今天给大家带来麒麟KYLINOS的kysec使用方法系列文章第二篇内容----使用命令开启及关闭exectl&#xff0c;可执行程序策略有三种模式&#xff0c;off/enforing/warning&#xf…

算法(圆的定义和相关术语)

无向图的度 图中每一个顶点的度定义为以该项点为一个端点的边的数目 #include <cstdio>const int MAXN 100;int degree[MAXN] { 0 };int main() {int n, m, u, v;scanf("%d%d", &n, &m);//在输出边度的时候就已经表示度的数目了&#xff0c;所以用一…