已知一序列无重复元素,对LCS通过LIS进行优化

Posted C_YCBX Py_YYDS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了已知一序列无重复元素,对LCS通过LIS进行优化相关的知识,希望对你有一定的参考价值。

题目

题目解析

看完题目,我们可以发现,只需要寻找到两个数组直接的最长公共子序列(LCS),便可知最少操作次数。

  • 所以毫不犹豫的写下了 O(n^2) 级别的 LCS 代码,然后毫不夸张的栈溢出了(毕竟是困难题总得想办法优化
class Solution {
public:
    int minOperations(vector<int> &target, vector<int> &arr) {
        int m = target.size(),n = arr.size();
        int dp [m+1][n+1];
        memset(dp,0,sizeof dp);
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                if(target[i-1]==arr[j-1]){
                    dp[i][j] = dp[i-1][j-1]+1;
                }else{
                    dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
                }
            }
        }
        return m-dp[m][n];
    }
};

那么我们到底该如何优化呢?
注意到:target不含重复元素,这就给了我们很大的信息量,通过这个我们可以构造正确的哈希映射,将 target 的值和下标进行映射,然后通过 arr 更新 index 数组,计算 LIS 即可得出正确的 LCS

下面的图片描述了原理,但注意的是我这里写反了,应该以 ·target· 作映射。

  • 自此我们得出做题思路:
  1. 映射数组(被映射的不能含重复元素)
  2. 得出下标数组
  3. 计算LIS

具体代码实现

class Solution {
public:
    int minOperations(vector<int> &target, vector<int> &arr) {
        //只能记录target中所有,数组的下标,因为target中无相同元素
            unordered_map<int,int>check;
            for(int i=0;i<target.size();i++)check[target[i]] = i;
//构造下标数组记录与target的交集元素在target数组中的对应下标,就算arr数组中有相同的元素也不用怕了,多记录一次相同下标即可。
            int index[arr.size()];
            int sz = 0;
            for(auto&& t:arr){
                if(check.count(t)){
                    index[sz++] = check[t];
                }
            }
            if(sz==0)return target.size();
        //开始进行通过LIS求取LCS
        //dp[i]表示长度为i+1的最长递增子序列的最小数值
        int dp[sz];memset(dp,0,sizeof dp);
        dp[0] = index[0];
        int len = 1;
//注意找到相同大小的得覆盖,因为另一个序列不含重复,所以用寻找左边界方式二分为宜
        for(int i=1;i<sz;i++){
            int l = 0,r=len;
            int target = index[i];
            while(l<r){
                int mid = (l+r)/2;
                if(dp[mid]>=target){
                    r = mid;
                }else{
                    l = mid+1;
                }
            }
            dp[l] = target;
            //别无脑len++,注意判断是否变长
            if(l==len)len++;
        }
        return target.size()-len;
    }
};

以上是关于已知一序列无重复元素,对LCS通过LIS进行优化的主要内容,如果未能解决你的问题,请参考以下文章

[luoguP1439] 排列LCS问题(DP + 树状数组)

求全排列(数组有重复元素和数组无重复元素) 回溯 递归

数据结构---无重复元素链表的实现

无重复元素的组合算法/n个列表中取n个不同的数

无重复元素的组合算法/n个列表中取n个不同的数

[洛谷P1439]排列LCS问题