python 无序列表中第k大元素_Leetcode 215. Python 数组中的第K个最大元素

在时间允许的情况下,建议动手实现一些经典的库内函数与数据结构

在逐渐形成自己的代码库的同时,可以加深对于概念的理解

本题题意简单,难度适中,因此更需注重降低时间复杂度

转载须附作者Id及原作品链接

利用排序算法来得到答案,这是最容易想到的解法之一

一般来说,快排 quickSort 效率最高 O ( n*logn )

在所有的实现方法中,以双指针快排最为简单易写 ( 具体代码见文末 )

选定基准base之后,使得区间两端的指针l,r不断地往中间靠拢

在此过程中,不断将不满足大小关系的位置互换,直至两指针相遇

然而,快排对于打乱顺序要求较高,导致最坏情况下效率降级

况且,实际只需数组的前k个元素有序排列,采用快排将造成性能浪费

为弥补以上不足,对于本题而言,在数据量不大的情况下,

冒泡排序也不失为一种可供采用的排序策略 O ( n*k )

除去排序的思路外,利用堆结构的特性也能降低时间复杂度 O ( n*logk )

事实上,本题也正是堆的重要应用之一

遍历数组的过程中,维护容积为k的最小堆,

若当前数大于堆顶数,则用前者更新后者,同时重新堆化 heapify

使得堆恒为前k最大的数的集合

遍历结束,返回堆顶元素即为所求值

python 内置堆数据结构可供调用

其实,堆结构的原理较为简单,其实现过程同样如此

利用堆为完全二叉树这一特性,可以直接获取当前节点的父节点 findRoot

这也是堆解构解题效率高的主要原因

class Solution(object):

def findKthLargest_0(self,nums,k):

# 排序算法

def quickSort(l,r):

if r-l<=0:return

i1,i2=l,r

base=nums[l]

while i1

while i1base:

i1+=1

while i1

i2-=1

if i1

nums[i1],nums[i2]=nums[i2],nums[i1]

if i1>l:

quickSort(l,i1-1)

quickSort(i1,r)

elif i1

quickSort(i1+1,r)

quickSort(0,len(nums)-1)

return nums[k-1]

def findKthLargest_1(self,nums,k):

from heapq import heappush,heapreplace

# 使用小顶堆

heap = []

for i in range(len(nums)):

if i 

heappush(heap,nums[i])

else:

if nums[i] > heap[0]:

heapreplace(heap,nums[i])

return heap[0]

def findKthLargest_2(self,nums,k):

h=Heap()

for num in nums:

if h.leng

h.insertNum(num)

else:

if num>h.tree[0]:

h.removeRoot()

h.insertNum(num)

return h.tree[0]

class Heap:

def __init__(self):

self.tree=[]

self.leng=0

def swap(self,i1,i2):

self.tree[i1],self.tree[i2]=self.tree[i2],self.tree[i1]

def findRoot(self,idx):

if idx==0:

return None

return (idx-1)>>1

def insertNum(self,num):

self.tree.append(num)

self.leng+=1

i=self.leng-1

p=self.findRoot(i)

while p!=None and self.tree[i]

self.swap(i,p)

i=p

p=self.findRoot(p)

def heapify(self,i):

if i>=self.leng:

return

c1=2*i+1

c2=2*i+2

if c1self.tree[c1]:

self.swap(i,c1)

if c2self.tree[c2]:

self.swap(i,c2)

self.heapify(c1)

self.heapify(c2)

def removeRoot(self):

res=self.tree[0]

self.tree[0]=self.tree[-1]

self.tree.pop()

self.leng-=1

self.heapify(0)

return res

if __name__ == "__main__":

nums=[3,2,1,5,6,4]

nums=[3,2,3,1,2,4,5,5,6]

sl=Solution()

print(sl.findKthLargest_0(nums,4))

print(sl.findKthLargest_1(nums,4))

print(sl.findKthLargest_2(nums,4))

此栏目预测共享自学之乐,共勉求知之友,共塑网站和谐好学的氛围。

欢迎大家在评论区发表合理的意见和指正。

如果觉得该栏目对您有帮助,望不吝点赞收藏。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值