题目链接:https://www.nowcoder.com/question/next?pid=13956292&qid=298692&tid=26431616
方法一:
最简单直接的方法:先排序再找
最简单直接的想法是首先进行排序。假设元素的数量不大,比如才几千个,那就可以先进行排序,比如用快排或堆排,平均时间复杂度为O(N*logN),然后取出前k个,于是总时间复杂度为O(NlogN)+O(k)=O(NlogN)。当然这种做法是浪费了不少的时间的,因为题目只要求找出第k大的元素,而不需要数据是有序的。
方法二:
比较直接的方法:部分元素排序
https://blog.csdn.net/qq_26286193/article/details/80683004
当k比较小的时候,k趟排序是个比较不错的方法。我们只需要排序最大的k个元素即可,剩下那些元素不需要管。
最简单明了的就是在冒泡排序中只进行k趟起泡。
方法三:
快排的分治法
快速排序使用了分治法的策略。它的基本思想是,选择一个基准数(一般称之为枢纽元),通过一趟排序将要排序的数据分割成独立的两部分:在枢纽元左边的所有元素都不比它大,右边所有元素都比它大,此时枢纽元就处在它应该在的正确位置上了。在本问题中,假设有N个数存储在数组a中。
我们从a中随机找出一个元素作为枢纽元,把数组分为两部分。其中左边元素都不比枢纽元大,右边元素都不比枢纽元小。此时枢纽元所在的位置记为mid。
如果右半边(包括a[mid])的长度恰好为k,说明a[mid]就是需要的第k大元素,直接返回a[mid]。
如果右半边(包括a[mid])的长度大于k,说明要寻找的第k大元素就在右半边,往右半边寻找。
如果右半边(包括a[mid])的长度小于k,说明要寻找的第k大元素就在左半边,往左半边寻找。
num = list(map(int,input()[1:-1].split(',')))
k = 3
def quick(num,left,right,k):
low = left
high = right
base = num[left]
while low < high:
while low < high and num[high] > base:
high -= 1
num[low] = num[high]
while low < high and num[low] < base:
low += 1
num[high] = num[low]
num[low] = base
if low == k:
return num[low]
elif low < k:
return quick(num,low+1,right,k)
else:
return quick(num,left,low-1,k)
print(quick(num,0,len(num)-1,k))