
本文介绍一种基于贪心策略的数组分组方法:遍历原数组,持续累加元素到当前组,一旦加入下一个元素会导致总和超过20,就结束当前组、开启新组;支持严格小于20或小于等于20两种边界条件。
本文介绍一种基于贪心策略的数组分组方法:遍历原数组,持续累加元素到当前组,一旦加入下一个元素会导致总和超过20,就结束当前组、开启新组;支持严格小于20或小于等于20两种边界条件。
在处理文件合并场景(如按大小分批打包上传)时,常需将一组带权重(如 MB 大小)的元素划分为若干子序列,使得每个子序列的权重和 不超过指定阈值(如 20),且尽可能“紧凑”——即在不超限前提下尽量多装元素。这并非经典子集和问题(无需回溯或动态规划),而是一个典型的在线贪心分组(online greedy grouping)问题。
核心逻辑是:从左到右扫描数组,维护一个当前组(初始为空),对每个新元素,判断将其加入当前组后总和是否仍满足 ≤ 20(或 )。若满足,则加入;否则,将当前组推入结果数组,并以该元素为起点新建一组。
以下为简洁、可读性强的函数式实现(使用 Array.prototype.reduce 模拟递归累积过程):
const add = (a, b) => a + b;
// 创建分组函数:根据比较函数决定是否开启新组
const groupBySum = (compareFn) => (result, value) => {
const lastGroup = result.at(-1) || [];
const currentSum = lastGroup.reduce(add, 0);
// 若当前组为空,或加入 value 后仍满足条件,则追加;否则新建组
if (lastGroup.length === 0 || compareFn(currentSum + value)) {
lastGroup.push(value);
} else {
result.push([value]);
}
return result;
};
// 边界条件定义
const atMost20 = (sum) => sum sum <p>✅ <strong>关键说明与注意事项:</strong> </p>
- 该算法时间复杂度为 O(n),空间复杂度为 O(n),高效适用于大规模文件列表;
-
reduce在此处模拟了“状态累积”的递归思想,避免显式递归调用栈风险(尤其对长数组); - 若某单个元素本身 > 20(如
25),它将单独成组——这是合理行为(无法拆分文件),你可根据业务需要提前过滤或抛出警告; - 如需真正递归版本(教学/特定约束),可改写为尾递归形式,但实际生产环境推荐上述迭代+reduce方案,更清晰且无栈溢出隐患。
此方法已成功应用于日志归档、附件分包、CDN 资源聚合等真实场景,兼顾效率、可维护性与语义明确性。










