“快慢指针”思想在物理或者逻辑循环中的应用

news2024/11/27 10:41:52

1 基础概念

1.1 什么是物理循环和逻辑循环?

物理循环是指物理索引访问顺序上相邻,逻辑上也相邻,比如循环链表,逻辑循环则指物理的索引上不一定相邻

1.2 快慢指针本质上可以解决逻辑循环问题,而物理循环也属于逻辑循环问题。

2 用快慢指针找出物理循环

2.1 LC141. 环形链表

public class Solution {
    public boolean hasCycle(ListNode head) {
        if(head==null||head.next==null)return false;
        ListNode f=head;
        ListNode s=head;

        while(f!=null&&f.next!=null){
            f=f.next.next;
            s=s.next;
            if(f==s){
                return true;
            }
        }
        return false;
    }
}

3 用快慢指针找出逻辑循环

3.1 LC457. 环形数组是否存在循环

在这里插入图片描述

3.1.1 解析

务必参考题解:快慢指针解法

class Solution {
    public boolean circularArrayLoop(int[] nums) {
        int n=nums.length;
        for(int i=0;i<n;i++){
            if(nums[i]==0)continue;
            int s=i;
            int f=next(nums,i);
            while(nums[s]*nums[f]>0&&nums[s]*nums[next(nums,f)]>0){
                if(s==f){
                    if(s!=next(nums,s)){
                        return true;
                    }else{
                        break;
                    }
                }
                s=next(nums,s);
                f=next(nums,next(nums,f));
            }

            int add=i;

            while(nums[add]*nums[next(nums,add)]>0){
                nums[add]=0;
                add=next(nums,add);
            }
        }
        return false;
    }
    int next(int nums[],int i){
        int n=nums.length;
        return ((i+nums[i])%n+n)%n;
    }
}

3.1.2 Q1:针对这道题,为什么可以用快慢指针呢?快慢指针本身不是针对链表嘛?而且每次只能走一步啊

您的疑问是非常合理的。快慢指针方法通常用于链表环路检测,但其实它也可以适用于这种环形数组问题。这里的关键在于理解快慢指针方法的本质:它是一种用于检测循环或周期性的算法。

在环形数组问题中,即使每次移动的步数不是一步,我们仍然可以使用快慢指针。在这个问题中,"快指针"每次移动两个nums[i]的距离,而"慢指针"每次移动一个nums[i]的距离。这种设置保证了如果存在一个循环,快指针最终会追上慢指针。这就是为什么可以使用快慢指针方法来解决这个问题。

具体到这个问题:

  • 每个元素nums[i]指示从当前位置应该移动的步数,正数表示向前移动,负数表示向后移动。
  • 环形数组意味着数组是循环的,即从数组末尾的下一个元素是数组开头的元素。
  • 快慢指针在这里是用来检测循环的存在。如果存在一个循环,那么快指针最终会在某个点上追上慢指针。
  • 在追踪快慢指针的过程中,还需要考虑移动的方向。如果在移动过程中方向改变(即从正转负或从负转正),则当前路径不构成有效循环。

因此,尽管这个方法最初是为链表设计的,但其检测循环的基本原理在环形数组问题中同样适用。

3.1.3 Q2:这里的步数是指逻辑上位置的步数对吧?

是的,您理解得正确。在这个环形数组问题中,"步数"指的是逻辑上位置的步数。具体来说:

  • 数组中的每个元素 nums[i] 表示从位置 i 出发应该移动的步数。
  • 如果 nums[i] 是正数,则表示向前(即下标递增的方向)移动 |nums[i]| 步。
  • 如果 nums[i] 是负数,则表示向后(即下标递减的方向)移动 |nums[i]| 步。
  • 由于数组是环形的,所以到达数组的末端后会再次从头开始,反之亦然。

在这个问题的上下文中,步数并不是指物理意义上的步行距离,而是指在数组索引上的移动距离。例如,如果 nums[i] = 3,则意味着从索引 i 向前移动3个索引位置。由于是环形数组,当超过数组末端时,计数会从数组开头继续。

3.1.4 Q3:对于快慢指针而言,只要存在环,无论快和慢指针的的初始位置怎么变,最终快慢可以相遇对吗(解释代码中slow和fast初始位置为什么设置的不同)

是的,对于快慢指针法来说,只要存在环,快指针最终都会追上慢指针,从而使两者相遇。这个结论是基于以下几个关键点的:

  1. 不同速度:快指针的移动速度是慢指针的两倍。这意味着如果存在一个环,快指针每轮会逐渐接近慢指针。

  2. 循环性:由于环的存在,快慢指针都会不断地绕环运动。这确保了,只要存在环,快慢指针永远不会“走出”环并停止。

  3. 相遇条件:快慢指针在环中的相对位置每次循环都会变化。由于快指针每次循环比慢指针多走一圈,它们最终必然会在某个点相遇。

