JZ51 数组中的逆序对 C++ 详细注释

https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5
思路1:从最后一个数字开始,依次与前面所有的数进行比较
空间复杂度 O(1),时间复杂度 O(n2)

class Solution {
public:
    int InversePairs(vector<int> data) {
        int ans = 0;
        for (int i = data.size()-1; i >=0 ; --i) {
            for (int j = i-1; j >= 0; --j) {
                if (data[i] < data[j]){
                    ans++;
                }
            }
            ans = ans % 1000000007;	// 防止溢出
        }
        return ans;
    }
};

思路2:归并排序
空间复杂度 O(n),时间复杂度 O(nlogn)

class Solution {
public:
    int ans = 0;
    vector<int> temp;

    void merge_sort(vector<int>& data, int left, int right) {
        if (left >= right)    return;          // 边界判断
        int mid = (left + right) >> 1;
        merge_sort(data, left, mid);           // 递归对左区间进行归并排序
        merge_sort(data, mid + 1, right);      // 递归对右区间进行归并排序

        // i为data的下标,k为temp的下标
        int i = left, j = mid + 1, k = left;

        while (i <= mid && j <= right) {
            // 从左右区间的第1个元素开始比较
            if (data[i] <= data[j])
                temp[k++] = data[i++];      // 将排序的结果存入temp
            else {                          // 找到左区间一个数data[i] > data[j]
                temp[k++] = data[j++];
                ans += mid - i + 1;         // 此时区间[i, mid]的数都大于data[j]
                ans %= 1000000007;
            }
        }

        while (i <= mid) temp[k++] = data[i++];         // 左区间有元素未进行比较,直接放入temp
        while (j <= right) temp[k++] = data[j++];       // 右区间有元素未进行比较,直接放入temp

        for (int ii = left; ii <= right; ii++)
            data[ii] = temp[ii];                        // 将排序结果重新写回data
    }

    int InversePairs(vector<int> data) {
        int len = data.size();
        temp.reserve(len);
        merge_sort(data, 0, len-1);            // 对data进行归并排序
        return ans;
    }
};

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值