数组小和问题:
int[] arr = new int[]{4,1,2,3,6};
每个位置的前面比自己小的数的累加和问题。
0:没有比自己小
1:没有比自己小
2:1比自己小,累加 1
3:1,2位置比自己小,累加 3
4:1,2,3位置比自己小,累加6;
总共:10;
归并排序变种处理
时间复杂度:O(N*logN)
和归并排序也就是下面一句代码的区别
ans += arr[p1] < arr[p2]?arr[p1] * (R - p2 +1):0;
public static int minSum(int[]arr ){
if(arr ==null || arr.length < 2){
return 0;
}
return process(arr,0,arr.length-1);
}
public static int process(int []arr ,int L,int R){
if(L == R){
return 0;
}
int M = L +((R-L)>>1);
return process(arr,L,M)+process(arr,M+1,R)+merge(arr,L,M,R);
}
public static int merge(int [] arr ,int L,int M,int R){
int ans = 0 ;
int[] help = new int[R - L +1];
int i = 0;
int p1 = L;
int p2 = M+1;
while (p1 <= M && p2 <= R){
ans += arr[p1] < arr[p2]?arr[p1] * (R - p2 +1):0;
help[i++]=arr[p1]<=arr[p2]?arr[p1++]:arr[p2++];
}
while (p1 <= M){
help[i++] = arr[p1++];
}
while (p2 <= R){
help[i++] = arr[p2++];
}
for (int j = 0;j<help.length;j++) {
arr[L+j] = help[j];
}
return ans;
}