LeetCode 题解工作台
最小数组和
给你一个整数数组 nums 和三个整数 k 、 op1 和 op2 。 你可以对 nums 执行以下操作: 操作 1 :选择一个下标 i ,将 nums[i] 除以 2,并 向上取整 到最接近的整数。你最多可以执行此操作 op1 次,并且每个下标最多只能执行 一次 。 操作 2 :选择一个下标 i …
2
题型
5
代码语言
3
相关题
当前训练重点
中等 · 状态·转移·动态规划
答案摘要
为了方便描述,我们将题目给定的 记为 。 接下来,定义 表示前 个数中,使用了 次操作 1 和 次操作 2 的最小和。初始时 $f[0][0][0] = 0$,其余 $f[i][j][k] = +\infty$。
Interview AiBoxInterview AiBox 实时 AI 助手,陪你讲清 状态·转移·动态规划 题型思路
题目描述
给你一个整数数组 nums 和三个整数 k、op1 和 op2。
你可以对 nums 执行以下操作:
- 操作 1:选择一个下标
i,将nums[i]除以 2,并 向上取整 到最接近的整数。你最多可以执行此操作op1次,并且每个下标最多只能执行一次。 - 操作 2:选择一个下标
i,仅当nums[i]大于或等于k时,从nums[i]中减去k。你最多可以执行此操作op2次,并且每个下标最多只能执行一次。
注意: 两种操作可以应用于同一下标,但每种操作最多只能应用一次。
返回在执行任意次数的操作后,nums 中所有元素的 最小 可能 和 。
示例 1:
输入: nums = [2,8,3,19,3], k = 3, op1 = 1, op2 = 1
输出: 23
解释:
- 对
nums[1] = 8应用操作 2,使nums[1] = 5。 - 对
nums[3] = 19应用操作 1,使nums[3] = 10。 - 结果数组变为
[2, 5, 3, 10, 3],在应用操作后具有最小可能和 23。
示例 2:
输入: nums = [2,4,3], k = 3, op1 = 2, op2 = 1
输出: 3
解释:
- 对
nums[0] = 2应用操作 1,使nums[0] = 1。 - 对
nums[1] = 4应用操作 1,使nums[1] = 2。 - 对
nums[2] = 3应用操作 2,使nums[2] = 0。 - 结果数组变为
[1, 2, 0],在应用操作后具有最小可能和 3。
提示:
1 <= nums.length <= 1000 <= nums[i] <= 1050 <= k <= 1050 <= op1, op2 <= nums.length
解题思路
方法一:动态规划
为了方便描述,我们将题目给定的 记为 。
接下来,定义 表示前 个数中,使用了 次操作 1 和 次操作 2 的最小和。初始时 ,其余 。
考虑 如何进行状态转移,我们可以枚举第 个数 ,然后考虑 的取值对 的影响:
- 如果 不使用操作 1 和操作 2,那么 ;
- 如果 ,那么可以使用操作 1,此时 ;
- 如果 并且 ,那么可以使用操作 2,此时 ;
- 如果 并且 ,那么可以同时使用操作 1 和操作 2。如果先使用操作 1,那么 变为 ,如果 ,那么可以使用操作 2,此时 ;如果先使用操作 2,那么 变为 ,如果 ,那么可以使用操作 1,此时 。
最终答案为 ,如果为 ,则输出 。
时间复杂度 ,空间复杂度 。其中 为数组 的长度。
class Solution:
def minArraySum(self, nums: List[int], d: int, op1: int, op2: int) -> int:
n = len(nums)
f = [[[inf] * (op2 + 1) for _ in range(op1 + 1)] for _ in range(n + 1)]
f[0][0][0] = 0
for i, x in enumerate(nums, 1):
for j in range(op1 + 1):
for k in range(op2 + 1):
f[i][j][k] = f[i - 1][j][k] + x
if j > 0:
f[i][j][k] = min(f[i][j][k], f[i - 1][j - 1][k] + (x + 1) // 2)
if k > 0 and x >= d:
f[i][j][k] = min(f[i][j][k], f[i - 1][j][k - 1] + (x - d))
if j > 0 and k > 0:
y = (x + 1) // 2
if y >= d:
f[i][j][k] = min(f[i][j][k], f[i - 1][j - 1][k - 1] + y - d)
if x >= d:
f[i][j][k] = min(
f[i][j][k], f[i - 1][j - 1][k - 1] + (x - d + 1) // 2
)
ans = inf
for j in range(op1 + 1):
for k in range(op2 + 1):
ans = min(ans, f[n][j][k])
return ans
复杂度分析
| 指标 | 值 |
|---|---|
| 时间 | Depends on the final approach |
| 空间 | Depends on the final approach |
面试官常问的追问
外企场景- question_mark
Look for understanding of dynamic programming and state transitions.
- question_mark
Candidates should be able to explain how tracking operations optimizes the problem-solving approach.
- question_mark
Focus on how the operations are managed and how the dynamic state affects decision-making.
常见陷阱
外企场景- error
Failing to track the correct number of operations left and overusing one type of operation.
- error
Not considering the dynamic nature of the operations, which can lead to suboptimal results.
- error
Overlooking edge cases where no operations are possible or the array length is very small.
进阶变体
外企场景- arrow_right_alt
Modify the problem to only allow a single operation (either op1 or op2).
- arrow_right_alt
Increase the constraints to allow for larger arrays or more operations.
- arrow_right_alt
Limit the number of times each operation can be applied to each element.