We use DP to track the minimum operations needed to make the array strictly increasing up to each index, considering both keeping the current value and replacing it with a value from arr2. Binary search helps efficiently find the next possible replacement.
classSolution {
publicintmakeArrayIncreasing(int[] arr1, int[] arr2) {
TreeSet<Integer> set =new TreeSet<>();
for (int x : arr2) set.add(x);
int[] b = set.stream().mapToInt(i->i).toArray();
Map<Integer, Integer> dp =new HashMap<>();
dp.put(-1, 0);
for (int a : arr1) {
Map<Integer, Integer> ndp =new HashMap<>();
for (int prev : dp.keySet()) {
int ops = dp.get(prev);
if (a > prev) ndp.put(a, Math.min(ndp.getOrDefault(a, Integer.MAX_VALUE), ops));
int idx = Arrays.binarySearch(b, prev+1);
if (idx < 0) idx =-idx-1;
if (idx < b.length) ndp.put(b[idx], Math.min(ndp.getOrDefault(b[idx], Integer.MAX_VALUE), ops+1));
}
dp = ndp;
}
if (dp.isEmpty()) return-1;
int ans = Integer.MAX_VALUE;
for (int v : dp.values()) ans = Math.min(ans, v);
return ans;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
classSolution {
funmakeArrayIncreasing(arr1: IntArray, arr2: IntArray): Int {
val set = arr2.toSet()
val b = set.sorted()
var dp = mutableMapOf(-1 to 0)
for (a in arr1) {
val ndp = mutableMapOf<Int, Int>()
for ((prev, ops) in dp) {
if (a > prev) ndp[a] = minOf(ndp.getOrDefault(a, Int.MAX_VALUE), ops)
val idx = b.binarySearch(prev+1).let { if (it < 0) -it-1elseit }
if (idx < b.size) ndp[b[idx]] = minOf(ndp.getOrDefault(b[idx], Int.MAX_VALUE), ops+1)
}
dp = ndp
}
if (dp.isEmpty()) return -1return dp.values.minOrNull() ?: -1 }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
classSolution:
defmakeArrayIncreasing(self, arr1: list[int], arr2: list[int]) -> int:
b = sorted(set(arr2))
dp = {-1: 0}
for a in arr1:
ndp = {}
for prev, ops in dp.items():
if a > prev:
ndp[a] = min(ndp.get(a, float('inf')), ops)
import bisect
idx = bisect.bisect_right(b, prev)
if idx < len(b):
ndp[b[idx]] = min(ndp.get(b[idx], float('inf')), ops+1)
dp = ndp
ifnot dp:
return-1return min(dp.values())