Leetcode-快速排序+深度之眼讲解笔记

题目:

LeetCode-215:
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
说明:

你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array

方法一:

利用python内置函数三行解决题目

class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        nums_sort = sorted(nums)
        n = len(nums)
        return nums_sort[n-k]

方法二:

自己编写排序函数:

快速排序:

挖坑法:

在这里插入图片描述
首先在基准数的位置挖坑,然后指针left向右遍历,right向左遍历,直到left和right相等。
如图,判断 r ,1小于4,将1填到4的坑里,原1处为新的坑,l向右移动,7大于4,则将7放到原1坑处,原7处成为新坑。r向左移,8大于4,不动,再左移动,2小于4,放到新坑原7处,原2成为新坑。l向右移,6大于4,放到原2新坑处,r向左移,3小于4,放到原6新坑处,l向右移,5大于4,放到原3新坑处。r右移,与l相等,结束。原5为新坑,将基准4放在此处.
在这里插入图片描述

def quick_sort(list, start, end):
    # start = end 说明只有一个数据要处理
    # start > end 说明右边没有数据
    if start >= end :
        return
    # 定义两个游标分别指向起始位置0,和末尾位置end
    left = start
    right = end
    # 设置一个基准pivot,假设起始位置为基准
    pivot = list[left]
    # right指的右边数若小于基准则放在基准左边
    while left < right:
        while left < right and list[right] >= pivot:
            right -= 1
        list[left] = list[right]
        # left指的左边数若大于基准则放在基准右边
        while left < right and list[left] <= pivot:
            left += 1
        list[right] = list[left]
    # 结束while后,将基准值放入到最后一处
    list[left] = pivot
    # 递归左边右边的数字
    quick_sort(list, start, left-1)
    quick_sort(list, left+1, end)

if __name__=='__main__':
    list = [2,1,3,6,4,8,5,1,3,7]
    quick_sort(list, 0, len(list)-1)
    print(list)
# 稳定性:不稳定
# 最优时间复杂度:O(nlogn)
# 最坏时间复杂度:O(n^2)

指针交换法:

在这里插入图片描述
这个方法要求两个指针指的数都满足交换的条件。l指的数字应小于pivot,r指的数字应大于pivot。假设r,l两个指针,l指向7,r指向1,1应该在4左边,7应该在4右边,所以两个交换。r向左移动指向8,8在4右边正确,r向前移,发现2应该在4前面,应该交换,移动l指向6,6应该在4右边,交换2和6。
在这里插入图片描述
同理交换3和5
在这里插入图片描述
r继续前移,与l相遇,算法跳出。
在这里插入图片描述
r移到的位置一定是小于pivot,交换3与pivot。最后得到如上图的排序结果。
快速排序是不稳定的排序算法。

发布了6 篇原创文章 · 获赞 0 · 访问量 63

猜你喜欢

转载自blog.csdn.net/qq_35493320/article/details/104080197