LCR 170 | 交易逆序对的总数

题目

在股票交易中,如果前一天的股价高于后一天的股价,则可以认为存在一个「交易逆序对」。请设计一个程序,输入一段时间内的股票交易记录 record,返回其中存在的「交易逆序对」总数。

示例 1:

输入:record = [9, 7, 5, 4, 6]
输出:8
解释:交易中的逆序对为 (9, 7), (9, 5), (9, 4), (9, 6), (7, 5), (7, 4), (7, 6), (5, 4)。

✨统计逆序对,可以理解为:对于数字x,记录它右方比x小的数字个数。将数组record中每个数字都求解一遍再相加,即使整个数组的逆序对个数。

✨我们用桶来记录数组record中,每个数字出现的次数。示例1得到的数组为:

index -> 1 2 3 4 5 6 7 8 9
value -> 0 0 0 1 1 1 1 0 1

可以看出,数组的前 i - 1 位的前缀和表示 比i小的数字个数。那么我们从后往前遍历record数组,对每个数字x,求它的前缀和c[i - 1]就是它右方比它小的数字个数。
但是,遍历时需要及时更新桶,就是将数字 x 对应 value + 1。
对于需要更新和查询前缀和的问题,可以用到树状数组

✨关于桶的大小
record的数字是-1e9 ~ 1e9,但是我们不可能开一个这么大的数组。这时需要离散化树状数组
我们先将原数组record去重排序,得到新数组a,对于每一次遍历,我们需要先得到该数组在数组a中的index,再通过新index执行更新、求和操作。

void Init(vector<int>& nums){
        a.assign(nums.begin(), nums.end());
        sort(a.begin(), a.end());
        a.erase(unique(a.begin(), a.end()), a.end());
        n = nums.size();
        m = a.size();
        c.resize(m + 1, 0);
    }

🔑完整代码:

private:
    int n, m;
    vector <int> a,c;
    void Init(vector<int>& nums){
        a.assign(nums.begin(), nums.end());
        sort(a.begin(), a.end());
        a.erase(unique(a.begin(), a.end()), a.end());
        n = nums.size();
        m = a.size();
        c.resize(m + 1, 0);
    }
    int getID(int x){
        int l = 0, r = m, mid;
        while(l <= r){
            mid = (l + r) / 2;
            if(a[mid] == x) return mid + 1;
            else if(a[mid] > x) r = mid - 1;
            else l = mid + 1;
        }
        return 0;
    }
    void upgrade(int index){
        for(int i = index; i <= m; i += i & -i){
            c[i]++;
        }
    }
    int Sum(int index){
        int res = 0;
        for(int i = index; i > 0; i -= i & -i){
            res += c[i];
        }
        return res;
    }
public:
    int reversePairs(vector<int>& record) {
        Init(record);
        int ans = 0, id;
        for(int i = n - 1; i >= 0; i--){
            id = getID(record[i]);
            upgrade(id);
            ans += Sum(id - 1);
            // cout<<"i = "<<i<<"  id = "<<id<<"  Sum(id) = "<<Sum(id)<<endl;;
        }
        return ans;
    }
};

posted @ 2026-03-19 20:53  hhhueu  阅读(1)  评论(0)    收藏  举报