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.

思路:

首先转化数组,其次是二分法。首先用哈希表<int, int>记录target中数字的index,key是target中的value,int是对应的index。之后把arr中,target里面出现过的数字,也转化成target中对应的index的形式。如例2中,target是[6, 4, 8, 1, 3, 2],它对应的index数组为[0, 1, 2, 3, 4, 5], 则arr对应的index数组为[1, 0, 5, 4, 2, 0, 3],这里要剔除7,因为它并没有在target中出现过。至此,此问题可以转化为arr数组对应的index数组求最长递增子序列,这里用二分法lower_bound即可,具体可以看本篇300. Longest Increasing Subsequence。得出的最大子序列的长度与target长度的差值即是要求的结果,因为我们可以在arr任意位置插入数字。

代码:

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> change;
        for(auto i : arr) {
            if(m.count(i)) {
                change.push_back(m[i]);
            }
        }
        vector<int> res;
        for(auto i : change) {
            auto itr = lower_bound(res.begin(), res.end(), i);
            if(itr == res.end()) {
                res.push_back(i);
            } else {
                *itr = i;
            }
        }
        return target.size() - res.size();
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值