题目
2种方法,都要理解掌握!最简单的基于HashSet的就不写在下面了,过于简单了。
法1:二分查找,O(nlogn)
必须熟练掌握!
class Solution {
public int findDuplicate(int[] nums) {
int n = nums.length;
int left = 1, right = n; // 1和n是数字,与数组索引无关
while (left < right) {
int mid = left + (right - left) / 2;
int count = 0;
for (int i : nums) {
if (i <= mid) {
++count;
}
}
if (count <= mid) { // 这种情况重复的数字一定大于mid!
left = mid + 1;
} else { // 有可能重复的数字是mid
right = mid;
}
}
return left;
}
}
法2:环形链表
class Solution {
public int findDuplicate(int[] nums) {
int slow = 0, fast = 0;
do {
slow = next(nums, slow);
fast = next(nums, next(nums, fast));
} while (slow != fast);
slow = 0;
while (slow != fast) {
slow = next(nums, slow);
fast = next(nums, fast);
}
return slow;
}
public int next(int[] nums, int inx) {
return nums[inx];
}
}