回溯基础

先看一个使用回溯方法求集合子集的例子(78. Subsets),以下代码基本说明了回溯使用的基本框架:

//78. Subsets
class Solution {
private:
    void backtrack(vector<vector<int>>& res,vector<int>& tmp,vector<int>& nums,int start){
        res.push_back(tmp);    //满足一定条件下将当前数据加入结果集
        for(int i=start;i<nums.size();i++){
            tmp.push_back(nums[i]);    //选择一条路径
            backtrack(res,tmp,nums,i+);    //DFS朝当前路径行进
            tmp.pop_back();    //回退路径
        }
    }
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> res;
        vector<int> tmp;
        backtrack(res,tmp,nums,);
        return res;
    }
};

即回溯方法主要有以下四个步骤

. 满足一定条件下将当前数据加入结果集
    (或检查到不满足要求当即返回)
. 选择一条路径
. DFS向前进行
. 回退路径

一些情况下需要对数据进行预先处理,或在第2步直接检查以决定是否抛弃当前路径,以避免过多地递归、带来时间损耗。换而言之,不满足条件的路径越早抛弃越好。

理解回溯

回溯方法用到递归,涉及到递归让我们理解起来就不那么直观。下图直观展示了以上Subsets求解代码的执行过程,第5步开始出现路径回退:

可以把回溯的执行理解为一颗树从根到叶、从左到右的展开过程。图片来源 这里

回溯时间复杂度

同样因为用到递归,时间复杂度亦不能够直观地计算,以上Subsets问题比较容易地能看出来为O(2^n)。如果对递归过程计算时间复杂度,详见 这里

相关LeetCode题:

78. Subsets  题解

90. Subsets II  题解

46. Permutations  题解

79. Word Search  题解

40. Combination Sum II  题解

51. N-Queens  题解  可视化

算法与数据结构基础 - 回溯(Backtracking)的更多相关文章

  1. 算法与数据结构基础 - 深度优先搜索(DFS)

    DFS基础 深度优先搜索(Depth First Search)是一种搜索思路,相比广度优先搜索(BFS),DFS对每一个分枝路径深入到不能再深入为止,其应用于树/图的遍历.嵌套关系处理.回溯等,可以 ...

  2. 算法与数据结构基础 - 堆(Heap)和优先级队列(Priority queue)

    堆基础 堆(Heap)是具有这样性质的数据结构:1/完全二叉树 2/所有节点的值大于等于(或小于等于)子节点的值: 图片来源:这里 堆可以用数组存储,插入.删除会触发节点shift_down.shif ...

  3. 算法与数据结构基础 - 广度优先搜索(BFS)

    BFS基础 广度优先搜索(Breadth First Search)用于按离始节点距离.由近到远渐次访问图的节点,可视化BFS 通常使用队列(queue)结构模拟BFS过程,关于queue见:算法与数 ...

  4. 算法与数据结构基础 - 哈希表(Hash Table)

    Hash Table基础 哈希表(Hash Table)是常用的数据结构,其运用哈希函数(hash function)实现映射,内部使用开放定址.拉链法等方式解决哈希冲突,使得读写时间复杂度平均为O( ...

  5. 算法与数据结构基础 - 二叉树(Binary Tree)

    二叉树基础 满足这样性质的树称为二叉树:空树或节点最多有两个子树,称为左子树.右子树, 左右子树节点同样最多有两个子树. 二叉树是递归定义的,因而常用递归/DFS的思想处理二叉树相关问题,例如Leet ...

  6. 算法与数据结构基础 - 分治法(Divide and Conquer)

    分治法基础 分治法(Divide and Conquer)顾名思义,思想核心是将问题拆分为子问题,对子问题求解.最终合并结果,分治法用伪代码表示如下: function f(input x size ...

  7. 算法与数据结构基础 - 双指针(Two Pointers)

    双指针基础 双指针(Two Pointers)是面对数组.链表结构的一种处理技巧.这里“指针”是泛指,不但包括通常意义上的指针,还包括索引.迭代器等可用于遍历的游标. 同方向指针 设定两个指针.从头往 ...

  8. 算法与数据结构基础 - 贪心(Greedy)

    贪心基础 贪心(Greedy)常用于解决最优问题,以期通过某种策略获得一系列局部最优解.从而求得整体最优解. 贪心从局部最优角度考虑,只适用于具备无后效性的问题,即某个状态以前的过程不影响以后的状态. ...

  9. 算法与数据结构基础 - 图(Graph)

    图基础 图(Graph)应用广泛,程序中可用邻接表和邻接矩阵表示图.依据不同维度,图可以分为有向图/无向图.有权图/无权图.连通图/非连通图.循环图/非循环图,有向图中的顶点具有入度/出度的概念. 面 ...

随机推荐

  1. 【MM系列】SAP 采购订单的批量修改

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP 采购订单的批量修改   前言 ...

  2. [AI开发]目标跟踪之计数

    基于视频结构化的应用中,目标在经过跟踪算法后,会得到一个唯一标识和它对应的运动轨迹,利用这两个数据我们可以做一些后续工作:测速(交通类应用场景).计数(交通类应用场景.安防类应用场景)以及行为检测(交 ...

  3. Jpa 笔记

    ORM 思想 对象关系映射, 建立实体类和表的关系映射关系, 实体类和表中字段的映射关系,我们操作实体类底层是操作数据表, 进而自动的拼接出SQL语句 Jpa规范 Jpa(Java Persisten ...

  4. 1.Solr安装与配置

    1.Solr安装 1:安装 Tomcat,解压缩即可. 2:解压 solr. 3:把 solr 下的dist目录solr-4.10.3.war部署到 Tomcat\webapps下(去掉版本号). 4 ...

  5. OpenCV多版本切换和配置--opencv 安装与卸载、添加 opencv_contrib modules 以及 OpenCv 多版本切换

    1. 查看安装Opencv的版本.以及libs和cflags $ pkg-config --modversion opencv $ pkg-config --cflags opencv // 编译链接 ...

  6. Unity 3d 脚本常用事件

    1.学习笔记,每天晚上看看unity 3d 的教程 学点东西,先上一张图 这是 系统中脚本执行的顺序图 Awake()在MonoBehavior创建后就立刻调用,在脚本实例的整个生命周期中,Awake ...

  7. Flutter学习笔记(9)--组件Widget

    如需转载,请注明出处:Flutter学习笔记(9)--组件Widget 在Flutter中,所有的显示都是Widget,Widget是一切的基础,我们可以通过修改数据,再用setState设置数据(调 ...

  8. [leetcode] 103 Binary Tree Zigzag Level Order Traversal (Medium)

    原题链接 题目要求以"Z"字型遍历二叉树,并存储在二维数组里. 利用BFS,对每一层进行遍历.对于每一层是从左还是从右,用一个整数型判断当前是偶数行还是奇数行就可以了. class ...

  9. Django REST Framework(DRF)_第一篇

    认识RESTful REST是设计风格而不是标准,简单来讲REST规定url是用来唯一定位资源,而http请求方式则用来区分用户行为. REST接口设计规范 HTTP常用动词 GET /books:列 ...

  10. SpringBoot(18)---通过Lua脚本批量插入数据到Redis布隆过滤器

    通过Lua脚本批量插入数据到布隆过滤器 有关布隆过滤器的原理之前写过一篇博客: 算法(3)---布隆过滤器原理 在实际开发过程中经常会做的一步操作,就是判断当前的key是否存在. 那这篇博客主要分为三 ...