PHP 实现数组全排列算法

6次阅读

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

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] 到末尾的子数组

该方法每次调用生成下一个排列,适合内存受限或需流式处理场景。

text=ZqhQzanResources