给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
要求:必须在不使用库的sort函数的情况下解决这个问题。
解决方法:
全部的值由 0、1、2组成,随机散列分布,所以直接写个排序算法也就可以完成相同数值相邻。如果不用排序算法,该怎么做呢?
类似与快速排序,定义两个指针,0都在左指针之前,2都在右指针后,1在两者之间即可。那么怎么实现呢?
1、遍历整个数组,如果当前值是0,那么就将其与左指针处的值交换,然后左指针右移。这样就可以实现左指针左边都是1。
2、如果当前值是2,则将其值与右指针处的值交换,右指针左移,这样就可以实现右指针右边都是2。但是这一步有一点需要注意,就是当我们检测到值是2时,是直接与右指针处的值交换,但右指针处的值也可能等于2,所以此时我们在重新检查一遍交换过去的值是否等于2,所以利用 i--,退回一个下标继续检查。
代码部分:
package Class02;
/**
* 荷兰三色旗问题
* 简单的可以直接用排序,但复杂度过高
* 所以用类似与快速排序,设两个指针 A、B 最后实现 0在A左边,2在B右边 即可。
*/
public class LeeetCode_75_sortColor {
public void sort_color(int[] nums) {
int left = 0;
int right = nums.length-1;
for(int i=0;i<=right;i++){
//如果值是0,就将当前值与nums[left]的值交换,然后 left 右移。
if(nums[i] == 0){
swap(left ++,i,nums);
}
//如果值是2,将其与nums[right]交换,然后right -- 左移。但有可能原来的right位置的值也为0,故还要判断交换过去的值是否为2,所以i--,继续判断。
else if (nums[i] == 2){
swap(right--,i--,nums); // 交换的right的值可能还是2,所以i--,继续比较交换后原来位置的值
}
}
}
public void swap(int a,int b,int [] nums){
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
}
}