I tried to solve the problem below using dynamic programming, but there is something wrong with my code and I could not figure it out. Could you help me with it? Thank you!
Problem: Given two arrays of length m and n with digits 0-9 representing two numbers. Create the maximum number of length k <= m + n from digits of the two. The relative order of the digits from the same array must be preserved. Return an array of the k digits.
Note: You should try to optimize your time and space complexity.
Example 1:
Input:
nums1 = [3, 4, 6, 5]
nums2 = [9, 1, 2, 5, 8, 3]
k = 5
Output: [9, 8, 6, 5, 3]
Example 2:
Input:
nums1 = [6, 7]
nums2 = [6, 0, 4]
k = 5
Output: [6, 7, 6, 0, 4]
Example 3:
Input:
nums1 = [3, 9]
nums2 = [8, 9]
k = 3
Output: [9, 8, 9]
My idea is as following:
dp[i][j][t] is the the maximum number of length i which is picked out of first j digits of array 1 and first t digits of array 2, where i goes from 0 to k, j goes from 0 to len(nums1), t goes from 0 to len(nums2). the state transition equation goes like this:
- when
nums1[j-1] > nums2[t-1]: if we already havek-2digits, then we have to take bothnums1[j-1]andnums2[t-1], and we must takenums1[j-1]first in order to maximize the result if we already havek-1digits, then we only have to take one more digit, and it must benums1[j-1], because it is bigger if we already havekdigits, then we do not need to take more digits, so we keep the last resultdp[i][j-1][t-1]
Given that we are looking for maximum, our current result should be the biggest among these 3 situations, so we have:
dp[i][j][t] = max(
(dp[i-2][j-1][t-1]*10+nums1[j-1])*10+nums2[t-1],
dp[i-1][j-1][t-1]*10+nums1[j-1],
dp[i][j-1][t-1]
)
- when
nums1[j-1] < nums2[t-1]: if we already havek-2digits, then we have to take bothnums1[j-1]andnums2[t-1], and this time we must takenums2[t-1]first because it is bigger if we already havek-1digits, then we only have to take one more digit, and it must benums2[t-1], because it is bigger if we already havekdigits, then we do not need to take more digits, so we keep the last resultdp[i][j-1][t-1]
Likewise, we take the biggest result from these possible ones:
dp[i][j][t] = max(
(dp[i-2][j-1][t-1]*10+nums2[t-1])*10+nums1[j-1],
dp[i-1][j-1][t-1]*10+nums2[t-1],
dp[i][j-1][t-1]
)
Here is my code:
import numpy as np
def maxNumber(nums1, nums2, k):
m = len(nums1)
n = len(nums2)
dp = [[[0 for _ in range(n + 1)] for _ in range(m + 1)] for _ in range(k + 1)]
for i in range(2, k + 1):
for j in range(i + 1):
if j > m or (i - j) > n:
continue
tmp = 0
tmp_nums1 = nums1[:j]
tmp_nums2 = nums2[:(i-j)]
while tmp_nums1 or tmp_nums2:
if tmp_nums1 > tmp_nums2:
tmp = tmp * 10 + tmp_nums1.pop(0)
else:
tmp = tmp * 10 + tmp_nums2.pop(0)
dp[i][j][i - j] = tmp
for i in range(m + 1):
for j in range(n + 1):
if not i and not j:
continue
dp[1][i][j] = max(nums1[:i] + nums2[:j])
for i in range(2, k+1):
for j in range(m+1):
for t in range(i+1-j, n + 1):
if nums1[j - 1] > nums2[t - 1]:
dp[i][j][t] = max((dp[i-2][j-1][t-1]*10+nums1[j-1])*10+nums2[t-1], dp[i][j-1][t-1], dp[i-1][j-1][t-1]*10+nums1[j-1])
else:
dp[i][j][t] = max((dp[i-2][j-1][t-1]*10+nums2[t-1])*10+nums1[j-1], dp[i][j-1][t-1], dp[i-1][j-1][t-1]*10+nums2[t-1])
# print(np.array(dp))
res = []
tmp_res = dp[-1][-1][-1]
while tmp_res:
res.append(tmp_res % 10)
tmp_res //= 10
return res[::-1]
But it outputs [8, 9, 9] on Example 3, and I cannot figure out the reason. Could you help me with it?
Thank you in advance!