快排前置
问题1: 给定一个数组,让小于target的放置在数组左侧,大于target的放置在数组右侧,要求空间复杂度为O(1),时间复杂度为O(N)
public class PreQuickSort{
/**
* 给定一个数组,让小于target的放置在数组左侧,大于等于target放置在数组右侧
*
* @param arr
* @param target 定义两个指针
* point1 -> 永远指向比target小于或等于的数的最右侧
* point2 -> 用于遍历 arr
*/
public static void preQuickSort1(int[] arr, int target) {
int point1 = -1;
int point2 = 0;
while (point2 < arr.length) {
if (arr[point2] <= target) {
swap(arr, ++point1, point2++);
} else {
++point2;
}
}
}
/**
* 相比上面一个方法,省略了一个无效的交换动作(即自己跟自己交换)
*
* @param arr
* @param target 定义两个指针
* point1 -> 永远指向比target小的数的最右侧
* point2 -> 用于遍历 arr
*/
public static void preQuickSort12(int[] arr, int target) {
int point1 = -1;
int point2 = 0;
while (point2 < arr.length) {
if (arr[point2] <= target && (point1 + 1) == point2) {
point1++;
point2++;
} else if (arr[point2] <= target) {
swap(arr, ++point1, point2++);
} else {
++point2;
}
}
}
}
问题2: 给定一个数组,让<target的数在左侧,大于target在右侧,等于target的在中间。该问题又称之为荷兰国旗问题。要求空间复杂度O(1),时间复杂度O(N);
public class PreQuickSort{
/**
* 给定一个数组,让<target在左侧,大于target在右侧,等于target在中间
*
* @param arr
* @param target
*/
public static void preQuickSort2(int[] arr, int target) {
int l = -1;
int r = arr.length;
int point = 0;
while (point < r) {
if (arr[point] < target) {
swap(arr, ++l, point++);
} else if (arr[point] == target) {
point++;
} else {
swap(arr, --r, point);
}
}
}
/**
* 给定一个数组,让<target在左侧,大于target在右侧,等于target在中间
*
* @param arr
* @param target
*/
public static void preQuickSort21(int[] arr, int target) {
int left = -1;
int right = arr.length;
int point = 0;
while (point < right) {
if (arr[point] < target && (point == left + 1)) {
left++;
point++;
} else if (arr[point] == target) {
point++;
} else if (arr[point] > target) {
swap(arr, point, --right);
} else {
swap(arr, point, ++left);
}
}
}
}