题目
题解
本题是经典的「荷兰国旗问题」,由计算机科学家 Edsger W. Dijkstra 首先提出。
单指针(两次遍历)
class Solution {
public void sortColors(int[] nums) {
int ptr=0;
//所有0换到最前面
for(int i=0;i<nums.length;i++){
if(nums[i]==0){
swap(i,ptr,nums);
ptr++;
}
}
int oneBegin=ptr;
for(int i=oneBegin;i<nums.length;i++){
if(nums[i]==1){
swap(i,ptr,nums);
ptr++;
}
}
}
public void swap(int i,int j,int[] nums){
int tmp=nums[i];
nums[i]=nums[j];
nums[j]=tmp;
}
}
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( 1 ) O(1) O(1)
双指针(一次遍历)
从前往后遍历
class Solution {
public void sortColors(int[] nums) {
int p0=0,p1=0;
for(int i=0;i<nums.length;i++){
if(nums[i]==0){
swap(i,p0,nums);
//如果p0<p1,表示当前已经将一些1连续地放在头部,此时一定会把一个1交换出去,导致答案错误
//所以要交换i和p1,将1换到p1位置
if(p0<p1){
swap(i,p1,nums);
}
p0++;
p1++;//1肯定在0后面,所以p1也要向后移动一位
}
else if(nums[i]==1){
swap(i,p1,nums);
p1++;
}
}
}
public void swap(int i,int j,int[] nums){
int tmp=nums[i];
nums[i]=nums[j];
nums[j]=tmp;
}
}
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( 1 ) O(1) O(1)
p0从前往后+p2从后往前
class Solution {
public void sortColors(int[] nums) {
int p0=0,p2=nums.length-1;
//p2后面都是2,已排好,因此i到p2即可
for(int i=0;i<=p2;i++){
//将nums[i]与nums[p2]进行交换之后,
//新的nums[i]可能仍然是2,也可能是0
//因此需要重复判断nums[i]
while(i<=p2&&nums[i]==2){
swap(i,p2,nums);
p2--;
}
if(nums[i]==0){
swap(i,p0,nums);
p0++;
}
}
}
public void swap(int i,int j,int[] nums){
int tmp=nums[i];
nums[i]=nums[j];
nums[j]=tmp;
}
}
时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( 1 ) O(1) O(1)