
本文介绍一种基于整数均值分配的数组再平衡算法:在保持总和不变的前提下,将数组各元素调整为尽可能接近的整数,使最大值与最小值之差不超过 1,从而实现“视觉与数值上最均衡”的分布。
本文介绍一种基于整数均值分配的数组再平衡算法:在保持总和不变的前提下,将数组各元素调整为尽可能接近的整数,使最大值与最小值之差不超过 1,从而实现“视觉与数值上最均衡”的分布。
在实际开发中(如资源配额分配、负载模拟、统计归一化等场景),我们常需将一个整数数组“再平衡”为一组数值尽可能相等的新数组,同时严格保持原始总和不变。由于整数除法存在余数,无法让所有元素完全相等,因此最优策略是:使所有元素等于 floor(平均值),并将余数均匀分配给前 r 个元素(各 +1),从而确保结果数组中最大值与最小值之差 ≤ 1,且总和严格守恒。
该方法本质是求解整数划分问题中的“最小方差分配”,其数学基础为:
设原数组长度为 n,总和为 sum,则商 q = floor(sum / n),余数 r = sum % n。最终数组由 r 个 q + 1 和 n − r 个 q 构成,按顺序排列即可。
以下是完整、健壮的 PHP 实现:
<?php function rebalanceArray(array $arr): array {
if (empty($arr)) {
return [];
}
$sum = array_sum($arr);
$n = count($arr);
$q = (int)floor($sum / $n); // 整数商
$r = $sum % $n; // 余数(0 ≤ r < n)
$result = [];
for ($i = 0; $i < $n; $i++) {
$result[] = ($i < $r) ? $q + 1 : $q;
}
return $result;
}
// 示例 1:[2, 4, 1, 2] → sum=9, n=4 → q=2, r=1 → [3,2,2,2]
print_r(rebalanceArray([2, 4, 1, 2]));
// 输出:Array ( [0] => 3 [1] => 2 [2] => 2 [3] => 2 )
// 示例 2:[2, 3, 1, 2] → sum=8, n=4 → q=2, r=0 → [2,2,2,2]
print_r(rebalanceArray([2, 3, 1, 2]));
// 输出:Array ( [0] => 2 [1] => 2 [2] => 2 [3] => 2 )
?>
✅ 关键特性说明:
- ✅ 总和守恒:array_sum(rebalanceArray($arr)) === array_sum($arr) 恒成立;
- ✅ 最小差异:结果中任意两元素之差 ∈ {0, 1},达到理论最优均衡;
- ✅ 确定性顺序:余数优先分配给索引靠前的元素(可依需求改为随机或按权重分配);
- ✅ 零边界安全:支持空数组、单元素、全零等边界情况。
⚠️ 注意事项:
- 本方案仅适用于非负整数输入(若含负数,需先统一偏移或改用浮点均值截断策略);
- 若业务要求“最小移动量”(即最小化 ∑|new[i] − old[i]|),则需额外贪心调整(本文方案已天然接近最优,但不保证绝对最小移动);
- 键名(如 [1]=>2)在 PHP 索引数组中会重置为数字键;如需保留原始键,可用 array_combine(array_keys($arr), $result) 显式重建关联结构。
该算法时间复杂度 O(n),空间复杂度 O(n),简洁高效,适用于高频调用场景。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











