代码随想录第二十四天|回溯法理论基础、77. 组合

回溯法理论基础:

回溯法:

回溯搜索法,用于搜索,实际上是递归函数

效率:

是穷举,暴力搜索,效率不高。剪枝可以更高效。

应用场景:

组合问题:N个数里面按一定规则找出k个数的集合

切割问题:一个字符串按一定规则有几种切割方式

子集问题:一个N个数的集合里有多少符合条件的子集

排列问题:N个数按一定规则全排列,有几种排列方式

棋盘问题:N皇后,解数独等等

如何理解:

将问题抽象成树形结构,集合的大小就构成了树的宽度,递归的深度,都构成的树的深度。终止条件限制其为高度有限的N叉树。

回溯法模板:


void backtracking(参数) {

    if (终止条件) {

        存放结果;

        return;

    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {

        处理节点;

        backtracking(路径,选择列表); // 递归

        回溯,撤销处理结果

    }

}


77. 组合

思路:

按照模板,确定参数,终止条件和单层逻辑

确定参数:n,k

终止条件:一维数组的size==k,将一维数组放进二维数组

单层逻辑:for循环确认第一个元素,不知道应该用什么方式回溯

看视频后:

确认参数:

全局变量:一维数组,二维数组

参数:n,k,startIndex

终止条件:一维数组的size==k,将一维数组放进二维数组

单层逻辑:

for(int i=startIndex;i<=n;i++)

        {

            vec.push_back(i);

            backtracking(n,k,i+1);

            vec.pop_back();

        }


剪枝:

对单层逻辑中i的范围进行缩小,i<=n-(k-vec.size())+1

vec.size()为已有元素

k-vec.size()为还需要多少元素

n-(k-vec.size())+1为至多需要多少元素

剪枝最好是画出树图找到能剪枝的部分

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容