LeetCode-287. Find the Duplicate Number
来源:互联网 发布:瓷砖一开二加工费算法 编辑:程序博客网 时间:2024/05/01 22:04
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.
方法一:暴力搜索
题目中说明有且仅有一个重复数字,那么我们可以从前往后一个一个比较,只要找到了相同的数字就说明那个是重复的,返回结果。
时间复杂度:O(n^2)
空间复杂度:O(1)
时间复杂度过大,不满足题意,但测试可以通过。
class Solution { public int findDuplicate(int[] nums) { int duplicate=nums[0]; for(int i=0;i<nums.length;++i) { for(int j=i+1;j<nums.length;++j) { if(nums[i]==nums[j]) { duplicate=nums[i]; break; } } } return duplicate; }}
方法二:排序查找
先将所有数字排序,排序后重复的数肯定就在一起,只需要遍历一次数组就能找到。
时间复杂度:O(nlgn)
空间复杂度:O(1)
因为经过了排序,所以时间复杂度还是不满足题意,测试可以通过。
class Solution { public int findDuplicate(int[] nums) { int duplicate=nums[0]; Arrays.sort(nums); for(int i=1;i<nums.length;++i) { if(nums[i]==nums[i-1]) { duplicate=nums[i]; break; } } return duplicate; }}
方法三:利用额外空间
使用Map集合来保存每个数出现的次数,如果有数字重复出现,则返回该数字。后来看了官网中的推荐解答,里面用的是Set这个集合,比Map简单不少。
时间复杂度:O(n)
空间复杂度:O(n)
因为用到了额外空间,所以空间复杂度不满足题意,测试可以通过。
class Solution { public int findDuplicate(int[] nums) { int duplicate=nums[0]; Map<Integer,Integer> numsMap=new HashMap<>(); for(int num:nums) { if(!numsMap.containsKey(num)) numsMap.put(num,1); else { int newCount=numsMap.get(num); newCount++; numsMap.put(num,newCount); } } for(int num:nums) { if(numsMap.get(num)>1) { duplicate=num; break; } } return duplicate; }}
方法四:
上面三个不满足题意的方法都是我想到的,但是我实在没想出怎样在满足题目要求的前提下解决此题,后面看了推荐解答,发现实在太巧妙了,利用寻找环的起始点这一模型来解决。
这种方法之所以可行是因为
由于数组的n + 1个元素范围从1到n,我们可以将数组考虑成一个从集合{1, 2, …, n}到其本身的函数f。这个函数的定义为f(i) = A[i]。基于这个设定,重复元素对应于一对下标i != j满足 f(i) = f(j)。我们的任务就变成了寻找一对(i, j)。一旦我们找到这个值对,只需通过f(i) = A[i]即可获得重复元素。
更具体的解释说明请看
英文原版
中文翻译版
时间复杂度:O(n)
空间复杂度:O(1)
class Solution { public int findDuplicate(int[] nums) { int fast=0; int slow=0; while(true) { slow=nums[slow]; fast=nums[nums[fast]]; if(slow==fast) break; } int duplicate=0; while(true) { duplicate=nums[duplicate]; slow=nums[slow]; if(duplicate==slow) break; } return duplicate; }}
- [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
- 蓝牙HID知识【BLE HID:HOGP 设备开发指引】【 Keyboard/Keypad Page键码】
- 开发过程问题总结
- keras之lstm
- QT中PRO文件写法的详细介绍
- STL纵谈——阅读的重要性
- LeetCode-287. Find the Duplicate Number
- RocketMQ的消息存储
- 字符串的声明
- 面试题及解答
- 成功解析成功CHAK结尾的勒索病毒
- HTML-表单from
- android 读取excel数据并保存为xml文件
- Apache Tiles 学习(四)、Tiles实战
- (转)以C++为核心语言的高频交易系统的讨论?