数组全排列是将数组所有元素按不同顺序生成全部可能排列,如[1,2,3]有6种排列;php无内置函数,常用递归(固定+交换+回溯)或字典序法实现。

什么是数组全排列
全排列是指将一个数组中的所有元素按不同顺序进行排列,生成所有可能的排列组合。比如数组 [1, 2, 3] 的全排列有 6 种:[1,2,3]、[1,3,2]、[2,1,3]、[2,3,1]、[3,1,2]、[3,2,1]。PHP 没有内置函数直接生成全排列,需要手动实现。
递归实现全排列(基础版)
最直观的方式是用递归:每次固定一个元素在当前位置,再对剩余元素递归求全排列。
- 定义函数接收当前数组和起始索引
- 当起始索引到达末尾时,保存当前排列结果
- 否则遍历从起始位置到末尾的每个位置,与起始位置交换,递归处理下一位,之后回溯(换回来)
示例代码:
function permute(&$arr, $start = 0, &$result = []) {
$n = count($arr);
if ($start === $n) {
$result[] = $arr;
return;
}
for ($i = $start; $i < $n; $i++) {
// 交换
[$arr[$start], $arr[$i]] = [$arr[$i], $arr[$start]];
permute($arr, $start + 1, $result);
// 回溯:恢复原状
[$arr[$start], $arr[$i]] = [$arr[$i], $arr[$start]];
}
}
$arr = [1, 2, 3];
$result = [];
permute($arr, 0, $result);
print_r($result);
支持重复元素去重的全排列
如果数组含重复值(如 [1, 1, 2]),基础递归会产生重复排列。可在每层递归中跳过已使用过的相同值。
立即学习“PHP免费学习笔记(深入)”;
- 对数组先排序,便于识别相邻重复元素
- 在循环中,若 $i > $start 且 $arr[$i] === $arr[$i-1],跳过本次循环
- 确保同一层不选相同值,避免重复结果
只需在上面的 for 循环内加一行判断:
if ($i > $start && $arr[$i] === $arr[$i - 1]) continue;
非递归实现(字典序法)
适用于已排序数组,通过“下一个字典序排列”迭代生成全部排列,空间更省,无需栈深度。
- 从右往左找第一个降序位置 i(即 $arr[i] )
- 再从右往左找第一个比 $arr[i] 大的数 $arr[j]
- 交换 $arr[i] 和 $arr[j]
- 反转 $arr[i+1] 到末尾的子数组
该方法每次调用生成下一个排列,适合内存受限或需流式处理场景。











