颜色分类
题目
版本1 正确
public static void sortColors(int[] nums) {
// 荷兰国旗问题, 就是将数组分成三个区域
// 第一个区域的值全部小于目标值
// 第二各区域的值全部等于目标值
// 第三个区域的值全部大于目标值
// lessBound为第一个区域的右边界, 闭区间
int lessBound = -1;
// moreBound为第三个区域的左边界, 闭区间
int moreBound = nums.length;
// 遍历一遍数组 目标值是1
// 需要注意的是, 这里不能不能用for循环, 因为交换完元素后, 当前位置的元素不一定符合要求
// 需要再次判断, 因此不能让i自增
int cur = 0;
while (cur < moreBound) {
if (nums[cur] > 1) {
// 放入第三区域, 交换一次元素
// 不移动cur指针
// 这里不移动cur指针的原因是, 第三区域边界外边的元素可能小于目标值, 也可能大于等于目标值, 因此cur对应的元素还需要判断一次
moreBound --;
int temp = nums[moreBound];
nums[moreBound] = nums[cur];
nums[cur] = temp;
} else if (nums[cur] < 1) {
// 放入第一区域
// 在第一区域必须移动cur指针, 不然cur指针就会一直停留在小于1的位置上
// 这里能移动的原因就是lessBound以外的元素, 一定是大于等于目标值的, 是可以移动的
lessBound ++;
int temp = nums[lessBound];
nums[lessBound] = nums[cur];
nums[cur] = temp;
cur ++;
} else {
// 如果相等, 移动cur指针
cur++;
}
}
}
正确的原因
(1) 利用两个指针, 定义两个区间的边界
(2) 注意什么情况下需要移动cur指针, 什么情况下不用移动