【LeetCode】一文吃透回溯算法(附例题)

news2024/11/14 22:52:08

回溯 DFS 算法深入浅出,一文吃透!

原文同步在:https://github.com/EricPengShuai/Interview/blob/main/algorithm/回溯算法.md

回溯算法

主要参考的是 liweiwei 的总结

0. 概念

回溯法 采用试错的思想,它尝试分步的去解决一个问题。在分步解决问题的过程中,当它通过尝试发现现有的分步答案不能得到有效的正确的解答的时候,它将取消上一步甚至是上几步的计算,再通过其它的可能的分步解答再次尝试寻找问题的答案。回溯法通常用最简单的 递归 方法来实现,在反复重复上述的步骤后可能出现两种情况:

  • 找到一个可能存在的正确的答案
  • 在尝试了所有可能的分步方法后宣告该问题没有答案

深度优先搜索 算法(Depth-First-Search,DFS)是一种用于 遍历或搜索树或图 的算法。这个算法会 尽可能深 的搜索树的分支。当结点 v 的所在边都己被探寻过,搜索将 回溯 到发现结点 v 的那条边的起始结点。这一过程一直进行到已发现从源结点可达的所有结点为止。如果还存在未被发现的结点,则选择其中一个作为源结点并重复以上过程,整个进程反复进行直到所有结点都被访问为止。

典型的 DFS 但是没有回溯的题目:17. 电话号码的字母组合

简单比较

「回溯算法」与「深度优先遍历」都有**「不撞南墙不回头」**的意思。「回溯算法」强调了「深度优先遍历」思想的用途,用一个 不断变化 的变量,在尝试各种可能的过程中,搜索需要的结果。

  • 回溯强调了 回退 操作对于搜索的合理性
  • DFS 强调一种 遍历 的思想,与之对应的遍历思想是 BFS

1. 例题(46.全排列)

题目

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案

题解

这是一到回溯算法的入门题,很好的说明了回溯算法在选择回退时的用法,几个比较重要的点是:

  1. 递归的重点条件是排列中数字已经选满,可以使用 depth 表示递归深度 或者 index 表示数组下标
  2. 需要使用 used 来标记使用过那些变量
class Solution {
    vector<vector<int>> res;

public:
    vector<vector<int>> permute(vector<int>& nums) {
        vector<int> path;
        vector<int> used(nums.size(), 0);

        backtrace(path, used, nums, 0, nums.size());
        return res;
    }

    void backtrace(vector<int>& path, vector<int>& used, vector<int>& nums, int dep, int n) {
        if (dep == n) {
            res.push_back(path);
            return;
        }

        for (int i = 0; i < n; ++ i) {
            if (used[i]) continue;

            path.push_back(nums[i]);
            used[i] = 1;

            backtrace(path, used, nums, dep+1, n);

            used[i] = 0;    // 回溯
            path.pop_back();
        }

    }
};

另外在 C++ 里,最好还是不要写vector<bool>,因为vector<bool>返回的是一个std::vector<bool>::reference的对象,数据量大时比vector<int>要慢,参考

思考

有重复元素的全排列(LC.47)

  • 排序之后再根据 nums[i-1]==nums[i] 判重
  • 在上一个相同的元素撤销之后去重效率更高

组合问题的排列(LC.39)

  • 排列问题:讲究顺序,例如 [LC46.全排列](即 [2, 2, 3] 与 [2, 3, 2] 视为不同列表时),需要记录哪些数字已经使用过,此时用 used 数组
  • 组合问题:不讲究顺序(即 [2, 2, 3] 与 [2, 3, 2] 视为相同列表时),需要按照某种顺序搜索,此时使用 begin 变量

有一个小经验就是 used 数组begin 变量 一般不用一起使用

2. 相关问题

排列型回溯

题目说明题解
46. 全排列回溯入门问题,无重复元素的排列问题通过
47. 全排列 II去重是关键,排序比较,上一个相同的元素撤销之后再剪枝剪枝图

组合型回溯

题目说明题解
39. 组合总和组合问题需要按照某种顺序搜索:每一次搜索的时候设置 下一轮搜索的起点 begin,也可以排序之后加速剪枝通过
40. 组合总和 II和 LC.39 区别是这个有重复元素,需要去掉当前层第二个数值重复的节点 🔥剪枝
216. 组合总和 III和 LC.40 类似,这题没有重复元素,两个剪枝:小于最小的 || 大于最大的 🔥0x3F
77. 组合和 LC.39 类似,按照 begin 为起点遍历然后回溯就可以,注意不能重复通过

子集型回溯

