或者先排序再找第
k
k
k 个元素,复杂度为
O
(
n
log
n
)
O(n\log n)
O(nlogn)
建立
k
k
k 个元素的大根堆,遍历后续
n
−
k
n-k
n−k 个元素,如果比根小就替换根, 复杂度
O
(
n
log
k
)
O(n\log k)
O(nlogk)
利用分割技术 (partitioning),复杂度为
O
(
n
log
k
)
O(n\log k)
O(nlogk)
迭代形式
import random
defkthSmallest(data, k):"Find the nth rank ordered element (the least value has rank 0)."
data =list(data)ifnot0<= k <len(data):raise ValueError('not enough elements for the given rank')whileTrue:
pivot = random.choice(data)
pcount =0
low, high =[],[]for elem in data:if elem < pivot:
low.append(elem)elif elem > pivot:
high.append(elem)else:
pcount +=1if k <len(low):
data = low
elif k <len(low)+ pcount:return pivot
else:
data = high
k -=len(low)+ pcount
递归形式
defkthSmallest(data, k):ifnot0<= k <len(data):raise ValueError('not enough elements for the given rank')
pivot = random.choice(data)
pcount =0
low, high =[],[]for elem in data:if elem < pivot:
low.append(elem)elif elem > pivot:
high.append(elem)else:
pcount +=1if k <len(low):return kthSmallest(low, k)elif k <len(low)+ pcount:return pivot
else:return kthSmallest(high, k-len(low)-pcount)
测试
A =[i for i inrange(1000)]
random.shuffle(A)for i inrange(len(A)):assert(kthSmallest(A, i)== i)