算法与数据结构基础 - 回溯(Backtracking)
回溯基础
先看一个使用回溯方法求集合子集的例子(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题:
算法与数据结构基础 - 回溯(Backtracking)的更多相关文章
- 算法与数据结构基础 - 深度优先搜索(DFS)
DFS基础 深度优先搜索(Depth First Search)是一种搜索思路,相比广度优先搜索(BFS),DFS对每一个分枝路径深入到不能再深入为止,其应用于树/图的遍历.嵌套关系处理.回溯等,可以 ...
- 算法与数据结构基础 - 堆(Heap)和优先级队列(Priority queue)
堆基础 堆(Heap)是具有这样性质的数据结构:1/完全二叉树 2/所有节点的值大于等于(或小于等于)子节点的值: 图片来源:这里 堆可以用数组存储,插入.删除会触发节点shift_down.shif ...
- 算法与数据结构基础 - 广度优先搜索(BFS)
BFS基础 广度优先搜索(Breadth First Search)用于按离始节点距离.由近到远渐次访问图的节点,可视化BFS 通常使用队列(queue)结构模拟BFS过程,关于queue见:算法与数 ...
- 算法与数据结构基础 - 哈希表(Hash Table)
Hash Table基础 哈希表(Hash Table)是常用的数据结构,其运用哈希函数(hash function)实现映射,内部使用开放定址.拉链法等方式解决哈希冲突,使得读写时间复杂度平均为O( ...
- 算法与数据结构基础 - 二叉树(Binary Tree)
二叉树基础 满足这样性质的树称为二叉树:空树或节点最多有两个子树,称为左子树.右子树, 左右子树节点同样最多有两个子树. 二叉树是递归定义的,因而常用递归/DFS的思想处理二叉树相关问题,例如Leet ...
- 算法与数据结构基础 - 分治法(Divide and Conquer)
分治法基础 分治法(Divide and Conquer)顾名思义,思想核心是将问题拆分为子问题,对子问题求解.最终合并结果,分治法用伪代码表示如下: function f(input x size ...
- 算法与数据结构基础 - 双指针(Two Pointers)
双指针基础 双指针(Two Pointers)是面对数组.链表结构的一种处理技巧.这里“指针”是泛指,不但包括通常意义上的指针,还包括索引.迭代器等可用于遍历的游标. 同方向指针 设定两个指针.从头往 ...
- 算法与数据结构基础 - 贪心(Greedy)
贪心基础 贪心(Greedy)常用于解决最优问题,以期通过某种策略获得一系列局部最优解.从而求得整体最优解. 贪心从局部最优角度考虑,只适用于具备无后效性的问题,即某个状态以前的过程不影响以后的状态. ...
- 算法与数据结构基础 - 图(Graph)
图基础 图(Graph)应用广泛,程序中可用邻接表和邻接矩阵表示图.依据不同维度,图可以分为有向图/无向图.有权图/无权图.连通图/非连通图.循环图/非循环图,有向图中的顶点具有入度/出度的概念. 面 ...
随机推荐
- 实现markdown功能
前言 由于个人一直想弄一个博客网站,所以写博客的功能也就必须存在啦,而之前想过用富文本编辑器来实现的.但是接触了markdown后,发现真的是太好玩了,而且使用markdown的话可以在博客园.CSD ...
- leetcode 136 Single Number bBt Option
Linked Url:https://leetcode.com/problems/single-number/ Given a non-empty array of integers, every e ...
- Spring Boot日志使用
前言: 这是我第一次仔细研究Spring Boot相关的知识,就拿日志下手了,欢迎大家指点 Spring Boot日志关系 这个是Spring Boot的启动器,我们点击spring-boot-sta ...
- NOIP 2004 虫食算题解
问题 E: [Noip2004]虫食算 时间限制: 1 Sec 内存限制: 128 MB 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一 ...
- 20131227-backgroundPosition
background-position 用法详细介绍 语法: background-position : length || length background-position : position ...
- 20131221-Dom练习-第二十六天(未完)
[1] //总结,写代码,一要动脑,理解用脑 //二要练,要动手,要有用身体记忆代码的觉悟,记忆用手 //三学编程最快的方法是,直接接触代码,用脑,用手接触代码 //面向对象的编码方式,对象还是对象, ...
- NET Core CSharp初级篇 1-3面向对象
.NET Core CSharp初级篇 1-3 本节内容为面向对象初级教程 类 简介 面向对象是整个C#中最核心最有特色的一个模块了,它很好的诠释了程序与现实世界的联系. 面向对象的三大特征:继承.多 ...
- 【弱化版】【P3371 【模板】单源最短路径(弱化版)】-C++
→原题传送门← 看到题目描述我就知道,这道题不能用SPFA[手动补滑稽] 那么我这道题目采用的是dijkstra算法不了解的去补一下知识哈. dij的模板: #include<bits/stdc ...
- Python 3.5学习笔记(第一章)
本章内容: 1.安装python 3.5 和 PyCharm 社区版 2.第一个python程序 3.变量 4.字符编码 5.用户输入 6.字符串格式化输出 7.if .else .elif 8.fo ...
- 最大公约数GCD学习笔记
引理 已知:k|a,k|b 求证:k|(m*a+n*b) 证明:∵ k|a ∴ 有p*k=a 同理可得q*k=b ∴ p*k*m=m*a,q*k*n=n*b ∴ k(p*m+q*n)=m*a+n*b ...