1. 双指针两次遍历
解题思路:时间复杂度O(
n
n
n),空间复杂度O(
1
1
1),需要遍历两次数组 |
---|
- 第一遍遍历,将所有0放到前面
- 第二遍遍历,将所有1放在0后面
class Solution {
public static void changePosition(int arr[],int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public void sortColors(int[] nums) {
int n = nums.length;
int left = 0;
for(int right = 0;right<n;right++){
if(nums[right] == 0) changePosition(nums,left++,right);
}
for(int right = left;right<n;right++){
if(nums[right] == 1) changePosition(nums,left++,right);
}
}
}
2. 三指针
解题思路:时间复杂度O(
n
n
n),空间复杂度O(
1
1
1),只遍历1次数组 |
---|
- p0指向下一个0需要放置的位置,同理p1指向下一个1需要放置的位置
- 我们使用p2指针来进行遍历数组,如果发现p2指向的是1就和p1位置交换,同时p1++
- 当p2指向0时,需要和p0交换,但是有一种特殊情况
- 例如001122
0
,其中1是p0位置,2是p1位置,0
是p2位置 - 此时,我们发现p1的位置是超过p0的,也就是说,此时p1后面一定是1,而p0的下一个插入位置,就在p1的后面,也就是p0比如指向1
- 此时我们要让p0和p2交换位置,结果为000122
1
。我们发现,虽然现在p0位置放上了0,但是p0原来指向的1,却放到了p2位置 - 也就是说,我们为了换一个0,把1交给了p2.此时就需要p1和p2将这个1要回来
- 因此只要我们p0和p2交换完成后,发现p0<p1,就需要再让p1和p2额外进行一次交换,结果为000112
2
class Solution {
public static void changePosition(int arr[],int i,int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public void sortColors(int[] nums) {
int p0 = 0;int p1 = 0;int p2 = 0;
while(p2<nums.length) {
if(nums[p2] == 1) changePosition(nums,p1++,p2);
else if(nums[p2] == 0) {
changePosition(nums,p0,p2);
if(p0<p1) changePosition(nums,p1,p2);
p0++;p1++;
}
p2++;
}
}
}