leetcode75. 颜色分类-快速排序

文章讨论了如何在不使用内置排序函数的情况下,对包含红、白、蓝三种颜色元素的数组进行排序,使相同颜色的元素相邻并按红色、白色、蓝色顺序排列。作者首先采用双指针的方法实现,然后回顾了快速排序中的partition过程,并用此思想优化了解决方案。
摘要由CSDN通过智能技术生成

题目

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

必须在不使用库内置的 sort 函数的情况下解决这个问题。

示例 1:

输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]
示例 2:

输入:nums = [2,0,1]
输出:[0,1,2]

思路和代码

今天写的时候想起了左神说的快速排序中的partition过程,可惜具体的想不起来了,自己写了一个笨方法,一次从前往后遍历,把2放在后面,一次从后往前遍历,把0放在前面。调了好几次才通过,心情有那么一点不爽。

class Solution:
    def sortColors(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        n = len(nums)
        #想到一个笨方法 两次遍历
        #pre-last 把所有的2放在后面
        last = n-1
        for i in range(n):
            while last > 0 and nums[last] == 2:
                last -=1
            if nums[i] == 2 and i < last:    
                nums[i], nums[last] = nums[last], nums[i]
        pre = 0
        for i in range(last,-1,-1):
            while pre < n and nums[pre]==0:
                pre += 1
            if nums[i] == 0 and i > pre:
                nums[i], nums[pre] = nums[pre],nums[i]

回顾了一下左神说的partition过程。

目的就是把小于num的数放在左边,等于num的数放在中间,大于num的数放在右边。(在快速排序中,这样操作就把中间为num的值放好了位置,然后对两边重复该操作就而已得到有序数组)。

具体做法:
1.小于区,初始为-1,大于区,初始值为n。
2.当当前值<num时,当前值和小于区的下一个值交换位置,小于区往右边扩大1,i++
3.当当前值=num时,i++
4.当当前值>num时,当前值和大于区的前一个值交换位置,大于区往左边扩大1,i不变。不变的原因是当前的值换了一个新的值,要重新进行判断
5.当i与大于区发生碰撞,过程截止

代码:

class Solution:
    def sortColors(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        n = len(nums)
        small = -1
        big = n
        i = 0
        while i < big:
            if nums[i] == 0:
                nums[i], nums[small+1] = nums[small+1], nums[i]
                small += 1
                i += 1
            elif nums[i] == 1:
                i += 1
            else:
                nums[i], nums[big-1] = nums[big-1], nums[i]
                big -= 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值