8000 fixed #11 · konanrobot/LeetCode@19a6856 · GitHub
[go: up one dir, main page]

Skip to content

Commit 19a6856

Browse files
committed
fixed pezy#11
1 parent f606c12 commit 19a6856

File tree

2 files changed

+33
-12
lines changed

2 files changed

+33
-12
lines changed

067. Search for a Range/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,21 @@ if (A[0] == A[n-1] && A[0] == target) return vector<int>{0, n-1};
2222
```
2323
2424
方法不惊艳,希望有更好解法的能告诉我。
25+
26+
-----
27+
28+
在 [issue #11](https://github.com/pezy/LeetCode/issues/11) 中,@ender233 告诉了我一个更好的思路。
29+
30+
他的本质思想,是用三次**二分查找**来避免最坏情况。但后两次,皆为二分查找的变种,即查找的不是目标,而是目标应该插入的位置。
31+
32+
这个"变种"的二分查找我尝试写了一下,判断要多得多,而且写的很丑。智商捉急且懒散成性的情况下,我略改了一下思路:
33+
34+
既然二分法可以从根本上将 O(n) 的情况减少到 O(logn) 的层次,那么三次二分与多次二分,差别其实并不大。(仍处于 O(logn) 的级别)
35+
36+
那么:
37+
38+
- 第一次二分,找到 target, 以及 `iPos`。
39+
- 接着二分左边 [0, iPos-1], 以及右边 [iPos+1, n-1]。依然找 target, 左边位置设为 `lo`(low), 右边位置设为 `hi`(high).
40+
- 不断循环往左、右二分查找 target,直到找不到为止。那么此刻范围也就确定好了。
41+
42+
代码已更新。这样效率的确高,我去 LeetCode 试了一下,15ms, 属于 C++ 目前最高效率。

067. Search for a Range/solution.h

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,23 @@
33
using std::vector;
44

55
class Solution {
6+
int binarySearch(int A[], int l, int r, int target) {
7+
for (int mid; l <= r; ) {
8+
mid = ( l + r ) >> 1;
9+
if ( A[mid] < target ) l = mid + 1;
10+
else if ( A[mid] > target ) r = mid - 1;
11+
else return mid;
12+
}
13+
return -1;
14+
}
615
public:
716
vector<int> searchRange(int A[], int n, int target) {
8-
if (A[0] == A[n-1] && A[0] == target) return vector<int>{0, n-1};
9-
vector<int> retv{-1, -1};
10-
for (int i=0, j=n-1; i<=j; ) {
11-
int mid = (i + j) >> 1;
12-
if (target == A[mid]) {retv[0] = retv[1] = mid; break;}
13-
else if (target < A[mid]) j = mid-1;
14-
else i = mid + 1;
17+
int iPos = binarySearch( A, 0, n-1, target ), l = -1, r = -1;
18+
if ( iPos != -1 ) {
19+
l = r = iPos;
20+
for (int lo = l; (lo = binarySearch(A, 0, lo-1, target)) != -1; l = lo ) ;
21+
for (int hi = r; (hi = binarySearch(A, hi+1, n-1, target)) != -1; r = hi ) ;
1522
}
16-
while (retv[0]>0 && A[retv[0]-1] == target)
17-
--retv[0];
18-
while (retv[1]<n-1 && A[retv[1]+1] == target)
19-
++retv[1];
20-
return retv;
23+
return {l ,r};
2124
}
2225
};

0 commit comments

Comments
 (0)
0