LeetCode-287. Find the Duplicate Number

Description

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.

Solution 1(C++)

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

            fast = 0;
            while (fast != slow)
            {
                fast = nums[fast];
                slow = nums[slow];
            }
            return slow;
        }
        return -1;
    }
};

后续更新

其他类似的题目可参考:

算法分析

这道题,其实很重要,LeetCode-141. Linked List Cycle,这道题其实告诉了我数列,array与链表之间完全是可以相互转换的。

当然,对数列的值有所要求,那就是数列的值是可以转换为索引的。当完成这一步之后,数列就可以转换为链表了。那就是将值转换为索引,然后由此可以访问下一个元素。

那么,成功将数列转换为链表之后,我们就可以换个角度看问题了,所谓数列中有重复元素,其实就是链表存在环。所以也可以使用“龟兔”赛跑的方法来判断是否存在环。

那么第一部分很明显,fast与slow是按照不同的速度遍历链表的,由于题目中的数组肯定存在闭环,所以,fast与slow一定会相遇。而且相遇在环中。但是,不是说在环中就意味着相遇的地方就是重复的元素,其实重复的元素应该是环的入口。因为环开始和结束的地方是同一个,这同一个地方就是要找到。

所以第二部分就是让fast从头开始走,slow保持原来的位置不变。二者按相同步长走,直到二者相遇,那么相遇的地方就是环的起点。这个是可以证明的。

简单的逻辑就是,假设环起点与链表起点距离为a,fast与slow相遇的点与环起点距离为c,环长度为b,那么可以证明:

a+c = Nb;

就是a+c是b的常数倍N,那么这时fast重新从起点出发,slow还是在c处,slow比fast多a+c,但是slow在环内,所以二者必然在经过一定时间(与N有关)后在起点相遇。

程序分析

略。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值