如何通过增减操作以最少步骤处理数字集合?求优化思路
优化思路
1. 明确问题核心模型
我们的目标是找到一个目标值k(k可为正整数,或选择移除所有元素对应k=0),对每个元素x计算两种选择的最小代价:
- 移除x:代价为
x(将x减到0的步数) - 保留x并调整到k:代价为
abs(x - k)
累加所有元素的最小代价,找到总和最小的方案即可。
注意:当k=0时,所有元素都移除,总代价为sum(x),这是一个基础候选方案。
2. 缩小候选k的范围
最优的k一定是原数组中的元素,无需遍历所有整数:
- 假设k是两个数组元素之间的整数,比如数组中有a和b(a < k < b),调整到a或b的总代价不会比调整到k更大。因为对于任意x,
abs(x -k)的最小值要么等于abs(x -a),要么等于abs(x -b),而每个元素的min(x, abs(x -k))也不会比min(x, abs(x -a))或min(x, abs(x -b))更小。
因此,我们只需要遍历原数组中的所有唯一元素作为候选k,再加上k=0的情况,计算每个候选的总代价即可。
3. 计算每个候选k的总代价
对每个候选k,遍历数组中的每个元素x,累加min(x, abs(x - k)),记录最小的总代价。
示例验证
对于数组
[1,4,4]:- k=4:总代价为
min(1, 3) + min(4,0) + min(4,0) = 1 + 0 + 0 = 1(最优方案:移除1,保留两个4) - k=1:总代价为
min(1,0) + min(4,3) + min(4,3) = 0 +3 +3=6 - k=0:总代价为
1+4+4=9
显然k=4的方案最优,符合预期。
- k=4:总代价为
对于数组
[1,2,3,4]:- k=2:总代价为
min(1,1)+min(2,0)+min(3,1)+min(4,2)=1+0+1+2=4(保留所有元素调整到2) - k=3:总代价为
min(1,2)+min(2,1)+min(3,0)+min(4,1)=1+1+0+1=3(移除1,调整2→3、4→3,得到[3,3]) - k=0:总代价为
1+2+3+4=10
这里k=3的方案总步数更少,说明你之前的例子只是保留所有元素的情况,允许移除的话存在更优解。
- k=2:总代价为
4. 优化计算效率
如果数组规模很大(比如上万元素),可以先对数组排序,再利用前缀和快速计算总代价:
- 排序后,找到第一个大于等于k的元素位置,将数组分为小于k和大于等于k的两部分。
- 小于k的部分,
abs(x -k)总和为k * cnt_left - prefix_left(cnt_left是左侧元素数量,prefix_left是左侧元素和) - 大于等于k的部分,
abs(x -k)总和为prefix_right - k * cnt_right(prefix_right是右侧元素和,cnt_right是右侧元素数量) - 再结合每个元素
x与abs(x -k)的大小比较,快速累加对应的最小值。
5. 特殊情况处理
- 如果数组中有0:直接移除,代价为0,无需考虑调整到其他k。
- 如果所有元素的
x都小于abs(x -k):比如数组[1,2,3]对应k=5,此时最优方案是移除所有元素,总代价6,比调整到5的总代价9更小。
内容的提问来源于stack exchange,提问作者user28883522
相关产品推荐
相关产品推荐

