回溯算法+全排列问题

回溯算法解全排列问题

前言

食用前,若了解递归、树的基本结构及前中后序遍历,风味更佳~

概述

回溯算法

  1. 走不通就退回再走
  2. 虚拟设置N叉树,不需要构造一棵真正的树结构
  3. 递归调用前:每走到一个分支,做出选择后剪除该分支,记录该选择进行下一层分支的深度遍历;
  4. 递归调用后:回到上一层决策树时,把该选择及结果恢复

递归

  1. 自己调用自己
  2. 利用函数的入栈出栈特性,并在入栈出栈前后不断重复搞事情

代码

// 回溯算法解全排列问题(排列数字唯一不重复版)
function backtrack(&$globalSelectList, &$res, $thisSelectList, $thisRes)
{
    // 记录当前深度遍历完成后的结果
    if (count($globalSelectList) == count($thisRes)) {
        $res[] = $thisRes;
    }

    foreach ($thisSelectList as $k => $v) {
        // 记录到当前深度遍历的结果
        if (!in_array($v, $thisRes)) {
            $thisRes[] = $v;
        }
        // echo 'before::', json_encode([$k, $v, $thisSelectList, $thisRes]), '; '; // 可输出帮助理解

        // 剪枝(在当前决策树该选择已做过,往下深度遍历前删掉该选择)
        unset($thisSelectList[$k]);
        backtrack($globalSelectList, $res, $thisSelectList, $thisRes);

        // 深度遍历后回到上一层决策树时,把该选择及结果恢复
        $thisSelectList[$k] = $v;
        array_pop($thisRes);
        // echo 'after::', json_encode([$k, $v, $thisSelectList, $thisRes]), '; '; // 可输出帮助理解
    }
}

$globalSelectList = range(1, 3);
$res = [];
$thisSelectList = $globalSelectList;
$thisRes = [];
backtrack($globalSelectList, $res, $thisSelectList, $thisRes);
// echo 'resCount:', count($res), ';res:', json_encode($res);
// resCount:6;res:[[1,2,3],[1,3,2],[2,3,1],[2,1,3],[3,1,2],[3,2,1]]

建议

建议将递归调用前后的情况输出看看,可帮助加深理解

参考

  1. 公众号labuladong学算法
  2. https://blog.csdn.net/gardenpalace/article/details/84625537
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值