Leetcode 每日一题
题目链接: 321. 拼接最大数
难度: 困难
解题思路: 首先确定每个数组取的字符的数量。满足两者x + y = k。其中x和y分别是两个字符数组的中取值的数量。分别从这两个大的字符数组中取其中的最大的子序列。通过对这些子序列的字典序比较,获取到最大的拼接数。在获取拼接数的时候可以使用单调栈进行操作。保证栈顶存的一直是字典序相对较大的序列。
题解:
class Solution:
def maxNumber(self, nums1: List[int], nums2: List[int], k: int) -> List[int]:
# 比较两个剩下的串的字典序和长度大小
def compare(list1, idx1, list2, idx2):
len1, len2 = len(list1), len(list2)
while idx1 < len1 and idx2 < len2:
d = (list1[idx1] - list2[idx2])
if d != 0:
return d
idx1 += 1
idx2 += 1
return (len1 - idx1) - (len2 - idx2)
# 单调栈
def monoStack(list1, list2) -> List[int]:
len1, len2 = len(list1), len(list2)
stack = list()
i, j = 0, 0
while i < len1 and j < len2:
if compare(list1, i, list2, j) > 0:
stack.append(list1[i])
i += 1
else:
stack.append(list2[j])
j += 1
while i < len1:
stack.append(list1[i])
i += 1
while j < len2:
stack.append(list2[j])
j += 1
return stack
# 获取长度为length 的最大子序列
def maxSubSeq(seq, length):
stack = list()
remain = len(seq) - length
for num in seq:
while len(stack) > 0 and stack[-1] < num and remain > 0:
stack.pop()
remain -= 1
if len(stack) < length:
stack.append(num)
else:
remain -= 1
return stack
m, n = len(nums1), len(nums2)
# 两个数组取的长度分别为x + y = k
start, end = max(0, k - n), min(k, m)
res = []
first = True # 第一次计算
for x in range(start, end + 1):
# print(x, k - x)
digit1 = maxSubSeq(nums1, x)
digit2 = maxSubSeq(nums2, k - x)
digit = monoStack(digit1, digit2)
# print(digit1, digit2, digit)
if first:
res = digit
first = False
else:
res = max(digit, res) # 找到字典序最大的
return res