https://leetcode-cn.com/problems/minimum-operations-to-make-a-subsequence/
思路:如果序列
a
、
b
a、b
a、b的最长公共子序列的长度为
l
e
n
len
len,且序列
a
a
a的长度为
n
n
n,那么最少需要的次数就等于
n
−
l
e
n
n-len
n−len。但是我们所熟知的最长公共子序列解法的时间复杂度是
O
(
n
∗
m
)
O(n*m)
O(n∗m)的,显然本题的数据范围不允许这样做。注意到题目中的一个重要条件:
a
a
a中的元素互不相同。那么我们可以通过函数:
f
(
a
i
)
=
i
f(a_i)=i
f(ai)=i对序列
b
b
b做转换得到序列
c
c
c(如果某个元素没有在
a
a
a中出现,可以直接忽略掉它),那么问题就转换为求序列
[
0
,
1
,
2
,
…
n
−
1
]
[0,1,2,…n-1]
[0,1,2,…n−1]和序列
c
c
c的最长公共子序列,因为前者是单调递增的,且序列
c
c
c是前者的子集(不考虑重复元素),因此二者的最长公共子序列LCS就等于序列
c
c
c的最长上升子序列LIS。
class Solution {
public:
int minOperations(vector<int>& target, vector<int>& arr) {
unordered_map<int,int> h;
int n=target.size(),m=arr.size();
for(int i=0;i<n;i++)
h[target[i]]=i;
vector<int> vec;
for(int i=0;i<m;i++)
{
if(h.count(arr[i]))
{
int val=h[arr[i]];
if(vec.empty()||val>vec.back())
vec.push_back(val);
else
*lower_bound(vec.begin(),vec.end(),val)=val;
}
}
return n-vec.size();
}
};