Backtracking algorithm梳理
回溯法简介
注意下面这句话
由于回溯通常结果集都记录在回溯树的路径上,因此如果不进行撤销操作, 则可能在回溯后状态不正确导致结果有差异, 因此需要在递归到底部往上冒泡的时候进行撤销状态。
如果你每次递归的过程都拷贝了一份数据,那么就不需要撤销加粗样式状态,相对地空间复杂度会有所增加
回溯法都可以抽象为树形结构,其实每一层都代表了一个for循环
以下面题为例,k=2时是两个for循环,k=50是50个for循环,后者写不出来,但是回溯能够写得出来。
77. 组合
给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
输入: n = 4, k = 2
输出:
[[2,4],[3,4],[2,3],[1,2],[1,3],[1,4]]
剪枝优化
class Solution {public:vector<vector<int>> combine(int n, int k) {vector< int > temp;dfs(temp, n, 1, k);return ret;}void dfs(vector<int>& v, int n, int nowIndex, int k){if (v.size() == k){ret.emplace_back(v);return;}else if (nowIndex > n){return;}//加入路径,遍历,消除关系for (int i = nowIndex; i <= n&& n-i+1 >= (k-v.size()); i++){v.emplace_back(nowIndex);dfs(v, n, ++nowIndex, k);v.pop_back(); }}
public:vector<vector<int>>ret;
};
216. 组合总和 III
找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:
只使用数字1到9
每个数字 最多使用一次
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
每个for循环也是从开始索引遍历剩下的数
class Solution {public:vector<vector<int>> combinationSum3(int k, int n) {vector<int>temp;dfs(n,k,1,temp);return ret;}void dfs(int target,int k,int startindex,vector<int>&temp){//找到目标值为target的 k个数//终止条件 1、当前为k个值了,并且目标值为0 即成功加入最后集合中//2、非正常结束 超过k个值了或者目标值小于0了,错误退出,直接returnif(temp.size() == k && target == 0){ret.emplace_back(temp);return;}//这里的等于是上面没有被挑选的else if(temp.size() >= k || target <= 0) return ;//正常逻辑,加入,执行dfs,取消加入 for(int i = startindex; i <= 9 || 10-i > k-temp.size() ; i++){temp.emplace_back(i);dfs(target-i,k,i+1,temp);temp.pop_back();}}
public:vector<vector<int>> ret;
};
17. 电话号码的字母组合
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
输入:digits = “23”
输出:[“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”]
如果用for循环怎么做
对于给的每个数进行循环
这里训练的是string的一些使用方法
39.组合总和
给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target 的不同组合数少于 150 个。
但还有种方法,要么加本元素,要么开始下一个元素(用这种方法)
class Solution {public:vector<vector<int>> combinationSum(vector<int>& candidates, int target) {vector<int>temp;dfs(candidates, target, 0, temp);return ret;}void dfs(vector<int>& candidates, int target, int startIndex, vector<int>&temp){//1、返回,target = 0if (target == 0){ret.emplace_back(temp);return;}else if (startIndex > candidates.size() - 1 || target < 0) return;//1、继续用当前值temp.emplace_back(candidates[startIndex]);dfs(candidates, target-candidates[startIndex], startIndex, temp);temp.pop_back();//2、用下一个值dfs(candidates, target, startIndex + 1, temp);}
public:vector<vector<int>> ret;
};
40. 组合总和 II
给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用 一次 。
注意:解集不能包含重复的组合。
加上如下重复的判断,会出错,因为是从左向右判断的(有的编译器可能是相反的),因此需要将i>0放大前面。
if (candidates[i] == candidates[i - 1] && i > 0)continue;
放到前面来
if (i > 0 &&candidates[i] == candidates[i - 1])continue;
但这样会出错,有的时候可能是重复的两个都加上,比如 1 1 5,这样加上判断后会省略当前的元素
如果加上used标记是否已经使用
或者不用used,直接用同一层的移动
二、切割问题
切割问题,切了以后两边就没有关系了
针对切割问题,可以通过for来的,就像下面图一样,第一层for循环,我可以选择在g切,也可以在goog处切,切了以后就没关系了,下次的递归是选择新的字符串的切割位置,也就是我切了以后,前边和后边就没有关系了,将前面加到容器里,这是产品。然后一直遍历,等到没地方切了,也就是切得位置到了最终位置,那么就是递归完成了,没有产品再往容器里放了
131. 分割回文串
给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。
回文串 是正着读和反着读都一样的字符串。
google的[[“g”,“o”,“o”,“g”,“l”,“e”],[“g”,“oo”,“g”,“l”,“e”],[“goog”,“l”,“e”]]
class Solution {public:vector<vector<string>> partition(string s) {//对于n判断后面的vector<string> cur;dfs(s, cur, 0);return ret;}//1、需要有个s,线回文串缓存,startIndexvoid dfs(const string& s, vector<string>&cur,int startIndex){if (startIndex > s.size()-1){ret.emplace_back(cur);return;}/** 1、对于每一个加入startindex,判断加上这个是否是回文,是回文则开辟分支,让其进行下一个for循环* 2、不是则绕过*/for (int i = startIndex; i < s.size(); i++)//在这层for循环里寻找一切可以切割的位置,然后切下去调用新的切割 {if (isHW(s, startIndex, i)){cur.emplace_back(s.substr(startIndex,i - startIndex + 1));dfs(s, cur, i+1);cur.pop_back();}}}bool isHW(const string &s,int Startindex,int Endindex){while (Startindex != Endindex && Startindex < Endindex){if (s[Startindex] != s[Endindex]){return false;}else {Startindex++;Endindex--;} }return true;}
public:vector<vector<string>> ret;};
93. 复原 IP 地址
终止条件为段数大于4,
三、子集问题
78. 子集
90. 子集 II
给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。
和上题一样,只不过要去除重复,本层不能有相同的,不同层的可以
491. 递增子序列
给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。
数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。
在每执行一次dfs时都加入ret里面
46.全排列
虽然这样看上去是层次一样的,但是用used的话,是每个分支弄完才会到另一个分支上,这个dfs是深度遍历的
47.全排列 II
同一层回溯,前面用了,后面就不能用
Backtracking algorithm梳理相关推荐
- 数据结构与算法(Python)– 回溯法(Backtracking algorithm)
数据结构与算法(Python)– 回溯法(Backtracking algorithm) 1.回溯法 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条 ...
- 回溯法(backtracking algorithm)求解N皇后问题(N-Queens puzzle)
转载自:用回溯法(backtracking algorithm)求解N皇后问题(N-Queens puzzle) N皇后问题 八皇后问题,是一个古老而著名的问题.该问题是国际西洋棋棋手马克斯·贝瑟尔于 ...
- 回溯算法(Backtracking Algorithm)之八皇后问题
文章目录 1. 回溯算法思想 2. 算法应用 2.1 八皇后问题 1. 回溯算法思想 前面讲过贪心算法并不能保证得到最优解,那怎么得到最优解呢? 回溯思想,有点类似枚举搜索.枚举所有的解,找到满足期望 ...
- Handbook of Constraints Programming——Chapter4 Backtracking Search Algorithms-Preliminaries
来源:F.Rossi, P.Van Beek, T. Walsh. Handbook of Constraints Programming. Elsevier, 2006. There are thr ...
- LeetCode 51. N-Queens--回溯法 pyhon,java,c++解法
题目地址: The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two q ...
- knight tour java_The Knight’s tour problem
Backtracking | Set 1 (The Knight's tour problem骑士周游算法 ) Backtracking is an algorithmic paradigm that ...
- 矢量切片_数据粒度均衡的二维矢量瓦片构建方法
作 者 信 息 应 申1,2,王子豪1,杜志强3,丁火平4, 李翔翔4 (1. 武汉大学 资源与环境科学学院,湖北 武汉 430079:2. 自然资源部城市国土资源监测与仿真重点实验室,广东 深圳 5 ...
- 回溯算法和贪心算法_回溯算法介绍
回溯算法和贪心算法 回溯算法 (Backtracking Algorithms) Backtracking is a general algorithm for finding all (or som ...
- 回溯算法和递归算法_回溯算法:递归和搜索示例说明
回溯算法和递归算法 Examples where backtracking can be used to solve puzzles or problems include: 回溯可用于解决难题或问题 ...
最新文章
- H264码流打包分析(精华)
- UA SIE545 优化理论基础3 Fritz-John与Kuhn-Tucker理论总结 带等式约束与不等式约束的极值问题
- 推荐:数据竞赛的利器XGBoost的常见面试题
- 框架会使程序员变笨吗?
- 使用CocoaPods做项目管理
- php-mysql rpm_Linux下的mysql apache php rpm安装方法步骤(转载并补充细节)
- java properties $,如何引用java.util.Properties中的另一个属性?
- 有人认为,“中文编程”是解决中国程序员效率的秘密武器,请问它是一个“银弹”么?...
- linux 下ifconfig修改IP
- java计算机毕业设计ssm宠物店管理系统element vue前后端分离
- 使用robo3t操作mongodb以及文档的插入、更新、删除以及查询操作
- 纸张的规格A3.A4.A5.A6纸的尺寸大小
- Source Insight 常用颜色代表种类
- 大数据解决方案:Hadoop监控
- java建立英文停用词表_pyhanlp 停用词与用户自定义词典
- Unity 大面积草风吹动效果+受人物影响
- 家居家装行业人群洞察白皮书.pdf
- Error mounting /dev/sda7 at 解决方法
- Thinking in Java:并发
- Ceph知识树和技能树