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

Leetcode 回溯详解

回溯法

回溯法有“通用解题法”之称,用它可以系统地搜索问题的所有解。回溯法是一个既带有系统性又带有跳跃性的搜索算法。

在包含问题的所有解的解空间树中,按照深度优先搜索(DFS))的策略,从根结点出发深度探索解空间树。当探索到某一结点时,要先判断该结点是否包含问题的解,如果包含,就从该结点出发继续探索下去,如果该结点不包含问题的解,则逐层向其祖先结点回溯。(其实回溯法就是对隐式图的深度优先搜索算法)。

若用回溯法求问题的所有解时,要回溯到根,且根结点的所有可行的子树都要已被搜索遍才结束。 而若使用回溯法求任一个解时,只要搜索到问题的一个解就可以结束。

DFS

解题步骤

  1. 针对所给问题,定义问题的解空间
  2. 确定易于搜索的解空间结构
  3. 以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索

子集树与排列树

下面的两棵解空间树是回溯法解题时常遇到的两类典型的解空间树,子集树排列树

子集树

当所给问题是从n个元素的集合S中找出S满足某种性质的子集时,相应的解空间树称为子集树。例如从n个物品的0-1背包问题所相应的解空间树是一棵子集树,这类子集树通常有2n{2^n}2n个叶结点,其结点总个数为2n+1−1{2 ^{n+1}- 1}2n+11。遍历子集树的算法需O(2n{2^n}2n)计算时间

用回溯法搜索子集树的一般算法可描述为:

/*** output(x)     记录或输出得到的可行解x* constraint(t) 当前结点的约束函数* bount(t)      当前结点的限界函数* @param t  t为当前解空间的层数*/
void backtrack(int t){if(t >= n)output(x);elsefor (int i = 0; i <= 1; i++) {x[t] = i;if(constraint(t) && bount(t))backtrack(t+1);}
}

排列树

当所给问题是确定n个元素满足某种性质的排列时,相应的解空间树称为排列树。例如旅行售货员问题的解空间树是一棵排列树,这类排列树通常有n!{n!}n!个叶结点。遍历子集树的算法需O(n!{n!}n!)计算时间

用回溯法搜索排列树的一般算法可描述为:

/*** output(x)     记录或输出得到的可行解x* constraint(t) 当前结点的约束函数* bount(t)      当前结点的限界函数* @param t  t为当前解空间的层数*/
void backtrack(int t){if(t >= n)output(x);elsefor (int i = t; i <= n; i++) {swap(x[t], x[i]);if(constraint(t) && bount(t))backtrack(t+1);swap(x[t], x[i]);}
}

Leetcode真题

电话号码的字母组合

解题思路:
经典排列树,按节点遍历

