Leetcode287_寻找重复数

文章介绍了如何利用快慢指针的方法解决LeetCode中的一个问题,即在一个给定的整数数组中找到唯一重复的数,算法保证不修改数组且仅使用O(1)的额外空间。通过将数组视为链表并找到环的入口来解决此问题。
摘要由CSDN通过智能技术生成

1.leetcode原题链接:. - 力扣(LeetCode)

2.题目描述

给定一个包含 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

示例 3 :

输入:nums = [3,3,3,3,3]
输出:3

提示:

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

3.实现方法

思路:使用快慢指针

    把 nums 看成是顺序存储的链表,nums 中每个元素的值是下一个链表节点的地址,如果 nums 有重复值,说明链表存在环,本问题就转化为了找链表中环的入口节点,因此可以用快慢指针解决。
比如数组
[3,2,1,4,8,6,2]

保存为

[0,1,2,3,4,5,6]

[3,2,1,4,8,6,2]


整体思路如下:
 第一阶段,寻找环中的节点
a) 初始时,都指向链表第一个节点 nums[0];
b) 慢指针每次走一步,快指针走两步;
c) 如果有环,那么快指针一定会再次追上慢指针;相遇时,相遇节点必在环中
 第二阶段,寻找环的入口节点(重复的地址值)
d) 重新定义两个指针,让 before,after 分别指向链表开始节点,相遇节点
e) before 与 after 相遇时,相遇点就是环的入口节点


第二次相遇时,应该有:
慢指针总路程 = 环外 0 到入口 + 环内入口到相遇点 (可能还有 + 环内 m 圈)
快指针总路程 = 环外 0 到入口 + 环内入口到相遇点 + 环内 n 圈
并且,快指针总路程是慢指针的 2 倍。所以:
环内 n-m 圈 = 环外 0 到入口 + 环内入口到相遇点。
把环内项移到同一边,就有:
环内相遇点到入口 + 环内 n-m-1 圈 = 环外 0 到入口
所以,从环外 0 开始,和从相遇点开始,走同样多的步数之后,一定可以在
入口处相遇。所以第二阶段的相遇点,就是环的入口,也就是重复的元素。

    //快慢指针
public int findDuplicate(int[] nums) {
    //定义快慢指针
    int slow=0;
    int fast=0;

    //1. 寻找环内的相遇点
    do{
        // 快指针一次走两步,慢指针一次走一步
        slow=nums[slow];
        fast=nums[nums[fast]];
    }while(slow!=fast);

    //循环结束,slow和fast相等,都是相遇点
    //2. 寻找环的入口点
    // 另外定义两个指针,固定间距
    int before=0;
    int after=slow;

    while(before!=after){
        before=nums[before];
        after=nums[after];
    }
    // 循环结束,相遇点就是环的入口点,也就是重复元素
    return before;
}

  • 23
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@好好学习天天向上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值