一、荷兰国旗问题。将由0,1,2 三个数字组成的数组顺序排列。 扩展问题:将数组中的第一个元素,比它小的放在左边,相等的放在中间,大于的放在后边。
解法:时间复杂度O(n).
我们的思路如下:将前部和后部各排在数组的前边和后边,中部自然就排好了。具体的:
设置两个标志位begin和end分别指向这个数组的开始和末尾,然后用一个标志位current从头开始进行遍历:
1)若遍历到的位置为0,则说明它一定属于前部,于是就和begin位置进行交换,然后current向前进,begin也向前进(表示前边的已经都排好了)。
2)若遍历到的位置为1,则说明它一定属于中部,根据总思路,中部的我们都不动,然后current向前进。
3)若遍历到的位置为2,则说明它一定属于后部,于是就和end位置进行交换,由于交换完毕后current指向的可能是属于前部的,若此时current前进 则会导致该位置不能被交换到前部,所以此时current不前进,end向前走一个。
public void sort(int[] arr){
int start=0,end=arr.length-1,current=0; //start之前的,end之后的已经排好
while(current<=end){
if(arr[current]<1){ //current小于1时
int tmp=arr[current]; //交换current和start,current往前,start往前
arr[current]=arr[start];
arr[start]=tmp;
start++;
current++;
}
else if(arr[current]>1){ //current大于1时
int tmp=arr[current]; //交换current和end,current不动,end向前
arr[current]=arr[end];
arr[end]=tmp;
end--;
}else //current等于1时
current++; //current往前
}
}
//扩展问题
public void sort02(int[] arr){
int val=arr[0];
int start=0,end=arr.length-1,current=0;
while(current<=end){
if(arr[current]<val){
int tmp=arr[current];
arr[current]=arr[start];
arr[start]=tmp;
start++;
current++;
}
else if(arr[current]>val){
int tmp=arr[current];
arr[current]=arr[end];
arr[end]=tmp;
end--;
}else
current++;
}
}