private String[] voc = new String[]{"","*", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
List<String> res = new ArrayList();
public List<String> letterCombinations(String digits) {if (digits == null || digits.length() == 0) {return res;}backtrack(digits, 0, new StringBuffer());return res;
}public void backtrack(String digits, int index, StringBuffer s) {if (index == digits.length()) {res.add(s.toString());return;}int i = digits.charAt(index) - '0';for (char c : voc[i].toCharArray()) {s.append(c);backtrack(digits, index + 1, s);s.deleteCharAt(s.length() - 1);}
}

括号生成

解题思路:
排列树,按节点遍历

  1. 回溯结束条件:左括号数 = 右括号数 = 总数
  2. 左括号数<总数, 字符串加入左括号
  3. 右括号数<总数 且 左括号数>右括号数,字符串加入右括号
List<String> res = new ArrayList<>();
public List<String> generateParenthesis(int n) {backtrack(n, 0, 0, "");return res;
}void backtrack(int n, int l, int r, String str) {if (l == n && r == n) {res.add(str);}if (l < n) {backtrack(n, l + 1, r, str + "(");}if (r < n && l > r) {backtrack(n, l, r + 1, str + ")");}
}

N皇后

解题思路:
子集树,按节点遍历

  1. 回溯结束条件:所有层数放置完毕
  2. 每列循环遍历,当满足非冲突条件时(列,主对角线,副对角线不冲突)
    • 放置该行的皇后
    • 执行下一级回溯

两点位于同一对角线时,行列值相加/相减的值相等

List<List<String>> res = new ArrayList<>();
public List<List<String>> solveNQueens(int n) {if (n <= 0) {return res;}backtrack(0, n, new int[n]);return res;
}/*** output(x)     记录或输出得到的可行解x* constraint(t) 当前结点的约束函数** @param t      t为当前解空间的层数* @param n 总层数* @param queens 结果集,下标为行号,值为列号*/
void backtrack(int t, int n, int[] queens) {if (t >= n) {output(res, n, queens);return;} else {for (int j = 0; j < n; j++) {if (constraint(t, j, n, queens)) {queens[t] = j;backtrack(t + 1, n, queens);}}}
}/*** 检查是否存在冲突(列,主对角线,副对角线)* 两点位于同一对角线时,行列值相加/相减的值相等*/
boolean constraint(int t, int j, int n, int[] queens) {for (int i = 0; i < t; i++) {if (queens[i] == j || i - queens[i] == t - j || i + queens[i] == t + j) {return false;}}return true;
}void output(List<List<String>> res, int n, int[] queens) {List<String> list = new ArrayList<>();for (int i = 0; i < n; i++) {char[] chars = new char[n];Arrays.fill(chars, '.');chars[queens[i]] = 'Q';list.add(new String(chars));}res.add(list);
}

参考资料:

  1. 回溯法的解题步骤与例子解析
  2. leetcode
  3. 深度优先搜索

相关文章:

Leetcode 回溯详解

回溯法 回溯法有“通用解题法”之称&#xff0c;用它可以系统地搜索问题的所有解。回溯法是一个既带有系统性又带有跳跃性的搜索算法。 在包含问题的所有解的解空间树中&#xff0c;按照深度优先搜索(DFS)&#xff09;的策略&#xff0c;从根结点出发深度探索解空间树。当探索…...

AI_Papers:第一期

2023.02.06—2023.02.12 文摘词云 Top Papers Subjects: cs.CL 1.Multimodal Chain-of-Thought Reasoning in Language Models 标题&#xff1a;语言模型中的多模式思维链推理 作者&#xff1a;Zhuosheng Zhang, Aston Zhang, Mu Li, Hai Zhao, George Karypis, Alex Sm…...

C/C++内存管理

C/C内存管理C/C内存分布C语言中内存管理的方式&#xff1a;malloc/calloc/realloc/freeC内存管理方式内置类型自定义类型operator new 与operator deletenew和delete的实现原理内置类型自定义类型定位new表达式(placement-new)new/delete与malloc/free的区别C/C内存分布 我们先…...

【大数据hive】hive 函数使用详解

一、前言 在任何一种编程语言中&#xff0c;函数可以说是必不可少的&#xff0c;像mysql、oracle中&#xff0c;提供了很多内置函数&#xff0c;或者通过自定义函数的方式进行定制化使用&#xff0c;而hive作为一门数据分析软件&#xff0c;随着版本的不断更新迭代&#xff0c…...

彻底搞懂分布式系统服务注册与发现原理

目录 引入服务注册与发现组件的原因 单体架构 应用与数据分离...

安卓Camera2用ImageReader获取NV21源码分析

以前如何得到Camera预览流回调 可以通过如下方法&#xff0c;得到一路预览回调流 Camera#setPreviewCallbackWithBuffer(Camera.PreviewCallback)&#xff0c;可以通过如下方法&#xff0c;设置回调数据的格式&#xff0c;比如 ImageFormat.NV21 Camera.Parameters#setPreview…...

24. 两两交换链表中的节点

文章目录题目描述迭代法递归法参考文献题目描述 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 示例 1&#xff1a; 输入&a…...

linux006之帮助命令

linux帮助命令简介&#xff1a; linux的命令是非常多的&#xff0c;光靠人是记不住的&#xff0c;在工作中一般都会去网上查&#xff0c;这是有外网的情况下&#xff0c;如果项目中不允许访问外网&#xff0c;那么linux的帮助命令就可以派上用场了&#xff0c; linux帮助命令是…...

【C++初阶】十三、模板进阶(总)|非类型模板参数|模板的特化|模板分离编译|模板总结(优缺点)

目录 一、非类型模板参数 二、模板的特化 2.1 模板特化概念 2.2 函数模板特化 2.3 类模板特化 2.3.1 全特化 2.3.2 偏特化 三、模板分离编译 四、模板总结&#xff08;优缺点&#xff09; 前言&#xff1a;之前模板初阶并没有把 C模板讲完&#xff0c;因为当时没有接触…...

Linux之文本搜索命令

文本搜索命令学习目标能够知道文本搜索使用的命令1. grep命令的使用命令说明grep文本搜索grep命令效果图:2. grep命令选项的使用命令选项说明-i忽略大小写-n显示匹配行号-v显示不包含匹配文本的所有行-i命令选项效果图:-n命令选项效果图:-v命令选项效果图:3. grep命令结合正则表…...

微信小程序Springboot 校园拼车自助服务系统java

系统管理员&#xff1a; 管理员账户管理&#xff1a;在线对管理员的账户信息进行管理&#xff0c;包括对管理员信息的增加修改以及密码的修改等。 站内新闻管理&#xff1a;在后台对站内新闻信息进行发布&#xff0c;并能够对站内新闻信息进行删除修改等。 论坛版块管理&#x…...

【Unity3D 常用插件】Haste插件

一&#xff0c;Haste介绍 Haste插件是一款针对 Unity 3D 的 Everthing软件&#xff0c;可以实现基于名称快速定位对象的功能。Unity 3D 编辑器也自带了搜索功能&#xff0c;但是在 project视图 和 Hierarchy视图 中的对象需要分别查找&#xff0c;不支持模糊匹配。Haste插件就…...

【c++面试问答】全局变量和局部变量的区别

问题 C中的全局变量和局部变量有什么区别&#xff1f; 注&#xff1a;内容全部参考自文末的参考资料 全局变量和局部变量的区别 可以从以下4个角度来区分&#xff1a; 区别全局变量局部变量作用域全局作用域局部作用域内存分配全局变量在静态数据区静态局部变量在静态数据区…...

Java List集合

6 List集合 List系列集合&#xff1a;添加的元素是有序&#xff0c;可重复&#xff0c;有索引 ArrayList: 添加的元素是有序&#xff0c;可重复&#xff0c;有索引LinkedList: 添加的元素是有序&#xff0c;可重复&#xff0c;有索引Vector &#xff1a;是线程安全的&#xff…...

linux服务器挂载硬盘/磁盘

1. 查看机器所挂硬盘个数及分区情况&#xff1a;fdisk -l可以看出来目前/dev/vda 目前有300G可用.内部有两个分区&#xff08;/dev/vda1,/dev/vda2&#xff09;。2. 格式化磁盘格式化磁盘命令为【mkfs.磁盘类型格式 目录路径组成】查看磁盘文件格式&#xff1a;df -T格式化磁盘…...

Java 抽象类

文章目录1、抽象方法和抽象类2、抽象类的作用当编写一个类时&#xff0c;常常会为该类定义一些方法&#xff0c;用于描述该类的行为方式&#xff0c;这些方法都有具体的方法体。但在某些情况下&#xff0c;某个基类只是知道其子类应该包含那些方法&#xff0c;但不知道子类是如…...

OpenPPL PPQ量化(5):执行引擎 源码剖析

目录 PPQ Graph Executor(PPQ 执行引擎) PPQ Backend Functions(PPQ 算子库) PPQ Executor(PPQ 执行引擎) Quantize Delegate (量化代理函数) Usage (用法示例) Hook (执行钩子函数) 前面四篇博客其实就讲了下面两行代码&#xff1a; ppq_ir load_onnx_graph(onnx_impor…...

【脚本开发】运维人员必备技能图谱

脚本&#xff08;Script&#xff09;语言是一种动态的、解释性的语言&#xff0c;依据一定的格式编写的可执行文件&#xff0c;又称作宏或批处理文件。脚本语言具有小巧便捷、快速开发的特点&#xff1b;常见的脚本语言有Windows批处理脚本bat、Linux脚本语言shell以及python、…...

N字形变换-力扣6-java

一、题目描述将一个给定字符串 s 根据给定的行数 numRows &#xff0c;以从上往下、从左到右进行 Z 字形排列。比如输入字符串为 "PAYPALISHIRING" 行数为 3 时&#xff0c;排列如下&#xff1a;P A H NA P L S I I GY I R之后&#xff0c;你的输出需要从左往右逐行读…...

概论_第5章_中心极限定理1__定理2(棣莫弗-拉普拉斯中心极限定理)

在概率论中&#xff0c; 把有关论证随机变量和的极限分布为正态分布的一类定理称为中心极限定理称为中心极限定理称为中心极限定理。 本文介绍独立同分布序列的中心极限定理。 一 独立同分布序列的中心极限定理 定理1 设X1,X2,...Xn,...X_1, X_2, ...X_n,...X1​,X2​,...Xn…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

安卓基础(Java 和 Gradle 版本)

1. 设置项目的 JDK 版本 方法1&#xff1a;通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分&#xff0c;设置 Gradle JDK 方法2&#xff1a;通过 Settings File → Settings... (或 CtrlAltS)…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...