颜色分类
力扣第75题 : https://leetcode-cn.com/problems/sort-colors/
给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
注意:
不能使用代码库中的排序函数来解决这道题。
示例:
输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]
1. 计数排序
这道题其实说白了就是排序,可以按照普通的排序直接做,但是它这里只会出现0, 1, 2 这三种数字,所以使用计数排序是一个很好的选择。
1 | class Solution: |
复杂度分析
时间复杂度: 扫描一遍数组算出各个数字的次数,时间复杂度为O(N),然后在重写数组,所以总的时间为O(N)
空间复杂度: 用了一个列表来作为桶,长度为3,所以空间复杂度为O(1)
2. 一次遍历
因为只有0, 1, 2 这三个数字,所以0肯定为最左边,2为最右边,我们使用两个指针,一个指向左,一个指向右边,当我们遍历数组时,如果当前数位0,则将其与左边的数交换,如果为2就和右边的数交换。我后来看了题解,是叫荷兰国旗问题。
1 | class Solution: |
复杂度分析
时间复杂度:由于对长度 N 的数组进行了一次遍历,时间复杂度为O(N)。
空间复杂度: 用了一个列表来作为桶,长度为3,所以空间复杂度为O(1)。
3. 三路快排
参考自 https://leetcode-cn.com/problems/sort-colors/solution/kuai-su-pai-xu-partition-guo-cheng-she-ji-xun-huan/
作者:liweiwei1419
如果循环不变量是这样定义的:
所有在子区间 [0, zero) 的元素都等于 0;
所有在子区间 [zero, i) 的元素都等于 1;
所有在子区间 [two, len - 1] 的元素都等于 2。
- 编码的时候,zero 和 two 初始化的值就应该保证上面的三个子区间全为空。
- 在遍历的过程中,“索引先加减再交换”、还是“先交换再加减”就看初始化的时候变量在哪里。
- 退出循环的条件也看上面定义的循环不变量,在 i == two 成立的时候,上面的三个子区间就正好“不重不漏”地覆盖了整个数组,并且给出的性质成立,题目的任务也就完成了。
1 | from typing import List |