当前位置: 首页 > news >正文

回溯算法章末总结

在这里插入图片描述

  1. 组合问题的特点
    (1)ab=ba 选中a之后,就不再选了
    (2)找出所有的组合 (长度可以不相等)

  2. 组合问题模板
    在这里插入图片描述

  3. 做回溯题步骤
    在这里插入图片描述

    (0)判断问题类型
    (1)树状图
    (2)递归三部曲
    (3)剪枝条件

  4. 组合问题中的纵横剪枝 ----> 216.组合总和III
    ==有图==

  5. 去重
    (1)横向去重
    在这里插入图片描述
    (2)set横向去重

在这里插入图片描述

代码

 public void findSubsequencesBT(int[] nums,int startIndex) {HashSet<Integer> set = new HashSet<>();for (int i = startIndex; i < nums.length; i++) {// 剪枝if (findSubsequencesPath.size()>0&&findSubsequencesPath.get(findSubsequencesPath.size()-1)[0]>nums[i]){continue;}// 此处不能是==,只能是>= 为空时也要判断去重if ((findSubsequencesPath.size()==0||findSubsequencesPath.size()>0&&findSubsequencesPath.get(findSubsequencesPath.size()-1)[0]<=nums[i])&&set.contains(nums[i])){continue;}//三件套//using[i]=true;findSubsequencesPath.add(new int[]{nums[i],i});set.add(nums[i]);if (findSubsequencesPath.size()>=2){ArrayList<Integer> temp = new ArrayList<>();for (int j = 0; j <findSubsequencesPath.size() ; j++) {temp.add(findSubsequencesPath.get(j)[0]);}ires.add(temp);}findSubsequencesBT(nums,i+1);findSubsequencesPath.remove(findSubsequencesPath.size()-1);// set 不用回溯,每层一个// using[i]=false;}}

关键
在这里插入图片描述

  1. 分割递归终止条件
    分割常用的递归出口
    (1)startIndex==数组长度
    缺点: 如果是分割有段数要求,例如ip,可能分割很多段后才到递归出口,1.1.1.1.1.1.1 再判断,白白浪费性能。
    改进:当已经分割三段时,第四段直接判断,这样可以剪掉部分,但是最后还是会一个一个试
   public void restoreIpAddressesBT(String s,int startIndex) {if (startIndex==s.length()){if (restoreIpAddressesPath.size()==4){StringBuilder sb = new StringBuilder();for (String s1 : restoreIpAddressesPath) {sb.append(s1+".");}sb.delete(sb.length()-1,sb.length());slist.add(sb.toString());}return;}for (int i = startIndex; i <s.length() ; i++) {String substring = s.substring(startIndex, i + 1);// 剪枝// 如果已经有3个了,直接看剩下的能不能凑成第四个就行if (restoreIpAddressesPath.size()==3&&valIsValid(s.substring(startIndex))==-1){return;  // 本层全不能用}if (valIsValid(substring)==-1){continue;}restoreIpAddressesPath.add(substring);restoreIpAddressesBT(s,i+1);restoreIpAddressesPath.remove(restoreIpAddressesPath.size()-1);}}

(2)如果有段数要求,直接用段数作为剪枝条件

  if (restoreIpAddressesPath.size()==4){if (startIndex==s.length()){StringBuilder sb = new StringBuilder();for (String s1 : restoreIpAddressesPath) {sb.append(s1+".");}sb.delete(sb.length()-1,sb.length());slist.add(sb.toString());}return;}

在这里插入图片描述
这样只要到段数,就会判断,不会再 1.1.1.1.1.1.1这样分

题型

组合问题

每条从根出发的子路径是一个结果

  1. 传统组合问题 每一条子路径都是一种组合 —>● 77. 组合● 216.组合总和III
  2. 从筐中取球类型–>● 17.电话号码的字母组合
  3. 组合,元素不重,元素可重复取 39. 组合总和
  4. 组合,元素重复,结果不重,横向去重–> 40.组合总和II

子集问题

  1. 组合问题之子集问题,找到所有从根节点出发的子路径,包含【】
    ---->78.子集
  2. 组合问题之递增序列,本质是子集问题,使用set去重,注意第一层时path可能为空 491.递增子序列

分割

每条路径是一个结果
5. 标准分割 --> 131.分割回文串 ● 93.复原IP地址

排列

  1. 排列,借助used数组 46.全排列 47.全排列 II

递归树

  1. 传统组合
    在这里插入图片描述

  2. 筐中取球
    在这里插入图片描述

  3. 组合,每个元素可重复
    在这里插入图片描述

  4. 组合,元素重复,结果不重,横向去重
    在这里插入图片描述

  5. 标准分割
    在这里插入图片描述
    (2)分割模板

// 131.分割回文串 public void partitionBT(String s,int startIndex) {if (startIndex==s.length()){sres.add(new ArrayList<>(spath));return;}// 引擎for (int i = startIndex; i <s.length() ; i++) {// 剪枝if (!isPalindrome(s,i,startIndex)){return;}spath.add(s.substring(i, startIndex + 1));partitionBT(s,i+1);spath.remove(spath.size()-1);// 本层下一个}}

(3)不同之处
在这里插入图片描述
6. 子集问题
78.子集
(2)子集问题模板

 // 78. 子集public void subsetsBT(int[] nums,int startIndex) {// 找所有从根节点的子路径,为处理空置,先加入ires.add(new ArrayList<>(ipath));// 递归终止条件  直接使用循环终止// 循环引擎for (; startIndex <nums.length ; startIndex++) {// 剪枝 无//三件套ipath.add(nums[startIndex]);subsetsBT(nums,startIndex+1);ipath.remove(ipath.size()-1); //  删除的是startIndex}}

(3)不同之处
在这里插入图片描述
7. 递增序列问题

在这里插入图片描述

代码

 public void findSubsequencesBT(int[] nums,int startIndex) {HashSet<Integer> set = new HashSet<>();for (int i = startIndex; i < nums.length; i++) {// 剪枝if (findSubsequencesPath.size()>0&&findSubsequencesPath.get(findSubsequencesPath.size()-1)[0]>nums[i]){continue;}// 此处不能是==,只能是>= 为空时也要判断去重if ((findSubsequencesPath.size()==0||findSubsequencesPath.size()>0&&findSubsequencesPath.get(findSubsequencesPath.size()-1)[0]<=nums[i])&&set.contains(nums[i])){continue;}//三件套//using[i]=true;findSubsequencesPath.add(new int[]{nums[i],i});set.add(nums[i]);if (findSubsequencesPath.size()>=2){ArrayList<Integer> temp = new ArrayList<>();for (int j = 0; j <findSubsequencesPath.size() ; j++) {temp.add(findSubsequencesPath.get(j)[0]);}ires.add(temp);}findSubsequencesBT(nums,i+1);findSubsequencesPath.remove(findSubsequencesPath.size()-1);// set 不用回溯,每层一个// using[i]=false;}}

关键
在这里插入图片描述
8. 排列

    public void permuteBT(int[] nums,boolean[] used) {if (ipath.size()==nums.length){ires.add(new ArrayList<>(ipath));return;}for (int i = 0; i <nums.length ; i++) {if (used[i]==true){continue;}// 剪枝// 三件套used[i]=true;ipath.add(nums[i]);permuteBT(nums,used);ipath.remove(ipath.size()-1);used[i]=false;}}

在这里插入图片描述

http://www.lryc.cn/news/7999.html

相关文章:

  • 【SpringBoot】为异步任务规划线程池
  • SAP ABAP 输出结果带有空格
  • Opengl ES之踩坑记
  • 设计模式第六讲:责任链模式和迭代器模式详解
  • K8s 架构简介(一)
  • xshell6运行报错:由于找不到mfc110u.dll、MSVCR110.dll无法继续执行代码
  • Baklib知识库管理平台,协助组织提升知识管理水平
  • 一文搞懂core-scheduling核心机制
  • IP地址在金融行业有哪些应用?
  • GT-suite v2016解决许可证过期问题(附新版liscense下载地址)
  • 小红书商业笔记与普通笔记区别是什么?小红书笔记有哪几种
  • DataWhale-统计学习方法打卡Task01
  • Java面试——Spring 事务
  • Python语言零基础入门教程(十九)
  • 重生之我是赏金猎人-SRC漏洞挖掘(一)-某SRC测试系统无脑Getshell
  • Sciter 结合 PReact 实现组件公共逻辑抽离
  • OpenTracing协议规范链接
  • 金三银四面试必看,自动化测试如何解决日志问题
  • 微信怎么开小店?【企业商家微信开店】
  • Java 中FastJson的使用【吃透FastJson】
  • Redis5.0集群搭建
  • 继企业级信息系统开发学习1.1 —— Spring配置文件管理Bean
  • Web 容器、HTTP 服务器 、Servlet 容器区别与联系
  • eBPF 进阶: 内核新特性进展一览
  • 2.输入子系统学习-multi-touch-protocol-2023.02
  • 【靶机】vulnhub靶机pylington
  • 【大数据】大数据学习路线
  • 【Python爬虫案例教学】采集某网站壁纸,实现壁纸自由
  • 波卡2022年第四季度报告
  • 第一章:初始化react项目+antd+less