287. Find the Duplicate Number
2016-05-10 15:07
495 查看
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
There is only one duplicate number in the array, but it could be repeated more than once.
加入忽略题目对时间复杂度(less than O(N^2))和空间复杂度(O(1))的要求,可以想到有以下几种方法:
(1)直接搜索法
时间复杂度O(N^2),空间复杂度O(1).
针对每个元素,向后寻找是否存在其重复元素。
(2)哈希表法
时间复杂度O(N),空间复杂度O(N).
用一个集合/map记录已经遍历过的数,如果已经有了说明是重复数字。(集合中元素不可重复,map中key不可重复)
(3)排序法
时间复杂度O(N*logN),空间复杂度O(1)/O(N). (如果不复制数组,则空间复杂度为O(1),但是排序时会改变原数组;复制数组则空间复杂度为O(N)).
然后看了网上的一些参考答案,寻找到一些符合题目要求的算法:
(1)二分法
由于这n+1个数字介于1~n之间,首先用二分法选择n/2作为比较对象,当整个数组中小于等于n/2的数字超过n/2,说明1~n/2之间肯定有重复数字,否则n/2~n之间肯定有重复数字,下次在有重复数字的区间内再次使用二分法。
元素index和元素本身之间存在一个映射关系,从下标0开始,可以产生一个类似链表的序列,如果存在重复元素,则会出现环路,我们就是要寻找环路的起点。
https://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare
有时间多看看==
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.
加入忽略题目对时间复杂度(less than O(N^2))和空间复杂度(O(1))的要求,可以想到有以下几种方法:
(1)直接搜索法
时间复杂度O(N^2),空间复杂度O(1).
针对每个元素,向后寻找是否存在其重复元素。
(2)哈希表法
时间复杂度O(N),空间复杂度O(N).
用一个集合/map记录已经遍历过的数,如果已经有了说明是重复数字。(集合中元素不可重复,map中key不可重复)
public int findDuplicate(int[] nums){ Map<Integer,Integer> myMap = new HashMap<Integer,Integer>(); //Set<Integer> mySet = new HashSet<Integer>(); for(int num:nums){ if(myMap.containsKey(num)) return num; myMap.put(num, 1); /* * if(mySet.contains(num)) return num; * mySet.add(num); */ } return 0; }
(3)排序法
时间复杂度O(N*logN),空间复杂度O(1)/O(N). (如果不复制数组,则空间复杂度为O(1),但是排序时会改变原数组;复制数组则空间复杂度为O(N)).
public int findDuplicateBySort(int[] nums){ Arrays.sort(nums); for(int i=1;i<nums.length;i++){ if(nums[i] == nums[i-1]) return nums[i]; } return 0; } public int findDuplicateBySortAndCopy(int[] nums){ int[] newArr = Arrays.copyOf(nums, nums.length); Arrays.sort(newArr); for(int i=1;i<nums.length;i++){ if(newArr[i] == newArr[i-1]) return newArr[i]; } return 0; }
然后看了网上的一些参考答案,寻找到一些符合题目要求的算法:
(1)二分法
由于这n+1个数字介于1~n之间,首先用二分法选择n/2作为比较对象,当整个数组中小于等于n/2的数字超过n/2,说明1~n/2之间肯定有重复数字,否则n/2~n之间肯定有重复数字,下次在有重复数字的区间内再次使用二分法。
public class Solution { public int findDuplicate(int[] nums) { int min = 0, max = nums.length-1; while(min<=max){ int mid = (max-min)/2+min; int count = 0; for(int i=0;i<nums.length;i++) if(nums[i]<=mid) count++; if(count<=mid) min = mid+1;//后半部分有重复 else max = mid-1; //前半部分有重复 } return min; } }(2)寻找环路法
元素index和元素本身之间存在一个映射关系,从下标0开始,可以产生一个类似链表的序列,如果存在重复元素,则会出现环路,我们就是要寻找环路的起点。
https://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare
有时间多看看==
相关文章推荐
- bzoj4460
- Struts1 和 Struts2区别
- 通过学习学生信息管理系统软件,C程序中,如何设计和编写一个应用系统
- 通过mac地址查询ip
- centos 6.7 ssh 免密码
- SQL Server与SQL Server Express的区别
- 开源Android-PullToRefresh下拉刷新源码分析
- 同步和异步的区别
- NoSQL basic knowledge
- 【S2HS学习笔记】第二章节:JSP/Servlet及相关技术详解
- iOS swift学习之入门详解(对象和类)
- 解决org.hibernate.QueryException illegal attempt to dereference collection 异常错误
- 织梦模板安装后不能显示css的解决办法
- oracle 11g导出表和索引的定义
- 常见算法
- 检查一个算术表达式中的括号是否匹配
- ios客户端学习-iOS使用png,jpg的区别
- PHP开发入门2---->PHP扩展开发入门2 HELLO WORLD
- bzoj 3120: Line
- PullToRefresh原理解析