1713. Minimum Operations to Make a Subsequence

题目:

You are given an array target that consists of distinct integers and another integer array arr that can have duplicates.

In one operation, you can insert any integer at any position in arr. For example, if arr = [1,4,1,2], you can add 3 in the middle and make it [1,4,3,1,2]. Note that you can insert the integer at the very beginning or end of the array.

Return the minimum number of operations needed to make target a subsequence of arr.

subsequence of an array is a new array generated from the original array by deleting some elements (possibly none) without changing the remaining elements' relative order. For example, [2,7,4] is a subsequence of [4,2,3,7,2,1,4] (the underlined elements), while [2,4,2] is not.

Example 1:

Input: target = [5,1,3], arr = [9,4,2,3,4]Output: 2
Explanation: You can add 5 and 1 in such a way that makes arr  = [5,9,4,1,2,3,4], then target will be a subsequence of arr.

Example 2:

Input: target = [6,4,8,1,3,2], arr = [4,7,6,2,3,8,6,1]Output: 3

Constraints:

  • 1 <= target.length, arr.length <= 10^5
  • 1 <= target[i], arr[i] <= 10^9
  • target contains no duplicates.

思路:

这题乍一看是LCS的题目,因为只要我们找出两个array中的最长公共子序列,比较它和target数组的size的差就是答案,但是数量级是10的5次,如果是LCS,即使使用DP,时间复杂度最快也要O(n^{2}),因此需要换一种思路。这里我们找的是LIS,及最长增长子序列。因为target中都是unique的数字,那么我们就可以按照增序来排列它们,以example2为例子, target = [6, 4, 8, 1, 3, 2],那么转换一下就是[0, 1, 2, 3, 4, 5],而arr是[4, 7, 6, 2, 3, 8, 6, 1],按照我们之前转换的,6是0,4是1这样,arr是[1, 0, 5, 4, 2, 0, 3],在这个过程中我们忽略不在target中的数字,它们并不影响结果。那么总体思路就是先用一个哈希表来存放target里的数字和它对应的转换后的大小,其实也就是它的index,我们这里用index来表示大小。然后建立数组res,用来记录最长增长子序列。遍历arr中的数字,如果它在target中,那么就按照LIS问题处理,用二分法,这里直接用lower_bound找到当前数字应该放的位置,如果位置在数组end,说明res为空,或者当前数字比res.back()都要大,那么直接塞入res即可;否则用当前数字替代对应位置的数字。最后我们比较target和res的长度,返回他们的差值。

代码:

class Solution {
public:
    int minOperations(vector<int>& target, vector<int>& arr) {
        unordered_map<int,int> m;
        for(int i=0;i<target.size();i++)
            m[target[i]]=i;
        vector<int> res;
        for(auto i:arr)
        {
            if(m.count(i))
            {
                auto itr=lower_bound(res.begin(),res.end(),m[i]);
                if(itr==res.end())
                    res.push_back(m[i]);
                else
                    *itr=m[i];
            }
        }
        return target.size()-res.size();
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_49991368/article/details/112168478