287. Find the Duplicate Number 寻找重复数
来源:互联网 发布:金十数据官方网站 编辑:程序博客网 时间:2024/05/18 01:17
Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate element 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 extra space.
- Your runtime complexity should be less than
O(n2)
.
Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.
这道题给了我们n+1个数,所有的数都在[1, n]区域内,首先让我们证明必定会有一个重复数,这不禁让我想起了小学华罗庚奥数中的抽屉原理(又叫鸽巢原理), 即如果有十个苹果放到九个抽屉里,如果苹果全在抽屉里,则至少有一个抽屉里有两个苹果,这里就不证明了,直接来做题吧。题目要求我们不能改变原数组,即不能给原数组排序,又不能用多余空间,那么哈希表神马的也就不用考虑了,又说时间小于O(n2),也就不能用brute force的方法,那我们也就只能考虑用二分搜索法了,我们在区别[1, n]中搜索,首先求出中点mid,然后遍历整个数组,统计所有小于等于mid的数的个数,如果个数大于mid,则说明重复值在[mid+1, n]之间,反之,重复值应在[1, mid-1]之间,然后依次类推,直到搜索完成,此时的low就是我们要求的重复值,参见代码如下:
解法一:
class Solution {public: int findDuplicate(vector<int>& nums) { int low = 1, high = nums.size() - 1; while (low < high) { int mid = low + (high - low) * 0.5; int cnt = 0; for (auto a : nums) { if (a <= mid) ++cnt; } if (cnt <= mid) low = mid + 1; else high = mid; } return low; }};笔记:如果要求时间复杂度不能为O(n)或者O(n^2),可以考虑使用额外空间(哈希表),或者采用二分查找法(时间复杂度为O(log(n)))。
经过热心网友waruzhi的留言提醒还有一种O(n)的解法,并给了参考帖子,发现真是一种不错的解法,其核心思想快慢指针在之前的题目Linked List Cycle II中就有应用,这里应用的更加巧妙一些,由于题目限定了区间[1,n],所以可以巧妙的利用坐标和数值之间相互转换,而由于重复数字的存在,那么一定会形成环,我们用快慢指针可以找到环并确定环的起始位置,确实是太巧妙了!
class Solution {public: int findDuplicate(vector<int>& nums) { int slow = 0, fast = 0, t = 0; while (true) { slow = nums[slow]; fast = nums[nums[fast]]; if (slow == fast) break; } while (true) { slow = nums[slow]; t = nums[t]; if (slow == t) break; } return slow; }};
笔记:首先确定映射关系,从而形成带有环的链表。其次知道链表环的入口即为需要求解的重复数据,先用快慢指针找到环内某一节点,再从该节点和原点同时出发,经数学推导可知,它们首次相遇的节点即为链表环的入口,即为ans。
- 287. Find the Duplicate Number 寻找重复数
- LeetCode-287. Find the Duplicate Number (JAVA)寻找重复元素
- 287. Find the Duplicate Number 找到重复出现的数
- 【Leecode】287Find the Duplicate Number找到重复的数
- leetcode 287. Find the Duplicate Number,数组中找重复的数
- LeetCode 287. Find the Duplicate Number(找重复数字)
- 287.leetcode Find the Duplicate Number(hard)[数组 重复元素]
- 287. 发现重复的数量(Find the Duplicate Number)
- Find the Duplicate Number--重复数字问题
- 287. Find the Duplicate Number
- 287. Find the Duplicate Number
- 287. Find the Duplicate Number
- 287. Find the Duplicate Number
- 287. Find the Duplicate Number
- 287. Find the Duplicate Number
- 287. Find the Duplicate Number
- 287. Find the Duplicate Number
- 287. Find the Duplicate Number
- Build Path
- Java中守护线程
- react集成 VS 继承
- 性能测试体系的知识分享
- Java 移位操作符注意
- 287. Find the Duplicate Number 寻找重复数
- Linux技巧: Linux终端打印如何设置不同的颜色及显示方式
- Nginx负载均衡-如何自定义URL中的hash key
- C++类中的静态成员变量和静态成员函数的作用
- Unity3D的SystemInfo类,用于获取运行设备硬件信息(CPU、显卡、类型等)
- leetcode 106. Construct Binary Tree from Inorder and Postorder Traversal
- Delphi根据方法名调用方法
- SSM框架整合(IntelliJ IDEA + maven + Spring + SpringMVC + MyBatis)
- Windows下VS2013编译Caffe完全手册