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. You should try to optimize your time and space complexity.
Example 1:
nums1 = [3, 4, 6, 5]
nums2 = [9, 1, 2, 5, 8, 3]
k = 5
return [9, 8, 6, 5, 3]
Example 2:
nums1 = [6, 7]
nums2 = [6, 0, 4]
k = 5
return [6, 7, 6, 0, 4]
Example 3:
nums1 = [3, 9]
nums2 = [8, 9]
k = 3
return [9, 8, 9]
思路:
从数组nums1取i个元素,从数组nums2中k-i个元素,再将两者组合,取得最大的组合整数即可。
i的范围为:Math.max(0, k - nums2.length),因为有可能所有元素都从nums2中取, 如
nums1 = [1, 2, 3]
nums2 = [9, 8, 7, 6]
k = 3
也有可能至少需要从nums1中取k-nums2.length个元素,比如Example2,至少要从nums1中取2个元素。这是因为nums2中元素较少,同时k又相对nums2元素个数多的时候。
判断两个数组大小的时候有些细节需要注意,比如
nums1 = [3, 8]
nums2 = [3]
k = 3
应该理解为nums1 > nums2,因为需要先取nums1中的3, 才能构成最大值383,否则如果先取nums2中的3,则变成338了。
程序如下所示:
class Solution {
public int[] maxNumber(int[] nums1, int[] nums2, int k) {
int[] ans = new int[k];
for (int i = Math.max(0, k - nums2.length); i <= k&&i <= nums1.length; ++ i){
int[] ret = mergeArray(maxArray(nums1, i), maxArray(nums2, k - i), k);
ans = isGreater(ans, 0, ret, 0)?ans:ret;
}
return ans;
}
public int[] mergeArray(int[] nums1, int[] nums2, int k){
int[] ret = new int[k];
for (int i = 0, j = 0, r = 0; r < k; ++r){
ret[r] = isGreater(nums1, i, nums2, j) ? nums1[i++] : nums2[j++];
}
return ret;
}
public boolean isGreater(int[] nums1, int i, int[] nums2, int j){
while (i < nums1.length&&j < nums2.length&&nums1[i] == nums2[j]){
i ++;
j ++;
}
return j == nums2.length || (i < nums1.length && nums1[i] > nums2[j]);
}
public int[] maxArray(int[] nums, int k){
int[] ret = new int[k];
int index = 0;
for (int i = 0; i < nums.length; ++ i){
while (nums.length-i+index > k&&index > 0&&ret[index-1] < nums[i]){
index --;
}
if (index < k){
ret[index++] = nums[i];
}
}
return ret;
}
}