题目说明题解
78. 子集和 LC.39 类似,按照 begin 为起点遍历回溯就可以通过
90. 子集 II在 LC.78 的基础上有重复元素的考虑,和 LC.40 类似的剪枝 🔥通过
131. 分割回文串枚举字符之间的逗号,按照 idx 顺序回溯,判断回文通过
698. 划分为k个相等的子集抽象成 k 个桶,每个桶的容量为子集和大小通过
473. 火柴拼正方形和 LC.698 一模一样,抽象成 4 个桶通过
2305. 公平分发饼干k 个桶,但是桶大小未知,从大到小DFS回溯通过
854. 相似度为 K 的字符串DFS 回溯,剪枝,有点难…通过

3. 参考

  • 回溯算法入门级详解 + 练习(持续更新)
  • 回溯算法套路①子集型回溯【基础算法精讲 14】
  • 经典回溯算法:集合划分问题「重要更新 🔥🔥🔥」

最后附一份我整理的 CPP 面试相关知识点

https://github.com/EricPengShuai/Interview

logo
如果觉得不错的话可以 ⭐️ 一下

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/175864.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MATLAB | 如何使用MATLAB绘制韦恩图的高阶版本:upset图

韦恩图随着阶数升高会越来越复杂&#xff0c;当阶数达到7或者以上时几乎没办法绘制&#xff1a; 但是使用upset图却可以比较轻易的绘制&#xff1a; 两种类型图的对应关系&#xff1a; 这期便教大家如何绘制这样的upset图&#xff1a; 教程部分 0 数据准备 数据需要的是0,1矩…

SQL注入现象