这些原则不仅适用于链表中的环检测,也同样适用于类似的环形数组问题。关键是环的存在以及快慢指针的相对速度差。在实际应用中,初始位置一般会从一个固定点开始,例如数组的起始位置,以确保能够覆盖所有可能的环。

3.4.5 (1) 在环中,如果让快指针走三步,慢指针走1步,也最终能相遇吗?(2) 在环中,如果让快指针走三步,慢指针走2步,也最终能相遇吗

在环形结构中,快慢指针是否能相遇取决于它们的相对速度差,而不仅仅是它们各自的速度。我们来分析一下您提出的两种情况:

  1. 快指针每次走三步,慢指针每次走一步:在这种情况下,快指针和慢指针之间的相对速度差是两步。这意味着如果存在一个环,快指针最终会追上慢指针。这是因为快指针每次循环都会逐渐接近慢指针,并最终在某个点与慢指针相遇。

  2. 快指针每次走三步,慢指针每次走两步:在这种情况下,快指针和慢指针之间的相对速度差是一步。这同样意味着如果存在一个环,快指针仍然会最终追上慢指针。虽然这种情况下快慢指针相遇的时间可能会比速度差更大的情况更长,但只要环存在,它们最终还是会相遇。

总结来说,只要快慢指针之间存在速度差,它们就会在环中最终相遇。速度差越大,相遇的可能性就越快出现。在实际应用中,通常选择让快指针的速度是慢指针的两倍,这样可以在保证检测效率的同时简化问题的复杂度。

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

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

相关文章

MCS-51系列与AT89C5x系列单片机的介绍与AT系列的命名规则

MCS-51系列与AT89C5x系列单片机 主要涉及MCS-51系列与AT89C5x系列单片机的介绍与AT系列单片机的命名规则 文章目录 MCS-51系列与AT89C5x系列单片机一、 MCS-51系列单片机二、AT89C5x系列单片机2.1 AT89C5x/AT89S5x系列单片机的特点2.2 AT89系列单片机的型号说明2.2.1 前缀2.2.2…

握这些员工管理技巧,助你打造高效团队!

人力资源是一个组织中至关重要的一环&#xff0c;而员工管理是确保团队高效运转的关键因素之一。一个优秀的经理需要具备多方面的技巧和能力&#xff0c;以便激发员工的潜力&#xff0c;促进合作和增加团队的效率。在这里&#xff0c;我将分享一些实用的员工管理技巧&#xff0…

使用肘部法则选择KMeans聚类中的k值

在这篇文章中&#xff0c;我们将讨论如何选择最好的k&#xff08;聚类数&#xff09;的k-Means聚类算法。 肘部法则简介 任何无监督算法的基本步骤是确定数据可以被聚类到的聚类的最佳数量。因为我们在无监督学习中没有任何预定义数量的聚类。我们倾向于使用一些可以帮助我们…

sar命令详解

sar是强大的linux系统活动状况收集、报告命令。可以收集CPU&#xff0c;内存&#xff0c;磁盘I/O&#xff0c;网络等诸多数据。对于性能分析是个可靠的利器。 安装 sar命令是sysstat下的一个工具&#xff0c;所以安装sar需要首先安装sysstat命令&#xff0c;可以考虑yum安装或…

UE Windows平台下Linux的交叉编译项目打包

UE Windows平台下Linux的交叉编译项目打包 交叉编译&#xff08;Cross-compilation&#xff09; 使得在以Windows为中心的工作流程中工作的游戏开发者能够以Linux为目标对项目进行打包。目前&#xff0c;只有Windows支持交叉编译。 交叉编译支持的平台 Windows | Linux-x86_…

有趣的代码——有故事背景的程序设计3

这篇文章再和大家分享一些有“背景”的程序设计&#xff0c;希望能够让大家学到知识的同时&#xff0c;对编程学习更感兴趣&#xff0c;更能在这条路上坚定地走下去。 目录 1.幻方问题 2.用函数打印九九乘法表 3.鸡兔同笼问题 4.字数统计 5.简单选择排序 1.幻方问题 幻方又…

【LeetCode】每日一题 2023_12_2 拼车(模拟/差分)

文章目录 刷题前唠嗑题目&#xff1a;拼车题目描述代码与解题思路学习大佬题解 刷题前唠嗑 LeetCode&#xff1f;启动&#xff01;&#xff01;&#xff01; 题目&#xff1a;拼车 题目链接&#xff1a;1094. 拼车 题目描述 代码与解题思路 func carPooling(trips [][]int…

智能优化算法应用:基于金鹰算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于金鹰算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于金鹰算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.金鹰算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

7个简单技巧,让你从容应对压力面试!

