思路:
方法一:暴力
方法二:循环不变量
代码:
暴力
class Solution {
public void sortColors(int[] nums) {
int n=nums.length;
for(int i=1;i<n;i++){
for(int j=0;j<i;j++){
if(nums[j]>nums[i]){
int temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
}
}
}
}
循环不变量
class Solution {
public void sortColors(int[] nums) {
int n=nums.length;
if(n<2){
return;
}
//[0,zero)-->0
//[zero,i)-->1
//[two,n-1]-->2
//根据边界的不同,初始化不同,才能使得区间为0
int zero=0,two=n,i=0;
//注意:循环终止的条件是i<two时,刚好覆盖三个区间
//因为two先减后交换,所以最后一次时,two--,就是i的位置
while(i<two){
if(nums[i]==0){
//先交换,再加
swap(nums,i,zero);
zero++;
i++;
}
else if(nums[i]==1){
i++;
}
//nums[i]==2
else{
//先减,再交换
two--;
swap(nums,i,two);
}
}
}
private void swap(int[] nums,int i,int j){
int temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
}
分解:
1)循环不变量是设置了3个遍历,划分为3个区间,初始时要保持区间为空,所以根据划分的边界不同,初始值不同:
[0,zero)-->0
[zero,i)-->1
[two,n-1]-->2
初始:int zero=0,two=n,i=0;
注意:
a.此时zero先加后交换,two先交换再减
b.循环的条件是:i<two,因为two先减后交换,所以最后一次时,two--,就是i的位置,这样所有数都循环到了
复杂度分析:
暴力:
时间复杂度:O(N^2)
空间复杂度:O(1)
循环不变量:
时间复杂度:O(N)
空间复杂度:O(1)