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.
두 개의 정수 배열 arr1과 arr2가 주어질 때, arr1이 엄격한 오름차순 정렬이 되기 위해 필요한 최소 연산 수를 return 하라.
한 연산 당 arr1[i] = arr2[j] (0 <= i < arr1.length, 0 <= j < arr2.length)
class Solution:
def makeArrayIncreasing(self, arr1: List[int], arr2: List[int]) -> int:
dp = {}
arr2.sort()
def dfs(prev, i):
# i가 range를 벗어날 경우 0을 return
if i >= len(arr1):
return 0
# dp 배열 안에 dfs(prev, i) 값이 이미 존재하면 return (메모이제이션)
if (prev, i) in dp:
return dp[(prev, i)]
cost = float('inf')
# 이미 arr1[i]가 prev보다 크면, arr[i + 1:]의 최소 횟수를 구해 cost에 넣는다
# 아닐 경우 cost는 inf로 유지
# 현재 값이 prev보다 작은 경우에는 값을 안 바꾸면 답이 없다는 뜻이다
if arr1[i] > prev:
cost = dfs(arr1[i], i + 1)
# 현재 index의 값을 교체할 경우 값 구하기 (이진탐색)
idx = bisect.bisect_right(arr2, prev)
# arr2에 존재?
if idx < len(arr2):
# 존재할 경우, 현재 값 바꾸지 않을 경우 (cost)와 바꿀 경우 (1 + dfs(arr2[idx], i + 1)) 중,
# 더 작은 값을 cost에 할당한다
cost = min(cost, 1 + dfs(arr2[idx], i + 1))
dp[(prev, i)] = cost
return cost
dfs(-1, 0)
return dp[(-1, 0)] if dp[(-1, 0)] < float('inf') else -1
dfs(i, prev): arr[i - 1] = prev일 때 arr[i:]를 정렬된 배열로 만들 수 있는 최소 연산 수를 계산
class Solution:
def makeArrayIncreasing(self, arr1: List[int], arr2: List[int]) -> int:
dp = {-1: 0}
arr2.sort()
n = len(arr2)
# 매 반복마다, arr1[:i+1]까지의 최소 연산 수를 계산
for i in range(len(arr1)):
new_dp = collections.defaultdict(lambda: float('inf'))
# dp 딕셔너리에 저장된 이전 인덱스까지의 경우의 수를 사용
for prev in dp:
# arr1[i]가 prev보다 크면(이미 증가), new_dp[arr[i]]를 new_dp[arr1[i]]와 dp[prev] 둘 중 작은 것으로 할당한다(전 단계까지 중 가장 최솟값을 선택한다)
if arr1[i] > prev:
new_dp[arr1[i]] = min(new_dp[arr1[i]], dp[prev])
# 이진 탐색을 사용해 arr2에서 arr1의 현재 인덱스에 할당할 값의 위치 찾기
idx = bisect.bisect_right(arr2, prev)
# arr2에 존재하면?
if idx < n:
# 바꿨을 경우에 대한 값 할당
new_dp[arr2[idx]] = min(new_dp[arr2[idx]], 1 + dp[prev])
dp = new_dp
return min(dp.values()) if dp else -1
arr1, arr2의 길이를 각각 m, n이라고 할 때, 시간복잡도: O(m ⋅ n ⋅ logn)
공간복잡도: O(m ⋅ n) --> dp의 최대 크기
arr1, arr2의 길이를 각각 m, n이라고 할 때, 시간복잡도: O(m ⋅ n ⋅ logn)
공간복잡도: O(n)