方法一:用排序算法,O(NlogN)
方法二:单指针,扫两遍,O(N)
第一遍挪0,第二遍挪1
class Solution {
public void sortColors(int[] nums) {
int p = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 0) {
swap(nums, i, p);
p++;
}
}
for (int i = p; i < nums.length; i++) {
if (nums[i] == 1) {
swap(nums, i, p);
p++;
}
}
}
public void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
}
方法二:双指针,扫一遍,O(N)
- i从左往右扫,指针p0是下一个放0的位置,指针p1是下一个放1的位置。
- 遇到了0,swap,然后p0和p1都+1,
- 下一个放0的位置+1
- 因为1肯定要排在0后面,所以p1也要+1
- 需要处理1被0覆盖的情况。
- 遇到了1,swap,只有p1 + 1
class Solution {
public void sortColors(int[] nums) {
// p0为存放下一个0的位置,p1为存放下一个1的位置, cur为遍历指针
int p0 = 0, p1 = 0, cur = 0;
while (cur < nums.length) {
if (nums[cur] == 0) {
//这时,把nums[i]=0换回前面会覆盖1,需要再把nums[i]=1换到下一个放1的位置
if (p0 < p1) {
swap(nums, cur, p0);
swap(nums, cur, p1);
p0++;
p1++;
} else {
swap(nums, cur, p0);
p0++;//填充下一个0的位置加一
p1++;//填充下一个1的位置加一
}
} else if (nums[cur] == 1) {
swap(nums, cur, p1);//填充下一个1的位置+1,填充下一个0的位置不变
p1++;
}
cur++;
}
}
public void swap(int[] nums, int m, int n) {
int tmp = nums[m];
nums[m] = nums[n];
nums[n] = tmp;
}
//由于一开始p0=p1,所以当p1 > p0 时,说明p1肯定已经向右移动了,p0的位置上必然是1
//这时候如果swap一下i和p0,相当于把1又换出去了,然后应该把1再换到下一个期待1的位置,即p1
// p0 p1 i
// +-------------------+
// | 0 | 1 | | | 0 |
// +-------------------+
}