Statement▼
You are given two integer arrays, nums1
and nums2
, of lengths m
and n
, respectively. Each array represents the digits of a number.
You are also given an integer k
. Create the largest possible number of length k
(where k
m
n
) using digits from both arrays. You may interleave digits from the two arrays, but the relative order of digits within the same array must be preserved.
Return an array of k
digits representing the maximum number.
Constraints:
m
= nums1.length
n
= nums2.length
1≤ m
,n
≤500 0≤ nums1[i]
,nums2[i]
≤9 1≤ k
≤ m
+ n
nums1
andnums2
do not have leading zeros.
Solution
This problem asks us to build the lexicographically largest number of length k
by trying every possible way to divide k
digits between the two arrays and keeping the best result. Concretely, if we take i
digits from nums1
, we must take k − i
from nums2
. The valid values of i
are max(0, k − n) ≤ i ≤ min(k, m)
, so both arrays can supply the needed digits without breaking their lengths, all while preserving each array’s internal order.
This structure suggests three complementary steps:
Explore all valid splits: For each valid
i
, consider the split (i
digits fromnums1
,k − i
digits fromnums2
). We don’t guess the best division ahead of time, because in some cases the optimal answer leans heavily on one array, while in others it requires careful interleaving of both.Pick the strongest subarray from each input: Once we fix how many digits to take from an array, we select the largest possible subarray of that length while preserving order. Intuitively, we prefer bigger digits and are willing to drop smaller ones that block us from keeping larger ones later, as long as we still have enough digits remaining to reach the required length.
Merge the two chosen subarrays: With the “best” subarray from each array in hand, we merge them into one result array of length
k
. If the leading digits are equal at each step, we look ahead at the remaining parts of both arrays and choose from the one whose remainder is lexicographically larger. This ensures that every choice contributes to the maximum possible overall number.
After building numbers for all splits, we keep the largest and return it as the final answer.
We will implement the first and second step with a monotonic decreasing stack (greedy “drop smaller to keep bigger later”), and the last step with a two‑pointer merge that resolves ties via a suffix comparison (look ahead beyond the next digit).
A small intuition example:
If nums1 = [6, 7]
, nums2 = [6, 0, 4]
, k = 5
, both sides start with 6
. We look ahead: nums1
continues with [7]
while nums2
continues with [0, 4]
. As [7] > [0, 4]
lexicographically, we should first take from nums1
.
Now, let’s look at the solution steps below:
Step 1: Determine the valid split ranges between the arrays
The number of digits taken from nums1
must be at least max(0, k − n)
and, at most, min(k, m)
. This ensures the remaining digits can come from nums2
without exceeding k
.
For each split, we use pick_max_subarray()
to extract the strongest subarray of the required length. The key variable here is to_remove = len(digits) − subseq_length
, which tells us how many we can drop. We maintain a stack
and iterate through the array:
While
to_remove > 0
and the last element in the stack is smaller than the current digit, pop from the stack.Append the current digit to the stack.
At the end, the first subseq_length
elements of the stack form the lexicographically largest subarray of that length. When merging, the next step is to decide which array’s remaining digits to take from when the choice isn’t obvious.
Step 2: Compare suffixes to decide between two sequences
We use is_greater_suffix(seq1, i, seq2, j)
to decide which array should contribute the next digit during merging.
Starting at indexes
i
andj
, we advance in both arrays as long asseq1[i] == seq2[j]
.If
seq2
runs out of digits first, we return TRUE becauseseq1
has the longer or lexicographically greater remainder.Otherwise, we compare the first differing digit: if
seq1[i] > seq2[j]
, return TRUE; if not, return FALSE.
This guarantees that tie-breaking always favors the lexicographically larger remainder. With this tie-breaking rule, we can merge the two chosen subarrays.
Step 3: Merge the two subsequences into the lexicographically largest sequence
We initialize two pointers, p1
for the first subarray and p2
for the second, starting at position 0
.
At each step, we call
is_greater_suffix(seq1, p1, seq2, p2)
to decide which subarray will yield the larger final number.We append that digit to the
merged
array and advance the pointer (p1
orp2
) of the array we chose from.
We repeat this process until both subarrays are exhausted, producing a merged
array of length k
. This gives us the result for one particular split of digits between the two inputs. The final step is to evaluate all possible splits and keep the overall largest number.
Step 4: Try all valid splits and keep the best result
For each valid digits_from_nums1
taken from nums1
, we build:
subsequence1 = pick_max_subarray(nums1, digits_from_nums1)
and,subsequence2 = pick_max_subarray(nums2, k − digits_from_nums1)
We then merge subsequence1
and subsequence2
into a single result array, candidate_sequence
, of length k
. If candidate_sequence
is lexicographically larger than the current best_sequence
, we update best_sequence
.
After evaluating all possible splits, we return the best_sequence
array as the largest number of length k
that can be formed.
Now let’s look at the following illustration to get a better understanding of the solution: