(一)题目描述(典型的荷兰国旗问题)
给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
(二)解题思路
1)使用java自带排序函数:Arrays.sort(nums);
2)单指针法:设置一个pre,其表示pre下标及其之前的范围都已排好序,主要使用方法为:首先pre指向当前数组头部,用i遍历当前数组,若找到0,则将nums[i]与pre[i]进行交换,并进行pre++;当i遍历到数组尾端时,此时pre即起之前都是0,且此时pre位置为数1的起点,当此趟遍历完后,表明0、1都以归位,因而剩余的2也已归位
3)双指针法:设置p0、p1分别记录当前需要放置0、1的位置。遍历nums[i],碰到0则p0、p1指针均需要向后移动,同时在p0<p1时,被交换出去的p0指向的位置的元素必定为1,所以还需将该交换出去的1再与p1所指向位置元素进行一次交换.
(三)代码如下
1)单指针
class Solution23 {
public void sortColors(int[] nums) {
//单指针法
/* 时间复杂度:O(n)O(n),其中 nn 是数组nums 的长度。
空间复杂度:O(1)O(1)。*/
int pre = 0;
int len = nums.length;
for (int i = pre; i < len; i++) {
if(nums[pre]==0){
pre++;
continue;
}
if (nums[i] == 0) {
int temp=nums[i];
nums[i]=nums[pre];
nums[pre]=temp;
pre++;
}
}
for (int i = pre; i < len; i++) {
if(nums[pre]==1){
pre++;
continue;
}
if(nums[i]==1){
int temp=nums[i];
nums[i]=nums[pre];
nums[pre]=temp;
pre++;
}
}
}
}
2)双指针
public void sortColorsMethod2(int[] nums) {
//(1)设置双指针
int p0 = 0, p1 = 0;
int len = nums.length;
for (int i = 0; i < len; i++) {
//如果当前找到0的话,p0、p1指针都需要向后移动一个,因为p1指向的1的位置总是在0的位置之后
if (nums[i] == 0) {
int temp = nums[i];
nums[i] = nums[p0];
nums[p0] = temp;
if (p0 < p1){
temp=nums[p1];
nums[p1]=1;
nums[i]=temp;
}
p0++;
p1++;
}else if(nums[i]==1){
//直接与p1进行交换即可
int temp = nums[i];
nums[i] = nums[p1];
nums[p1] = temp;
p1++;
}
//当前指向0的指针在指向1的指针之前,则被换出的元素必为1,所以还需要将1换回到p1所指位置
}
}