1.题目
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1:
输入:[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof
2.题解
(1)没有任何要求的
HashMap:
HashMap<Integer,Integer> mp=new HashMap<Integer,Integer>();
for(int i=0;i<nums.length;i++){
if(mp.containsKey(nums[i])){int temp=mp.get(nums[i]);temp++;mp.put(nums[i],temp);}
else{mp.put(nums[i],1);}
}
for(Integer i:mp.keySet()){
if(mp.get(i)>1){return i;}
}
return -1;
排序
Arrays.sort(nums);
for(int i=1;i<nums.length;i++){
if(nums[i]==nums[i-1]){return nums[i];}
}
return -1;
(2)不修改数组
在创建一个新数组,对每个出现的数字进行统计,若有大于1的,立即返回(鸽巢原理)
class Solution {
public int findRepeatNumber(int[] nums) {
int[] result = new int[nums.length];
for(int j=0;j<result.length;j++) {
result[j]=-1;
}
for(int i = 0; i < nums.length; i++) {
if(nums[i]==result[nums[i]]) {
return nums[i];
} else {
result[nums[i]]=nums[i];
}
}
return -1;
}
}
(3)不修改数组,且原地O(1)
先找到数组总长度的中间数,在中间数的左边或者右边统计一个有多少个数字,若大于中间数则说明该边存在重复数,然后循环缩小范围,直至找到重复数。(此题好像不可以用,书里有这种算法)
3.效率
(1)鸽巢原理效率最高
(2)Hash
(3)排序