用归并排序思想解决小和问题
在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组的小和。
例子:
[1,3,4,2,5]
1左边比1小的数,没有;
3左边比3小的数,1;
4左边比4小的数,1、3;
2左边比2小的数,1;
5左边比5小的数,1、3、4、2;
所以小和为1+1+3+1+1+3+4+2=16
public class Test {
public static void main(String[] args) {
int []arr={6,7,5,3,9};
System.out.println(mergeSort(arr));
}
public static int mergeSort(int []arr){
if(arr==null || arr.length<2){
return 0;
}
return mergeSort1(arr,0,arr.length-1);
}
private static int mergeSort1(int[] arr,int l,int r) {
if(l==r){
return 0;
}
int mid=l+((r-l)>>1);
int mergeLeft=mergeSort1(arr,l,mid);
int mergeRight=mergeSort1(arr,mid+1,r);
int mergerA=merge(arr,l,r);
return mergeLeft+mergeRight+mergerA;
}
private static int merge(int[] arr, int l, int r) {
int i=l;
int mid=l+((r-l)>>1);
int j=mid+1;
int []help=new int[r-l+1];
int index=0;
int sum=0;
while (i<=mid&&j<=r){
sum+=arr[i]<arr[j]?arr[i]*(r-j+1):0;
help[index++]=arr[i]<arr[j]?arr[i++]:arr[j++];
}
while (i<=mid){
help[index++]=arr[i++];
}
while (j<=r){
help[index++]=arr[j++];
}
for(int p=0;p<help.length;p++){
arr[p+l]=help[p];
}
return sum;
}
}