题目:
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
.
A 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 makesarr
= [5,9,4,1,2,3,4], then target will be a subsequence ofarr
.
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();
}
};