题目
题干
问题:拼接最大数
You are given two integer arrays nums1 and nums2 of lengths m and n respectively. nums1 and nums2 represent the digits of two numbers. You are also given an integer k. Create the maximum number of length k <= m + n from digits of the two numbers. The relative order of the digits from the same array must be preserved. Return an array of the k digits representing the answer.
给定长度分别为 m 和 n 的两个数组,其元素由 0-9 构成,表示两个自然数各位上的数字。现在从这两个数组中选出 k (k <= m + n) 个数字拼接成一个新的数,要求从同一个数组中取出的数字保持其在原数组中的相对顺序。
求满足该条件的最大数。结果返回一个表示该最大数的长度为 k 的数组。
说明: 请尽可能地优化你算法的时间和空间复杂度。
示例
示例 1: 输入: nums1 = [3, 4, 6, 5] nums2 = [9, 1, 2, 5, 8, 3] k = 5 输出: [9, 8, 6, 5, 3]
示例 2: 输入: nums1 = [6, 7] nums2 = [6, 0, 4] k = 5 输出: [6, 7, 6, 0, 4]
示例 3: 输入: nums1 = [3, 9] nums2 = [8, 9] k = 3 输出: [9, 8, 9]
题解
这道题和之前的316. 去除重复字母类似,只不过之前的题目要求的是一个最小值,这里变成了一个最大值。并且这里是对两个数组进行取值。
- 由于有两个列表,都可以取值。当所需取得个数为k的时候,从第一个列表可取 i 个,则第二个列表可以 k - i 个。注意在取值的时候,我们的输入 pick_max(nums, k)的k是所需要取得个数,加入一个nums长度为2, 那么我们的输入 k 最多为2。因此需要对输入pick_max的长度k进行限制。
- 两个列表所取总的个数为k,在对两个列表进行总循环的时候,我们for内的值应该是(k+1),这样才能取到长度 k。
- 在pick_max内,我们的stack不需要以来就赋值,因为在循环中我们在栈为空的情况下,while循环不成立,所以会有一个入栈的操作。
- 最后就是找到了两个列表所取得不同长度得最大列表后怎么进行组合得问题。我们知道python 中列表之间得大小比较是根据第一位数来确定得,所以我们可以直接对两个列表作比较,取出两者之间得较大值。
注意:列表的赋值是一个引用的过程,所以我们对得到的较大列表不用管他是谁,将第一个数字加入输出之后,直接pop第一个数字就可以了进行下一步比较了。
Python
class Solution:
def __init__(self, nums1, nums2, k):
self.nums1 = nums1
self.nums2 = nums2
self.k = k
@staticmethod
def pick_max(num, k):
"""从列表中找到最大的k个数组合(不改变位置)"""
n = len(num)
drop = n - k
stack = []
for i in range(n):
while drop and stack and num[i] > stack[-1]:
stack.pop()
drop -= 1
stack.append(num[i])
return stack[:k]
def max_number(self):
out = []
m, n = len(self.nums1), len(self.nums2)
for i in range(self.k + 1):
if i <= m and self.k - i <= n:
res = []
res1 = self.pick_max(self.nums1, i)
res2 = self.pick_max(self.nums2, self.k - i)
while res1 or res2:
ans = res1 if res1 > res2 else res2
res.append(ans[0])
ans.pop(0)
out = max(out, res)
return out
|