题目 给定一个数组arr,和一个数num,请把小于num的数放在数组的 左边,等于num的数放在数组的中间,大于num的数放在数组的 右边。 要求额外空间复杂度O(1),时间复杂度O(N)
思路 设置三个指针,分别指向小于num的最后一个值[fl]、当前值[i]、大于num的第一个值[fr]。从头开始遍历,若当前值小于num,则将其与fl+1位置的值做交换,并继续遍历;若当前值等于num,则不做任何处理,继续遍历;若当前值大于num,则将其与fr-1位置的值做交换,并继续考察交换后的当前位置的值(因为换到当前位置的值不确定其与num的关系)。遍历停止条件:i=fr。
package section1;
import java.util.Arrays;
public class NetherlandsFlag {
public static void netherlandsFlag(int[] arr, int num){
if (arr == null || arr.length < 2) return;
int fl = -1;
int fr = arr.length;
for (int i = 0; i < fr; i++ ){
if (arr[i] < num) change(arr, ++fl, i);
else if (arr[i] == num) continue;
else change(arr, --fr, i--);
}
}
public static void change(int[] arr, int a, int b){
int f = arr[a];
arr[a] = arr[b];
arr[b] = f;
}
// for test
public static int[] generateArray() {
int[] arr = new int[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 10);
}
return arr;
}
// for test
public static void printArray(int[] arr) {
if (arr == null) {
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
int[] test = generateArray();
printArray(test);
int num = (int) (Math.random() * 10);
System.out.println("num: " + num);
netherlandsFlag(test, num);
printArray(test);
}
}