描述
有一个整数数组,请你根据快速排序的思路,找出数组中第 k 大的数。
给定一个整数数组 a ,同时给定它的大小n和要找的 k ,请返回第 k 大的数(包括重复的元素,不用去重),保证答案存在。
要求:时间复杂度 O(nlogn)O(nlogn),空间复杂度 O(1)O(1)
数据范围:0 <=n <= 1000, 0<K<n, 数组中每个元素满足 0<=val<=10000000。
示例1:
输入:[1,3,5,2,2],5,3
返回值:2
示例2
输入:[10,10,9,9,8,7,5,6,4,3,4,2],12,3
返回值:9
说明:去重后的第3大是8,但本题要求包含重复的元素,不用去重,所以输出9。
思想:
利用快排将数组先排序,排序之后,将第K大的取出即可。
快排的思想:
先从数列中取出一个数作为基准数(通常取第一个数)。
分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
再对左右区间重复第二步,直到各区间只有一个数。
快排的时间复杂度:O(nlogn)
需要注意的地方:
1)快排实质上是一个分治的思想,所以需要用到递归,递归的出口是left和right一致时,不需要再次排序,直接返回数组即可。
2)快排为了找到当前基准数的正确位置,需要用到两个游标 i 和 j,分别从两边开始找比基准值大和小的值,这里需要注意,如果选择的基准是最左测,这时需要先动j,即选从最右边选择到比基准值小的,因为选动的那个确定了截止范围,因为后面需要找到 i 和 j 相遇位置和基准数换,这个位置所在的数一定是要比基准数小的,因为基准数在最左测;同样的,要是选择最右侧的值作为基准值就要选择左边的i先动。
主要代码如下:
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param a int整型一维数组
# @param n int整型
# @param K int整型
# @return int整型
#
class Solution:
def findKth(self , a: List[int], n: int, K: int) -> int:
self.kp(a, 0, n-1) # 将数组a进行快排
return a[n-K] # 返回第K大的数
def kp(self, a: List[int], left : int, right: int):
# 将数据快排后返回
if left >= right: # 递归出口
return
else:
p = a[left] # 取最左测为基准值
i = left # 设置两个游标
j = right
while(i != j): # 直到相遇
while(a[j] >= p and i < j): # i < j 保证不会过头 要是过头的话后面都是比基准值大的数 循环不会停止了
j= j - 1;
while(a[i] <= p and i < j):
i= i + 1;
temp = a[i] # 在相遇之前,遇到右侧小的和左侧大的进行数值的交换
a[i] = a[j]
a[j] = temp
a[left] = a[i] # 两个游标相遇,相遇的位置就是基准值应该在的位置,进行交换
a[i] = p
self.kp(a, left, i-1) # 从基准值处分成两段,递归进行排序
self.kp(a, i+1, right)
扩展: 当K很小的时候,可使用冒泡排序,因为冒泡排序的思想每一次就是确定好一个位置。这时相对的时间复杂度会小,为O(n * k)。
冒泡排序的思想: 冒泡排序属于一种典型的交换排序。
交换排序顾名思义就是通过元素的两两比较,判断是否符合要求,如过不符合就交换位置来达到排序的目的。冒泡排序名字的由来就是因为在交换过程中,类似水冒泡,小(大)的元素经过不断的交换由水底慢慢的浮到水的顶端。
冒泡排序的思想就是利用的比较交换,利用循环将第 i 小或者大的元素归位,归位操作利用的是对 n 个元素中相邻的两个进行比较,如果顺序正确就不交换,如果顺序错误就进行位置的交换。通过重复的循环访问数组,直到没有可以交换的元素,那么整个排序就已经完成。
所以,只需要进行K此冒泡,就把最大的交换到它应该在的位置。
class Solution:
def findKth(self , a: List[int], n: int, K: int) -> int:
for i in range(K): # 注意这两个循环设置的范围
for j in range(n-1):
if a[j] > a[j+1]:
temp = a[j+1]
a[j+1] = a[j]
a[j] = temp
return a[n - K]
补充一个进阶的思路过程,如果感兴趣可以都实现一下:
https://mp.weixin.qq.com/s/FFsvWXiaZK96PtUg-mmtEw
链接