一、问题
给定一个数组arr,和一个数num,请把小于等于num的数放在数 组的左边,大于num的数放在数组的右边。
要求额外空间复杂度O(1),时间复杂度O(N)
二、解释
问题应该很好理解。数组中的每个数和num相比,小于等于num放左边,大于num放右边。
解决这个问题最普遍的思路就是建立一个辅助数组,然后对arr进行遍历,把每一个数字与num相比较,并且对辅助数组就行赋值。但是这样的方法会多增加一种O(N)的额外空间。 并不符合题意。而若需要额外空间复杂度O(1),我们只能在arr中进行操作。
思路:
初始化定义左边区域指针 less=0 表示 0-less为小于等于num区域,定义右边区域指针more=N-1 ,表示 N-1-more为大于num区域。将每一个元素与num比较。若当前元素比num小,则将less++(小于等于范围扩大一位),并且当前元素指针右移;若当前元素比num大,则将该元素与more-1位置元素互换,右边区域大于范围扩大一位。具体配合代码进行理解。
三、代码
package algorithm_02;
/*
*
*小于等于num得数放左边 大于得数放右边
*/
public class Partition {
public static void swap(int arr[],int i,int j ){
if(i==j)
return;
arr[i]=arr[i]^arr[j];//异或运算进行交换操纵比较快
arr[j]=arr[i]^arr[j];
arr[i]=arr[i]^arr[j];
}
public static void partition(int arr[],int num){
if (arr==null||arr.length<2) {
return;
}
int less=0;
int more=arr.length-1;
while(less<more){
//当前元素比比较数字大时 与最右端数字交换
if (arr[less]>num) {
swap(arr, less, more--);
}else{//小于等于时 左端位置右移一位
less++;
}
}
}
public static void main(String[] args) {
int arr[]={1,5,4,2,8,6,3,0};
partition(arr, 3);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+" ");
}
}
}