Skip to content

Commit 09de487

Browse files
committed
更新 problem 287
1 parent d9474e0 commit 09de487

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

Algorithms/0287. Find the Duplicate Number/287. Find the Duplicate Number.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package leetcode
22

33
import "sort"
44

5-
// 解法一
5+
// 解法一 快慢指针
66
func findDuplicate(nums []int) int {
77
slow := nums[0]
88
fast := nums[nums[0]]
@@ -18,8 +18,27 @@ func findDuplicate(nums []int) int {
1818
return walker
1919
}
2020

21-
// 解法二
21+
// 解法二 二分搜索
2222
func findDuplicate1(nums []int) int {
23+
low, high := 0, len(nums)-1
24+
for low < high {
25+
mid, count := low+(high-low)>>1, 0
26+
for _, num := range nums {
27+
if num <= mid {
28+
count++
29+
}
30+
}
31+
if count > mid {
32+
high = mid
33+
} else {
34+
low = mid + 1
35+
}
36+
}
37+
return low
38+
}
39+
40+
// 解法三
41+
func findDuplicate2(nums []int) int {
2342
if len(nums) == 0 {
2443
return 0
2544
}

Algorithms/0287. Find the Duplicate Number/README.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Note:
2222

2323
- You must not modify the array (assume the array is read only).
2424
- You must use only constant, O(1) extra space.
25-
- Your runtime complexity should be less than O(n2).
25+
- Your runtime complexity should be less than O(n^2).
2626
- There is only one duplicate number in the array, but it could be repeated more than once.
2727

2828
## 题目大意
@@ -31,7 +31,6 @@ Note:
3131

3232
## 解题思路
3333

34-
这道题比较巧的思路是,将这些数字想象成链表中的结点,数组中数字代表下一个结点的数组下标。找重复的数字就是找链表中成环的那个点。由于题目保证了一定会有重复的数字,所以一定会成环。所以用快慢指针的方法,快指针一次走 2 步,慢指针一次走 1 步,相交以后,快指针从头开始,每次走一步,再次遇见的时候就是成环的交点处,也即是重复数字所在的地方。
35-
36-
37-
另外一个做法是,先将数组排序,依照下标是从 0 开始递增的特性,那么数组里面的数字与下标的差值应该是越来越大。如果出现了相同的数字,下标变大,差值应该比前一个数字小,出现了这个情况就说明找到了相同数字了。
34+
- 这道题比较巧的思路是,将这些数字想象成链表中的结点,数组中数字代表下一个结点的数组下标。找重复的数字就是找链表中成环的那个点。由于题目保证了一定会有重复的数字,所以一定会成环。所以用快慢指针的方法,快指针一次走 2 步,慢指针一次走 1 步,相交以后,快指针从头开始,每次走一步,再次遇见的时候就是成环的交点处,也即是重复数字所在的地方。
35+
- 这一题有多种做法。可以用快慢指针求解。还可以用二分搜索,题目中规定,给出 [1,n] 个数,如果每个数都不重复,那么就有 `n + 1` 个数。以 [1, 2, 2, 3, 4, 5, 6, 7] 为例,一共有 8 个数,每个数都在 1 和 7 之间。1 和 7 的中位数是 4,遍历整个数组,统计小于 4 的整数的个数,至多为 3 个,如果超过 3 个就说明重复的数存在于区间 `[1,4)` 中;否则,重复的数存在于区间 `[4,7]` 中。这里小于 4 的整数有 4 个(它们是 1, 2, 2, 3),因此砍掉右半区间,连中位数也去掉。如此反复,最后二分区间越来越小,直到变成 1 个整数,这个整数就是我们要找的重复的数。
36+
- 另外一个做法是,先将数组排序,依照下标是从 0 开始递增的特性,那么数组里面的数字与下标的差值应该是越来越大。如果出现了相同的数字,下标变大,差值应该比前一个数字小,出现了这个情况就说明找到了相同数字了。

0 commit comments

Comments
 (0)