-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProblem_0215_findKthLargest.cc
155 lines (142 loc) · 3.2 KB
/
Problem_0215_findKthLargest.cc
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <iostream>
#include <random>
#include <vector>
#include "UnitTest.h"
using namespace std;
class Solution
{
public:
int getRandom(int min, int max)
{
random_device seed;
ranlux48 engine(seed());
uniform_int_distribution<> distrib(min, max);
int res = distrib(engine);
return res;
}
void swap(vector<int> &arr, int i, int j)
{
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
vector<int> generateRandomArray(int maxSize, int maxValue)
{
int len = getRandom(1, maxSize);
vector<int> arr(len);
for (int i = 0; i < len; i++)
{
arr[i] = getRandom(1, maxValue + 1) - getRandom(0, maxValue);
}
return arr;
}
// 群友的写法
int partition(vector<int> &nums, int left, int right)
{
int pivot = nums[left];
int i = left;
int j = right;
while (i < j)
{
while (i < j && nums[j] >= pivot)
j--;
while (i < j && nums[i] <= pivot)
i++;
if (i < j)
std::swap(nums[i], nums[j]);
}
nums[left] = nums[i];
nums[i] = pivot;
return i;
}
int findKthLargest1(vector<int> &nums, int k)
{
int n = nums.size();
int left = 0;
int right = n - 1;
int target = n - k;
while (true)
{
int index = partition(nums, left, right);
if (index == target)
return nums[index];
else if (index < target)
left = index + 1;
else
{
right = index - 1;
}
}
}
// 我的写法
vector<int> partition(vector<int> &arr, int L, int R, int pivot)
{
int less = L - 1;
int more = R + 1;
int cur = L;
while (cur < more)
{
if (arr[cur] < pivot)
{
swap(arr, ++less, cur++);
}
else if (arr[cur] > pivot)
{
swap(arr, cur, --more);
}
else
{
cur++;
}
}
return {less + 1, more - 1}; // 这个范围的数是等于pivot的数
}
int process(vector<int> &arr, int L, int R, int index)
{
if (L == R)
{
// L == R ==INDEX
return arr[L];
}
// 不止一个数 L + [0, R -L]
int pivot = arr[L + getRandom(0, R - L + 1)];
vector<int> range = partition(arr, L, R, pivot); // range 返回的是等于pivot的区间
if (index >= range[0] && index <= range[1]) // 长度在区间内
{
return arr[index];
}
else if (index < range[0]) // 小于这个区间,就从左半区找
{
return process(arr, L, range[0] - 1, index);
}
else // 大于这个区间就从右半区找
{
return process(arr, range[1] + 1, R, index);
}
}
int findKthLargest2(vector<int> &nums, int k) { return process(nums, 0, nums.size() - 1, nums.size() - k); }
};
void testFindKthLargest()
{
Solution s;
int testTime = 500000;
int maxSize = 20;
int maxValue = 100;
bool succeed = true;
for (int i = 0; i < testTime; i++)
{
vector<int> arr1 = s.generateRandomArray(maxSize, maxValue);
vector<int> arr2 = arr1;
vector<int> arr3 = arr1;
int k = s.getRandom(1, arr1.size());
int a = s.findKthLargest1(arr1, k);
int b = s.findKthLargest2(arr2, k);
EXPECT_EQ_INT(a, b);
}
EXPECT_SUMMARY;
}
int main()
{
testFindKthLargest();
return 0;
}