题目:
给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
示例1:
示例2:
思路1:
根据题目中描述,因为数组中只包含三种元素,所以我们申明3个计数变量,第一次遍历数组,分别统计一下三种元素的个数;然后第二遍便利数组,按照数量,构建一个目标数组;
package Lq_算法练习;
import java.util.Arrays;
public class Demo_颜色分类02 {
public static void main(String[] args) {
int[] nums= {2,0,2,1,1,0};
System.out.println("原始数组为:");
System.out.println(Arrays.toString(nums));
//调用方法实现颜色分类
//Bean的中文含义是“豆子”,Bean的含义是可重复使用的Java组件。
Demo_颜色分类02 bean=new Demo_颜色分类02();
bean.sortColor(nums);
System.out.println("按颜色分类后的数组内容为:");
System.out.println(Arrays.toString(nums));
}
public static void sortColor(int[] nums) {
if(nums==null||nums.length==1) {
return;
}
int num0Count=0,num1Count=0,num2Count=0;//遍历数组,统计数组中0,1,2的个数
int index=0;//索引
while(index<nums.length) {
if(nums[index]==0) {
num0Count++;
}else if(nums[index]==1) {
num1Count++;
}else if(nums[index]==2) {
num2Count++;
}
index++;
}
//重置遍历数组,重置数组内容
index=0;
while(num0Count>0) {
nums[index++]=0;
num0Count--;
}
while(num1Count>0) {
nums[index++]=1;
num1Count--;
}
while(num2Count>0) {
nums[index++]=2;
num2Count--;
}
}
}
运行结果1:
思路2:
利用双指针思路。因为0肯定在数组最前面,2一定在数组最后面。所以需设置两个指针,zero和two,分别指向数组的头部和尾部。
如果遇到元素2,则与尾部指针two所在的位置进行交换,然后two-1;
如果遇到元素0,则与首部指针zero所在的位置进行交换,然后zero+1;
package Lq_算法练习;
import java.util.Arrays;
public class Demo_颜色分类01 {
public static void main(String[] args) {
int[] nums = {2, 0, 2, 1, 1, 0};
System.out.println("原始数组为:");
System.out.println(Arrays.toString(nums));//以数组形式打印出来
Demo_颜色分类01 bean=new Demo_颜色分类01();
bean.sortColor(nums);
System.out.println("按颜色分类后的数组内容为:");
System.out.println(Arrays.toString(nums));
}
public static void sortColor(int[] nums) {
int two = nums.length - 1;//数组最后一位
int zero = 0;// 指向1的前一位
int i = 0;
while (i <= two) {
if (nums[i] == 2) {// 如果是2直接和最后一个交换
swap(nums, i, two--);//将该元素与最后元素进行交换
} else if (nums[i] == 0) {// 只要是0就和zero交换
swap(nums, zero++, i++);
} else {
i++;
}
}
}
//元素进行交换
public static void swap(int[] nums, int i, int j) {
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
}
运行结果2: