Given two integer arrays arr1
and arr2
, your task is to determine the minimum number of operations needed to make arr1
strictly increasing. In a single operation, you can replace an element in arr1
with an element from arr2
. If it's impossible to make arr1
strictly increasing, return -1. Assume that 0 <= i < arr1.length
and 0 <= j < arr2.length
and do the assignment arr1[i] = arr2[j]
.
Here's a breakdown:
arr2
and use it to replace any element in arr1
.arr1
strictly increasing.Example 1:
arr1 = [1, 5, 3, 6, 7]
arr2 = [1, 3, 2, 4]
Output: 1
Explanation: Replace 5
with 2
, resulting in arr1 = [1, 2, 3, 6, 7]
. Only one operation was needed.
Example 2:
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]
. Two operations were needed.
Example 3:
arr1 = [1, 5, 3, 6, 7]
arr2 = [1, 6, 3, 3]
Output: -1
Explanation: It's impossible to make arr1
strictly increasing with the given arrays and operations.
Write a function that takes arr1
and arr2
as input and returns the minimum number of operations needed to make arr1
strictly increasing, or -1 if it is not possible.
A brute-force approach would involve trying all possible combinations of replacements from arr2
into arr1
to see if we can make arr1
strictly increasing. This involves recursion and backtracking. For each element in arr1
, we can either keep it as is (if it's greater than the previous element) or try replacing it with elements from arr2
. We would need to check all possible replacements and keep track of the minimum number of operations.
This approach is highly inefficient due to the exponential number of possible combinations. It would quickly exceed the time limit for larger input sizes.
arr1
and 'm' is the length of arr2
. In the worst case, for each element in arr1
, we might try replacing it with every element in arr2
.A more efficient approach uses dynamic programming and binary search. We can define a DP state dp[i][j]
as the minimum number of operations to make arr1[0...i]
strictly increasing, with the last element being j
. Here, j
can be either arr1[i]
(if we don't replace it) or an element from arr2
that we use to replace arr1[i]
.
arr1
.arr1
, we have two choices:
arr2
that is greater than the previous element.arr2
that is greater than the previous element, we can use binary search after sorting arr2
and removing duplicate elements.arr1
or arr2
are empty.arr2
: Sort and deduplicate arr2
before using binary search.import bisect
def makeArrayIncreasing(arr1, arr2):
arr2 = sorted(list(set(arr2)))
n = len(arr1)
dp = {}
def solve(i, prev):
if i == n:
return 0
if (i, prev) in dp:
return dp[(i, prev)]
ans = float('inf')
# Option 1: Keep arr1[i] if possible
if arr1[i] > prev:
ans = min(ans, solve(i + 1, arr1[i]))
# Option 2: Replace arr1[i] with an element from arr2
idx = bisect.bisect_right(arr2, prev)
if idx < len(arr2):
ans = min(ans, 1 + solve(i + 1, arr2[idx]))
dp[(i, prev)] = ans
return ans
result = solve(0, -1)
return result if result != float('inf') else -1
arr1
and 'm' is the length of arr2
. The n
comes from iterating through arr1
. The m log m
comes from the initial sorting of arr2
and the usage of bisect
method (Binary Search on sorted arr2
).solve
function with memoization.