1. 题目来源
前导题:
2. 题目解析
很重要的一个知识点。当数组元素不重复的时候,LCS
问题可以转化成 LIS
问题。LIS
采用贪心可以将时间复杂度从
O
(
n
2
)
O(n^2)
O(n2) 搞到
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn),具备处理 10^5
数据范围的能力。
不过 LIS
的贪心写法涉及到二分,边界蛮多的。建议直接背下板子即可!
- 时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)。
- 空间复杂度: O ( n ) O(n) O(n)
代码:
class Solution {
public:
int minOperations(vector<int>& target, vector<int>& arr) {
unordered_map<int, int> ha;
int n = target.size(), m = arr.size();
for (int i = 0; i < n; i ++ ) ha[target[i]] = i;
vector<int> c;
for (int i = 0; i < m; i ++ )
if (ha.count(arr[i]))
c.push_back(ha[arr[i]]); // c数组存arr中在target中出现过的数的下标
int len = 0; // 最长上升子序列的长度标记
vector<int> f(c.size() + 1); // 经典的 LIS 贪心求解
for (int i = 0; i < c.size(); i ++ ) {
int l = 0, r = len;
while (l < r) {
int mid = l + r + 1 >> 1;
if (f[mid] >= c[i]) r = mid - 1; // 找到比c[i]小的最大的一个
else l = mid;
}
len = max(len, r + 1); // 令f[r+1] 继承 x,更新最大值
f[r + 1] = c[i];
}
return target.size() - len;
}
};