LeetCode C++ 劍指 Offer 51. 陣列中的逆序對【歸併排序/樹狀陣列/線段樹】

memcpy0發表於2020-12-26

在陣列中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個陣列,求出這個陣列中的逆序對的總數。

示例 1:

輸入: [7,5,6,4]
輸出: 5

限制: 0 <= 陣列長度 <= 50000


解法1 歸併排序

先這麼寫,日後有時間就多更新幾種解法:

class Solution {
private:
    int ans = 0;
    vector<int> tmp;
    void mergeSort(vector<int>& nums, int l, int r) {
        if (l >= r) return;
        int m = l + (r - l) / 2;
        mergeSort(nums, l, m);
        mergeSort(nums, m + 1, r);
        int i = l, j = m + 1, k = l;
        while (i <= m && j <= r) {
            if (nums[i] <= nums[j]) tmp[k++] = nums[i++];
            else {
                tmp[k++] = nums[j++];
                ans += j - k;
            }
        }
        while (i <= m) tmp[k++] = nums[i++];
        while (j <= r) tmp[k++] = nums[j++];
        for (int x = l; x <= r; ++x) nums[x] = tmp[x];
    }
public:
    int reversePairs(vector<int>& nums) {
        if (nums.empty()) return 0;
        tmp.resize(nums.size());
        mergeSort(nums, 0, nums.size() - 1);
        return ans;
    }
};

執行效率如下:

執行用時:256 ms, 在所有 C++ 提交中擊敗了92.20% 的使用者
記憶體消耗:43.9 MB, 在所有 C++ 提交中擊敗了47.48% 的使用者

類似的題目還有:LeetCode 315,327,493。

相關文章