forked from lennylxx/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
275.c
73 lines (58 loc) · 1.86 KB
/
275.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <stdio.h>
#include <assert.h>
static inline int min(int a, int b) {
return (a < b) ? a : b;
}
/* from current position to the end, we can caculate an hIndex array
the hIndex will first ascend and then descend
so the problem is to find the peak of the hIndex array
we use binary search */
int hIndex(int* citations, int citationsSize) {
if (citations == NULL || citationsSize == 0) return 0;
if (citationsSize == 1) return min(citations[0], 1);
int i = 0, j = citationsSize - 1;
int h_prev, h_middle, h_next;
while (i <= j) {
int m = i + (j - i) / 2;
h_prev = min(citations[m - 1], citationsSize - m + 1);
h_middle = min(citations[m], citationsSize - m);
h_next = min(citations[m + 1], citationsSize - m - 1);
if (h_prev <= h_middle && h_middle > h_next) {
break;
}
else if (h_middle <= h_next) {
i = m + 1;
}
else if (h_middle > h_next) {
j = m - 1;
}
else {
i++;
}
}
return h_middle;
}
int hIndex0(int* citations, int citationsSize) {
if (citations == NULL || citationsSize == 0) return 0;
int i = 0, j = citationsSize - 1;
while (i <= j) {
int m = i + (j - i) / 2;
if (citations[m] >= citationsSize - m) {
j = m - 1;
}
else {
i = m + 1;
}
}
return citationsSize - i;
}
int main() {
int citations0[] = { 0, 1, 3, 5, 6 };
int citations1[] = { 0, 3, 3, 3, 4 };
int citations2[] = { 0, 3, 4, 4, 4, 4, 5, 5 };
assert(hIndex(citations0, sizeof(citations0) / sizeof(citations0[0])) == 3);
assert(hIndex(citations1, sizeof(citations1) / sizeof(citations1[0])) == 3);
assert(hIndex(citations2, sizeof(citations2) / sizeof(citations2[0])) == 4);
printf("all tests passed!\n");
return 0;
}