剑指offer—数组中的逆序对

剑指offer—数组中的逆序对

题目描述

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

示例 1:

输入: [7,5,6,4]
输出: 5
思路

取第一个数和它后面的数进行比较,若比后面的数大,则 count++,依次取第二个数…但是这样时间复杂度就是 O ( N 2 ) O(N^2) O(N2) ( n − 1 ) + ( n − 2 ) + . . . + 1 = n ( n − 1 ) / 2 = O ( N 2 ) (n-1) + (n-2) + ... + 1=n(n-1)/2=O(N^2) (n1)+(n2)+...+1=n(n1)/2=O(N2)
因为需要每一次都要比较两个数,在排序算法中也需要两两比较,只不过排序算法在比较后调动了数的位置,那么这两者有什么联系吗?
下图是归并排序的过程:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
所以可以修改归并排序就能够求出数组中的逆序对的总数

代码
class Solution {
public:
	//计数变量
    int count = 0;
    void merge(vector<int>& nums, int left, int mid, int right){
        vector<int> temp;
        int i = left, j = mid+1;
        while(i <= mid && j <= right)
        {
            if(nums[i] <= nums[j]){
                temp.push_back(nums[i]);
                i++;
            }else{
                temp.push_back(nums[j]);
                j++;
                //在归并代码上增加的计数
                count += mid-i+1;
            }
        }
         while(i <= mid)
        {
            temp.push_back(nums[i]);
            i++;
        }
        while(j <= right)
        {
            temp.push_back(nums[j]);
            j++;
        }
        for(int k = 0; k < temp.size(); k++){
            nums[left + k] = temp[k];
        }
    }
    void mergeSort(vector<int>& nums, int left, int right){
        //存在两个数才进行归并
        if(left < right){
            int mid = (left + right) >> 1;
            mergeSort(nums, left, mid);
            mergeSort(nums, mid+1, right);

            merge(nums, left, mid, right);
        }
    }
    int reversePairs(vector<int>& nums) {

        mergeSort(nums, 0, nums.size()-1);

        return count;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值