美文网首页
回溯算法

回溯算法

作者: 狼爷的号 | 来源:发表于2021-02-15 14:55 被阅读0次

更多文章,可关注我的 博客园掘金

回溯算法

什么是回溯算法

回溯算法本质就是枚举,在给定的枚举集合中不断从其中尝试搜索找到问题的解,如果在搜索过程中发现不满足求解条件,则回溯返回,尝试其他路径继续搜索解决,这种走不通就回退再尝试其他路径的方法就是回溯法。

回溯算法解题通用套路

解决一个回溯问题,实际上就是一个决策树的遍历过程。你只需要思考3个问题:

  1. 路径:也就是已经做出的选择。
  2. 选择列表:也就是你当前可以做的选择。
  3. 结束条件:也就是到达决策树底层,无法再做选择的条件。

通用解决方案伪代码

result = []
function backtrack(路径, 选择列表) {
    if 满足结束条件:
        result.add(路径)
        return

    for 选择 in 选择列表:
        做选择
        backtrack(路径, 选择列表)
        撤销选择
}

它一般是解决树形问题的,问题分解成多个阶段,每个阶段有多个解,这个就构成了一颗树,所以判断问题是否可以用回溯算法的关键在于它是否可以转成一个树形问题。
另外我们也发现如果能够缩小每个阶段的可选解,就能让问题的搜索规模都缩小,这种叫做剪枝,通过剪枝能有效降低整个问题的搜索复杂度。

回溯算法解决全排列问题

我们在高中的时候就做过排列组合的数学题,我们也知道 n 个不重复的数,全排列共有 n! 个。
那么我们当时是怎么穷举全排列的呢?比方说给三个数 [1,2,3],你肯定不会无规律地乱穷举,一般是这样:

先固定第一位为 1,然后第二位可以是 2,那么第三位只能是 3;然后可以把第二位变成 3,第三位就只能是 2 了;然后就只能变化第一位,变成 2,然后再穷举后两位……

其实这就是回溯算法,我们高中无师自通就会用,或者有的同学直接画出如下这棵回溯树:


全排列
public class Test {

    public static void main(String[] args) {
        Test test = new Test();
        int[] nums = {1, 2, 3};
        System.out.println(test.permute(nums));
    }

    public List<List<Integer>> permute(int[] nums) {
        if (nums == null || nums.length == 0) {
            return Collections.emptyList();
        }

        List<List<Integer>> result = new ArrayList<>();
        backtrack(result, new ArrayList<>(), nums);

        return result;
    }

    private void backtrack(List<List<Integer>> result, List<Integer> selectNums, int[] allNums) {
        if (selectNums.size() == allNums.length) {
            result.add(new ArrayList<>(selectNums));
            return;
        }

        for (Integer num : allNums) {
            // 剪枝
            if (selectNums.contains(num)) {
                continue;
            }

            selectNums.add(num);
            backtrack(result, selectNums, allNums);
            selectNums.remove(num);
        }
    }

}

参考资料

相关文章

  • 回溯算法

    回溯算法 回溯算法介绍   回溯算法并不是非常复杂的算法, 很多人接触过但是未必知道这是回溯算法; 典型的回溯算法...

  • 回溯算法:八皇后问题和0-1背包问题

    文章结构 如何理解回溯算法 回溯算法的经典应用 完整源码 图片来源 1. 如何理解回溯算法 1.1 什么是回溯算法...

  • Algorithm进阶计划 -- 回溯算法

    滑动窗口算法回溯算法框架回溯算法运用 1. 回溯算法框架 回溯算法,是类似枚举的搜索尝试过程,主要是在搜索尝试过程...

  • 回溯算法总结

    回溯法学习总结 回溯算法也是算法导论中常用的算法,回溯算法类似于暴力求解算法,经常用在求可能解的问题。下面我将从三...

  • 77. Combinations.go

    回溯算法

  • 递归2-回溯与递归

    I. 回溯算法基础 回溯与递归的区别和联系  很多人不理解回溯与递归到底是什么关系。其实很简单,回溯算法是一种算法...

  • 回溯算法之-组合总和

    回溯算法模版 首先上一套回溯算法模版,很多回溯算法都可以使用该模版解决 leetcode 39 组合总和 给定一个...

  • 17. Letter Combinations of a Pho

    使用回溯算法

  • 「回溯算法」专题介绍

    「回溯算法」专题介绍 第 1 节:从全排列问题开始理解回溯搜索算法 引言 大家好,今天要和大家分享的主题是“回溯算...

  • 450,什么叫回溯算法,一看就会,一写就废

    什么叫回溯算法 对于回溯算法的定义,百度百科上是这样描述的:回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索...

网友评论

      本文标题:回溯算法

      本文链接:https://www.haomeiwen.com/subject/uboexltx.html