标签:shm 个数 初始化 正数 number 更改 重复数 slow 查找
思路
/**
* 使用HashMap 2ms 但不能满足 要求2
*/
public static int findDuplicate(int[] nums) {
int ans=0;
Map<Integer,Integer> map=new HashMap<>();
for (int num : nums) {
if (map.containsKey(num)) {
return num;
} else {
map.put(num, 1);
}
}
return ans
/**
* 2ms 但不满足要求 1
*
* 非重复的数字只会改一次正数变成负数,之后就不会访问了,
* 重复的数字会在第二次索引看到之前变为负数的值
*/
public int findDuplicate3(int[] nums){
for(int i=0;i<nums.length;i++){
if(nums[Math.abs(nums[i])]<0) return Math.abs(nums[i]);
nums[Math.abs(nums[i])]=-nums[Math.abs(nums[i])];
}
return -1;
}
原文思路参考:
liweiwei1419:使用二分法查找一个有范围的整数(结合抽屉原理)
/*
* 2ms
*
*/
public int findDuplicate(int[] nums) {
int len = nums.length;
int left = 1;
int right = len - 1;
while (left < right) {
// 在 Java 里可以这么用,当 left + right 溢出的时候,无符号右移保证结果依然正确
int mid = (left + right + 1) >>> 1;
int cnt = 0;
for (int num : nums) {
if (num < mid) {
cnt += 1;
}
}
// 根据抽屉原理,严格小于 4 的数的个数如果大于等于 4 个,
// 此时重复元素一定出现在 [1, 3] 区间里
if (cnt >= mid) {
// 重复的元素一定出现在 [left, mid - 1] 区间里
right = mid - 1;
} else {
// if 分析正确了以后,else 搜索的区间就是 if 的反面
// [mid, right]
// 注意:此时需要调整中位数的取法为上取整
left = mid;
}
}
return left;
}
题解参考
/*
*0ms
*时间复杂度O(n)
*空间复杂度O(1)
*/
class Solution {
public int findDuplicate(int[] nums) {
int slow = 0, fast = 0;
do {
slow = nums[slow];
fast = nums[nums[fast]];
} while (slow != fast);
slow = 0;
while (slow != fast) {
slow = nums[slow];
fast = nums[fast];
}
return slow;
}
}
题解参考
class Solution {
public int findDuplicate(int[] nums) {
if(nums.length <= 2){
return nums[0];
}
//初始化i,j不应该为0.应该是指向第一个index与nums[index]不相等的位置.
int i = 0,j = 0;
for(int index = 0; index<nums.length; index++){
if(index != nums[index]){
i = index;
j = index;
break;
}
}
while(true){
i = nums[i];
j = nums[nums[j]];
if(i == j) break;
}
i = 0;
while(true){
i = nums[i];
j = nums[j];
if(i == j) break;
}
return i;
}
}
标签:shm 个数 初始化 正数 number 更改 重复数 slow 查找
原文地址:https://www.cnblogs.com/yh-simon/p/12994881.html