1187. Make Array Strictly Increasing
Given two integer arrays arr1
and arr2
, return the minimum number of operations (possibly zero) needed to make arr1
strictly increasing.
In one operation, you can choose two indices 0 <= i < arr1.length
and 0 <= j < arr2.length
and do the assignment arr1[i] = arr2[j]
.
If there is no way to make arr1
strictly increasing, return -1
.
Example 1:
Input: arr1 = [1,5,3,6,7], arr2 = [1,3,2,4]
Output: 1
Explanation: Replace 5 with 2, then arr1 = [1, 2, 3, 6, 7].
Example 2:
Input: arr1 = [1,5,3,6,7], arr2 = [4,3,1]
Output: 2
Explanation: Replace 5 with 3 and then replace 3 with 4. arr1 = [1, 3, 4, 6, 7].
Example 3:
Input: arr1 = [1,5,3,6,7], arr2 = [1,6,3,3]
Output: -1
Explanation: You can't make arr1 strictly increasing.
Constraints:
1 <= arr1.length, arr2.length <= 2000
0 <= arr1[i], arr2[i] <= 10^9
题目:给你两个整数数组 arr1
和 arr2
,返回使 arr1
严格递增所需要的最小「操作」数(可能为 0)。每一步「操作」中,你可以分别从 arr1
和 arr2
中各选出一个索引,分别为 i
和 j
, 0 <= i < arr1.length
和 0 <= j < arr2.length
,然后进行赋值运算 arr1[i] = arr2[j]
。如果无法让 arr1
严格递增,请返回 -1
。
思路:动态规划,参考link。和最长递增子序列类似。对于 arr1
中的每个元素,均有一个状态集合 mp
,如对于第 i
个元素,其状态集合为(
s
t
a
t
e
k
state_k
statek,
c
n
t
k
cnt_k
cntk),表示为了使 arr1[0...i]
严格递增,所需的操作数为
c
n
t
k
cnt_k
cntk, 此时对应的 arr[i]
的值填充为
s
t
a
t
e
k
state_k
statek。那么对于第 i+1
个元素(记其状态集合为 m
),如果 arr1[i+1]
比
s
t
a
t
e
k
state_k
statek大,那么操作数不变,由
c
n
t
k
cnt_k
cntk决定;或者从 arr2
中查找比
s
t
a
t
e
k
state_k
statek大的数,进行替换,此时操作数加1。
如例子2: arr1 = [1, 5, 3, 6, 7]
, arr2 = [4, 3, 1]
:
对于 arr1
:
初始状态: mp
: (-1, 0)
i=0
时, arr1[i]=1
, mp
: (1, 0), (1, 1), (3, 1), (4, 1)
=> (1, 0), (3, 1), (4, 1)
i=1
时, arr1[i]=5
, mp
: (5, 0), (3, 1), (4, 1); (5, 1), (4, 2); (5, 1)
=> (5, 0), (3, 1), (4, 1)
i=2
时, arr1[i]=3
, mp
: (4, 2)
i=3
时, arr1[i]=6
, mp
: (6, 2)
i=4
时, arr1[i]=7
, mp
: (7, 2)
class Solution {
public:
int makeArrayIncreasing(vector<int>& arr1, vector<int>& arr2) {
sort(arr2.begin(), arr2.end());
unordered_map<int, int> mp;
mp[-1] = 0;
for(auto num : arr1){
unordered_map<int, int> m;
for(auto state : mp){
// state:(val, cnt)
int prev_val = state.first, prev_cnt = state.second;
// arr1中的值比状态state的数大,满足条件
if(num > prev_val){
int cnt = m.count(num) == 0 ? INT_MAX : m[num];
m[num] = min(prev_cnt, cnt);
}
// 在arr2中的值找满足比当前state大的那个数,此时的操作数相对于状态state加1
auto iter_idx = upper_bound(arr2.begin(), arr2.end(), prev_val);
if(iter_idx != arr2.end()){
int num2 = *iter_idx;
int cnt = m.count(num2) == 0 ? INT_MAX : m[num2];
m[num2] = min(prev_cnt + 1, cnt);
}
}
mp = m;
}
if(mp.empty())
return -1;
int res = INT_MAX;
for(auto item : mp)
res = min(res, item.second);
return res;
}
};