算法从零到精通 (一) ~ 快慢双指针

1. 前言

快慢双指针是一种常用的算法技巧,通常用于解决涉及链表或数组的问题。它的基本思想是使用两个指针,一个移动速度快(快指针),一个移动速度慢(慢指针),来解决特定的问题。这两个指针通常从序列的起始位置开始,并以不同的步伐向前移动,直到达到特定的条件为止。

  • 快慢双指针是指在算法处理过程中,使用两个指针,分别从序列的起始位置出发,按照不同的步伐向前移动,直到满足某种条件。通常快指针的移动速度比慢指针快,这样可以加快算法的执行速度。
  • 判断链表是否有环:快指针每次移动两步,慢指针每次移动一步,如果存在环,快指针最终会追上慢指针。

  • 找到链表的中间节点:快指针每次移动两步,慢指针每次移动一步,当快指针到达链表末尾时,慢指针所在位置即为中间节点。

  • 移除排序数组中的重复项:使用快慢指针,当快指针遇到不同的元素时,将其复制到慢指针位置,然后慢指针前进一步。

 2. 我对快慢指针的理解

1. 数组划分

  1. cur:从左到右扫描数组,遍历数组(快指针)
  2. dest:已处理的区间内,非零元素的最后一个位置
  3. cur(快指针)遇到符合题意的值,把他加入这个区间。一般是先dest++然后和cur交换

如何做到维护该区间一直到结束,是解题的关键。

// 符合题意           不符合题意            未处理元素
// [0~dest]        [dest + 1 ~ cur]       [cur + 1 ~ n]

达到最终的目的就是持续这三块区域的关系

2. 判断是否成环

快指针每次移动两步,慢指针每次移动一步,如果存在环,快指针最终会追上慢指针。

3 例题分析

3.1 移动零 (数组划分)

 

