lintode(532)逆序对

本文介绍了一种利用归并排序解决逆序对计数问题的方法。通过递归地将数组分为两部分,并分别计数每部分内的逆序对数量,最终合并两个有序数组时再计算跨部分的逆序对,以此实现高效计算逆序对总数。

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

描述:

在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。给你一个数组,求出这个数组中逆序对的总数。
概括:如果a[i] > a[j] 且 i < j, a[i] 和 a[j] 构成一个逆序对。

样例:

序列 [2, 4, 1, 3, 5] 中,有 3 个逆序对 (2, 1)(4, 1)(4, 3),则返回 3 。

思路:

归并排序,复制一个数组保存排序结果,然后递归解题。一开始嵌套for循环来做,超时了,参考了其他人的方法

public class Solution {
    /**
     * @param A an array
     * @return total of reverse pairs
     */
    //归并排序
    public long reversePairs(int[] A) {
        // Write your code here
        long result = 0;
        if(A == null || A.length == 0){
            return result;
        }
        int[] a = new int[A.length];
        for(int i = 0;i<A.length;i++){
            a[i] = A[i];
        }
        result = search(A , a , 0 , A.length - 1);
        return result;
    }
    
    public long search(int[] A , int[] a , int low , int high){
        if(high == low){
            return 0;
        }
        int mid = (low + high)/2;
        long left = search(A , a , low , mid);
        long right = search(A , a , mid + 1 , high);
        int i = mid;
        int j =high;
        long result = 0;
        int copy = high;
        while(i>=low && j>mid){
            if(A[i] > A[j]){
                a[copy--] = A[i--];
                result += j-mid;
            }else{
                a[copy--] = A[j--];
            }
        }
        for(;i>=low;i--){
            a[copy--] = A[i];
        }
        for(;j>mid;j--){
            a[copy--] = A[j];
        }
        for(int p = low;p<=high;p++){
            A[p] = a[p];
        }
        return (result+left+right);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值