1. 程式人生 > 實用技巧 >20.11.28 leetcode493翻轉對

20.11.28 leetcode493翻轉對

題目連結:https://leetcode-cn.com/problems/reverse-pairs/

題意:給你一個數組,求滿足i<j且nums[i]>2*num[j]的(i,j)對的數量

分析:本質上,就是對陣列中的每一個元素,統計位於它左側或右側,且取值位於某個區間內的值的數量,和leetcode327統計區間和個數基本一樣。我這次還是用歸併做的,然後我把樹狀陣列的程式碼也貼一下。

歸併

class Solution {
public:
    int recursive(vector<int>& nums,int left,int right){
        
if(left==right)return 0; int mid=(left+right)/2; int res1=recursive(nums,left,mid); int res2=recursive(nums,mid+1,right); int res=res1+res2; int i=left,j=mid+1; while(i<=mid){ while(j<=right&&(long long)nums[i]>2*(long long)nums[j])j++; res
+=(j-mid-1); i++; } vector<int> sorted; i=left,j=mid+1; while(i<=mid&&j<=right){ if(nums[i]<=nums[j]){ sorted.push_back(nums[i]); i++; }else{ sorted.push_back(nums[j]); j
++; } } while(i<=mid){ sorted.push_back(nums[i]); i++; } while(j<=right){ sorted.push_back(nums[j]); j++; } for(int i=0;i<sorted.size();i++){ //cout<<sorted[i]<<" "; nums[left+i]=sorted[i]; } // cout<<endl; return res; } int reversePairs(vector<int>& nums) { if(nums.size()==0)return 0; return recursive(nums,0,nums.size()-1); } };

樹狀陣列:

class BIT {
private:
    vector<int> tree;
    int n;

public:
    BIT(int _n) : n(_n), tree(_n + 1) {}

    static constexpr int lowbit(int x) {
        return x & (-x);
    }

    void update(int x, int d) {
        while (x <= n) {
            tree[x] += d;
            x += lowbit(x);
        }
    }

    int query(int x) const {
        int ans = 0;
        while (x) {
            ans += tree[x];
            x -= lowbit(x);
        }
        return ans;
    }
};

class Solution {
public:
    int reversePairs(vector<int>& nums) {
        set<long long> allNumbers;
        for (int x : nums) {
            allNumbers.insert(x);
            allNumbers.insert((long long)x * 2);
        }
        // 利用雜湊表進行離散化
        unordered_map<long long, int> values;
        int idx = 0;
        for (long long x : allNumbers) {
            values[x] = ++idx;
        }

        int ret = 0;
        BIT bit(values.size());
        for (int i = 0; i < nums.size(); i++) {
            int left = values[(long long)nums[i] * 2], right = values.size();
            ret += bit.query(right) - bit.query(left);
            bit.update(values[nums[i]], 1);
        }
        return ret;
    }
};