Skip to content

Commit 11fd66b

Browse files
committed
feat: add solutions to lcof problem: No.40
1 parent dc5f255 commit 11fd66b

File tree

6 files changed

+348
-126
lines changed

6 files changed

+348
-126
lines changed

lcof/面试题39. 数组中出现次数超过一半的数字/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343

4444
一般而言,摩尔投票法需要对输入的列表进行**两次遍历**。在第一次遍历中,我们生成候选值 $m$,如果存在多数,那么该候选值就是多数值。在第二次遍历中,只需要简单地计算候选值的频率,以确认是否是多数值。由于本题已经明确说明存在多数值,所以第一次遍历结束后,直接返回 m 即可,无需二次遍历确认是否是多数值。
4545

46-
时间复杂度 $O(n)$,空间复杂度 $O(1)$。
46+
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组长度。
4747

4848
<!-- tabs:start -->
4949

lcof/面试题40. 最小的k个数/README.md

Lines changed: 248 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -28,44 +28,274 @@
2828

2929
## 解法
3030

31+
**方法一:排序**
32+
33+
我们可以直接对数组 `arr` 按从小到大排序,然后取前 $k$ 个数即可。
34+
35+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 为数组 `arr` 的长度。
36+
37+
**方法二:优先队列(大根堆)**
38+
39+
我们可以用优先队列(大根堆)维护最小的 $k$ 个数。
40+
41+
遍历数组 `arr`,对于当前遍历到的数 $x$,我们先将其加入优先队列中,然后判断优先队列的大小是否超过 $k$,如果超过了,就将堆顶元素弹出。最后将优先队列中的数存入数组并返回即可。
42+
43+
时间复杂度 $O(n \times \log k)$,空间复杂度 $O(k)$。其中 $n$ 为数组 `arr` 的长度。
44+
45+
**方法三:快排思想**
46+
47+
我们可以利用快速排序的思想,每次划分后判断划分点的位置是否为 $k$,如果是,就直接返回划分点左边的数即可,否则根据划分点的位置决定下一步划分的区间。
48+
49+
时间复杂度 $O(n)$,空间复杂度 $O(\log n)$。其中 $n$ 为数组 `arr` 的长度。
50+
3151
<!-- tabs:start -->
3252

3353
### **Python3**
3454

3555
```python
3656
class Solution:
3757
def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
38-
if k == 0:
39-
return []
40-
heap = []
41-
for e in arr:
42-
heappush(heap, e)
43-
return nsmallest(k, heap)
58+
arr.sort()
59+
return arr[:k]
60+
```
61+
62+
```python
63+
class Solution:
64+
def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
65+
h = []
66+
for x in arr:
67+
heappush(h, -x)
68+
if len(h) > k:
69+
heappop(h)
70+
return [-x for x in h]
71+
```
72+
73+
```python
74+
class Solution:
75+
def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
76+
def quick_sort(l, r):
77+
i, j = l, r
78+
while i < j:
79+
while i < j and arr[j] >= arr[l]:
80+
j -= 1
81+
while i < j and arr[i] <= arr[l]:
82+
i += 1
83+
arr[i], arr[j] = arr[j], arr[i]
84+
arr[i], arr[l] = arr[l], arr[i]
85+
if k < i:
86+
return quick_sort(l, i - 1)
87+
if k > i:
88+
return quick_sort(i + 1, r)
89+
return arr[:k]
90+
91+
n = len(arr)
92+
return arr if k == n else quick_sort(0, n - 1)
4493
```
4594

4695
### **Java**
4796

