最小和解析:
例:arr = {1,3,4,2,5}
1前面小于1的:0
3前面小于3的:1
4前面小于4的:1+3
2前面小于2的:1
5前面小于5的:1+3+4+2
总和=16
等价于:
1后面大与1的有4个:1x4
3后面大与3的有2个:3x2
4后面大与4的有1个:4x1
2后面大与2的有1个:2x1
5后面大与5的有0个:5x0
总和=16
常规思路:利用两个for循环遍历数组并求最小和。时间复杂度为O(N)
优化:利用归并排序解决,时间复杂度O(N*logN)
不理解归并排序的同学可以看
java排序(四)归并排序
java代码实现:
package MergeSort;
import java.util.Random;
public class smallSum {
public static void main(String[] args) {
int[] arr=new int[10];
Random r=new Random();
for(int i=0;i<arr.length;i++){
arr[i]=r.nextInt(100);
}
print(arr);
//验证
int res = 0;
for(int i = 0;i < arr.length;i++) {
for(int j=i + 1;j < arr.length;j++) {
res += arr[i] < arr[j] ? arr[i] : 0;
}
}
System.out.println(res);
System.out.println("----------------------------------");
int result = smallSum(arr);
print(arr);
System.out.println(result);
}
public static int smallSum(int[] arr) {
if(arr == null && arr.length < 2) {
return 0;
} else {
return process(arr, 0, arr.length - 1);
}
}
public static void print(int[] arr) {
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i] + "\t");
}
System.out.println();
}
public static int process(int[] arr,int l,int r) {
if(l == r) {
return 0;
}
int mid = l + ((r - l) >> 1);
return process(arr,l,mid) +
process(arr,mid + 1,r) +
merge(arr, l, mid, r);
}
public static int merge(int[] arr,int l, int m, int r) {
int[] help = new int[r - l + 1];
int i = 0;
int p1 = l;
int p2 = m + 1;
int res = 0;
while (p1 <= m && p2 <= r) {
res += arr[p1] < arr[p2] ? (r - p2 +1) * arr[p1] :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(i = 0; i < help.length; i++){
arr[l + i] = help[i];
}
return res;
}
}
运行结果: