💡 LeetCode风格算法题解:最少操作次数使数组和能被K整除
📝 题目描述
给你一个整数数组 nums
和一个整数 k
。你可以执行如下操作任意次:
选择一个下标 i
,并将 nums[i]
替换为 nums[i] - 1
。
每次操作会让数组的总和减小 1。
请你返回:使整个数组元素之和能被 k
整除,所需的最少操作次数。
🧠 解题分析
这是一个看似操作“很自由”的题目,但其实本质非常简单。我们只关心一个目标:
让数组的总和 sum(nums)
变成 k
的倍数。
操作的方式——每次任意元素减 1——其实只是让我们能够“逐步减小总和”。
🚩转化目标:
从数学角度来说:
我们需要使:
sum(nums) % k == 0
如果当前 sum(nums)
已经能整除 k
,那么我们不需要任何操作,直接返回 0。
否则,我们需要让这个余数归零,那就意味着:
操作次数 = sum(nums) % k
每次操作都减掉 1,所以只需要减掉这个余数次,就能使 sum(nums)
恰好成为 k
的倍数。
🧩 解法一:最简洁的数学解法
class Solution:
def minOperations(self, nums: List[int], k: int) -> int:
total = sum(nums)
return total % k
✅ 分析:
- 直接计算总和,再取余数
- 余数就是我们需要的操作次数
- 时间复杂度:O(n)(只遍历一次数组)
🧩 解法二:加入逻辑判断(更可读)
虽然数学上等价,但更具语义表达性的代码可以是:
class Solution:
def minOperations(self, nums: List[int], k: int) -> int:
total = sum(nums)
remainder = total % k
return 0 if remainder == 0 else remainder
或者更 Pythonic 的写法:
class Solution:
def minOperations(self, nums: List[int], k: int) -> int:
return sum(nums) % k
这样在逻辑上更清晰地表明:“如果已经能整除,就不需要任何操作。”
🧪 示例说明
示例 1:
nums = [4, 2, 3]
k = 5
总和为 4 + 2 + 3 = 9
,
9 % 5 = 4
,所以最少需要进行 4
次操作,使得总和变为 5
。
示例 2:
nums = [1, 2, 3]
k = 3
sum = 6
,刚好是 3
的倍数,不需要任何操作,返回 0
。
🔄 延伸讨论:更复杂的变种
这道题还可以衍生出一些有趣的变体,例如:
- 只能对特定下标操作
- 每次操作的代价不同
- 可以将一个数变为任意数(而不仅仅是减 1)
这些变体可能会涉及到动态规划、贪心算法或者前缀和技巧,大大增加了挑战性。
📌 小结
解法 |
时间复杂度 |
空间复杂度 |
优点 |
数学解法 |
O(n) |
O(1) |
简洁高效 |
加逻辑判断 |
O(n) |
O(1) |
语义清晰,适合面试场景 |
✅ 最终感悟
这道题的核心是简化问题,通过观察“每次操作只会减 1”,从而聚焦在如何让总和成为 k
的倍数。写题过程中保持清晰的数学思维和良好的代码风格,是写出高质量解法的关键。
如果你对这个题目有其他思路,或者想我帮你实现变种题目,欢迎留言交流!👏