4897
```java
4998
class Solution {
5099
public int[] getLeastNumbers(int[] arr, int k) {
51-
if (k == 0) {
52-
return new int[] {};
100+
Arrays.sort(arr);
101+
int[] ans = new int[k];
102+
for (int i = 0; i < k; ++i) {
103+
ans[i] = arr[i];
53104
}
54-
PriorityQueue<Integer> bigRoot = new PriorityQueue<>(k, Collections.reverseOrder());
55-
for (int e : arr) {
56-
if (bigRoot.size() < k) {
57-
bigRoot.offer(e);
58-
} else if (e < bigRoot.peek()) {
59-
bigRoot.poll();
60-
bigRoot.offer(e);
105+
return ans;
106+
}
107+
}
108+
```
109+
110+
```java
111+
class Solution {
112+
public int[] getLeastNumbers(int[] arr, int k) {
113+
PriorityQueue<Integer> q = new PriorityQueue<>((a, b) -> b - a);
114+
for (int x : arr) {
115+
q.offer(x);
116+
if (q.size() > k) {
117+
q.poll();
118+
}
119+
}
120+
int[] ans = new int[k];
121+
for (int i = 0; i < k; ++i) {
122+
ans[i] = q.poll();
123+
}
124+
return ans;
125+
}
126+
}
127+
```
128+
129+
```java
130+
class Solution {
131+
private int[] arr;
132+
private int k;
133+
134+
public int[] getLeastNumbers(int[] arr, int k) {
135+
int n = arr.length;
136+
this.arr = arr;
137+
this.k = k;
138+
return k == n ? arr : quickSort(0, n - 1);
139+
}
140+
141+
private int[] quickSort(int l, int r) {
142+
int i = l, j = r;
143+
while (i < j) {
144+
while (i < j && arr[j] >= arr[l]) {
145+
--j;
146+
}
147+
while (i < j && arr[i] <= arr[l]) {
148+
++i;
149+
}
150+
swap(i, j);
151+
}
152+
swap(i, l);
153+
if (k < i) {
154+
return quickSort(l, i - 1);
155+
}
156+
if (k > i) {
157+
return quickSort(i + 1, r);
158+
}
159+
return Arrays.copyOf(arr, k);
160+
}
161+
162+
private void swap(int i, int j) {
163+
int t = arr[i];
164+
arr[i] = arr[j];
165+
arr[j] = t;
166+
}
167+
}
168+
```
169+
170+
### **C++**
171+
172+
```cpp
173+
class Solution {
174+
public:
175+
vector<int> getLeastNumbers(vector<int>& arr, int k) {
176+
sort(arr.begin(), arr.end());
177+
return vector<int>(arr.begin(), arr.begin() + k);
178+
}
179+
};
180+
```
181+
182+
```cpp
183+
class Solution {
184+
public:
185+
vector<int> getLeastNumbers(vector<int>& arr, int k) {
186+
priority_queue<int> q;
187+
for (int& x : arr) {
188+
q.push(x);
189+
if (q.size() > k) {
190+
q.pop();
61191
}
62192
}
63-
int[] res = new int[k];
193+
vector<int> ans(k);
64194
for (int i = 0; i < k; ++i) {
65-
res[i] = bigRoot.poll();
195+
ans[i] = q.top();
196+
q.pop();
66197
}
67-
return res;
198+
return ans;
68199
}
200+
};
201+
```
202+
203+
```cpp
204+
class Solution {
205+
public:
206+
vector<int> getLeastNumbers(vector<int>& arr, int k) {
207+
int n = arr.size();
208+
function<vector<int>(int, int)> quickSort = [&](int l, int r) -> vector<int> {
209+
int i = l, j = r;
210+
while (i < j) {
211+
while (i < j && arr[j] >= arr[l]) {
212+
--j;
213+
}
214+
while (i < j && arr[i] <= arr[l]) {
215+
++i;
216+
}
217+
swap(arr[i], arr[j]);
218+
}
219+
swap(arr[i], arr[l]);
220+
if (k < i) {
221+
return quickSort(l, i - 1);
222+
}
223+
if (k > i) {
224+
return quickSort(i + 1, r);
225+
}
226+
return vector<int>(arr.begin(), arr.begin() + k);
227+
};
228+
return k == n ? arr : quickSort(0, n - 1);
229+
}
230+
};
231+
```
232+
233+
### **Go**
234+
235+
```go
236+
func getLeastNumbers(arr []int, k int) []int {
237+
sort.Ints(arr)
238+
return arr[:k]
239+
}
240+
```
241+
242+
```go
243+
func getLeastNumbers(arr []int, k int) (ans []int) {
244+
q := hp{}
245+
for _, x := range arr {
246+
heap.Push(&q, x)
247+
if q.Len() > k {
248+
heap.Pop(&q)
249+
}
250+
}
251+
for i := 0; i < k; i++ {
252+
ans = append(ans, heap.Pop(&q).(int))
253+
}
254+
return
255+
}
256+
257+
type hp struct{ sort.IntSlice }
258+
259+
func (h hp) Less(i, j int) bool { return h.IntSlice[i] > h.IntSlice[j] }
260+
func (h *hp) Push(v interface{}) { h.IntSlice = append(h.IntSlice, v.(int)) }
261+
func (h *hp) Pop() interface{} {
262+
a := h.IntSlice
263+
v := a[len(a)-1]
264+
h.IntSlice = a[:len(a)-1]
265+
return v
266+
}
267+
func (h *hp) push(v int) { heap.Push(h, v) }
268+
func (h *hp) pop() int { return heap.Pop(h).(int) }
269+
```
270+
271+
```go
272+
func getLeastNumbers(arr []int, k int) []int {
273+
n := len(arr)
274+
if k == n {
275+
return arr
276+
}
277+
var quickSort func(l, r int) []int
278+
quickSort = func(l, r int) []int {
279+
i, j := l, r
280+
for i < j {
281+
for i < j && arr[j] >= arr[l] {
282+
j--
283+
}
284+
for i < j && arr[i] <= arr[l] {
285+
i++
286+
}
287+
arr[i], arr[j] = arr[j], arr[i]
288+
}
289+
arr[i], arr[l] = arr[l], arr[i]
290+
if k < i {
291+
return quickSort(l, i-1)
292+
}
293+
if k > i {
294+
return quickSort(i+1, r)
295+
}
296+
return arr[:k]
297+
}
298+
return quickSort(0, n-1)
69299
}
70300
```
71301

