* 荷兰国旗:将给定一个数组arr,和一个数num,请把小于num的数放在数组的左边,等于num的数放在数组的中间,大于num的数放在数组的右边。
* 要求额外空间复杂度O(1),时间复杂度O(N)
* 思路:需要三个指针(小于num指针small、等于num指针equal、大于num指针big) 有以下三种情况
* 1、cur小于num,samll指针加一,同时推动equal指针加一;
* 2、cur等于num,equal指针加一,
* 3、cur大于num,big指针值和cur指针的值交换,同时big指针加一,cur不用动。
注意:要想清楚循环条件中是哪两个下标进行对比。
public class DutchFlag {
public static void dutchFlag(int[] arr,int l,int r,int num){
int small = l-1;
int big =r+1;
int cur=l;
// while(cur<r){
for(;cur<big;){
/* 在cur=5,big=6时候已经成功了,再往下就没有意义了,反而会打乱已经正常的排序导致最后错误结果为1,3,4,8,2,9,5,5,6,7
因此选择循环的条件很重要。应该是cur和big比较,而不是和r比较。
注意while循环和for循环的区别。while循环中没有增量,增量是在方法体内完成的,而for通常是有增量的,需要小心for循环的增量会影响代码内的增量。
错误for(;cur<big;cur++)正确 for(;cur<big;){
主要是想好算法的中心*/
// 如果当前值比给定值小,则交换当前值和small指针指向的值,同时++
if(arr[cur]<num){
SimpleSorting.swap(arr,++small,cur++);
// cur大于num,交换当前值和big指针指向的值,big--,因为还要在此判断交换过的值,
}else if(arr[cur]>num){
SimpleSorting.swap(arr, cur, --big);
}else{
// cur等于num,equal指针加一,
cur++;
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = {1,3,5,7,9,5,2,4,6,8};
// 调用方法
dutchFlag(arr,0,arr.length-1,5);
for (int i : arr) {
System.out.println(i);
}
}
}