寻找重复数-快慢指针

news2025/1/12 13:45:48

给定一个包含 n + 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n),可知至少存在一个重复的整数。

假设 nums 只有 一个重复的整数 ,返回 这个重复的数 。

你设计的解决方案必须 不修改 数组 nums 且只用常量级 O(1) 的额外空间。

示例 1:

输入:nums = [1,3,4,2,2]
输出:2
示例 2:

输入:nums = [3,1,3,4,2]
输出:3

提示:

1 <= n <= 1 0 5 10^5 105
nums.length == n + 1
1 <= nums[i] <= n
nums 中 只有一个整数 出现 两次或多次 ,其余整数均只出现 一次

进阶:

如何证明 nums 中至少存在一个重复的数字?
你可以设计一个线性级时间复杂度 O(n) 的解决方案吗?

数组形式的链表

题目设定的问题是 N+1 个元素都在 [1,n] 这个范围内。这样我们可以用那个类似于 ‘缺失的第一个正数’ 这种解法来做,但是题意限制了我们不能修改原数组,我们只能另寻他法。也就是本编题解讲的方法,将这个题目给的特殊的数组当作一个链表来看,数组的下标就是指向元素的指针,把数组的元素也看作指针。如 0 是指针,指向 nums[0],而 nums[0] 也是指针,指向 nums[nums[0]].
这样我们就可以有这样的操作

int point = 0;
while(true){
    point = nums[point]; // 等同于 next = next->next; 
}

链表中的环

假设有这样一个样例:[1,2,3,4,5,6,7,8,9,5]。如果我们按照上面的循环下去就会得到这样一个路径: 1 2 3 4 5 [6 7 8 9] [6 7 8 9] [6 7 8 9] . . .这样就有了一个环,也就是6 7 8 9。point 会一直在环中循环的前进。
这时我们设置两个一快(fast)一慢(slow)两个指针,一个每次走两步,一个每次走一步,这样让他们一直走下去,直到他们在重复的序列中相遇

在这里插入图片描述

int fast = 0, slow = 0;
while(true){
    fast = nums[nums[fast]];
    slow = nums[slow];
    if(fast == slow)
        break;
}

如上图,slow和fast会在环中相遇,先假设一些量:起点到环的入口长度为m,环的周长为c,在fast和slow相遇时slow走了n步,则fast走了2n步,fast比slow多走了n步,而这n步全用在了在环里循环(n%c==0)。当fast和last相遇之后,我们设置第三个指针finder,它从起点开始和slow(在fast和slow相遇处)同步前进,当finder和slow相遇时,就是在环的入口处相遇,也就是重复的那个数字相遇。

为什么 finder 和 slow 相遇在入口
fast 和 slow 相遇时,slow 在环中行进的距离是n-m,其中 n%c0。这时我们再让 slow 前进 m 步——也就是在环中走了 n 步了。而 n%c0 即 slow 在环里面走的距离是环的周长的整数倍,就回到了环的入口了,而入口就是重复的数字。
我们不知道起点到入口的长度m,所以弄个 finder 和 slow 一起走,他们必定会在入口处相遇。

class Solution:
    def findDuplicate(self, nums: list) -> int:
        slow, fast = 0, 0
        while True:
            slow = nums[slow]
            fast = nums[nums[fast]]
            if slow == fast:
                break
        finder = 0
        while True:
            finder = nums[finder]
            slow = nums[slow]
            if finder == slow:
                break
        return finder

参考

https://leetcode.cn/problems/find-the-duplicate-number/solution/kuai-man-zhi-zhen-de-jie-shi-cong-damien_undoxie-d/

https://leetcode.cn/problems/find-the-duplicate-number/solution/287-xun-zhao-zhong-fu-shu-by-ming-zhi-shan-you-m9r/

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

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

相关文章

使用 MATLAB 和 Simulink 对雷达系统进行建模和仿真

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

ClickHouse(二十五):ClickHouse 可视化工具操作

​​​​​​​ 进入正文前&#xff0c;感谢宝子们订阅专题、点赞、评论、收藏&#xff01;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; &#x1f3e1;个人主页&#xff1a;含各种IT体系技术&#xff0c;IT贫道_Apache Doris,大数据OLAP体系技术栈,Kerberos安全认证…

vite创建项目命令

1.第一步运行创建命令&#xff08;npm&#xff09; npm create vitelatest也可以使用yarn yarn create vite还可以 pnpm create vite注意的地方&#xff1a;首次创建的时候会出现这个 Need to install the following packages:create-vitelatest Ok to proceed? (y) 直接y就…

如何设计一个订单号生成服务?

一、数据量的大小二、有意义的ID三、高可用四、高性能五、唯一性六、包含分库分表的业务字段七、实战 1) Redis2) Leaf-segment 数据库生成3)Leaf-snowflake方案4) UUID 如何设计要给订单号生成服务 一、数据量的大小 在设计订单号的生成服务时候&#xff0c;我们首先要考虑的…

【深度学习 | ResNet核心思想】残差连接 跳跃连接:让信息自由流动的神奇之道

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

ms-tpm-20-ref 在linux下编译

1、代码地址&#xff0c; GitHub - microsoft/ms-tpm-20-ref: Reference implementation of the TCG Trusted Platform Module 2.0 specification.Reference implementation of the TCG Trusted Platform Module 2.0 specification. - GitHub - microsoft/ms-tpm-20-ref: Refe…

企业/公司电脑图纸加密软件系统——「天锐绿盾加密软件」

