首先回溯法是深度搜索(DFS)的一种,即把所有可能穷举,根据条件筛选出符合条件的路径。
回溯法模板格式

dfs(...){//根据递归终止条件进行筛选
if(符合需要的条件){存储合理路径
return ...;
}
//对可能路径进行遍历
for(int i=起始条件;i<极限边界;i++){向路径便令中添加元素
//进行下一轮搜索
def(...);
//深度优化的回头
...removeLast();
}
return ...;
}

下面举一个leetCode上的题目:
给出正整数n,k,求出1,2,3,4…n;求出所有含k个数字且无重复的全部结果。(题目大致是这样的)
用回溯法的解决如下:

public class Backtrack {private static Backtrack test;public static void main(String[] args) {int k = 3;int n = 5;shen = new Backtrack2();test.cobine(n, k);}public List<List<Integer>> cobine(int n, int k) {List<List<Integer>> res = new ArrayList<>();if (k <= 0 || n < k) {return res;}
//        创建一个list记录搜索路径List<Integer> path = new ArrayList<>();dfs(n, k, 1, path, res);return res;}public List<List<Integer>> dfs(int n, int k, int start, List<Integer> path, List<List<Integer>> res) {//        递归终止条件是:path的长度为k
//        System.out.println(path);思路不清晰的话可以打印出每条路径path看下过程对理解很有帮助if (path.size() == k) {res.add(new ArrayList<Integer>(path));return res;}
//        遍历可能的搜索起点for (int i = start; i <= n; i++) {//            向路径变量中添加一个数字path.add(i);
//            下一轮搜索,设置的搜索起点要加1,因为组合数里不允许出现重复的元素dfs(n, k, i + 1, path, res);
//            重点理解这里,深度优化遍历有回头的过程,因此递归之前做了什么,递归之后就要做相同的逆操作path.remove(path.size() - 1);}return res;}
}

上面的题目是要求不能有重复元素的,下面给出一道可以有重复题目:
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的数字可以无限制重复被选取
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
一个简单的java解题代码如下:
这里假设target=7,candidate={2,3,6,7}

public class CombinationSum {public static void main(String[] args) {int target = 7;int[] candidates = {2, 3, 6, 7};CombinationSum shen = new CombinationSum();System.out.println("结果是:" + shen.combinationSum(candidates, target).toString());}public List<List<Integer>> combinationSum(int[] candidates, int target) {//        判断cambinationSum是否为空,若是空值接返回不需要往下算了List<List<Integer>> res = new ArrayList<>();if (candidates == null || candidates.length == 0) {return null;}
//        创建路径记录变量List<Integer> path = new ArrayList<>();dfs(0,path,candidates,target,res);return res;}public void dfs(int start, List<Integer> path,  int[] candidates, int target,List<List<Integer>> res) {//        根据终止条件这里先求出每个路径的和再来判断,容易理解,但是代码会比较臃肿int sum = 0;for (int i = 0; i < path.size(); i++) {sum += path.get(i);}System.out.println(path);//思路不清晰的话可以打印出每条路径path看下过程对理解很有帮助
//        下面的这两个if的判断条件非常重要,DFS里面需要思考的就是这个判断条件部分,其他部分的格式几乎是一样的if (sum > target) {return ;}if (sum == target) {res.add(new ArrayList<Integer>(path));return ;}
//       遍历可能的搜索起点for (int i = start; i < candidates.length; i++) {//            想路径变量中添加元素path.add(candidates[i]);
//            这里需要注意一下第一个值:i, 元素可以重复的话搜索起点为:i;元素不可重复的话搜索起点为:i+1dfs( i, path, candidates, target, res);
//            深度优化搜索的回头过程,这里使用的是List作为搜索路径path,也可以使用其他容器path.remove(path.size()-1 );}}
}

上面两种做法只是完成了最基本的功能并没有进行优化,比较适合像我一样刚接触回溯和dfsd的小白,在这基础上可以进行剪枝,减去不合理路径,使得运算效率更快,下面是对借鉴的另一种解法:

public class Solution {public List<List<Integer>> combinationSum(int[] candidates, int target) {int len = candidates.length;List<List<Integer>> res = new ArrayList<>();if (len == 0) {return res;}Deque<Integer> path = new ArrayDeque<>();dfs(candidates, 0, len, target, path, res);return res;}/*** @param candidates 候选数组* @param begin      搜索起点* @param len        冗余变量,是 candidates 里的属性,可以不传* @param target     每减去一个元素,目标值变小* @param path       从根结点到叶子结点的路径,是一个栈* @param res        结果集列表*/private void dfs(int[] candidates, int begin, int len, int target, Deque<Integer> path, List<List<Integer>> res) {// target 为负数和 0 的时候不再产生新的孩子结点if (target < 0) {return;}if (target == 0) {res.add(new ArrayList<>(path));return;}// 重点理解这里从 begin 开始搜索的语意for (int i = begin; i < len; i++) {path.addLast(candidates[i]);// 注意:由于每一个元素可以重复使用,下一轮搜索的起点依然是 i,这里非常容易弄错dfs(candidates, i, len, target - candidates[i], path, res);// 状态重置path.removeLast();}}
}

这是leetCode比较经典的解法,使用了剪枝,也用了Deque容器,进入链接看具体的讲解:
链接:https://leetcode-cn.com/problems/combination-sum/solution/hui-su-suan-fa-jian-zhi-python-dai-ma-java-dai-m-2/

DFS中的回溯法(纯暴力穷举)相关推荐

