回溯法

回溯法常见题目总结

风流意气都作罢 提交于 2019-11-27 13:44:15
1.电话号码的字母组合 题目描述: 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 示例: 输入:"23" 输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. 说明: 尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。 实现代码: class Solution { public: vector<string> letterCombinations(string digits) { if(digits == ""){ return res; } letter(digits,0,""); return res; } private: string lett[10] = { " ", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; vector<string>res; void letter(string digits,int index,string s){ if(index == digits.size()){ res.push_back(s); return; } char c = digits[index]; string

Java算法——回溯法

那年仲夏 提交于 2019-11-27 08:13:38
回溯法 一种选优搜索法,又称试探法。利用试探性的方法,在包含问题所有解的解空间树中,将可能的结果搜索一遍,从而获得满足条件的解。搜索过程采用深度遍历策略,并随时判定结点是否满足条件要求,满足要求就继续向下搜索,若不满足要求则回溯到上一层,这种解决问题的方法称为回溯法。 回溯法解求解问题步骤 针对给定问题,定义问题的解空间树; 确定易于搜索的解空间结构; 以深度优先方式搜索解空间,并且在搜索过程中用剪枝函数避免无效搜索; 用回溯法求解问题,重点是设计问题的解空间树,其解题过程则是深度遍历解空间树的过程。 解空间树 是依据待求解问题的特性,用树结构表示问题的解结构、用叶子表示问题所有可能的解的一棵树。 解空间树的形成过程 我们可以把求解问题的过程当作一系列的决定来考虑,回溯法对每一个决定都系统地分析所有可能的结果。而每一次决定即为解空间树中的一个分支结点,各种可能的结果便形成了各棵不同的子树,问题最终所有可能的解将展现在所有的叶子上。这便是解空间树的形成过程。 对解空间树的遍历可搜索到问题所有可能的解,因此,可获得满足要求的全部解,也可通过对所有解的比较选择获得最优解。 由于空间问题,下面给出一个三皇后问题的解空间树(3皇后问题无解),树中第i层的结点决定第i行皇后的摆放位置,均有三种不同的选择,便形成了三个孩子结点,但其中不包括不符合要求的布局

回溯法-变态跳台阶

这一生的挚爱 提交于 2019-11-27 07:23:02
牛客网-变态跳台阶 内容描述 题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。 解题思路 尝试使用回溯法进行解决问题,遍历全部方法,从而找到跳法(本题目有更简单的方法,见后面) 回溯法模板 try(int i) { if(i>n) 输出结果; else { for(j = 下界; j <= 上界; j=j+1) // 枚举i所有可能的路径 { if(fun(j)) // 满足限界函数和约束条件 { a[i] = j; ... // 其他操作 try(i+1); 回溯前的清理工作(如a[i]置空值等); } } } 实现代码 public class Solution { public int JumpFloorII(int target) { int count=0; int sum=0; count=digui(target,sum,count); return count; } public int digui(int target,int sum,int count) { if (target==sum){ count++; return count; } else { for(int i=target-sum;i>0;i--){ if (sum+i<=target){ sum=sum+i; count

算法设计

不羁的心 提交于 2019-11-27 03:55:47
一、分治法 递归,找最大值最小值,整数相乘,归并排序,快速排序,线性时间选择,最近点对问题 二、动态规划   0-1背包问题 ,矩阵相乘问题,装配线调度问题,最长公共子序列,最优二分检索树,凸多边形最优三角剖分 三、贪心法   背包问题,活动选择问题,哈夫曼编码,最小生成树算法(Kruskal 和 Prim) 四、回溯法   n皇后问题,子集和数问题,0-1背包问题,旅行商问题,着色问题 五、图算法   图的表示,广度优先搜索,Dijkstra算法 来源: https://www.cnblogs.com/eaglezb/p/11343106.html

回溯法之地图着色

≡放荡痞女 提交于 2019-11-26 20:19:09
//program 5-3 #include <iostream> #include <string.h> #define MX 50 using namespace std; int x[MX]; //解分量 int map[MX][MX]; //图的邻接矩阵 int sum=0; //记录解的个数 int n,m,edge; //节点数和颜色数 //创建邻接矩阵 void CreatMap() { int u,v; cout << "请输入边数:"; cin >> edge; memset(map,0,sizeof(map));//邻接矩阵里面的数据初始化为0,meset需要引入#include <string.h> cout << "请依次输入有边相连的两个结点u和v,用空格分开:"; for(int i=1;i<=edge;i++) { cin>>u>>v; map[u][v]=map[v][u]=1; } } //约束条件 bool OK(int t) { for(int j=1;j<t;j++) { if(map[t][j]) //如果t与j邻接 { if(x[j]==x[t]) //判断t与j的着色号是否相同 return false; } } return true; } //搜索函数 void Backtrack(int t) { if(t>n) //到达叶子

Leetcode之回溯法专题-90. 子集 II(Subsets II)

∥☆過路亽.° 提交于 2019-11-26 18:16:54
Leetcode之回溯法专题-90. 子集 II(Subsets II) 给定一个可能包含重复元素的整数数组 nums ,返回该数组所有可能的子集(幂集)。 说明:解集不能包含重复的子集。 示例: 输入: [1,2,2] 输出: [ [2], [1], [1,2,2], [2,2], [1,2], [] ] 分析:是78题的升级版,新增了一些限制条件,nums数组是会重复的,求子集。 class Solution { List<List<Integer>> ans = new ArrayList<>(); public List<List<Integer>> subsetsWithDup(int[] nums) { if(nums.length==0) return ans; dfs(nums,0,new ArrayList<Integer>()); return ans; } public void dfs(int[] nums,int step,ArrayList<Integer> list){ if(step>=nums.length){ List<Integer> tmp = new ArrayList<>(list); Collections.sort(tmp); if(!ans.contains(tmp)){ ans.add(new ArrayList<>(tmp));

Leetcode之回溯法专题-52. N皇后 II(N-Queens II)

微笑、不失礼 提交于 2019-11-26 15:04:18
Leetcode之回溯法专题-52. N皇后 II(N-Queens II) 与51题的代码80%一样,只不过52要求解的数量,51求具体解, 点击进入51 class Solution { int ans = 0; public int totalNQueens(int n) { char mp[][] = new char[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { mp[i][j] = '.'; } } dfs(mp, n, 0, 0); return ans; } public void dfs(char[][] mp, int len, int i, int queen) { int x = i / len; int y = i % len; if ((x >= len || y >= len)) { if (queen != len) return; ans++; return; } dfs(mp, len, i + 1, queen); if (ok(mp, len, x, y)) { mp[x][y] = 'Q'; dfs(mp, len, i + 1, queen + 1); mp[x][y] = '.'; } } public boolean ok(char[][] mp,

回溯法之八皇后问题

*爱你&永不变心* 提交于 2019-11-25 22:09:20
//program 5-4 #include <iostream> #include<cmath> //求绝对值函数需要引入该头文件 #define M 105 using namespace std; int n;//n表示n个皇后 int x[M]; //x[i]表示第i个皇后放置在第i行第x[i]列 long long countn; //countn表示n皇后问题可行解的个数 bool Place(int t) //判断第t个皇后能否放置在第i个位置 { bool ok=true; for(int j=1;j<t;j++) //判断该位置的皇后是否与前面t-1个已经放置的皇后冲突 { if(x[t]==x[j]||t-j==fabs(x[t]-x[j]))//判断列、对角线是否冲突 { ok=false; break; } } return ok; } void Backtrack(int t) { if(t>n) //如果当前位置为n,则表示已经找到了问题的一个解 { countn++; // for(int i=1; i<=n;i++) //打印选择的路径 // cout<<x[i]<<" "; // cout<<endl; // cout<<"----------"<<endl; } else for(int i=1;i<=n;i++) //分别判断n个分支