「力扣」第 75 题:颜色分类


「力扣」第 75 题:颜色分类

传送门:75. 颜色分类

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

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

注意:
不能使用代码库中的排序函数来解决这道题。

示例:

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

进阶:

  • 一个直观的解决方案是使用计数排序的两趟扫描算法。
    首先,迭代计算出0、1 和 2 元素的个数,然后按照0、1、2的排序,重写当前数组。
  • 你能想出一个仅使用常数空间的一趟扫描算法吗?

说明:三路快排的 partition 是非常基础且重要的算法,一定要掌握。

Python 代码1:分别统计个数,然后逐个赋值,感觉有些麻烦,但是思路还是很清晰的

class Solution:
    def sortColors(self, nums):
        """
        :type nums: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        counter = [0] * 3
        for num in nums:
            counter[num] += 1

        i = 0
        for _ in range(counter[0]):
            nums[i] = 0
            i += 1
        for _ in range(counter[1]):
            nums[i] = 1
            i += 1
        for _ in range(counter[2]):
            nums[i] = 2
            i += 1

Python 代码2:与上一个版本等价

class Solution:
    def sortColors(self, nums):
        """
        :type nums: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        counter = [0] * 3
        for num in nums:
            counter[num] += 1
        i = 0
        for idx, count in enumerate(counter):
            for _ in range(count):
                nums[i] = idx
                i += 1

Python 代码3:三路快排,不用借助额外的存储空间,直接遍历一遍数组,通过交换元素的位置就完成了排序

class Solution:
    def sortColors(self, nums):
        l = len(nums)

        # 循环不变量的定义:
        # [0, zero] 中的元素全部等于 0
        # (zero, i) 中的元素全部等于 1
        # [two, l - 1] 中的元素全部等于 2
        zero = -1
        two = l
        i = 0  # 马上要看的位置

        while i < two:
            if nums[i] == 0:
                zero += 1
                nums[zero], nums[i] = nums[i], nums[zero]
                i += 1
            elif nums[i] == 1:
                i += 1
            else:
                two -= 1
                nums[two], nums[i] = nums[i], nums[two]

(本节完)

参考资料

「力扣」第 75 题:颜色分类

传送门:75. 颜色分类

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

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

注意:
不能使用代码库中的排序函数来解决这道题。

示例:

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

进阶:

  • 一个直观的解决方案是使用计数排序的两趟扫描算法。
    首先,迭代计算出0、1 和 2 元素的个数,然后按照0、1、2的排序,重写当前数组。
  • 你能想出一个仅使用常数空间的一趟扫描算法吗?

说明:三路快排的 partition 是非常基础且重要的算法,一定要掌握。

Python 代码 1:分别统计个数,然后逐个赋值,感觉有些麻烦,但是思路还是很清晰的

class Solution:
    def sortColors(self, nums):
        """
        :type nums: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        counter = [0] * 3
        for num in nums:
            counter[num] += 1

        i = 0
        for _ in range(counter[0]):
            nums[i] = 0
            i += 1
        for _ in range(counter[1]):
            nums[i] = 1
            i += 1
        for _ in range(counter[2]):
            nums[i] = 2
            i += 1

Python 代码 2:与上一个版本等价

class Solution:
    def sortColors(self, nums):
        """
        :type nums: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        counter = [0] * 3
        for num in nums:
            counter[num] += 1
        i = 0
        for idx, count in enumerate(counter):
            for _ in range(count):
                nums[i] = idx
                i += 1

Python 代码3:三路快排,不用借助额外的存储空间,直接遍历一遍数组,通过交换元素的位置就完成了排序

class Solution:
    def sortColors(self, nums):
        l = len(nums)

        # 循环不变量的定义:
        # [0, zero] 中的元素全部等于 0
        # (zero, i) 中的元素全部等于 1
        # [two, l - 1] 中的元素全部等于 2
        zero = -1
        two = l
        i = 0  # 马上要看的位置

        while i < two:
            if nums[i] == 0:
                zero += 1
                nums[zero], nums[i] = nums[i], nums[zero]
                i += 1
            elif nums[i] == 1:
                i += 1
            else:
                two -= 1
                nums[two], nums[i] = nums[i], nums[two]

三路快排:https://www.liwei.party/2019/01/09/algorithms-and-data-structures/quick-sort-3/。


文章作者: liweiwei1419
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 liweiwei1419 !
评论
 上一篇
「力扣」第 80 题 :删除排序数组中的重复项 II 「力扣」第 80 题 :删除排序数组中的重复项 II
「力扣」第 80 题 :删除排序数组中的重复项 II 中文网址:80. 删除排序数组中的重复项 II ; 英文网址:80. Remove Duplicates from Sorted Array II 。 给定一个排序数组,你需要在
下一篇 
「力扣」第 67 题:二进制加法 「力扣」第 67 题:二进制加法
「力扣」第 67 题:二进制加法 链接:https://leetcode-cn.com/problems/add-binary 题解链接:https://leetcode-cn.com/problems/add-binary/soluti
  目录