回溯算法学习

外在

显然,给你一个选择列表,让你在选择列表中不断的进行选择。最终返回一个包含所有选择的结果集

结果集 fun(选择列表 nums) {

}

构造基本解题结构

结果集都是从从路径一步步走出来的,backtrack多出了一个路径参数,无需返回。

结果集 result;
void backtrack(选择列表 chooses, 路径 track){

}
结果集 fun(选择列表 chooses) {
    // 路径是结果的子集,一步步扩充成结果
    路径 track;
    backtrack(chooses, track);
    return res;
}

构造回溯结构

回溯是一个递归结构,带结束条件,调用自身。
每次选择是可多选的,故以遍历选择列表的方式逐个尝试。
由于尝试时,将选择添加进了路径中,故下次选择前,要回退上次的选择。
选择不合法时咋办?两种做法:在开头排除,在遍历尝试时不管;认为调用传进来的必然合法,调用前先完成排除。

void backtrack(选择列表 chooses, 路径 track) {
   
    if (触发结束条件) {
        result.add(track);
        // 如果没有return,则可能沿着剩余选择再搞搞,说不定会死循环
        return;
    }
	// 遍历选择列表
    for (choose:chooses) {
        if (选择不合法)
            continue;
        // 做选择,路径中加入当前选择
        track.add(choose);
        // 进入下一层决策树
        backtrack(nums, track);
        // 回退选择,还原原本的track再进入下个操作
        track.remove(choose);
    }
}

选择和回退是一对的,是为了不影响数据。此外,把路径copy一个新的也阔以啊,就是效率低。

回溯算法只返回其中一个结果

boolean backtrack(选择列表 chooses, 路径 track) {
   
    if (触发结束条件) {
        result.add(track);
        // 如果没有return,则可能沿着剩余选择再搞搞,说不定会死循环
        return true;
    }
	// 遍历选择列表
    for (choose:chooses) {
        if (选择不合法)
            continue;
        // 做选择,路径中加入当前选择
        track.add(choose);
        // 进入下一层决策树
        if(backtrack(nums, track)){
        	return true;
        }
        // 回退选择,还原原本的track再进入下个操作
        track.remove(choose);
    }
    return false;
}

再次简化的话,可以去掉result这个量

与动态规划的关系

能采用动态规划的解决的问题,也是符合回溯算法特征的,动态规划的优势在于重叠子集上,做了更大幅度的剪枝。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值