Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9f359c2

Browse files
modify 33
1 parent 388c26a commit 9f359c2

File tree

1 file changed

+50
-23
lines changed

1 file changed

+50
-23
lines changed
Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,73 @@
11
/*
2-
* Copyright (C) 2017, Saul Lawliet <october dot sunbathe at gmail dot com>
2+
* Copyright (C) 2017-2022, Saul Lawliet <october dot sunbathe at gmail dot com>
33
* All rights reserved.
44
*
5-
* 很好理解的写法, 以为性能可能不是最好的, 但耗时是第一梯队的.
5+
* https://leetcode.com/problems/search-in-rotated-sorted-array/
6+
* Q: 在一个循环有序数组中(想象一个循环链表, 但起始位置可能不在数组头部), O(log n)的时间复杂度找到一个元素的位置
7+
*
8+
* 看到题目, 就是要实现一个升级版本的二分查找, 接下来就要考虑如何计算 low 和 high
9+
* 第1步: 判断哪边是有序的
10+
* 第2步: 找出异常情况: 要找的值在边界之外
11+
*
12+
* 修改记录:
13+
* 2022年03月28日: 今天才发现, 之前没按规则实现, 于是重写了
14+
* 2017年08月25日: 按照顺序查找实现的, 虽然AC并且耗时也是第一梯队的, 但代码不符合规则
615
*/
716

8-
#include <stdbool.h>
917
#include "c/data-structures/array.h"
1018
#include "c/test.h"
1119

12-
void swap(int *a, int *b) {
13-
int tmp = *a;
14-
*a = *b;
15-
*b = tmp;
16-
}
17-
1820
int search(int *nums, int numsSize, int target) {
19-
int index = -1;
20-
for (int i = 0; i != numsSize; i++) {
21-
if (index == -1 && nums[i] == target) {
22-
index = i;
23-
}
24-
if (index != -1) {
25-
for (int j = i; j != i - index; j--) {
26-
swap(&nums[j], &nums[j-1]);
21+
int low = 0, high = numsSize - 1, mid;
22+
while (low <= high) {
23+
mid = (low + high) / 2;
24+
if (nums[mid] == target)
25+
return mid;
26+
27+
if (nums[low] <= nums[mid]) { // 左侧有序
28+
if (nums[mid] > target) { // 可能在左边
29+
// 但特殊情况在右边
30+
if (nums[low] > target)
31+
low = mid + 1;
32+
else
33+
high = mid - 1;
34+
} else {
35+
low = mid + 1;
36+
}
37+
} else { // 右侧有序
38+
if (nums[mid] < target) { // 可能在右边
39+
// 但特殊情况在左边
40+
if (nums[high] < target)
41+
high = mid - 1;
42+
else
43+
low = mid + 1;
44+
} else {
45+
high = mid - 1;
2746
}
2847
}
2948
}
30-
return index;
49+
return -1;
3150
}
3251

33-
void test(constchar*expect, int result, const char *str, int target) {
34-
arrayEntry *e = arrayParse1D(str, ARRAY_INT);
52+
void test(int except, const char *nums, int target) {
53+
arrayEntry *e = arrayParse1D(nums, ARRAY_INT);
3554

36-
EXPECT_EQ_INT(result, search(arrayValue(e), arraySize(e), target));
37-
EXPECT_EQ_STRING_AND_FREE_ACTUAL(expect, arrayToString(e));
55+
EXPECT_EQ_INT(except, search(arrayValue(e), arraySize(e), target));
3856

3957
arrayFree(e);
4058
}
4159

4260
int main(void) {
43-
test("[4,5,6,7,0,1,2]", 3, "[0,1,2,4,5,6,7]", 4);
61+
test(4, "[4,5,6,7,0,1,2]", 0);
62+
test(-1, "[4,5,6,7,0,1,2]", 3);
63+
test(-1, "[1]", 0);
64+
65+
// 以下是提交错误时的测试用例
66+
test(0, "[3,5,1]", 3);
67+
test(2, "[5,1,3]", 3);
68+
test(0, "[5,1,3]", 5);
69+
test(4, "[4,5,6,7,8,1,2,3]", 8);
70+
test(1, "[3,1]", 1);
4471

4572
return testOutput();
4673
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /