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 2b5de17

Browse files
committed
improved quicksort code
1 parent d5cb9f3 commit 2b5de17

File tree

2 files changed

+97
-32
lines changed

2 files changed

+97
-32
lines changed

‎basic_algorithm/quicksort.py

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
1-
def partition(A, start, end):
2-
if start >= end:
1+
import random
2+
3+
def partition(nums, left, right):
4+
if left >= right:
35
return
4-
5-
l, r = start, end - 1
6-
while l < r:
7-
while l < r and A[l] <= A[end]:
8-
l += 1
9-
while l < r and A[r] >= A[end]:
10-
r -= 1
11-
12-
A[l], A[r] = A[r], A[l]
13-
14-
swap = r + int(A[r] < A[end])
156

16-
A[end], A[swap] = A[swap], A[end]
7+
pivot_idx = random.randint(left, right)
8+
pivot = nums[pivot_idx]
9+
10+
nums[right], nums[pivot_idx] = nums[pivot_idx], nums[right]
11+
12+
partition_idx = left
13+
for i in range(left, right):
14+
if nums[i] < pivot:
15+
nums[partition_idx], nums[i] = nums[i], nums[partition_idx]
16+
partition_idx += 1
17+
18+
nums[right], nums[partition_idx] = nums[partition_idx], nums[right]
1719

18-
partition(A, swap + 1, end)
19-
partition(A, start, swap - 1)
20+
partition(nums, partition_idx + 1, right)
21+
partition(nums, left, partition_idx - 1)
2022

2123
return
2224

‎basic_algorithm/sort.md

Lines changed: 79 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,27 @@
55
### 快速排序
66

77
```Python
8-
def partition(A, start, end):
9-
if start >= end:
8+
import random
9+
10+
def partition(nums, left, right):
11+
if left >= right:
1012
return
11-
12-
l, r = start, end - 1
13-
while l < r:
14-
while l < r and A[l] <= A[end]:
15-
l += 1
16-
while l < r and A[r] >= A[end]:
17-
r -= 1
18-
19-
A[l], A[r] = A[r], A[l]
20-
21-
swap = r + int(A[r] < A[end])
2213

23-
A[end], A[swap] = A[swap], A[end]
14+
pivot_idx = random.randint(left, right)
15+
pivot = nums[pivot_idx]
16+
17+
nums[right], nums[pivot_idx] = nums[pivot_idx], nums[right]
18+
19+
partition_idx = left
20+
for i in range(left, right):
21+
if nums[i] < pivot:
22+
nums[partition_idx], nums[i] = nums[i], nums[partition_idx]
23+
partition_idx += 1
24+
25+
nums[right], nums[partition_idx] = nums[partition_idx], nums[right]
2426

25-
partition(A, swap + 1, end)
26-
partition(A, start, swap - 1)
27+
partition(nums, partition_idx + 1, right)
28+
partition(nums, left, partition_idx - 1)
2729

2830
return
2931

@@ -131,6 +133,67 @@ if __name__ == '__main__':
131133
print(heapsort(a))
132134
```
133135

136+
## 题目
137+
138+
### [kth-largest-element-in-an-array](https://leetcode-cn.com/problems/kth-largest-element-in-an-array/)
139+
140+
思路 1: sort 后取第 k 个,最简单直接,复杂度 O(N log N) 代码略
141+
142+
思路 2: 使用最小堆,复杂度 O(N log k)
143+
144+
```Python
145+
class Solution:
146+
def findKthLargest(self, nums: List[int], k: int) -> int:
147+
# note that in practice there is a more efficient python build-in function heapq.nlargest(k, nums)
148+
min_heap = []
149+
150+
for num in nums:
151+
if len(min_heap) < k:
152+
heapq.heappush(min_heap, num)
153+
else:
154+
if num > min_heap[0]:
155+
heapq.heappushpop(min_heap, num)
156+
157+
return min_heap[0]
158+
```
159+
160+
思路 3: Quick select,方式类似于快排,每次 partition 后检查 pivot 是否为第 k 个元素,如果是则直接返回,如果比 k 大,则继续 partition 小于 pivot 的元素,如果比 k 小则继续 partition 大于 pivot 的元素。相较于快排,quick select 每次只需 partition 一侧,因此平均复杂度为 O(N)
161+
162+
```Python
163+
class Solution:
164+
def findKthLargest(self, nums: List[int], k: int) -> int:
165+
166+
k -= 1 # 0-based index
167+
168+
def partition(left, right):
169+
pivot_idx = random.randint(left, right)
170+
pivot = nums[pivot_idx]
171+
172+
nums[right], nums[pivot_idx] = nums[pivot_idx], nums[right]
173+
174+
partition_idx = left
175+
for i in range(left, right):
176+
if nums[i] > pivot:
177+
nums[partition_idx], nums[i] = nums[i], nums[partition_idx]
178+
partition_idx += 1
179+
180+
nums[right], nums[partition_idx] = nums[partition_idx], nums[right]
181+
182+
return partition_idx
183+
184+
left, right = 0, len(nums) - 1
185+
while True:
186+
partition_idx = partition(left, right)
187+
if partition_idx == k:
188+
return nums[k]
189+
elif partition_idx < k:
190+
left = partition_idx + 1
191+
else:
192+
right = partition_idx - 1
193+
```
194+
195+
196+
134197
## 参考
135198

136199
[十大经典排序](https://www.cnblogs.com/onepixel/p/7674659.html)

0 commit comments

Comments
(0)

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