剑指 Offer 03. 数组中重复的数字 - 力扣(LeetCode)
(1)Arrays.sort(array),判断当前与下一个元素是否相等,时间O(nlogn),空间O(logn)
(2)哈希表,遍历,判断哈希表是否已有该元素,没有就存入哈希表,有就返回,O(n),O(n)
(3)原地哈希,萝卜坑,鸽巢原理,下面贴几个大佬的解释,时间O(n),空间O(1)
巧妙利用了0到n-1这个范围
萝卜坑解释:
- 所谓原地交换,就是如果发现这个坑里面的萝卜不是这个坑应该有的萝卜,就看看你是哪家的萝卜,然后把你送到哪家,再把你家里现在那个萝卜拿回来。
- 拿回来之后,再看看拿回来的这个萝卜应该是属于哪家的,再跟哪家交换。
- 就这样交换萝卜,直到想把这个萝卜送回它家的时候,发现人家家里已经有了这个萝卜了(双胞胎啊),那这个萝卜就多余了,就把这个萝卜上交给国家。
交换萝卜(原地交换,C++/Python3) - 数组中重复的数字 - 力扣(LeetCode)
原地置换,时间空间100% - 数组中重复的数字 - 力扣(LeetCode)
(4)二分查找,用时间换空间,时间O(nlogn),空间O(1)
public int findRepeatNumber(int[] nums) {
//统计nums中元素位于0到m的数量,如果数量大于这个值,那么重复的元素肯定是位于0到m的
int min = 0 ;
int max = nums.length-1;
while(min<max){
int mid = (max+min)>>1;
int count = countRange(nums,min,mid);
if(count > mid-min+1) {
max = mid;
}else{
min = mid+1;
}
}
最后min=max
return min;
}
//统计范围内元素数量,时间O(n)
private int countRange(int[] nums,int min,int max){
int count = 0 ;
for(int num:nums){
if(num>=min && num<=max){
count++;
}
}
return count;
}
大家有兴趣可以看看这道题,很像,解法右二分查找,和快慢指针(为什么上面议题不能用呢),等我想明白在更新,先复习别的题去了