问题1 :给定一个数组,和一个数num,请把小于等于num的数放在数组的左边,大于num的数放在数组的右边,要求额外空间复杂度O(1),时间复杂度O(N)
把一个数组分为两个区域,分别为小于等于区域和待定区域。假设num = 4;
1)i指针位置的数小于等于num,交换i指针位置的数和小于等与区域的前一个数
图中所示情况就是3和自己交换,因为i指针是3,小于等于区前一个数也是3
2)i指针位置大于num,i加1就行。
当i到达2的位置时,交换2和5然后小于等于区加1,i加1。
后面就是一样的了,代码如下
public static void sort(int[] arr,int num) {
int p1 = -1;//代表小于等于区域
int i = 0;//代表指针i也就是未知区域
while(i<arr.length) {
if(arr[i]<=num) {//小于等于的时候,交换i和小于等于区域的前一个值,并且小于等于区域加1
swap(arr,i,++p1);
}
i++;//无论大于还是小于i指针都是要加1的
}
}
问题二:给定一个数组和一个数num,请把小于num的数放在左边,等于num的数放在中间,大于num的数放在右边,要求额外空间复杂度O(1),时间复杂度O(N)
假设num= 5
1)i指针的值小于num
小于区加1,i加1
2)i指针等于num
i+1就行
3)i指针的值大于num
交互i指针的值和大于区前一个数的值,大于区的值减小1,i不变。
结束条件是i的值碰到了大于区。
代码如下
public static void sort2(int[] arr,int num) {
int p1 = -1;//小于区域【数组左边】
int i = 0;
int p2 = arr.length;//大于区域【数组右边】
while(i!=p2) {
if(arr[i]<num) {//小于的时候,小于区域的前一个值和i交换,并且小于区域加1,也就是++p1和i交换后,i再加1
swap(arr,++p1,i++);
}
else if(arr[i]==num) {
i++;
}
else if(arr[i]>num) {
swap(arr,i,--p2);
}
}
}