《程序员代码面试指南》小和问题和逆序对——java实现

本文介绍了一种利用递归算法解决小和问题的方法,并通过实例详细解释了其工作原理。小和问题是在随机数组中寻找所有左边比右边元素小的元素之和。文章还介绍了递归算法如何确保排序的稳定性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

小和问题和逆序对

题目描述:

小和问题:在随机元素,随机数组大小的数组中,找出左边比右边元素小的所有元素之和。
示例1:

数组[4,2,5,1,7,3,6] 第一个元素4比2大,不算小和,5比4和2都大,那就是4+2=6;1比4和2和5都小,不算小和;7比前面的都大,那就是上次小和6+4+2+5+1=18;然后3前面比2和1大,那就是18+2+1=21;最后6比4、2、5、1、3都大,结果就是21+4+2+5+1+3=36。那么最后的结果就是36。

题目思路:

求小和问题,本题采用递归算法的思想。将数组分为左右两个部分求解,若左侧的数比右侧的数小,则一定比右侧数后面所有的数都要小。则此时的最小和为res=(r - right + 1) * arr[left],然后采用递归的思想依次求和累计。
其实本题采用递归的思想,要求右侧比左侧大的数。主要是看中了递归排序的稳定性。因为稳定性,才不会打乱原数组的顺序。

题目难度:

medium

代码实现:

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

    public static int mergeSortSum(int[] arr, int begin, int end) {
        if (begin == end) {
            return 0;
        }
        int mid = begin + ((end - begin) >> 1);
        return mergeSortSum(arr, begin, mid) + mergeSortSum(arr, mid + 1, end) + merge(arr, begin, mid, end);
    }

    public static int merge(int[] arr, int l, int mid, int r) {
        int left = l;
        int right = mid + 1;
        int[] help = new int[r - l + 1];
        int i = 0;
        int res = 0;
        while (left <= mid && right <= r) {
        //一旦在右边遇到比当前值大的,则之后的数一定比当前值大
            res += arr[left] < arr[right] ? (r - right + 1) * arr[left] : 0;

            help[i++] = arr[left] < arr[right] ? arr[left++] : arr[right++];
        }
        while (left <= mid) {
            help[i++] = arr[left++];
        }

        while (right < r) {
            help[i++] = arr[right++];
        }
        for (int j = 0; j < help.length; j++) {
            arr[l + j] = help[j];
        }
        return res;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值