问题一
给定一个数组arr,和一个数num,请把小于等于num的数放在数 组的左边,大于num的数放在数组的右边。
要求额外空间复杂度0(1),时间复杂度0(N)
给定一个小于等于区域,遍历,如果当前数小于等于num,则当前数和小于等于把区域紧挨着的下一个位置数字交换,小于等于区域顺序扩张一个数;如果当前数大于num,则继续遍历。如下代码:minuteArray是核心函数
代码展示部分保证除了包之外整个代码拷贝过去是可以正常运行的
代码如下:
package yzy.algorithm;
public class dutchFlag {
//给定一个数组arr,和一个数num,请把小于等于num的数放在数 组的左边,大于num的数放在数组的右边
public static void minuteArray(int[] arr, int num){
int x = -1; //小于等于区域[0,x]
int i=0;
while(i<arr.length){
if(arr[i]<=num) {
int tmp = arr[i];
arr[i] = arr[x + 1];
arr[x + 1] = tmp;
x += 1;
}
i++;
}
}
//对数器: 生成一个长度范围在[1, size]的任意长度并且任意位置是随机值的数组
//随机值的范围在:[0, value]
public static int[] generateRandomArray2(int size, int value) {
//Math.random() 返回[0, 1)范围中的随机小数
//(size+1)*Math.random() [0, size+1)-->[0, size]
int[] arr = new int[(int)((size+1)* Math.random())+1]; //(size+1)* Math.random()是[0, size]范围中的随机小数
for(int i=0; i<arr.length; ++i) {
arr[i] = (int) ((value+1)* Math.random());
}
return arr;
}
public static void showArr(int[] arr){
for(int i=0; i<arr.length; ++i){
System.out.print(arr[i]+" ");
}
System.out.println();
}
public static void main(String[] args) {
int num = 5;
int[] arr = generateRandomArray2(10, 10);
System.out.print("对数器产生的数组:");
showArr(arr);
minuteArray(arr, num);
System.out.print("结果数组:");
showArr(arr);
}
}
问题二(荷兰国旗问题1)
给定一个数组arr,和一个数niwn,请把小于num的数放在数组的 左边,等于num的数放在数组的中间,大于num的数放在数组的 右边。
要求额外空间复杂度0(1),时间复杂度0(N)
解决办法和上述小于等于类似,给定小于区域和大于区域,遍历一遍,遇到小于num的数和小于区域的下一个数交换并扩张小于区域一个位置,如果遇到大于num的数,和大于区域的前一个位置的数交换并扩张大于区域一个数,特别注意,交换后还需判断当前数字是不是小于num。等于的情况下跳过这个数并继续遍历(遍历过程当前位置直到大于区域的前一个结束)。如下代码:dutchflag是核心函数
package yzy.algorithm;
public class dutchFlag {
public static void dutchflag(int[] arr, int num){
int l = -1; //小于区域[0,x]
int r = arr.length; //大于区域[r,n)
int i=0;
while(i<arr.length && i<r){
if(arr[i]>num){
int tmp = arr[i];
arr[i] = arr[r-1];
arr[r-1] = tmp;
r -= 1;
i--; //特别注意,交换后还需判断当前数字是不是小于num
}
else if(arr[i]<num) {
int tmp = arr[i];
arr[i] = arr[l + 1];
arr[l + 1] = tmp;
l += 1;
}
i++;
}
}
//对数器: 生成一个长度范围在[1, size]的任意长度并且任意位置是随机值的数组
//随机值的范围在:[0, value]
public static int[] generateRandomArray2(int size, int value) {
//Math.random() 返回[0, 1)范围中的随机小数
//(size+1)*Math.random() [0, size+1)-->[0, size]
int[] arr = new int[(int)((size+1)* Math.random())+1]; //(size+1)* Math.random()是[0, size]范围中的随机小数
for(int i=0; i<arr.length; ++i) {
arr[i] = (int) ((value+1)* Math.random());
}
return arr;
}
public static void showArr(int[] arr){
for(int i=0; i<arr.length; ++i){
System.out.print(arr[i]+" ");
}
System.out.println();
}
public static void main(String[] args) {
int num = 5;
int[] arr = generateRandomArray2(10, 10);
arr = new int[]{10, 8, 9, 6, 3, 0, 6};
System.out.print("对数器产生的数组:");
showArr(arr);
dutchflag(arr, num);
System.out.print("结果数组:");
showArr(arr);
}
}
我们对荷兰国旗代码进行改进,使得函数可以操作数组任意区间上的元素,如下代码:核心函数partition在规定时间空间复杂度下完成任务,partiton函数返回值是以数组的形式放回等于num的区间
package yzy.algorithm;
public class dutchFlag {
public static void swap(int[] arr, int i, int j){
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
//数组下标范围:闭区间
public static int[] partition(int[] arr, int L, int R, int num){
int less = L - 1;
int more = R + 1;
while(L < more){
if(arr[L] < num)
swap(arr, ++less, L++);
else if(arr[L] > num)
swap(arr, --more, L);
else
L++;
}
return new int[] {less+1, more-1};
}
//对数器: 生成一个长度范围在[1, size]的任意长度并且任意位置是随机值的数组
//随机值的范围在:[0, value]
public static int[] generateRandomArray2(int size, int value) {
//Math.random() 返回[0, 1)范围中的随机小数
//(size+1)*Math.random() [0, size+1)-->[0, size]
int[] arr = new int[(int)((size+1)* Math.random())+1]; //(size+1)* Math.random()是[0, size]范围中的随机小数
for(int i=0; i<arr.length; ++i) {
arr[i] = (int) ((value+1)* Math.random());
}
return arr;
}
public static void showArr(int[] arr){
for(int i=0; i<arr.length; ++i){
System.out.print(arr[i]+" ");
}
System.out.println();
}
public static void main(String[] args) {
int num = 5;
arr = generateRandomArray2(10, 10);
// arr = new int[]{3, 5, 8, 10, 7, 2 };
System.out.print("对数器产生的数组:");
showArr(arr);
int[] res = partition(arr, 0, arr.length-1, num);
System.out.println("等于num的区间是["+res[0]+","+res[1]+"]");
System.out.print("结果数组:");
showArr(arr);
}
}
可以对快排加速 ↩︎