python--查找数组第K大的数

这个问题应该是比较经典的,要求能在时间复杂度O(n)解决。

最暴力的方法当然是先排个序,时间复杂度是O(nlogn),但是这样浪费了很多不必要的计算。

O(n)的算法思想借鉴了快排的思想:

快速排序每次把一个元素交换到正确的位置,同时把左边的都放上大的,右边都放上小的。这个算法每一次选取一个枢纽元,排序之后,查看枢纽元的位置。如果它的位置大于K,就说明,要求出前面一个子序列的第K大的元素。反之,如果小于K,就说明要求出在后面一个序列的第K - 前一个序列的长度个元素。

如此,就把这个问题改变成了一个可以用快排思想解决的问题。对于快速排序,算法复杂度是O(N*logN)。而这个算法的算法复杂度是O(N)。为什么呢?

其实这个地方的算法复杂度分析很有意思。第一次交换,算法复杂度为O(N),接下来的过程和快速排序不同,快速排序是要继续处理两边的数据,再合并,合并操作的算法复杂度是O(1),于是总的算法复杂度是O(N*logN)(可以这么理解,每次交换用了N,一共logN次)。但是这里在确定枢纽元的相对位置(在K的左边或者右边)之后不用再对剩下的一半进行处理。也就是说第二次插入的算法复杂度不再是O(N)而是O(N/2),这不还是一样吗?其实不一样,因为接下来的过程是1+1/2+1/4+........ < 2,换句话说就是一共是O(2N)的算法复杂度也就是O(N)的算法复杂度。

代码实现:


def quicksort(num ,low ,high):  #快速排序
    if low< high:
        location = partition(num, low, high)
        quicksort(num, low, location - 1)
        quicksort(num, location + 1, high)

def partition(num, low, high):
    pivot = num[low]
    while (low < high):
        while (low < high and num[high] > pivot):
            high -= 1
        while (low < high and num[low] < pivot):
            low += 1
        temp = num[low]
        num[low] = num[high]
        num[high] = temp
    num[low] = pivot
    return low

def findkth(num,low,high,k):   #找到数组里第k个数
        index=partition(num,low,high)
        if index==k:return num[index]
        if index

 

你可能感兴趣的:(python)