LeetCode 题解工作台
形成三的最大倍数
给你一个整数数组 digits ,你可以通过按 任意顺序 连接其中某些数字来形成 3 的倍数,请你返回所能得到的最大的 3 的倍数。 由于答案可能不在整数数据类型范围内,请以字符串形式返回答案。如果无法得到答案,请返回一个空字符串。返回的结果不应包含不必要的前导零。 示例 1: 输入: digits…
5
题型
5
代码语言
3
相关题
当前训练重点
困难 · 状态·转移·动态规划
答案摘要
我们定义 表示在前 个数中选取若干个数,使得选取的数的和模 为 的最大长度。为了使得选取的数最大,我们需要尽可能选取更多的数,因此我们需要使得 尽可能大。我们初始化 $f[0][0] = 0$,其余的 $f[0][j] = -\infty$。 考虑 如何进行状态转移。我们可以不选取第 个数,此时 $f[i][j] = f[i - 1][j]$;我们也可以选取第 个数,此时 $f[i…
Interview AiBoxInterview AiBox 实时 AI 助手,陪你讲清 状态·转移·动态规划 题型思路
题目描述
给你一个整数数组 digits,你可以通过按 任意顺序 连接其中某些数字来形成 3 的倍数,请你返回所能得到的最大的 3 的倍数。
由于答案可能不在整数数据类型范围内,请以字符串形式返回答案。如果无法得到答案,请返回一个空字符串。返回的结果不应包含不必要的前导零。
示例 1:
输入:digits = [8,1,9] 输出:"981"
示例 2:
输入:digits = [8,6,7,1,0] 输出:"8760"
示例 3:
输入:digits = [1] 输出:""
示例 4:
输入:digits = [0,0,0,0,0,0] 输出:"0"
提示:
1 <= digits.length <= 10^40 <= digits[i] <= 9
解题思路
方法一:贪心 + 动态规划 + 逆推
我们定义 表示在前 个数中选取若干个数,使得选取的数的和模 为 的最大长度。为了使得选取的数最大,我们需要尽可能选取更多的数,因此我们需要使得 尽可能大。我们初始化 ,其余的 。
考虑 如何进行状态转移。我们可以不选取第 个数,此时 ;我们也可以选取第 个数,此时 ,其中 表示第 个数的值。因此我们有如下的状态转移方程:
如果 ,那么我们无法选取任何数,因此答案字符串为空。否则我们可以通过 数组进行逆推,找出选取的数。
定义 , ,从 开始逆推,记 ,如果 ,那么我们选取了第 个数,否则我们没有选取第 个数。如果我们选取了第 个数,那么我们将 更新为 ,否则我们保持 不变。为了使得同等长度的数最大,我们应该优先选取较大的数,因此,我们在前面首先对数组进行排序。
时间复杂度 ,空间复杂度 。其中 为数组的长度。
class Solution:
def largestMultipleOfThree(self, digits: List[int]) -> str:
digits.sort()
n = len(digits)
f = [[-inf] * 3 for _ in range(n + 1)]
f[0][0] = 0
for i, x in enumerate(digits, 1):
for j in range(3):
f[i][j] = max(f[i - 1][j], f[i - 1][(j - x % 3 + 3) % 3] + 1)
if f[n][0] <= 0:
return ""
arr = []
j = 0
for i in range(n, 0, -1):
k = (j - digits[i - 1] % 3 + 3) % 3
if f[i - 1][k] + 1 == f[i][j]:
arr.append(digits[i - 1])
j = k
i = 0
while i < len(arr) - 1 and arr[i] == 0:
i += 1
return "".join(map(str, arr[i:]))
复杂度分析
| 指标 | 值 |
|---|---|
| 时间 | complexity is O(n + k log k) where n is the number of digits and k is the remaining digits after removal, mainly due to sorting. Space complexity is O(n) for storing grouped digits and intermediate states required by the state transition dynamic programming approach. |
| 空间 | Depends on the final approach |
面试官常问的追问
外企场景- question_mark
Check if the sum of digits modulo three is zero to quickly identify multiples of three.
- question_mark
Consider edge cases with many zeros or a single digit that cannot form a multiple of three.
- question_mark
Verify your state transitions correctly remove minimal digits to maximize the final number.
常见陷阱
外企场景- error
Failing to remove the smallest number of digits needed, resulting in suboptimal output.
- error
Leaving unnecessary leading zeros in the final string.
- error
Ignoring digits classification by modulo three, which breaks the dynamic programming logic.
进阶变体
外企场景- arrow_right_alt
Find the smallest multiple of three instead of the largest, adjusting sorting strategy.
- arrow_right_alt
Return the largest multiple of five from digits using similar state transition reasoning.
- arrow_right_alt
Compute the largest multiple of k for any k using remainder-based dynamic programming extensions.