优选算法——双指针(算法原理+力扣题)

优选算法------双指针(算法原理+力扣题)

文章摘要:本文深入解析双指针算法的核心思想与实战应用,涵盖同向、相向、快慢指针三大经典场景。通过移动零、复写零、快乐数、盛最多水的容器、有效三角形的个数、和为s的两个数、三数之和等七道力扣高频题目,系统讲解算法原理、解题思路与代码实现,助你快速掌握双指针技巧,提升算法解题效率。

目录

1.移动零

2.复写零

3.快乐数

4.盛最多水的容器

5.有效三角形的个数

6.和为s的两个数

7.三数之和

双指针简介

常⻅的双指针有两种形式,⼀种是对撞指针,⼀种是快慢指针。

对撞指针:⼀般⽤于顺序结构中,也称左右指针。

  • 对撞指针从两端向中间移动。⼀个指针从最左端开始,另⼀个从最右端开始,然后逐渐往中间逼
    近。
  • 对撞指针的终⽌条件⼀般是两个指针相遇或者错开(也可能在循环内部找到结果直接跳出循
    环),也就是:
    • left == right (两个指针指向同⼀个位置)
    • left > right (两个指针错开)
      快慢指针 :⼜称为⻳兔赛跑算法,其基本思想就是使⽤两个移动速度不同的指针在数组或链表等序列
      结构上移动。
      这种⽅法对于处理环形链表数组 ⾮常有⽤。
      其实不单单是环形链表或者是数组,如果我们要研究的问题出现循环往复 的情况时,均可考虑使⽤快
      慢指针的思想。
      快慢指针的实现⽅式有很多种,最常⽤的⼀种就是:
  • 在⼀次循环中,每次让慢的指针向后移动⼀位,⽽快的指针往后移动两位,实现⼀快⼀慢。

正文

1.移动零

  • 题目链接移动零

  • 题目描述

  • 算法原理:双指针(定义数组下标模拟指针)

    • cur:用来遍历数组
    • dest:指向已经处理过的区间内,非零元素的最后一个元素
      大概思路 :先定义两个指针,cur用来遍历数组,从第一个元素开始遍历,所以cur=0;
      dest用来指向处理过 的数组中,最后一个非零元素,cur等于0,还没有进行处理,所以dest=-1;
      当numscur!=0,交换numscur,numdest++;
      直到遍历整个数组
      代码:

2.复写零

  • 题目链接复写零

  • 题目描述

  • 算法原理:双指针(定义数组下标模拟指针)

    • cur:遍历需要复写的部分数组
    • dest:指向已经复写的最后一个元素

大概思路 :由于从前往后复写 时,就地解决,遇到零时要复写两次,会导致后面没有被cur遍历的元素被覆盖 。因此我们考虑从后往前复写

从后往前复写:

  • 1.cur找到最后一个要复写的数
    • 1.1判断cur的值
    • 1.2.决定dest走一步还是两步
    • 1.3.判断dest是否越界
    • 1.4.cur++
  • 2.考虑特殊情况:当最后一个复写数是0,复写两次,但是在复写之前,dest已经到达了arr.length-2,复写两次会导致dest=arr.lenth导致数组越界。这个时候就要我们手动处理最后一个要复写的数,即0,只需要复写一遍。给出一组特殊情况的数组,可自己模拟:1,0,2,3,0,4
  • 3.从后往前复写,!0复写一边,0复写两边

    代码

3.快乐数

  • 题目链接快乐数

  • 题目描述

  • 算法原理:快慢双指针(定义数组下标模拟指针)

    • slow:每次走一步
    • fast:每次走两步
      大概思路
  1. 问题转化:将数字按"快乐数"规则(每位平方和)不断迭代,看作一个隐式的链表。每个数字是链表的一个节点,其下一个节点是它各位平方和得到的数字。
  2. 判断循环 :如果迭代过程中出现 1,则链表到达"终点",该数是快乐数。如果进入循环(即出现之前出现过的数字),则该数不是快乐数。
  3. 快慢指针法
    • 定义两个"指针" slowfast,初始都等于原始数字 n
    • slow 每次计算一次各位平方和(走一步),fast 每次计算两次各位平方和(走两步)。
    • 如果 fast 最终等于 1,说明是快乐数。
    • 如果 fastslow 相遇(值相等)且不等于 1,说明进入了循环,不是快乐数。

      代码

4.盛最多水的容器

  • 题目盛最多水的容器

  • 题目描述

  • 算法原理:相撞双指针(定义数组下标模拟指针)

    • left:水柱左侧
    • right:水柱右侧

大概思路

代码

5.有效三角形的个数

  • 题目链接有效三角形的个数

  • 题目描述

  • 算法原理:双指针

    • left:指向a
    • right:指向b
      法一:暴力枚举,但是会超时
      法二:利用单调性,使用双指针
      大概思路:固定最大数c;在最大数的左区间,使用双指针算法,根据最小的两边之和大于第三边,即a+b>c,快速统计出符合要求的三元组的个数

      代码

6.和为s的两个数

大概思路:

  1. 问题转化 :在递增排序 的数组中,寻找两个数,使它们的和等于目标值 target
  2. 双指针法
    • 初始化两个指针:left 指向数组起始位置(最小元素),right 指向数组末尾(最大元素)。
    • 计算当前和 sum = nums[left] + nums[right]
    • 如果 sum == target,找到答案,返回这两个数。
    • 如果 sum < target,说明当前和太小,需要增大,因此 left 右移(选择更大的数)。
    • 如果 sum > target,说明当前和太大,需要减小,因此 right 左移(选择更小的数)。

代码

7.三数之和

大概思路:

  • 1.排序;
  • 2.固定一个数numsi;
  • 3.在该数的后面区间,利用"双指针算法"快速找到两个数为-numsi(此步原理同求两数之和的算法原理);
    • 细节问题:
      • 1.去重:找到一种结果之后 ,left和right要跳过重复的元素;使用完一次双指针之后,i也要跳过重复的元素。
      • 2.不漏:找到一种结果之后,缩小区间,继续找。
        代码:

        练习:四数之和
        提示:排序+固定一个数+三数之和算法原理(同样注意去重)
相关推荐
从琳开始9892 小时前
优选算法——滑动窗口(概念+解题模板+LeetCode例题讲解)
算法·leetcode·职场和发展
Nil2082 小时前
leetcode 94二叉树的中序遍历
算法·leetcode·职场和发展
不会就选b2 小时前
算法日常・每日刷题
算法
一只小小的芙厨2 小时前
最短路总结
数据结构·算法
致Great2 小时前
OpenAI 又把 Codex 往前推了一步: 以后做 Agent,没必要都造一个聊天框
算法
aqiu1111114 小时前
【算法刷题】蓝桥杯/AtCoder:删除元素后的中位数问题(Symmetry / Median)
算法·蓝桥杯·排序·中位数
圣保罗的大教堂4 小时前
leetcode 1386. 安排电影院座位 中等
leetcode
看我眼色行事^ \/ ^4 小时前
2024.05.11 360春招WEB前端编程题
算法
一只肥瘫瘫4 小时前
编码器 PLL 角度与速度观测器原理
人工智能·算法