“最小子数组”指满足特定约束(如连续相同值、累加和≤阈值、固定大小分块或原子化路径值对)且不可再分割的最小合法片段,常见实现包括按值分组、贪心切分、array_chunk及递归扁平化。

要将 PHP 数组拆分为“最小子数组”,关键先明确“最小子数组”的定义——它不是指长度为 1 的子数组,而是指满足某种约束条件(如和、乘积、元素类型、连续性等)的、不能再进一步分割的最小合法片段。常见场景包括:按连续相同值分组、按累加和不超过阈值切分、按键/值结构递归扁平化后重组,或 按业务规则(如每组最多 N 项且保持顺序)进行极小化分块。
按连续相同值拆分(最自然的“最小子数组”)
这是最符合直觉的“最小子数组”:每个子数组内元素完全相同,且相邻子数组值不同。无法再拆(否则会破坏“相同值”性质),也无法合并(否则违反“最小子”原则)。
实现方式:遍历原数组,累积相同值,遇不同值则保存当前组并重置。
- 使用
foreach+ 临时变量记录上一个值和当前组 - 注意处理空数组、单元素、全相同等边界情况
- 示例:
[1,1,2,2,2,3]→[[1,1], [2,2,2], [3]]
按累加和 ≤ 阈值的贪心切分
给定正整数数组和最大允许和 $maxSum,要求将数组从左到右切分为最少数量的连续子数组,使得每个子数组元素和 ≤ $maxSum。此时每个子数组是满足约束的“最小子数组”(再往右加一个数就超限)。
立即学习“PHP免费学习笔记(深入)”;
这是经典的贪心策略:尽可能延长当前子数组,直到下一个元素会导致超限,立即切分。
- 初始化空结果数组、当前和
$currSum = 0、当前子数组[] - 遍历每个元素:若
$currSum + $val <= $maxSum,追加并更新和;否则保存当前子数组、重置 - 别忘了把最后一组加入结果
按固定大小向下取整的极小分块
有时“最小子数组”指在满足“每组不超过 N 项”前提下,让子数组数量最多(即每组尽量小,但至少含 1 个元素)。这实际等价于按 1 项分块——但通常不实用。更合理的是:要求所有子数组长度 ≤ N,且尽可能小,同时保持原顺序和完整性。此时最小可能长度是 1,最大是 N,而“最小子数组”应理解为不可再分的合法单元,即每个子数组长度为 min(剩余元素数, N),但需确保没有子数组为空。
- 用
array_chunk($arr, $size)可直接实现等长分块(最后组可能更短) - 若强调“最小子”而非“等长”,可设
$size = 1,但通常业务中$size ≥ 2更有意义 - 例如
array_chunk([a,b,c,d,e], 2)→[[a,b],[c,d],[e]],其中[e]是合法且不可再分的最小子数组
递归结构下的原子化拆分(如多维数组展平后按路径分组)
对嵌套数组(如配置树、JSON 结构),有时需将每个“叶子节点路径+值”视为一个最小子数组单元,例如:['db' => ['host' => '127.0.0.1', 'port' => 3306]] 拆为 [['db.host', '127.0.0.1'], ['db.port', 3306]]。每个子数组长度固定为 2(路径 + 值),不可再分,代表一个原子配置项。
实现依赖递归遍历 + 路径累积,遇到非数组值即生成一个子数组。
- 函数接收数组、当前路径前缀(初始为空字符串)、结果引用
- 对每个键值对:若值为数组,递归调用(路径更新为
$prefix . $key . '.');否则推入[$fullPath, $value] - 最终结果即一组不可再分的二维子数组











