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

【面试高频算法解析】算法练习2 回溯(Backtracking)

前言

本专栏旨在通过分类学习算法,使您能够牢固掌握不同算法的理论要点。通过策略性地练习精选的经典题目,帮助您深度理解每种算法,避免出现刷了很多算法题,还是一知半解的状态


专栏导航

  1. 二分查找
  2. 回溯(Backtracking)
  3. 双指针
  4. 滑动窗口
  5. 深度优先搜索
  6. 广度优先搜索
  7. 贪心算法
  8. 单调队列
  9. 堆(Heap)

算法解析

回溯(Backtracking)是一种通过试错来解决问题的算法思想。当它通过尝试分步去解决一个问题时,如果发现现有的分步答案不能得到有效的正确的解答时,它将取消上一步甚至是上几步的计算,再通过其他的可能的分步解答再次尝试寻找问题的答案。

回溯法通常用递归方式来实现,在解决问题的过程中尝试各种可能的分步方法。如果某一步骤失败了,回溯算法会退回到上一步骤,然后尝试另一种方法。回溯法常用于解决如下问题:

  • 组合问题:求解一个问题的所有满足条件的组合方式。
  • 排列问题:求解一个问题的所有满足条件的排列方式。
  • 划分问题:求解将一个对象分成几部分的方法。
  • 子集构造问题:求解一个集合的所有子集。
  • 棋盘问题:如八皇后问题、解数独和跳马问题等。
  • 图的遍历问题:如哈密顿路径问题、图的着色问题等。

回溯算法的关键在于解决决策树的遍历过程中,如何剪枝。剪枝通过检测是否已经不可能得到正确的解来减少不必要的计算。在实现回溯算法时,通常有以下几个步骤:

  1. 选择:选择下一个可能的分步解答。
  2. 约束:检查到目前为止的解答序列是否满足约束条件(即是否“合法”)。
  3. 目标:检查到目前为止的解答序列是否满足解答条件(即是否已经找到一个解答)。

如果以上步骤中的任何一步不能继续下去,那么就执行回溯(返回上一步),尝试其他可能的路径。这种算法可以看作穷举搜索的一种优化,它利用问题的约束条件大大减少了搜索空间。

回溯算法和深度优先搜索(DFS)有密切的关系,实际上,回溯算法可以视为带有剪枝功能的深度优先搜索。在实现时,通常使用递归方法来模拟整个决策树的深度优先遍历过程,递归结构的本质上是栈结构,与DFS的实现方式一致。


实战练习

组合总和

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

示例 1:
输入:candidates = [2,3,6,7], target = 7
输出:[[2,2,3],[7]]

解释:
2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
7 也是一个候选, 7 = 7 。
仅有这两种组合。

示例 2:
输入: candidates = [2,3,5], target = 8
输出: [[2,2,2,2],[2,3,3],[3,5]]

示例 3:
输入: candidates = [2], target = 1
输出: []

提示:
1 <= candidates.length <= 30
2 <= candidates[i] <= 40
candidates 的所有元素 互不相同
1 <= target <= 40

官方题解


全排列II

给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

示例 1:
输入:nums = [1,1,2]
输出:
[[1,1,2],
[1,2,1],
[2,1,1]]

示例 2:
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

提示:
1 <= nums.length <= 8
-10 <= nums[i] <= 10

官方题解


单词搜索

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例 1:
请添加图片描述

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
输出:true

示例 2:
请添加图片描述

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “SEE”
输出:true

示例 3:
请添加图片描述

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCB”
输出:false

提示:
m == board.length
n = board[i].length
1 <= m, n <= 6
1 <= word.length <= 15
board 和 word 仅由大小写英文字母组成

进阶: 你可以使用搜索剪枝的技术来优化解决方案,使其在 board 更大的情况下可以更快解决问题?

官方题解

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

相关文章:

  • 认识Git
  • @RequestParam,@RequestBody和@PathVariable 区别
  • vue3组件传参
  • React16源码: React中创建更新的方式及ReactDOM.render的源码实现
  • CentOS 7 系列默认的网卡接口名称
  • 多文件上传
  • 2024.1.7力扣每日一题——赎金信
  • C#中List<T>底层原理剖析
  • Leetcode 3003. Maximize the Number of Partitions After Operations
  • MySQL第一讲:MySQL知识体系详解(P6精通)
  • 逻辑回归简单案例分析--鸢尾花数据集
  • Python print 高阶玩法
  • Wpf 使用 Prism 实战开发Day09
  • 网络端口(包括TCP端口和UDP端口)的作用、定义、分类,以及在视频监控和流媒体通信中的定义
  • flink如何写入es
  • Java、Python、C++和C#的界面开发框架和工具的重新介绍
  • Java二叉树的遍历以及最大深度问题
  • Apollo 9.0搭建问题记录
  • 【心得】PHP文件包含高级利用攻击面个人笔记
  • [scala] 列表常见用法
  • python 使用urllib3发起post请求,携带json参数
  • 深入理解堆(Heap):一个强大的数据结构
  • 抖音在线查权重系统源码,附带查询接口
  • Spring Framework和SpringBoot的区别
  • 2024--Django平台开发-Django知识点(三)
  • Github 2024-01-08开源项目周报 Top14
  • vue3 的内置组件汇总
  • ARM工控机Node-red使用教程
  • Visual Studio 发布程序自动更新 ClickOnce和AutoUpdater测试
  • Codeforces Round 761 (Div. 2) E. Christmas Chocolates(思维题 树的直径 二进制性质 lca)