public void moveZeroes(int[] nums) {// 符合题意(非0元素)    不符合题意(0)    未处理元素// [0~dest]        [dest + 1 ~ cur]       [cur + 1 ~ n]// 要想维护上面的关系到结束,必须让cur遇到符合题意的和dest后一个元素(不符合题意的交换),//                        然后让dest++(扩大符合题意的范围),继续维护该区间int n = nums.length, cur = 0, dest = -1;while(cur != n){if (nums[cur] != 0){//遇到符合题意的,交换来维持三个区间关系dest++;int temp = nums[dest];nums[dest] = nums[cur];nums[cur] = temp;}cur++;}}

3.2 去重

下面的图,就是我对上题一步步的分析:

只要一直维持这三个区域到结束,就可以解答本题。

如何维持,就成了解答本题的关键。

    /*** 思路分析:* 1. dest(慢指针):确定没有重复元素的最后一个位置, cur(快指针):扫描完的最后一个位置* 2. 通过比较快慢指针的内容确定是否重复 (因为非严格递增,相同的都是连续的)* 3. 遇到一个不重复元素,就是符合[0 ~ dest]区间,就和dest+1不符合该区间的交换位置** @param arr* @return*/public static int[] arrayDeduplication(int[] arr) {//默认第一个元素不重复int n = arr.length, dest = 0, cur = 1;while (cur < n) {if (arr[cur] != arr[dest]) {//找到一个不符合题意的dest++;int temp = arr[dest];arr[dest] = arr[cur];arr[cur] = temp;}cur++;}return Arrays.copyOf(arr,dest + 1);}public static void main(String[] args) {int[] arr = {1, 1, 4, 4, 5, 6, 7, 7, 8, 8, 8, 8, 8};int[] distinction = arrayDeduplication(arr);System.out.println(Arrays.toString(distinction));System.out.println(Arrays.toString(arr));}

3.3 复写零

思路分析:

因为正序会造成覆盖,比如 0 1 2  正序读0索引->会变成 0 0 1,下次读1索引就被覆盖了。 

  1. 先判断要舍弃的元素。(因为要复写,数组大小不变总要舍去)
  2. 从后往前复写,0写两次,其余写一次
  3. 判断临界情况,防止最后一个为0且数组长度不够

剩下的内容代码有详细的注释。 

  // 正着写会被覆盖,因此倒序,倒序要确定复写舍弃的元素(复写位置),最后处理临界:cur越界// 1. 通过 0 cur移动两步 和 非0 cur移动一步,确定从dest位置开始复写// 2. 倒序开始写,dest读取到0复写 cur写两遍  非0  cur写一遍// 3. 处理临界:最后一个修改成0, dest-2  cur-1public static void duplicateZeros(int[] arr) {//因为读完写,所以dest(慢指针)为0,cur为-1int n = arr.length, dest = 0, cur = -1;//1.确定dest位置while(dest < n){if (arr[dest] == 0){//写两边cur++;cur++;}else {//写一遍cur++;}if (cur >= n - 1) break;//写到最后或者写过(最后一个为0),dest就不需要读了dest++;}//3. 处理临界if (cur == n){arr[n - 1] = 0;cur--;cur--;dest--;}//此时dest后面就是舍弃的元素//2. 倒序复写while(dest >= 0){if (arr[dest] == 0){//写两边arr[cur--] = 0;arr[cur--] = 0;}else {//写一遍arr[cur--] = arr[dest];}dest--;}}

 

3.4 快乐数(判断环)

 通过数字的取平方和来模拟移动,取一次移动一步,俩次移动两步,这样就可以模拟链表。和判断链表是否有环,原理一样,仅需判断链表中元素是否为1即可。

为什么是必定有环的呢???

原因就是鸽巢原理,所以数据范围有限的情况下,必定有环。5个人有6个糖,必定有一个人是有两个糖即以上的。

public class Test3 {//通过数来模拟指针移动,和判断链表是否有环,原理一样//仅需判断链表中元素是否为1即可//要么是1,要么无限循环的原因就是鸽巢原理,所以数据范围有限的情况下,必定有环public boolean isHappy(int n) {int slow = n, fast = bitSum(n);while(slow != fast){slow = bitSum(slow);fast = bitSum(bitSum(fast));}return slow == 1;}//求一个数各个元素的平方和,相当于移动一次private int bitSum(int num){int sum = 0;while(num != 0){int t = num % 10;sum += t * t;num /= 10;}return sum;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Vue中el的两种写法

大家好我是前端寄术区博主PleaSure乐事。今天了解到了Vue当中有关el的两种写法&#xff0c;记录下来与大家分享&#xff0c;希望对大家有所帮助。 方法一 解释 第一种方法我们直接用new创建并初始化一个新的 Vue 实例&#xff0c;并定义了 Vue 实例的数据对象&#xff0c;在给…

低代码如何加速数字化转型

数字化转型&#xff0c;正日益决定企业成功的关键。这里的一个关键因素是它可以以更快的速度和质量来实施技术计划。在当今瞬息万变的商业环境中&#xff0c;战略性地采用低代码平台对于旨在加快上市时间、增强业务敏捷性和促进跨团队无缝协作的首席技术官来说至关重要。日益增…

动手学深度学习——6.循环神经网络

1.序列模型 处理序列数据需要统计工具和新的深度神经网络架构。 为了简单起见&#xff0c;我们以 图8.1.1所示的股票价格&#xff08;富时100指数&#xff09;为例。 图8.1.1 近30年的富时100指数 其中&#xff0c;用&#x1d465;&#x1d461;表示价格&#xff0c;即在时间…

江科大/江协科技 STM32学习笔记P6

文章目录 LED闪烁&LE流水&蜂鸣器一、操作STM32的GPIO步骤二、RCC库函数什么是AHB与APB&#xff1f; 三、GPIO库函数GPIO初始化选择IO接口工作方式 四、四种方法实现LED闪灯 LED闪烁&LE流水&蜂鸣器 一、操作STM32的GPIO步骤 1、使用RCC开启GPIO的时钟 2、使用…

UE/Unity加载倾斜摄影太卡问题-使用局部网格简化重构导出为FBX/OBJ

工具 OSGB源数据灵易智模倾斜摄影编辑平台(下称OPEditor) 与另一篇文章里描述的导出时指定LOD层级的网格简化效果的区别 本功能属于导出时指定LOD层级的网格简化方法的升级版&#xff0c;可以基于某一LOD层级的局部数据进行进一步拓扑重构与纹理重烘焙自定义程度较高&#xff…

西蒙学习法

西蒙学习法 《世界十大学习方法》之西蒙学习法

Python 基于 Django 的内容管理系统库之feincms使用详解

概要 在现代 Web 开发中,内容管理系统(CMS)已经成为管理和发布内容的重要工具。FeinCMS 是一个基于 Django 的简单且灵活的内容管理系统,它专注于提供一种轻量级但功能强大的 CMS 解决方案。对于开发者来说,FeinCMS 提供了一种易于扩展和定制的方式,可以满足不同项目的需…

MongoDB教程(二十一):MongoDB大文件存储GridFS

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; 文章目录 引言一、GridFS…

数据库概念以及增删改

1.概念 、 2.通用语法 3.数据增删改

在 Postman 中设置全局 token

目录 问题描述解决方案 问题描述 在使用 Postman 进行接口测试时&#xff0c;经常会遇到在 Header 中添加 token 的情况。当接口数量较多时&#xff0c;需要为每个接口进行设置&#xff0c;而且当 token 失效时需要重新获取并设置&#xff0c;这样一来效率较低。 解决方案 下…

Python | Leetcode Python题解之第283题移动零

题目&#xff1a; 题解&#xff1a; class Solution:def moveZeroes(self, nums: List[int]) -> None:n len(nums)left right 0while right < n:if nums[right] ! 0:nums[left], nums[right] nums[right], nums[left]left 1right 1

TikTok Shop全托管上线JIT,并预计10月开放西班牙和爱尔兰站点

据悉&#xff0c;TikTok Shop官方近期在其全托管平台上正式推出了JIT&#xff08;Just-In-Time&#xff09;生产模式&#xff0c;这一创新举措彻底颠覆了传统供应链流程&#xff0c;实现了“先有订单&#xff0c;再精准供货”的高效运营模式。对于广大卖家而言&#xff0c;这无…

师资培训丨AIGC 技术与大模型应用开发实战线下广州班莅临泰迪智能科技参观调研

7月23日&#xff0c;2024年第二期全国数字人才技能提升师资培训班——AIGC 技术与大模型应用开发实战线下广州班莅临广东泰迪智能科技股份有限公司产教融合实训基地参观调研&#xff0c;来自全国各地三十多名高校教师参与本次活动。泰迪智能科技董事长张良均、校企合作经理吴桂…

PostgreSQL的学习心得和知识总结(一百四十九)|psql 的使用技巧:设置、预设、回显和已保存的查询

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…

rk3588s 定制版 USB adb , USB2.0与USB3.0 区别,adb 由typeC 转换到USB3.0(第二部分)

硬件资源&#xff1a; rk3588s 核心板定制的地板 软件资源&#xff1a; 网盘上的 android12 源码 1 硬件上 客户只想使用 type c 接口中的 usb2.0 OTG 。在硬件上&#xff0c;甚至连 CC芯片都没有连接。 关于一些前置的知识。 1 USB2.0 与 USB3.0 的区别。 usb3.0 兼容2.0 …

秋招复习笔记——八股文部分:网络TCP

TCP 三次握手和四次挥手 TCP 基本认识 序列号&#xff1a;在建立连接时由计算机生成的随机数作为其初始值&#xff0c;通过 SYN 包传给接收端主机&#xff0c;每发送一次数据&#xff0c;就「累加」一次该「数据字节数」的大小。用来解决网络包乱序问题。 确认应答号&#xf…

NOIP图论 最小生成树——Prim算法(详细图解)

最小生成树的概念 经典题目 prim算法简介 prim算法解析 &#xff08;详细图解&#xff09; 代码实现 代码实战 最小生成树的概念 在一给定的无向图G (V, E) 中&#xff0c;(u, v) 代表连接顶点 u 与顶点 v 的边&#xff0c;而 w(u, v) 代表此的边权重&#xff0c;若存在 …

利用Django和Ansible实现自动化部署

在软件开发的快节奏世界中&#xff0c;自动化部署是提高开发效率和确保软件质量的关键。Django是一个功能强大的Python Web框架&#xff0c;它允许开发者快速构建安全、可扩展的Web应用。Ansible则是一个简单且强大的自动化工具&#xff0c;它可以用于配置系统、部署软件以及执…

职业本科Web全栈式开发实训室解决方案

一、专业背景 随着网络普及和发展&#xff0c;网站作为一种很强大的工具和平台愈来愈融入了人们的生活&#xff0c;而与用户关系最密切的前端技术也逐渐获得应有的重视。咱们能够看到前端重构的行业发展潜力巨大&#xff0c;各大知名的网络公司对前端人才的求饥若渴。近年来HT…

DiffusionModel-Classifier Free Guidance Diffusion

论文: https://arxiv.org/abs/2207.12598 MOTIVATION We are interested in whether classifier guidance can be performed without a classifier. Classifier guidance complicates the diffusion model training pipeline it requires training an extra classifierthis c…