package com.bjpowernode.jdbc;import java.sql.*; import java.util.HashMap; import java.util.Map; import java.util.ResourceBundle; import java.util.Scanner; /*** 如果输入的用户名和密码是下面这样的&#xff0c;就会发生非注册人员登录的情况&#xff0c;叫做SQL注入…

【Java|golang】2287. 重排字符形成目标字符串

给你两个下标从 0 开始的字符串 s 和 target 。你可以从 s 取出一些字符并将其重排&#xff0c;得到若干新的字符串。 从 s 中取出字符并重新排列&#xff0c;返回可以形成 target 的 最大 副本数。 示例 1&#xff1a; 输入&#xff1a;s “ilovecodingonleetcode”, targ…

go tool pprof与trace的简单使用

pprof pprof是Google的程序采样分析工具&#xff0c;其使用分为&#xff0c;采样和分析。Go 语言内置了pprof。 Go 语言库中有两种方式使用pprof&#xff0c;一种是通过net/http/pprof库&#xff0c;另一种是通过runtime/pprof库。 net/http/pprof的简单使用 引入 _ "n…

【计算机网络】HTTP/HTTPS

HTTP网络协议 虽然我们说, 应用层协议是我们程序猿自己定的. 但实际上, 已经有大佬们定义了一些现成的, 又非常好用的应用层协议, 供我们直接参考使用. HTTP(超文本传输协议)就是其中之一 理解网络协议 协议是一种 “约定”. socket api的接口, 在读写数据时, 都是按 “字符…

零基础学MySQL(三)-- 对表中数据的增删改【新年快乐】

目录✨一、INSERT 语句&#xff08;添加表中数据&#xff09;1.基本语法2.应用案例3.使用细节&#x1f386;二、UPDATE 语句&#xff08;修改表中数据&#xff09;1.基本语法2.应用案例3.使用细节&#x1f387;三、DELETE 语句&#xff08;删除表中数据&#xff09;1.基本语法2…

【手写 Vue2.x 源码】第三十七篇 - 组件部分 - 组件的合并

一&#xff0c;前言 上篇&#xff0c;介绍了 Vue.extend 实现&#xff0c;主要涉及以下几个点&#xff1a; Vue.extend 简介&#xff1b;Vue.extend 实现&#xff0c;包括&#xff1a;组件初始化&#xff1b;子类继承父类&#xff1b;修复 constructor 指向问题&#xff1b; …

基于ssm jsp在线教育系统源码

演示视频&#xff1a; 基于ssm jsp在线教育系统源码范围 系统主要目标设计 随着互联网发展&#xff0c;在线教学成为一种支持知识共享&#xff0c;无距离知识交流的一种方式&#xff0c;我们的系统主要完成在线视频观看&#xff0c;在线教学&#xff0c;在线知识交流&#xff0…

虚幻引擎中CityEngine导入资产的自动化替换

在这篇博文中&#xff0c;我们将学习将 ArcGIS CityEngine Datasmith 场景导入虚幻引擎后替换资产的流程。 替换工作流由虚幻引擎的数据资产&#xff08;可以认为是简单的表格数据&#xff09;控制。 一旦设置正确&#xff0c;这些数据资产就可以在项目之间共享。 推荐&#x…

This old-style function definition is not preceded by a prototype

文章目录Introwarning 及解决 截屏知其然&#xff0c;却不知其所以然Intro 在 Xcode 14 中随意写了几个C命令行程序&#xff0c;编译运行OK。 但是有以下两种报错&#xff1a; This old-style function definition is not preceded by a prototype This function declaration…

联诚发携手电影《流浪地球2》,让电影特效和场景全面升级!

一万五千年前&#xff0c;一根愈合的人类股骨&#xff0c;标志着人类文明的诞生&#xff1b;一万五千年后&#xff0c;当太阳系将不复存在&#xff0c;人类的团结与勇气将延续文明的火种&#xff01;新年第一部精彩绝伦的国产科幻大片&#xff0c;大家期待已久的《流浪地球2》终…

动态规划的优化

动态规划的优化 一、空间优化 说明 动态规划空间优化为滚动数组优化&#xff0c;即对于一个多维数组&#xff0c;转移时均是由上一阶段转移来的&#xff0c;则可以将这一维省略&#xff0c;以降低空间复杂度&#xff0c;但要注意转移时的顺序&#xff1b; 例题 0 - 1 背包…

基础算法--背包问题(01背包问题、完全背包问题、多重背包问题、分组背包问题)

文章目录前言01背包问题完全背包问题多重背包问题分组背包问题前言 背包问题&#xff1a;给我们 i 件物品&#xff0c;每件物品都有体积 vi 和权重 wi &#xff0c;给我们限制条件&#xff0c;让我们选择在背包的容量内&#xff0c;物品达到权重最大 01背包问题 01背包问题描…

KK集团再冲刺港交所上市:期内被罚款30万元,曾存在“二清”问题

时隔一年&#xff0c;KK集团再次在港交所递交上市申请。2023年1月20日&#xff0c;KK集团&#xff08;KK Group Company Holdings Limited&#xff09;向港交所提交上市申请。据贝多财经了解&#xff0c;KK集团曾于2021年11月4日在港交所递表&#xff0c;后已“失效”。 相较于…

LeetCode_单周赛_329

2544. 交替数字和 代码1 转成字符串&#xff0c;逐个判断 class Solution {public int alternateDigitSum(int n) {char[] s ("" n).toCharArray();int t 1;int ans 0;for (int i 0; i < s.length; i) {ans (s[i] - 0) * t;t -t;}return ans;} }代码2 一…

国内做SaaS软件的知名企业有哪些?

SaaS厂商还挺多挺杂的。具体要列举的话&#xff0c;还是按照分类来吧。 通用业务和垂直行业的SaaS 对使用方来说&#xff0c;一般分为业务通用型和垂直行业型。 通用型是可以服务所有企业的&#xff0c;比如CRM&#xff08;客户管理软件&#xff09;、HR软件、协同办公软件&a…

linux系统中利用QT实现语音识别项目的操作方法

大家好&#xff0c;今天主要和大家分享一下&#xff0c;如何使用linux系统上的语音识别项目的操作方法与实现。 目录 第一&#xff1a;语音识别基本简介 第二&#xff1a;语音识别产品申请账号 第三&#xff1a;具体代码实现 第一&#xff1a;语音识别基本简介 AI音箱对传统…

Java_Git:3. 远程仓库

目录 1 添加远程库 1.1 在github上创建仓库 1.2 ssh协议 1.2.1 什么是ssh? 1.2.2 基于密匙的安全验证 1.2.3 ssh密钥生成 ​​​​​​​​​​​​​​1.2.4 ssh密钥配置 1.3 同步到远程仓库 1.3.1 使用git bash 1.3.2 使用TortoiseGit同步 2 从远程仓库克隆 2.1 …

CSS颜色:RGB颜色/HEX颜色/HSL颜色(网页颜色完全总结)

目录 CSS 颜色名 CSS 背景色 实例 CSS 文本颜色 ​编辑 实例 CSS 边框颜色 实例 CSS 颜色值 实例 RGB 值 rgb(red, green, blue) 实例 实例 RGBA 值 rgba(red, green, blue, alpha) 实例 HEX 值 #rrggbb 实例 实例 HSL 值 hsla(hue, saturation, lightn…

autojs模仿QQ长按弹窗菜单

牙叔教程 简单易懂 分析弹框菜单 圆角列表, 类似grid箭头位于文字中间上(下)方需求分析 如果要写一个这样的教程, 我们需要做什么 写一个列表, 用来触发长按选项写一个弹窗菜单代码分析 列表怎么写, 先来一个最简单的布局代码 "nodejs ui"; require("rhin…