LeetCode 287. Find the Duplicate Number
来源:互联网 发布:美加净防晒霜 知乎 编辑:程序博客网 时间:2024/06/05 04:01
- 题目
- 题意
- 分析
- 方法一 On2
- 方法二 On
题目
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:
- You must not modify the array (assume the array is read only).
- You must use only constant, O(1) extra space.
- Your runtime complexity should be less than O(n2).
- There is only one duplicate number in the array, but it could be repeated more than once.
题意
给出一个数组nums,包含了n+1个取值为1~n整数,证明至少存在一个数重复。假设这里只有一个重复的数,把它找出来。
提示
1. 不能修改原数组(假设数组是只读的)
2. 只能使用常数O(1)额外的空间
3. 时间复杂度必须少于O(n^2)
4. 数组中至少会有一个重复的数,但是它可能重复多次。
分析
这道题不难,但是,题目对存储空间进行了严格的控制,并且要求时间复杂度为O(n^2)。
我一开始的想法比较简单,也能解决问题。也就是方法一,后面看到了另一种解法,感觉更高效,便也贴出来分析了,即方法二
方法一 O(n^2)
类似冒泡排序,用两个for循环,如果a[i] == a[j] ,则找到了重复的数。
其时间复杂度为O(n^2),空间复杂度为0。
int findDuplicate(vector<int>& nums) { for (int i = 0; i<nums.size(); i++) { for (int j = i + 1; j<nums.size(); j++) if (nums[i] == nums[j]) return nums[i]; }}
LeetCode 上跑53个测试样例,耗时555ms 。
方法二 O(n)
看到了一个更好的解法。
首先。数组的值是在1~n,数组长度为n+1,这个是一个很特别的设定,因为,数组的值作为下标是合法的。
比如数组 [1,3,4,2,1]
1->3->2->4->1->3->2->4->1->…3->2->4->1->
因为有重复的数,所以一定存在闭环,而重复的数则是环的入口。
那么我们可以利用 Linked List Cycle的做法,用一个fast和一个slow,fast每次走两步,slow每次走一步,那么它们必定在闭环某个位置相遇。
然后,就需要找到闭环的入口了。使fast = 0,这次,fast和slow一样,每次走一步,当fast = slow的时候,它们就走到了入口
开始 : slow = 1 fast = 3
第一次 : slow = 3 fast = 4
第二次 : slow = 2 fast = 3
第三次 : slow = 4 fast = 4 相遇了找闭环入口,即重复的数字
开始 : slow = 4 fast = 0
第一次 : slow = 1 fast = 1 找到入口
这样做的时间复杂度为O(n),空间复杂度度O(1)
int findDuplicate(vector<int>& nums) { if (nums.size()<1) return -1; int slow = nums[0], fast = nums[nums[0]]; while (fast != slow) { cout << fast << " " << slow << endl; slow = nums[slow]; fast = nums[nums[fast]]; } cout << "stop: " << fast << " " << slow << endl; fast = 0; while (fast != slow) { cout << fast << " " << slow << endl; fast = nums[fast]; slow = nums[slow]; } return slow;}
LeetCode 上跑53个测试样例,耗时12ms 。
- [leetcode] 287.Find the Duplicate Number
- [leetcode] 287. Find the Duplicate Number
- <LeetCode OJ> 287. Find the Duplicate Number
- Leetcode 287. Find the Duplicate Number
- Leetcode - 287. Find the Duplicate Number
- [LeetCode]287. Find the Duplicate Number
- LeetCode 287. Find the Duplicate Number
- 【leetcode】287. Find the Duplicate Number
- 【leetcode】287. Find the Duplicate Number
- leetcode 287. Find the Duplicate Number
- LCP287 LeetCode 287. Find the Duplicate Number
- [Leetcode]287. Find the Duplicate Number
- Leetcode题解 287. Find the Duplicate Number
- [LEETCODE] 287. Find the Duplicate Number
- [LeetCode] 287. Find the Duplicate Number
- <leetcode>287. Find the Duplicate Number
- [leetcode]287.Find the Duplicate Number
- LeetCode 287. Find the Duplicate Number
- 2017Google Codejam round1b Problem C. Pony Express
- 电商数据分析基础指标体系
- Configuring LabVIEW, LabVIEW DSC, NI Variable Engine, and Lookout to Work with the Windows Firewall
- ImageLoader网络加载图片
- Linux安装配置SVN服务
- LeetCode 287. Find the Duplicate Number
- lintcode 155 二叉树的最小深度
- NS 网络模拟和协议仿真黄化吉教材的修正——continue用例P24
- XMU 1612 刘备闯三国之桃园结义 【二分】
- 1057: 天平平衡 [递归]
- 下一个爱因斯坦或许出自超级人工智能阶段
- SEH 进阶(1)
- NYOJ-171-聪明的kk(第三届河南省程序设计大赛D题(简单dp))
- opencv从零开始——3. 了解通道,对比度,亮度