在一个数组中, 每一个数左边比当前数小的数累加起来, 叫做这个数组的小和。 求一个数组 的小和
Java实现
public class smallSum {
public static int samllSumCount(int[] arr){
if (arr == null || arr.length <2){
return 0;
}
return mergeSort(arr, 0, arr.length-1);
}
public static int mergeSort(int[] arr, int l, int r){
if (l == r){
return 0;
}
int mid = l + ((r-l) >> 1); //注意当a的值大于0的时候,>>1表示除以2,a的值小于0的时候, >>1 比除2小1
return mergeSort(arr, l, mid) + mergeSort(arr, mid+1, r) + merge(arr, l, mid, r);
}
public static int merge(int[] arr, int l, int m, int r){
/**
* 其实就是在排序的过程当中插入了一些计算小数的代码
* 在计算的过程当中,其实i-m 和 m-r之间是已经排序好的数字
* 利用这一特点可以批处理完成小和的计算
*/
int[] help = new int[r-l+1];
int p0 = l;
int p1 = m+1;
int res = 0;
int i = 0;
while(p0 <=m && p1 <= r){
if(arr[p0] < arr[p1]){
res += arr[p0] * (r-p1+1);
help[i++] = arr[p0++];
} else{
help[i++] = arr[p1++];
}
}
while(p0 <= m){
help[i++] = arr[p0++];
}
while(p1 <= r){
help[i++] = arr[p1++];
}
for(i=0; i<help.length; i++){
arr[l+i] = help[i];
}
return res;
}
python实现
def small_sum_2(x):
if len(x) < 2:
return 0
return merge_sort(x, 0, len(x)-1)
def merge_sort(x, l, r):
if l == r:
return 0
m = (l+r) // 2
return merge_sort(x, l, m) + merge_sort(x, m+1, r) + merge(x, l, m, r)
def merge(x, l, m, r):
sum = 0
i = 0
p0 = l
p1 = m+1
help = [None] * (r-l +1)
while(p0 <= m, p1 <= r):
if x[p0] < x[p1]:
sum += (x[p0] * r-p1+1)
help[i] = x[p0]
p0 += 1
i += 1
else:
help[i] = x[p1]
p1 += 1
i += 1
while(p0 <= m):
help[i] = x[p0]
p0 += 1
i += 1
while(p1 <= r):
help[i] = x[p1]
p1 += 1
i += 1
for i in range(len(help)):
x[l+i] = help[i]
return sum