题目要求:
分析1:
刚看到这道题目的时候,我的第一反应是HashMap,事实上我也这样去做了,但是性能很差,只击败了百分之十几的用户。
具体代码如下:
class Solution {
public int findDuplicate(int[] nums) {
if(nums == null || nums.length == 0)
return 0;
Map<Integer, Integer> map = new HashMap<>();
for(int num : nums) {
if(!map.containsKey(num)) {
map.put(num, 1);
} else{
return num;
}
}
return 0;
}
}
分析2:
于是我看了别人的解答,发现这道题可以利用弗洛伊德算法来解决,类似于之前做的环形链表II这道题,具体分析跟那道题是一模一样的,这里不再重复。传送门: leetcode142——环形链表II——java实现
由于在该数组中,有一个重复了一次或n次的元素,那么就表明这个数组中一定存在一个环。所以我们可以设置快慢指针来求这个环的入口——即重复元素的第一个数字。
这里需要注意的一点是,这里的参数是数组而不是链表,不能利用next,所以这里的slow指针和fast指针的设置比较特殊,需要注意。
具体代码如下:
class Solution {
public int findDuplicate(int[] nums) {
if(nums == null || nums.length == 0)
return 0;
// 找到快慢指针相遇的地方
int slow = nums[0];
int fast = nums[nums[0]];
while (fast != slow) {
slow = nums[slow];
fast = nums[nums[fast]];
}
// 用一个新指针从头开始,直到和慢指针相遇
slow = 0;
while (fast != slow) {
slow = nums[slow];
fast = nums[fast];
}
return slow;
}
}
来源:https://blog.csdn.net/qq_41645636/article/details/99550296