leetcode刷题记录:归并排序和快速排序

1. 快速排序

https://labuladong.github.io/algo/di-yi-zhan-da78c/shou-ba-sh-66994/kuai-su-pa-39aa2/

1.1 快排基础

先看核心代码

def sort(nums, lo, hi):
    if (lo >= hi):
        return
    p = partition(nums, lo, hi)
    sort(nums, lo, p-1)
    sort(nums, p+1, hi)

一句话总结快排:先将一个元素排好序(nums[p]),再将剩下的元素排好序

快排的核心是partition函数,其作用是在nums[lo, …, hi]中寻找一个切分点索引p, 让nums[lo,...,p] <= nums[p] < nums[p+1, ..., hi]注意这里的边界条件,是小于等于和大于。即把nums[p]放到正确的位置上;再用递归把左边和右边的部分都排好序即可,其实就是一个二叉树的前序遍历。

partition函数的结果类似一个二叉搜索树nums[p]是根节点,左边是左子树,右边是右子树。或者说,快排就是一个构造二叉搜索树的过程

但是有可能会碰到极端不平衡的情况,比如每次选出的p都在两端,导致左子树或者右子树为空,这样时间复杂度会大幅度上升,因此需要增加数组的随机性。

class Solution(object):
    def quickSort(self, nums, lo, hi):
        if (lo >= hi):
            return
        p = self.partition(nums, lo, hi)
        self.quickSort(nums, lo, p-1)
        self.quickSort(nums, p+1, hi)
    def partition(self, nums, lo, hi):
        import random
        pivot_idx = random.randint(lo, hi)   
        self.swap(nums, lo, pivot_idx)                # 随机选择pivot
        pivot = nums[lo]
        i, j = lo+1, hi
        while i <= j:            
            while i < hi and nums[i] <= pivot:
                i += 1
            while j > lo and nums[j] > pivot:
                j -= 1                
            if (i >= j):
                break                
            self.swap(nums, i, j)
        self.swap(nums, lo, j)
        return j
    def swap(self, nums, i, j):
        nums[i], nums[j] = nums[j], nums[i]
    def sortArray(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        self.quickSort(nums, 0, len(nums)-1)
        return nums

1.2 快排变体:三路快排解决相同元素的case

以上方法是传统的两路快排,缺点是leetcode上有个[2,2,2,2…]的相同元素case过不了(官方的c++题解都过不了)。这里可以用以下三路排序的方式来解决,把整个数组分成pivot三段来解决。
代码如下&#x

你可能感兴趣的:(2024算法工程师求职,leetcode,算法,职场和发展)