LeetCode_75.颜色分类
难度:中等
传统代码的思路与实现🐼
class Solution {
public void sortColors(int[] nums) {
var red = 0;
var white = 0;
var blue = 0;
for (var item : nums) {
if (item == 0) {
red++;
}else if (item == 1) {
white++;
}else {
blue++;
}
}
for (int i = 0;i < nums.length;i++) {
if (i < red) {
nums[i] = 0;
}else if (i < red + white) {
nums[i] = 1;
}else {
nums[i] = 2;
}
}
}
}
-
1.思路🦁
- 由题目可知,数组里面的元素有且仅有三个元素,分别是[0,1,2]
- 根据示例可知,无非是将这三个数字进行排序罢了
- 我们不妨把这三个数字的个数分别统计起来,然后再将它们分别赋值给数组中对应的下标
-
2.代码分析🦁
- 如代码所示,第一个增强for循环用于对这三个数字分别进行统计,相应的我们要设置三个对应的变量用于统计对应的个数
- 第二个for循环用于给数组对应的位置赋值
不足之处及提升的方法🐼
不足:😀
- 该算法循环遍历了该数组两次,太多了,我不满意
提升的方法:😀
- 采用快速排序的思想来完成这道问题,即这道题对应的荷兰国旗问题算法的思想
荷兰国旗问题的思路分析🐼
- 数组中只可能存在三个不同的元素,我们不妨把他们分为三组
- [0,p0),这一组只可以放0
- [p0,i),这一组只可以放1
- [p2,nums.lengh-1]这一组只能放2
- 要点:
- 0和nums.length-1是闭区间的原因是这两个位置是可以肯定的,因为第一个区间一定从0开始,最后一个区间一定从nums.length-1结束
- 同理得,第二个区间一定是从p0开始,其他都是不确定的,所以用开区间
- 我们分别定义上面的三个变量i,p0,p1,然后得出一下的定义
- p0表示的是第一个区间的最后一个元素的后一个元素
- i表示的是第二区间的最后一个元素的后一个元素
- p2表示的是第三个区间的第一个元素的前一个元素
- 注意:我们要严格遵循变量定义不变的规则,我们不能写着写着程序这些变量的所对应的意义发生了改变,我更愿意称之为"变量定义不变性"
- 注意:这三个区间一开始应该是空的,因为一开始我们不知道谁应该有多少,有没有,所以应该是空的
荷兰国旗问题的代码实现与分析🐼
class Solution {
public void sortColors(int[] nums) {
var p0 = 0;
var p1 = nums.length - 1;
int i = 0;
while (i <= p1) {
if (nums[i] == 0) {
swap(nums,i,p0);
p0++;
i++;
}else if (nums[i] == 1) {
i++;
}else {
swap(nums,i,p1);
p1--;
}
}
}
public void swap(int[] nums,int n1,int n2) {
var temp = nums[n1];
nums[n1] = nums[n2];
nums[n2] = temp;
}
}
代码分析🐨:
- p0和i赋值为0,p1赋值为nums.length-1即他们三个对应的区间分别是[0,0) [0,0) (length-1,length-1]
- 可以清晰的得出他们三个区间一开始都是空区间
- 循环讲述
- 布尔表达式为i <= p1的原因
- 我们不妨看看定义,我们这三个区间最终组合起来应该是整个数组,我们不妨得到[0,p0) + [p0,i) + (p1,nums.length-1]
- 当我们的i = p1的时候刚好遍历到最后一个元素,即当i=p1的时候,就可以组成一个完整的数组
- 如果我们发现,i指向的元素是等于0的话,我们应该放在第一个区间中,由定义可知,p0是最后一个元素的后一个元素,所以i要与p0调换
- 调换之后,为了保持变量定义不变性,我们需要将p0++,因为p0++了,对应的i也要++,如果i不++,会导致第二个区间的i的定义发生了变化
- 如果我们发现i指向的元素等于1的话,由于变量定义不变性,i需要++
- 同理得
- 注意的是:如果放到第三个区间,i的定义并没有发生改变,所以不需要进行改变
- 布尔表达式为i <= p1的原因
结论🐼
题目的解法是以快速排序的基础上建立起来的,然而,在我的观点看来,这可以独立成一个区间问题,以后凡是遇到区间问题都可以借鉴该算法,我来总结该算法的核心掌握内容
1.变量定义不变性
2.区间的划分
这篇博客详细介绍了LeetCode 75题的解决方案——颜色分类,通过两种方法实现:传统代码和荷兰国旗问题算法。传统方法双遍历数组,而荷兰国旗问题算法则使用快速排序思想,通过定义变量维护三个区间的边界,实现了更高效的排序。文章强调了变量定义不变性和区间划分的重要性,并总结了该算法的核心内容。

954

被折叠的 条评论
为什么被折叠?