  1. C++ 求最大公约数 更相减损法 欧几里得算法 暴力穷举法

    两个数的最大公约数是指能同时被他们整除的最大正整数. 两个数的最大公约数等于它们中 较小的数 和 两数之差 的最大公约数. 252和105的最大公约数是21(252 = 21 × 12:105 = 2 ...

  2. java中穷举法排序_java穷举法小案例

    最近几天伤病没有更新  今天好点 看了一下基础的算法  现在简单更新一下 --穷举法 一.甲 .乙.丙 三位球迷分别预测进入半决赛的四队A.B.C.D的名次如下: 甲:A 第一名 .B 第二名 乙:C ...

  3. c语言变量相等问题穷举法,C语言穷举法经典例题.ppt

    <C语言穷举法经典例题.ppt>由会员分享,可在线阅读,更多相关<C语言穷举法经典例题.ppt(18页珍藏版)>请在人人文库网上搜索. 1.枚举法(穷举法),"笨人之 ...

  4. 百鸡问题用计算机什么法解决,《穷举法解决问题》教学设计

    一.教学目标 1.知识与技能 ⑴了解穷举法的基本概念及用穷举法设计算法的基本过程. ⑵分析建立正确的数学模型,归纳穷举法穷举技巧. ⑶能够根据具体问题的要求,使用穷举法设计算法,编写程序求解问题. 2 ...

  5. python穷举法列举_穷举法应用举例.doc

    无 止 境 穷举法应用举例 在数学问题中, 有一些需要计算总数或种类的趣题, 因其数量关系比较隐蔽, 很难找到"正统"的方式解答,让人感到无从下手.对此,我们可以先初步估计 其数目 ...

  6. 通过selenium,暴力穷举身份证号登陆某网站

    偶然发现小学女神在某大学读研,想联系一波.十多年没有联系,怎么办?发现研究生录取查询只用身份证号+姓名+验证码,身份证号学校在某些文件公布了14位,剩下四位要穷举,身份证最后一位校验位,倒数第二位性别 ...

  7. dfs中return回溯问题

    题目: 从1到n中选k个数进行排列 首先我们看这段代码: #include <iostream> using namespace std; int n, k; const int N = ...

  8. 部分和(dfs深搜回溯法)

    问题描述 给定整数序列a1,a2,.,an,判断是否可以从中选出若干数,使它们的和恰好为k, 1<=n<=20 -10^8<=ai<=10^8 -10^8<=k<= ...

  9. 【LeetCode 剑指offer刷题】回溯法与暴力枚举法题6:Number of Islands

    [LeetCode & 剑指offer 刷题笔记]目录(持续更新中...) Number of Islands Given a 2d grid map of '1's (land) and ' ...

最新文章

  1. MySQL 5.5 的COMPRESSED INNODB 表
  2. 设计模式 -(5)装饰模式(结构型)
  3. NYOJ 737---石子归并(GarsiaWachs算法)
  4. mysql下载备份数据库命令行,如何从MariaDB数据库备份和还原命令行
  5. VC6启用运行时类型识别 (RTTI)
  6. 数据结构 练习21-trie的原理分析和应用
  7. 继承AppCompatActivity的Activity无法隐藏标题栏
  8. 瑞友客户端无法建立跟远程计算机的连接,瑞友天翼终端错误信息的原因以及解决方法大全.doc...
  9. IDEA系列(六)一This file is indented with tabs instead of 4 space
  10. Spring Boot 概述、初始化器、spring-boot-maven-plugin 插件简化部署、starter 自动配置原理
  11. SpringMVC学习指南【笔记4】数据绑定、表单标签库、转换器、格式化、验证器
  12. 华为服务器怎么装win7系统教程视频教程,华为交换机配置教程|华为交换机配置视频教程完整版...
  13. jQuery 文档碎片处理
  14. PCB屏蔽罩图纸制作
  15. PMBOK 项目管理 九大知识领域和五大流程
  16. 微信小程序自定义函数返回值
  17. 网易七鱼客服 发起客服-触发两条会话
  18. damon ps2 android,DamonPS2模拟器
  19. HTML 樱花飘落界面效果
  20. excel一个表格分成多个的简单方法

热门文章

  1. 速轩三维 - 白光/蓝光/拍照式三维扫描仪
  2. 如何安装tree命令
  3. 软件测试 | 测试开发 | 探究 PHP_CodeSniffer 的代码静态分析原理
  4. php 在线选座,基于jquery实现在线选座订座之影院篇
  5. 2017最新整理python全栈工程师系统培训之路精品课程(全套)
  6. python_4.loc()和iloc()函数
  7. 从键盘输入整数n,输出n以内所有质数。
  8. 如何反编译pyc文件查看源代码
  9. java创建画板_Java版画板的实现方法
  10. easyui部分组件使用经验