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 arr1i = arr2j.
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 <= arr1i, arr2i <= 10^9
From: LeetCode
Link: 1187. Make Array Strictly Increasing
Solution:
Ideas:
dpj means after processing current prefix, using j replacements, the minimum possible last value. Smaller last value is better.
Code:
c
#include <stdlib.h>
#include <limits.h>
#define INF 0x3f3f3f3f
#define LLINF 4000000000000000000LL
int cmpInt(const void* a, const void* b) {
int x = *(int*)a, y = *(int*)b;
return (x > y) - (x < y);
}
int upperBound(int* arr, int size, long long target) {
int l = 0, r = size;
while (l < r) {
int m = l + (r - l) / 2;
if ((long long)arr[m] <= target) l = m + 1;
else r = m;
}
return l;
}
int makeArrayIncreasing(int* arr1, int arr1Size, int* arr2, int arr2Size) {
qsort(arr2, arr2Size, sizeof(int), cmpInt);
int m = 0;
for (int i = 0; i < arr2Size; i++) {
if (i == 0 || arr2[i] != arr2[i - 1]) {
arr2[m++] = arr2[i];
}
}
long long* dp = (long long*)malloc((arr1Size + 1) * sizeof(long long));
long long* ndp = (long long*)malloc((arr1Size + 1) * sizeof(long long));
for (int i = 0; i <= arr1Size; i++) dp[i] = LLINF;
dp[0] = -1;
for (int i = 0; i < arr1Size; i++) {
for (int j = 0; j <= arr1Size; j++) ndp[j] = LLINF;
for (int j = 0; j <= i; j++) {
if (dp[j] == LLINF) continue;
if ((long long)arr1[i] > dp[j]) {
if (arr1[i] < ndp[j]) ndp[j] = arr1[i];
}
int idx = upperBound(arr2, m, dp[j]);
if (idx < m) {
if ((long long)arr2[idx] < ndp[j + 1]) {
ndp[j + 1] = arr2[idx];
}
}
}
long long* temp = dp;
dp = ndp;
ndp = temp;
}
for (int i = 0; i <= arr1Size; i++) {
if (dp[i] != LLINF) {
free(dp);
free(ndp);
return i;
}
}
free(dp);
free(ndp);
return -1;
}