题目描述:
给出两个长度分别是m和n的数组来表示两个大整数,数组的每个元素都是数字0-9。从这两个数组当中选出k个数字来创建一个最大数,其中k满足k <= m + n。选出来的数字在创建的最大数里面的位置必须和在原数组内的相对位置一致。返回k个数的数组。你应该尽可能的去优化算法的时间复杂度和空间复杂度。
样例:
给出 nums1 = [3, 4, 6, 5], nums2 = [9, 1, 2, 5, 8, 3], k = 5
返回 [9, 8, 6, 5, 3]
给出 nums1 = [6, 7], nums2 = [6, 0, 4], k = 5
返回 [6, 7, 6, 0, 4]
给出 nums1 = [3, 9], nums2 = [8, 9], k = 3
返回 [9, 8, 9]
题目分析:
答案必须满足的条件为:
1.从数组nums中挑选x个数,在保持元素的相对顺序不变的情况下,使得所选出的子数组最大化。
2.在保持元素的相对顺序不变的前提下,将数组nums1和nums2合并,使合并后的数组最大。
nums1和nums2的长度x1和x2要满足x1+x2=k,枚举遍历求出最大的即可。
对于条件1思路:栈思路
首先得出nums中所有数字出现的次数,即为字典counter
遍历数组nums,记当前数字为c,讲counter[c]-1
如果c已经在栈stack中,继续遍历
将c和栈顶元素top进行比较,若top<c,并且counter[top]>0则弹栈,重复此过程,将c入栈。
对于条件2,解决思路:
两数组的合并使用归并排序中的merge操作
Python代码
class Solution:
# @param {int[]} nums1 an integer array of length m with digits 0-9
# @param {int[]} nums2 an integer array of length n with digits 0-9
# @param {int} k an integer and k <= m + n
# @return {int[]} an integer array
def maxNumber(self, nums1, nums2, k):
# Write your code here
def getMax(nums,x):
ans=[]
size=len(nums)
for i in range(size):
while ans and len(ans)+size-i>x and ans[-1]<nums[i]:
ans.pop()
if len(ans)<x:
ans+=nums[i],
return ans
def merge(nums1,nums2):
ans=[]
while nums1 or nums2:
if nums1>nums2:
ans+=nums1[0],
nums1=nums1[1:]
else:
ans+=nums2[0],
nums2=nums2[1:]
return ans
len1,len2=len(nums1),len(nums2)
res=[]
for i in range(max(0,k-len2),min(k,len1)+1):
tmp=merge(getMax(nums1,i),getMax(nums2,k-i))
res=max(tmp,res)
return res