LeetCode 题解工作台
可被三整除的最大和
给你一个整数数组 nums ,请你找出并返回能被三整除的元素 最大和 。 示例 1: 输入: nums = [3,6,5,1,8] 输出: 18 解释: 选出数字 3, 6, 1 和 8,它们的和是 18(可被 3 整除的最大和)。 示例 2: 输入: nums = [4] 输出: 0 解释: 4 …
4
题型
5
代码语言
3
相关题
当前训练重点
中等 · 状态·转移·动态规划
答案摘要
我们定义 表示前 个数中选取若干个数,使得这若干个数的和模 余 的最大值。初始时 ,其余为 。 对于 ,我们可以考虑第 个数 的状态:
Interview AiBoxInterview AiBox 实时 AI 助手,陪你讲清 状态·转移·动态规划 题型思路
题目描述
给你一个整数数组 nums,请你找出并返回能被三整除的元素 最大和。
示例 1:
输入:nums = [3,6,5,1,8] 输出:18 解释:选出数字 3, 6, 1 和 8,它们的和是 18(可被 3 整除的最大和)。
示例 2:
输入:nums = [4] 输出:0 解释:4 不能被 3 整除,所以无法选出数字,返回 0。
示例 3:
输入:nums = [1,2,3,4,4] 输出:12 解释:选出数字 1, 3, 4 以及 4,它们的和是 12(可被 3 整除的最大和)。
提示:
1 <= nums.length <= 4 * 1041 <= nums[i] <= 104
解题思路
方法一:动态规划
我们定义 表示前 个数中选取若干个数,使得这若干个数的和模 余 的最大值。初始时 ,其余为 。
对于 ,我们可以考虑第 个数 的状态:
- 如果我们不选 ,那么 ;
- 如果我们选 ,那么 。
因此我们可以得到状态转移方程:
最终答案为 。
时间复杂度 ,空间复杂度 。其中 为数组 的长度。
注意到 的值只与 和 有关,因此我们可以使用滚动数组优化空间复杂度,使空间复杂度降低为 。
class Solution:
def maxSumDivThree(self, nums: List[int]) -> int:
n = len(nums)
f = [[-inf] * 3 for _ in range(n + 1)]
f[0][0] = 0
for i, x in enumerate(nums, 1):
for j in range(3):
f[i][j] = max(f[i - 1][j], f[i - 1][(j - x) % 3] + x)
return f[n][0]
复杂度分析
| 指标 | 值 |
|---|---|
| 时间 | Depends on the final approach |
| 空间 | Depends on the final approach |
面试官常问的追问
外企场景- question_mark
Ability to recognize state transition patterns in dynamic programming.
- question_mark
Understanding of greedy techniques for optimizing the sum.
- question_mark
Comfort with handling arrays and ensuring the sum is divisible by three.
常见陷阱
外企场景- error
Not properly managing the modulo 3 states during dynamic programming updates.
- error
Confusing the maximum sum with the largest number divisible by three.
- error
Incorrectly handling edge cases where no sum is divisible by three.
进阶变体
外企场景- arrow_right_alt
Modify the problem to find the minimum sum divisible by three.
- arrow_right_alt
Extend the problem to include negative integers in the array.
- arrow_right_alt
Apply this approach to a multidimensional array for greater complexity.