天锐绿盾是一款企业级透明加密软件&#xff0c;旨在保护企业或设计院的图纸文件和电子文档&#xff0c;防止信息泄露和数据安全问题。 ​ 天锐绿盾采用了核心驱动层的透明加密 技术&#xff0c;可以在操作系统层自动对所有需要加密的文档进行加密和解密&#xff0c;用户在使用加…

交换机的基本原理与配置(二)

目录 2. 以太网交换机 2.1 交换机设备简介 2.2交换机的工作原理 2.3交换机接口的双工模式 2. 以太网交换机 下面通过交换机设备简介&#xff0c;交换机的工作原理及交换机接口模式来了解以太网交换机。 2.1 交换机设备简介 交换机的品牌众多&#xff0c;像Cisco公司&#xf…

自动设置服务器全教程

亲爱的爬虫探险家&#xff01;在网络爬虫的世界里&#xff0c;自动设置代理服务器是一个非常有用的技巧。今天&#xff0c;作为一家代理服务器供应商&#xff0c;我将为你呈上一份轻松实用的教程&#xff0c;帮助你轻松搞定爬虫自动设置代理服务器。 一、为什么需要自动设置代…

华为OD-第K长的连续字母字符串长度

题目描述 给定一个字符串&#xff0c;只包含大写字母&#xff0c;求在包含同一字母的子串中&#xff0c;长度第 k 长的子串的长度&#xff0c;相同字母只取最长的那个子串。 代码实现 # coding:utf-8 # 第K长的连续字母字符串长度 # https://www.nowcoder.com/discuss/353150…

差分走线的要求

1 等长&#xff1a;等长是指两条线的长度要尽量一样长&#xff0c;是为了保证两个差分信号时刻保持相反极性。减少共模分量。 2等宽等距&#xff1a;等宽是指两条信号的走线宽度需要保持一致&#xff0c;等距是指两条线之间的间距要保持不变&#xff0c;保持平行。 对走线要求最…

pytorch下的scatter、sparse安装

知道自己下载的torch配置 import torch print(torch.__version__) print(torch.version.cuda)进入网站&#xff0c;选择自己配置 https://pytorch-geometric.com/whl/下载相应的包 安装 pip install ******.whl

办公网络布线(三)

目录 3.布线施工设计 3.1 宿舍楼布线设计 3.布线施工设计 如图所示为宿舍楼平面图。 3.1 宿舍楼布线设计 前面讲解了布线系统的常识及具体实施的细节&#xff0c;但在实际工作中&#xff0c;作为工程的实施人员往往需要根据甲方提供的建筑平面图图纸给出网络建设方案&#xf…

Commonjs和Es6语法规范的理解

ES6 module和CommonJS到底有什么区别&#xff1f; “ES6 module是编译时加载&#xff0c;输出的是接口&#xff0c;CommonJS运行时加载&#xff0c;加载的是一个对象” 这里的“编译时”是什么意思&#xff1f;和运行时有什么区别&#xff1f;“接口”又是什么意思&#xff1f;…

Oracle-rolling upgrade升级19c

前言: 本文主要描述Oracle11g升19c rolling upgrade升级测试&#xff0c;通过逻辑DGautoupgrade方式实现rolling upgrade&#xff0c;从而达到在较少停机时间内完成Oracle11g升级到19c的目标 升级介绍&#xff1a; 升级技术: rolling upgrade轮询升级&#xff0c;通过采用跨版…

PS gif修改背景颜色(附加图片)

文章目录 问题描述.mp4转换为.gif 解决方案gif更换背景修改背景具体操作第一步第二步第三步第四步第五步第六步 总结 大家好&#xff01;不知不觉又到周二了&#xff0c;农历&#xff1a;七月七&#xff0c;本来今天可以高高兴兴的度过一天&#xff0c;唉&#xff0c;接到领导布…

强训第38天

选择 D 0作为本地宿主机&#xff0c;127作为内部回送&#xff0c;不予分配 A B C C 存储在浏览器 D A B B D 网络延迟是指从报文开始进入网络到它离开网络之间的时间 编程 红与黑 红与黑__牛客网 #include <iostream> #include <stdexcept> #include <string…

【仿写框架之仿写Tomact】一、详解Tomcat的工作流程

文章目录 1、启动阶段2、监听阶段&#xff1a;3、请求处理阶段&#xff1a;4、发送请求处理后的响应 当涉及到Java Web应用程序的部署和运行&#xff0c;Apache Tomcat无疑是一个备受欢迎的选择。Tomcat作为一个开源的、轻量级的Java Servlet容器和JavaServer Pages (JSP) 容器…

排兵布阵很重要

以正合&#xff0c;以奇胜&#xff0c;排兵布阵很重要 【安志强趣讲《孙子兵法》第17讲】 第五章&#xff1a;势篇 【全文趣讲大白话】 善于打仗&#xff0c;能恰当的分兵&#xff0c;能借势。 【原文】 孙子曰&#xff1a;凡治众如治寡&#xff0c;分数是也&#xff1b;斗众如…

SFL214-100-21-10喷嘴挡板伺服阀

SFL214-100-21-10、SFL214-150-21-15、SFL214-100-32-40、SFL214-100-21-40、SFL216-230-21-40、SFL216-230-32-40采用千式力马达和两级液压放大器结构前置级为无摩撩副的双喷嘴挡板阀性能优良&#xff0c;动态响应高适用于对位置&#xff0c;力和速度进行闭环控制可用作三通阀…