问题描述:
给定一个数组arr, 和一个数num, 请把小于num的数放在数组的左边, 等于num的数放在数组的中间, 大于num的数放在数组的右边。
要求额外空间复杂度O(1), 时间复杂度O(N)
思路:
(1)首先定义3个游标,less是用来标明其左边是小于num,初始位置为L-1;more是用来标明其右是大于num,初始位置为R+1;current是用来标明目前运动到什么位置了,初始位置当然是L。
(2)运动过程是这样运动的,首先从current开始,将current位置的数值与num进行比较。如果小于num,就将less游标的下一个位置的数值与其交换,此时less++,current++;如果等于num,此时就将current++;如果大于num,就将more游标的前一个位置的数值与其交换,此时more--,然后再将交换后的值(current位置的值)与num比较,再根据大于小于等于重复进行上述操作。
(3)不断地重复(2),直到current与more相撞时,停止。既然是不断重复操作,可使用循环进行
代码:
package NetherlandsFlag;
import java.util.Arrays;
public class NetherlandsFlag {
public static void partition(int[] arr,int L,int R,int num) {
int less=L-1;
int more=R+1;
int current=L;
while (current<more) {
if (arr[current]<num) {
change(arr, current++, ++less);
}else if (arr[current]>num) {
change(arr, current, --more);
}else {
current++;
}
}
}
//定义交换方法
public static void change(int[] arr,int i,int j) {
int tem=arr[i];
arr[i]=arr[j];
arr[j]=tem;
}
public static void main(String[] args) {
int[] arr= {1,4,3,2,7,6,5,4,3};
int num=4;
partition(arr,0,8,num);
System.out.println(Arrays.toString(arr));
}
}
运行结果: