786. 第k个数1
给定一个长度为 n n n 的整数数列,以及一个整数 k k k,请用快速选择算法求出数列从小到大排序后的第 k k k 个数。
输入格式
第一行包含两个整数 n n n 和 k k k。
第二行包含 n n n 个整数(所有整数均在 1∼109 范围内),表示整数数列。
输出格式
输出一个整数,表示数列的第 k k k 小数。
数据范围
1
≤
n
≤
100000
1≤n≤100000
1≤n≤100000,
1
≤
k
≤
n
1≤k≤n
1≤k≤n
输入样例:
5 3
2 4 1 5 3
输出样例:
3
思路:
采用快排的思想,将一个区间分为左右两个区间(本文以中间值为分界点)。所有不大于中间值的数都在中间点的左边,所有不小于中间值的数都在中间点的右边。只需要对第 k k k 个数和左边区间的个数进行比较。这样就只需排序一边。时间复杂度为 O ( n ) O(n) O(n)
代码:
# 采用快排模板稍微修改即可AC
def quick_sort(l,r,m):
if l == r:
return data[r]
x = data[l + r >> 1]
i = l - 1
j = r + 1
while i < j:
while 1:
i += 1
if data[i] >= x:
break
while 1:
j -= 1
if data[j] <= x:
break
if i < j:
data[i],data[j] = data[j],data[i]
# 统计左边区间的个数是否大于m,是就只对左边区间排序,否就只对右边区间排序。
left = j - l + 1
if m <= left:
return quick_sort(l,j,m)
else:
return quick_sort(j+1,r,m - left)
n,m = map(int,input().split())
data = [int(x) for x in input().split()]
print(quick_sort(0,n-1,m))
题目来源:AcWing ↩︎