@@ -112,54 +342,6 @@ var getLeastNumbers = function (arr, k) {
112342
};
113343
```
114344

115-
### **C++**
116-
117-
```cpp
118-
class Solution {
119-
public:
120-
int partition(vector<int>& arr, int begin, int end) {
121-
int l = begin;
122-
int r = end;
123-
int povit = arr[begin];
124-
125-
while (l < r) {
126-
// 从右边开始,找到第一个小于povit的数字(用于交换)
127-
while (l < r && arr[r] >= povit) { r--; }
128-
while (l < r && arr[l] <= povit) { l++; }
129-
if (l < r) { swap(arr[l], arr[r]); }
130-
}
131-
132-
swap(arr[begin], arr[l]);
133-
return l;
134-
}
135-
136-
void partSort(vector<int>& arr, int begin, int end, int target) {
137-
if (begin >= end) {
138-
return;
139-
}
140-
141-
// 思路类似快排,这样做比堆排序时间复杂度低
142-
// C++中,stl提供partial_sort()方法,就是这种实现方式
143-
int mid = partition(arr, begin, end);
144-
if (mid == target) {
145-
return;
146-
} else if (target < mid) {
147-
partSort(arr, begin, mid - 1, target);
148-
} else {
149-
partSort(arr, mid + 1, end, target);
150-
}
151-
152-
return;
153-
}
154-
155-
vector<int> getLeastNumbers(vector<int>& arr, int k) {
156-
partSort(arr, 0, arr.size() - 1, k - 1);
157-
vector<int> ret(arr.begin(), arr.begin() + k);
158-
return ret;
159-
}
160-
};
161-
```
162-
163345
### **TypeScript**
164346

165347
```ts

0 commit comments

Comments
 (0)