287. Find the Duplicate Number

本文介绍了一种利用快慢指针在O(n)时间内找到数组中重复数字的方法,此方法不修改原始数组且仅使用常数级额外空间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.

Note:

  1. You must not modify the array (assume the array is read only).
  2. You must use only constant, O(1) extra space.
  3. Your runtime complexity should be less than O(n2).
  4. There is only one duplicate number in the array, but it could be repeated more than once.

题目链接:


思路分析

给一个含有n+1个元素的数组,里面的元素的值一定在1-n之间。这个数组一定有重复的数字,找到这个重复的数字。

这个题目与Linked List Cycle是一样的,nums[0]相当于是链表的头;因为数组中有重复的数字,相当于链表中环的情况(可以理解为本来应该是一条线段的链表,因为一个重复的出现,把尾巴链到了自己身上。)

我们可以同样的用快慢两个指针,当fast和slow相遇了之后,将fast返回头部(不能乱选位置的),然后同样速度前进,再次相遇的时候一定是环开始的地方,也就是重复的元素了。

代码
class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        if (nums.size() < 2)
            return -1;
        int slow = nums[0];
        int fast = nums[nums[0]];
        while (fast != slow){
            slow = nums[slow];
            fast = nums[nums[fast]];
        }
        fast = 0;
        while (fast != slow){
            slow = nums[slow];
            fast = nums[fast];
        }
        return slow;
    }
};

时间复杂度: O(n)
空间复杂度: O(1)


反思

没能相当链表的方向上来。不过按照题目的要求,可以先排序一波,或者直接比对。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值