代码随想录 day24 第七章 回溯算法part01

今日内容:

●  理论基础

●  77. 组合

1. 理论基础

  • 回溯法也叫回溯搜索法
    • 是一种搜索方式
  • 递归的副产品,有递归就有回溯
  • 并不高效,本质就是暴力穷举。
  • 组合无序,排列有序
  • 回溯法解决的问题都可以额抽象为树形结构
    • N 叉树
  • 回溯法解决的都是在集合中递归查找子集
    • 集合的大小就构成了树的宽度,递归的深度,都构成的树的深度
  • 回溯法模板
    1. 回溯函数模板返回值以及参数

      1. 返回值一般为 void
      2. 参数
        1. 一般先写逻辑,根据逻辑中需要的来填写参数
    2. 回溯函数终止条件

      1. 从树的机构来看:
        1. 搜索到叶子节点,就保存这个答案,结束本层递归
    3. 回溯搜索的遍历过程

      1. for Loop 横向遍历

        1. 递归 纵向遍历
      2. 伪代码实现

        for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
            处理节点;
            backtracking(路径,选择列表); // 递归
            回溯,撤销处理结果
        }
        
    4. 回溯算法模板框架

      void backtracking(参数) {
          if (终止条件) {
              存放结果;
              return;
          }
      
          for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
              处理节点;
              backtracking(路径,选择列表); // 递归
              回溯,撤销处理结果
          }
      }
      

2. 组合

关联 leetcode 77. 组合

  • 思路
    • 如果无限的 for loop 嵌套,每 k+1, 就要手动多写一次 for loop
      • 不现实
    • 把组合抽象为树形结构
      • 输入参数是 n 【1~n】,天然有序
        • 可以逐步收缩集合的选择范围
      • n 是树的宽度,k是树的深度
      • 收集到叶子节点上,就是要找的一个结果
    • 回溯法三部曲
      • 递归函数的返回值以及参数
        • rets: 最终收集的全局结果集
        • ret:当前次回溯的单词结果集
        • startIdx:当前次开始往后走的起始位置
          • 每次往后递增1步,防止重复取到元素
      • 回溯函数终止条件
        • 走到叶子节点
        • 当前次回溯的单词结果集 == 题目要求的结果集大小【K】
      • 回溯搜索的遍历过程【单层搜索的过程】
        • for循环每次从startIndex开始遍历,然后用ret保存取到的节点i
          • 【Golang注意】:slice底层是数组指针,注意使用copy深拷贝
        • 递归结束后,及时弹出元素,避免重复计算

  • 题解
    • 回溯

      func combine(n int, k int) [][]int {
      	rets := make([][]int, 0)
      	ret := make([]int, 0, k)
      
      	var backtracing func(n int, k int, startIndex int)
      	backtracing = func(n int, k int, startIndex int) {
      		if len(ret) == k {
      			tmp:=make([]int,k)
      			copy(tmp,ret)
      			rets = append(rets, tmp)
      			return
      		}
      		for i := startIndex; i <= n; i++ { // 从start开始,不往回走,避免出现重复组合
      			ret = append(ret, i)
      			backtracing(n, k, i+1)
      			ret = ret[:len(ret)-1]
      		}
      	}
      	backtracing(n, k, 1)
      	return rets
      }
      
    • 剪枝优化

      • 只是对单层搜索逻辑做优化
      func combine(n int, k int) [][]int {
      	rets := make([][]int, 0)
      	ret := make([]int, 0, k)
      
      	var backtracing func(n int, k int, startIndex int)
      	backtracing = func(n int, k int, startIndex int) {
      		if len(ret) == k {
      			tmp := make([]int, k)
      			copy(tmp, ret)
      			rets = append(rets, tmp)
      			return
      		}
      		endIndex := n - (k - len(ret)) + 1 //剪枝, 至多从这里开始回溯
      		for i := startIndex; i <= endIndex; i++ {
      			ret = append(ret, i)
      			backtracing(n, k, i+1)
      			ret = ret[:len(ret)-1]
      		}
      	}
      	backtracing(n, k, 1)
      	return rets
      }
      

  • 24
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14天的训练营中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15天的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16天的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值