01-什么是压力面试&#xff1f; 压力面试是指有意制造紧张&#xff0c;以了解求职者将如何面对工作压力的一种面试形式。 事实上&#xff0c;压力面试不是单独存在的一类面试&#xff0c;往往是穿插在面试过程中。 面试人通过提出不礼貌、冒犯的问题&#xff0c;或者用怀疑、…

深入学习Synchronized各种使用方法

文章目录 前言一、synchronized关键字通用在下面四个地方&#xff1a;1.1synchronized修饰实例方法1.2synchronized修饰静态方法&#xff1a;1.3synchronized修饰实例方法的代码块1.4synchronized修饰静态方法的代码块2.读入数据 二.Sychronized关键特性2.1互斥2.2 刷新内存2.3…

Clion自定义管理和配置软件构建过程的工具(代替CMake)构建程序

在公司由于需要x86环境和其他arm环境&#xff0c;同时需要使用公司自定义的mine_x86或者mine_orin对代码进行编译。 编译命令如下mine_x86 build -Dlocal1 -j8,为使用Clion对程序进行调试&#xff0c;需要对程序进行设置。方便调试代码时能够断点查看变量。尝试了很多次&#…

python高级练习题库实验1(B)部分

文章目录 题目1代码实验结果题目2代码实验结果题目3代码实验结果题目4代码实验结果题目5代码实验结果题目总结题目1 打包糖果小游戏,用户输入糖果品牌与个数,还有一个盒子里面可以装多少个糖果,输出一些打印信息,如下图所示: 代码 print("Packaging lollies into…

基于springboot + vue大学生竞赛管理系统

qq&#xff08;2829419543&#xff09;获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;springboot 前端&#xff1a;采用vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xf…

详解十大经典排序算法(五):归并排序(Merge Sort)

算法原理 归并排序的核心思想是将一个大的数组分割成多个小的子数组&#xff0c;然后分别对这些子数组进行排序&#xff0c;最后将排序后的子数组合并起来&#xff0c;得到一个有序的大数组。 算法描述 归并排序&#xff08;Merge Sort&#xff09;是一种经典的排序算法&#x…

二百一十二、Flume——Flume实时采集Linux中的目录文件写入到HDFS中(亲测、附截图)

一、目的 在实现Flume实时采集Linux中的Hive日志写入到HDFS后&#xff0c;再做一个测试&#xff0c;用Flume实时采集Linux中的目录文件&#xff0c;即使用 Flume 监听Linux整个目录的文件&#xff0c;并上传至 HDFS中 二、前期准备 &#xff08;一&#xff09;安装好Hadoop、…

Linux使用root用户安装完MySQL软件后,配置MySQL这个普通用户登录

在 Linux 系统中&#xff0c;当您使用 root 用户安装 MySQL 后&#xff0c;系统会自动创建一个名为 mysql 的系统用户。这个 mysql 用户主要用于管理 MySQL 服务的运行&#xff0c;通常是没有登录系统的权限的。如果您希望使这个 mysql 用户能够登录到系统&#xff0c;您需要设…

JAVAEE初阶相关内容第十八弹--网络原理之TCP_IP【续集】

写在前 上一篇博客的重点内容主要讲了关于传输层的TCP协议、UDP协议。 点击跳转上一篇博客 重点介绍了协议的特点、协议端格式、需要重点理解并掌握TCP的工作机制&#xff08;十条&#xff09;。 TCP与UDP对比&#xff1f; TCP用于可靠传输的情况&#xff0c;应用于文件传输&am…

超完整的mysql安装配置方法(包含idea和navicat连接mysql,并实现建表)

mysql安装配置方法 1、下载mysql2、解压到指定的安装目录3、配置初始化文件my.ini4、配置用户变量和系统变量5、初始化mysql6、安装mysql服务并启动修改密码7、使用idea连接mysql8、使用Navicat可视化工具连接mysql&#xff0c;并实现新建数据库&#xff0c;新建表 1、下载mysq…

【数据结构与算法篇】八种排序 (C++实现)

多种排序算法的Cpp实现 一. 排序的概念及其运用排序的概念 二. 一图速览常见排序三. 排序的C实现1> 直接插入排序2> 希尔排序希尔排序代码实现(希尔所实现)希尔排序代码实现(优化版) 3> 选择排序选择排序的代码实现(同时选出最大和最小的元素) 4> 堆排序堆排序的代…

CSS面经(未完待续)

1. CSS选择器及其优先级 !important > 行内样式 > id选择器 > 类/伪类/属性选择器 > 标签/伪元素选择器 > 子/后台选择器 > *通配符 2. 重排和重绘是什么&#xff1f;浏览器的渲染机制是什么&#xff1f; 重排(回流)&#xff1a;当增加或删除dom节点&…