数据结构与算法之返回最小和问题

数据结构与算法之返回最小和问题

问题描述:

在一个数组中,一个数左边比它小的数的总和,叫数的小和,所有数的小和累加起来,叫数组小和。求数组小和。
例子: [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

思路:

思路:利用递归实现,对于一个数组,将其任意划分为两部分,如果左部分以及右部分分别是有序的,那么统计左边任意一个数产生的小和,可以看成是求解右边有多少个数比当前数大的问题,右边某一个数A大于左边这个数B,那么A后面的数都会大于B,当统计完完右边区域的长度数目n, 就有n个小和B产生。

图示:

代码:

public class day03_MergeSmall {
    public static void main(String[] args) {
    int [] arr = {1,3,4,2,5};
        System.out.println(mergeSmall(arr));
    }
    public static int mergeSmall(int [] arr){
        if (arr == null || arr.length < 2){
            return -1 ;
        }
        return process(arr,0,arr.length-1);
    }
    public static int process(int [] arr ,int left ,int right){
        if (left == right){
            return 0;
        }
        int mid = left + ((right-left)>>1);
        return process(arr,left,mid)
               +
               process(arr,mid+1,right)
               +
               merge(arr,left,mid,right);
    }
    public static int merge(int [] arr,int left,int mid ,int right){
        int [] help = new int[right - left + 1];
        int i = 0;
        int p1 = left;
        int p2 = mid + 1;
        int result = 0;
        while(p1 <= mid && p2 <= right){
            result += arr[p1] < arr[p2] ? arr[p1]*(right-p2+1):0;
            help[i++] = arr[p1] < arr[p2] ? arr[p1++]:arr[p2++];
        }
        while(p1 <= mid){
            help[i++] = arr[p1++];
        }
        while(p2 <= right){
            help[i++] = arr[p2++];
        }
        for (int j = 0; j <help.length ; j++) {
            arr[left+j] = help[j];
        }
        return result;
    }
}
posted @ 2020-12-23 16:56  等不到的口琴  阅读(159)  评论(0编辑  收藏  举报