【剑指offer】剑指 Offer 51. 数组中的逆序对

博客详细解析了《剑指Offer》中第51题——数组中的逆序对,通过使用归并排序的思想,逐层划分区间并计算逆序对,最后合并区间得到总逆序对数。代码实现中展示了如何通过迭代和递归计算逆序对,并优化了时间复杂度。

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

剑指 Offer 51. 数组中的逆序对

题目链接

在这里插入图片描述
剑指 Offer 51. 数组中的逆序对

思路分析

第一种方法是进行穷举暴力解法,但这肯定会超时
因此我们可以不断划分区间,使用归并排序的思想,求解每一个小区间的逆序对,然后将它们加在一起,就能得到最终的结果,也就是总的逆序对数。
[1,3,6,9] [2, 5, 8]
对于3 5来说 3 < 5 但是3 大于 5之前的所有数,例如2
再对于6来说,尽管6 < 8 但是6 大于8之前的所有数
我们将这些数加起来,就是我们最终求解的逆序对数

代码实现

class Solution {
public:
    int mergeSort(vector<int>& nums, vector<int>& arr, int start, int end)
    {
        if(start >= end)
            return 0;
        int mid = start + (end - start)/2;
        int cnt = mergeSort(nums, arr, start, mid) + mergeSort(nums, arr, mid+1, end);
        int left1 = start;
        int right1 = mid;
        int left2 = mid+1;
        int right2 = end;
        
        int index = start;
        while(left1 <= right1 && left2 <= right2)
        {
            //如果left1 < left2 说明left1所在的位置的数值,均大于left2前面的数值
            //[1,3,6,9] [2, 5, 8]
            //对于3 5来说 3 < 5 但是3 大于 5之前的所有数
            //这里要记住是 *****<=****一定要注意,如果是小于的话,就不会被计入次数   
            if(nums[left1] <= nums[left2])
            {
                arr[index] = nums[left1++];
                cnt += (left2 - (mid +1));
            }
            else
                arr[index] = nums[left2++];
            index++;
        }
        //如果left1没有结束,则每一个都存在逆序对
        while(left1 <= right1)
        {
            cnt += (left2 - (mid +1));
            arr[index++]  = nums[left1++];
        }
        while(left2 <= right2)
        {
            arr[index++] = nums[left2++];
        }
        for(int i = start; i <= end; ++i)
        {
            nums[i] = arr[i];
        }
        return cnt;
    }
    int reversePairs(vector<int>& nums) {
        //使用归并排序的思想寻找逆序对
        int cnt = 0;
        vector<int> arr(nums.size());
        cnt = mergeSort(nums, arr, 0, nums.size()-1);
        return cnt;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值