优秀解析:
(1)大根堆–调库 (2)手撸大根堆 (3)快排3种写法
基于快排的所有TopK问题简单python模板
解法一:快排
- 左右挖坑互填:(700ms/15.4MB)
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
n = len(nums)
l = 0
r = n - 1
while True:
idx = self.partition(nums, l, r)
if idx == k - 1:
return nums[idx]
elif idx < k - 1:
l = idx + 1
else:
r = idx - 1
#----左右挖坑互填
def partition(self, nums: List[int], l: int, r: int) -> int:
pivot = nums[l]
while l < r:
while l < r and nums[r] <= pivot:
r -= 1
nums[l] = nums[r]
while l < r and nums[l] >= pivot:
l += 1
nums[r] = nums[l]
nums[l] = pivot
return l
- 左右交换(732ms/15.2MB)
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
n = len(nums)
l = 0
r = n - 1
while True:
idx = self.partition(nums, l, r)
if idx == k - 1:
return nums[idx]
elif idx < k - 1:
l = idx + 1
else:
r = idx - 1
#----左右交换
def partition(self, nums: List[int], l: int, r: int) -> int:
pivot = nums[l]
begin = l
while l < r:
while l < r and nums[r] <= pivot:
r -= 1
while l < r and nums[l] >= pivot:
l += 1
if l < r:
nums[l], nums[r] = nums[r], nums[l]
nums[begin], nums[l] = nums[l], nums[begin]
return l
- 单方向遍历(444ms/15.4MB)
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
n = len(nums)
l = 0
r = n - 1
while True:
idx = self.partition(nums, l, r)
if idx == k - 1:
return nums[idx]
elif idx < k - 1:
l = idx + 1
else:
r = idx - 1
#----单向遍历
def partition(self, nums: List[int], l: int, r: int) -> int:
pivot = nums[l]
idx = l
for i in range(l + 1, r + 1):
if nums[i] >= pivot:
idx += 1
nums[idx], nums[i] = nums[i], nums[idx]
nums[idx], nums[l] = nums[l], nums[idx]
return idx
解法二:大根堆(72ms/15.3MB)
class Solution:
def findKthLargest(self, nums: List[int], k: int) -> int:
n = len(nums)
self.build_maxHeap(nums)
for i in range(k-1):
nums[0], nums[n-1-i] = nums[n-1-i], nums[0]
self.adjust_down(nums, 0, n-1-i-1)
return nums[0]
def build_maxHeap(self, nums: List[int]) -> None:
n = len(nums)
for root in range(n//2, -1, -1):
self.adjust_down(nums, root, n - 1)
def adjust_down(self, nums: List[int], root: int, hi: int) -> None:
if root > hi:
return
t = nums[root]
child = 2 * root + 1
while child <= hi:
if child + 1 <= hi and nums[child] < nums[child + 1]:
child += 1
if t >= nums[child]:
break
nums[root] = nums[child]
root = child
child = 2 * root + 1
nums[root] = t
leetcode链接:https://leetcode-cn.com/leetbook/read/top-interview-questions-medium/xvsehe/