0
点赞
收藏
分享

微信扫一扫

算法归并排序解决小和问题,时间复杂度O(nlog2n)

40dba2f2a596 2022-04-15 阅读 54
算法

在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。

举例:[1,4,5,3,7]

1,左边比它小数没有

4,左边比它小数:1

5,左边比它小的数:1,4

3,左边比它小的数:1

7,左边比它小的数:1,4,5,3

小和为:20

代码实现:

  public static void main(String[] args) {
        int[] arr = new int[]{1, 4, 5, 3, 7};
        int sum = smallSum(arr);
        System.out.println("小和为:"+sum);
    }


    public static int smallSum(int[] arr) {
        if (arr == null || arr.length < 2) {
            return 0;
        }
        return process(arr, 0, arr.length - 1);
    }

    // arr[L..R]既要排好序,也要求小和返回
    // 所有merge时,产生的小和,累加
    // 左 排序   merge
    // 右 排序  merge
    // merge
    public static int process(int[] arr, int l, int r) {
        if (l == r) {
            return 0;
        }
        int mid = l + ((r - l) >> 2);
        //分左边
        int lTotal = process(arr, l, mid);
        //分右边
        int rTotal = process(arr, mid + 1, r);
        int mTotal = merge(arr, l, mid, r);
        return lTotal + rTotal + mTotal;
    }

    public static int merge(int[] arr, int l, int m, int r) {
        int[] help = new int[r - l + 1];
        int lpos = l;
        int rpos = m + 1;
        int i = 0;
        int result = 0;
        while (lpos <= m && rpos <= r) {
            result += arr[lpos] < arr[rpos] ? (r - rpos + 1) * arr[lpos] : 0;
            help[i++] = arr[lpos] < arr[rpos] ? arr[lpos++] : arr[rpos++];
        }
        while (lpos <= m) {
            help[i++] = arr[lpos++];
        }
        while (rpos <= r) {
            help[i++] = arr[rpos++];
        }
        for (i = 0; i < help.length; i++) {
            arr[l + i] = help[i];
        }
        return result;
    }

 结果为:

 

举报

相关推荐

0 条评论