leetcode-287-Find the Duplicate Number

Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.

Example 1:

1
2
Input: [1,3,4,2,2]
Output: 2

Example 2:

1
2
Input: [3,1,3,4,2]
Output: 3

Note:

  • You must not modify the array (assume the array is read only).
  • You must use only constant, O(1) extra space.
  • Your runtime complexity should be less than O(n2).
  • There is only one duplicate number in the array, but it could be repeated more than once.
1
2
3
4
5
6
7
8
9
10
11
12
class Solution {
public int findDuplicate(int[] nums) {
Arrays.sort(nums);
for (int i = 1; i < nums.length; i++) {
if (nums[i] == nums[i-1]) {
return nums[i];
}
}

return -1;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public int findDuplicate(int[] nums) {
Set<Integer> seen = new HashSet<Integer>();
for (int num : nums) {
if (seen.contains(num)) {
return num;
}
seen.add(num);
}

return -1;
}
}

链表闭环判断(Floyd’s Tortoise and Hare)

给定一个链表,返回环路开始节点,如果没有则返回空。

Floyd算法分为两个不同的阶段。第一个阶段是判断在链表中是否有环路,如果不存在就马上返回空,也就不存在第二阶段。第二个阶段就是找到环路的入口。

第一阶段

在这里,我们初始化两个指针-快的hare和慢的tortoise。接下来,hare和tortoise从同一个节点出发(头节点),tortoise每次走一个节点,hare每次走两个节点。如果他们在前进若干步后在同一个节点相遇,我们就返回这个节点,如果最终没有返回节点信息,而是返回空,则代表不存在环路。

第二阶段

由于第一阶段确定了有环路,第二阶段就是找环的入口节点。接下来初始化连个指针,ptr1:它指向头节点, ptr2:指向第一阶段找到的相遇节点。然后将他们以一次移动一个节点的速度向前移动,直到他们再次相遇为止,并返回这个节点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public int findDuplicate(int[] nums) {
// Find the intersection point of the two runners.
int tortoise = nums[0];
int hare = nums[0];
do {
tortoise = nums[tortoise];//走一步
hare = nums[nums[hare]];//走两步
} while (tortoise != hare);

// Find the "entrance" to the cycle.
int ptr1 = nums[0];
int ptr2 = tortoise;
while (ptr1 != ptr2) {
ptr1 = nums[ptr1];//走一步
ptr2 = nums[ptr2];//走一步
}

return ptr1;
}
}
Donate? comment?