题目描述

题解
class Solution {
public int findDuplicate(int[] nums) {
HashSet<Integer> set = new HashSet<>();
for (int num : nums) {
if (!set.add(num))
return num;
}
return -1;
}
}
class Solution {
public int findDuplicate(int[] nums) {
Arrays.sort(nums);
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i] == nums[i + 1])
return nums[i];
}
return -1;
}
}
// 原地置换法
// 跟【剑指offer】03.数组中重复的数字 不一样的是,这里的数组是从1开始数到n
// 的,所以0索引对应元素1,1索引对应元素2。所以i索引对应元素nums[i] - 1,
// 我们定义i索引遍历nums,记遍历元素为nums[i],如果索引i不为nums[i]-1,
// 说明遍历值nums[i]不符合条件,将当前遍历值nums[i]和nums[i]-1索引遍历的
// nums[nums[i]-1]元素交换(如果nums[nums[i]-1]依然不等于nums[i],或者
// 依然nums[i]-1不等于i,继续循环交换),如果再交换过程中发现nums[nums[i]-1]
// 和nums[i]相等,直接返回nums[i]即可。如果nums[i]-1等于i成立了,
// 那么i右移,继续让i和nums[i]建立起【nums[i]-1 = i】的匹配关系。
//
// 针对实例[1,3,4,2,2]有过程如下:
// i
// [1,3,4,2,2] nums[i]-1 == i
// i
// [1,3,4,2,2] nums[i]-1 != i >> swap(nums, i, nums[i] - 1)
// i
// [1,4,3,2,2] nums[i]-1 != i >> swap(nums, i, nums[i] - 1)
// i
// [1,2,3,4,2] nums[i]-1 != i >> swap(nums, i, nums[i] - 1)
//
class Solution {
public int findDuplicate(int[] nums) {
int i = 0;
while (i < nums.length) {
if (nums[i] - 1 != i) {
if (nums[i] == nums[nums[i] - 1])
return nums[i];
swap(nums, i, nums[i] - 1);
}
else {
i++;
}
}
return -1;
}
public void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
// 双指针-快慢针
// 思路同【Leetcode】142. 环形链表 II 。
// 先用快慢针一个走一步一个走两步,找到在环内的交点,
// 然后其中一个点被重置回起点,两个指针一起一步一步移动,下一次交点就是环的
// 起点。
// 这道题执行用时怎么都降不下去,我也是没办法了。
//
// 执行用时:6 ms, 在所有 Java 提交中击败了10.81%的用户
// 内存消耗:54.2 MB, 在所有 Java 提交中击败了6.59%的用户
class Solution {
public int findDuplicate(int[] nums) {
int slow = nums[0], fast = nums[0]
fast = intersection(nums, slow, fast)
while (slow != fast) {
slow = nums[slow]
fast = nums[fast]
}
return slow
}
public int intersection(int[] nums, int slow, int fast) {
slow = nums[slow]
fast = nums[fast]
fast = nums[fast]
while (slow != fast) {
slow = nums[slow]
fast = nums[fast]
fast = nums[fast]
}
return slow
}
}
// 简化一下:
// 执行用时:5 ms, 在所有 Java 提交中击败14.94%的用户
// 内存消耗:55.7 MB, 在所有 Java 提交中击败了5.06%的用户
class Solution {
public int findDuplicate(int[] nums) {
int slow = nums[0], fast = nums[0]
slow = nums[slow]
fast = nums[fast]
fast = nums[fast]
while (slow != fast) {
slow = nums[slow]
fast = nums[nums[fast]]
}
slow = nums[0]
while (slow != fast) {
slow = nums[slow]
fast = nums[fast]
}
return slow
}
}