我们都知道荷兰国旗是由3种颜色组成,红色一长条在上方,白色长条在中间,蓝色长条在下方,对应的一道经典排序题就是大于i值的放i的右边,小于i值的放i的左边,等于i值的放中间。
要求之间复杂度为O(N), 就是一次遍历就排完成。
代码如下:
// 传统荷兰国旗问题
public static void netherlandsNationalFlag (int[] arr, int i) {
// 一次遍历,大于i的放数组右边,小于i的放左边,等于i的放中间
// 2, 3, 4, 5, 6, 1 -> i = 2
int left = 0;
int right = arr.length;
int index = 0;
while (index < right) {
if (arr[index] == i) {
index++;
} else if (arr[index] > i) {
swap(arr, index, --right);
} else {
swap(arr, index++, left++);
}
}
}
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
|
核心思想就是划分两个区,大于i的区 和小于i的区,如果arr[index]当前位置的值大于i,就把大于区的前一个数和index交换,index不动,如果arr[index]的值小于i,就把小于区的最后一个数与当前位置交换,index后移,小于区也后移,如果相等,则只把index后移。
这也是基本快排的核心代码