
本文介绍在php中将数组元素重新分配为尽可能相等的整数值,使总和不变且各元素差异最小——核心策略是计算商与余数,将余数均匀分给前若干个元素。
本文介绍在php中将数组元素重新分配为尽可能相等的整数值,使总和不变且各元素差异最小——核心策略是计算商与余数,将余数均匀分给前若干个元素。
在数据处理、负载均衡或资源配额分配等场景中,常需将一组整数重新“均摊”为总和相等、彼此最接近的新数组。由于整数约束,完全相等往往不可行(如 9 ÷ 4 = 2.25),因此最优解是:所有元素取向下取整值(即商),并将余数逐一分配给前 r 个位置,使它们加 1。最终结果满足: - 新数组总和严格等于原数组总和; - 所有元素为整数; - 最大值与最小值之差 ≤ 1(即最优均衡)。以下为完整实现代码:
<?php function rebalanceArray(array $arr): array {
if (empty($arr)) {
return [];
}
$total = array_sum($arr);
$n = count($arr);
$quotient = intdiv($total, $n); // PHP 7+ 推荐使用 intdiv() 替代 (int)($total / $n)
$remainder = $total % $n;
$result = [];
for ($i = 0; $i < $n; $i++) {
$result[] = ($i < $remainder) ? $quotient + 1 : $quotient;
}
return $result;
}
// 示例 1:[2, 4, 1, 2] → 总和=9,9÷4=2余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] → 总和=8,8÷4=2余0 → [2,2,2,2]
print_r(rebalanceArray([2, 3, 1, 2]));
// 输出:Array ( [0] => 2 [1] => 2 [2] => 2 [3] => 2 )
?>
✅ 关键说明:
- intdiv($total, $n) 比 (int)($total / $n) 更安全,避免浮点误差;
- 余数 remainder 必然满足 0 ≤ remainder
- 该算法时间复杂度 O(n),空间复杂度 O(n),无排序依赖,稳定高效;
- 若需保持原始键名(如关联数组),可改用 array_keys($arr) 遍历并重建键值对。
⚠️ 注意事项:
- 此方法仅适用于非负整数输入;若含负数,需先明确“均衡”的语义(如按绝对值?按代数均值?),逻辑需重构;
- 不改变数组长度,也不引入新元素或删除旧元素;
- 结果唯一(余数优先分配给索引靠前的元素),如需随机分配余数,可先 shuffle 键名再处理。
该策略本质是求解整数划分下的最小最大偏差问题,是经典贪心算法的典型应用——简洁、可靠,且易于扩展至批量数组或流式处理场景。











