

文章目录
-
- 摘要
- 描述
- 题解答案(核心思路)
- [题解答案(Swift 可运行 Demo)](#题解答案(Swift 可运行 Demo))
- 题解代码分析
-
- [1. 为什么先找最小值?](#1. 为什么先找最小值?)
- [2. 操作次数怎么累加?](#2. 操作次数怎么累加?)
- [3. 为什么直接累加就行?](#3. 为什么直接累加就行?)
- 示例测试及结果
-
- [示例 1](#示例 1)
- [示例 2](#示例 2)
- 再举一个负数的例子
- 实际场景结合
-
- [1. 数据归一化](#1. 数据归一化)
- [2. 资源平衡问题](#2. 资源平衡问题)
- [3. 面试中的常见陷阱](#3. 面试中的常见陷阱)
- 时间复杂度
- 空间复杂度
- 总结
摘要
这道题乍一看有点反直觉。
题目说的是:
每次操作让 n - 1 个元素加 1
很多人第一反应是:
- 模拟?
- 暴力?
- 反复加到一样?
但实际上,这道题一旦你 换一个视角,就会发现答案非常简单,甚至可以一行代码解决。
核心在于一句话:
"给 n - 1 个数加 1,本质上等价于给 1 个数减 1。"
只要想通这一点,这题基本就结束了。

描述
题目给你一个整数数组 nums,长度是 n。
规则是:
- 每次操作,可以让数组中 任意 n - 1 个元素加 1
- 目标是让 所有元素最终相等
- 问最少需要多少次操作
示例
text
nums = [1,2,3]
可以这样操作:
text
[1,2,3] -> [2,3,3] -> [3,4,3] -> [4,4,4]
答案是 3。
题解答案(核心思路)
一句话核心结论
最小操作次数 = 所有元素与最小值的差之和
公式表示就是:
text
sum(nums) - min(nums) * n
为什么可以这么算?
关键在于 等价变换。
原操作:
- 每次让
n - 1个数+1
等价理解:
- 整个数组都
+1 - 然后选 1 个数
-1
整体结果没变。
也就是说:
每次操作,相当于选择一个元素,让它 -1
问题就被简化成了什么?
变成了:
每次可以让某一个数减 1
要把所有数都变成同一个值(而且操作次数最少)
那目标值选谁最合理?
答案是:数组中的最小值。
为什么目标是最小值?
- 你只能"减",不能"加"
- 把大的数减到最小值,代价最小
- 如果选更小的值,反而要多做无意义的操作

题解答案(Swift 可运行 Demo)
swift
class Solution {
func minMoves(_ nums: [Int]) -> Int {
guard let minValue = nums.min() else {
return 0
}
var result = 0
for num in nums {
result += num - minValue
}
return result
}
}
题解代码分析
1. 为什么先找最小值?
swift
guard let minValue = nums.min() else {
return 0
}
这是整个算法的"锚点"。
我们最终的目标是:
- 所有元素 →
minValue
2. 操作次数怎么累加?
swift
result += num - minValue
含义非常直观:
- 当前元素是
num - 目标是
minValue - 每减少
1,就相当于一次操作 - 那需要
num - minValue次
3. 为什么直接累加就行?
因为:
- 每次操作,只影响一个"被减"的元素
- 不同元素之间互不干扰
- 总操作数就是每个元素单独的"减法次数"之和
示例测试及结果
示例 1
swift
let solution = Solution()
print(solution.minMoves([1, 2, 3]))
输出:
text
3
解释:
text
(1 - 1) + (2 - 1) + (3 - 1) = 0 + 1 + 2 = 3
示例 2
swift
print(solution.minMoves([1, 1, 1]))
输出:
text
0
所有元素已经相等,不需要操作。
再举一个负数的例子
swift
print(solution.minMoves([-1, 0, 2]))
计算过程:
text
min = -1
(-1 - -1) + (0 - -1) + (2 - -1)
= 0 + 1 + 3
= 4
实际场景结合
这道题在真实开发中,其实很常见,比如:
1. 数据归一化
你有一组数:
- 每次只能"整体提升"
- 想让所有数据回到同一基准
这时就可以反向思考:
- 谁是最低基准
- 其他值要"补齐"多少
2. 资源平衡问题
比如:
- 多个服务实例负载不均
- 每次只能"给大多数实例加资源"
那从另一个角度看:
- 是在"惩罚"负载最高的那个实例
3. 面试中的常见陷阱
这题非常适合考:
- 是否能跳出题面
- 是否具备等价转换能力
- 是否能把复杂操作转成简单数学问题
时间复杂度
- 找最小值:
O(n) - 遍历求和:
O(n)
总时间复杂度:
text
O(n)
空间复杂度
- 只使用了常量变量
空间复杂度:
text
O(1)
总结
LeetCode 453 是一道非常典型的:
- 看起来复杂
- 实际一行公式就能解决
- 极度考察"问题视角转换能力"的题
只要你记住这句话:
"给 n - 1 个数加 1,等价于给 1 个数减 1。"
这道题基本就是秒解。