Leetcode问题转换-置换

置换是一个排列到另一个排列的双射。例如

\[\left(\begin{array}{cccccc} x & 2 & 0 & 1 & 3 \\ P(x) & 1 & 2 & 3 & 4 \end{array}\right) \]

将这个置换应用于另一个数组\([0,1,2,3]\)上,其就变成了\([2, 3, 1, 4]\).
置换保证了对于\(num_1\)\(num_2\)中的相同元素,在置换后仍然是相同的,且元素的位置仍然是不变的,因此也不会影响答案。
好处是,通常我们可以将一个数组固定成有序的,对另一个进行统计即可。
这种题目的特征是:两个数组,且至少其中一个数组元素是互异的.

LC 1713. 得到子序列的最少操作次数

题解:本来是求两个数组的最长公共子序列,但是其中一个是互异的,因此将其置换到\(1...n\),因此题目转化为求另一个数组(经过相同置换后)的最长上升子序列。

const int INF = 0x3f3f3f3f;
class Solution {
public:
    int minOperations(vector<int>& target, vector<int>& arr) {
        unordered_map<int, int>mp;
        int cnt = 0;
        for(int num : target) mp[num] = (++cnt);
        vector<int>myarr;
        for(int& num : arr) {
            if(mp[num])  myarr.push_back(mp[num]);
        }
        int n = arr.size();
        vector<int>dp(n, INF);
        for(int num : myarr) {
            *lower_bound(dp.begin(), dp.end(), num) = num;
        }
        int lis = lower_bound(dp.begin(), dp.end(), INF)-dp.begin();
        return target.size() - lis;
    }
};

LC 2179. 统计数组中好三元组数目

题解:也是将其中一个置换到\(1...n\),对另一个使用相同的置换,然后用数组统计\(y\)左边有多少个小于其的\(x\)

const int maxn = 1e5+5;
class Solution {
public:
    int n;
    int c[maxn];  // [1...n]
    int lowbit(int x) {
        return x & (-x);
    }
    void add(int x, int val) {
        while(x <= n) {
            c[x] += val;
            x += lowbit(x);
        }
    }
    int sum(int x) {  // [1..x]的和
        int res = 0;
        while(x > 0) {
            res += c[x];
            x -= lowbit(x);
        }
        return res;
    }

    long long goodTriplets(vector<int>& nums1, vector<int>& nums2) {
        n = nums1.size();
        int convert[n+1], id = 0;
        for(int num : nums1)  convert[num] = (++id);
        for(int& num : nums2)  num = convert[num];
        long long ans = 0;
        for(int i = 0;i < n;i++) {
            add(nums2[i], 1);
            int less = sum(nums2[i]-1);
            ans += 1ll*less * (n-nums2[i]-(i-less));
        }
        return ans;
    }
};
posted @ 2022-02-26 14:51  Rogn  阅读(62)  评论(0编辑  收藏  举报