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

回溯法经典难题解析

本文将通过几个经典的回溯问题,展示回溯算法的应用及其在解决问题时的核心思想和技巧。这些问题包括全排列、全排列II、N皇后以及数独问题,本文将分别介绍每个问题的思路与实现。

46. 全排列

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

示例 1:

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

示例 2:

输入:nums = [0,1]
输出:[[0,1],[1,0]]

示例 3:

输入:nums = [1]
输出:[[1]]

思路:
对于给定的数组,我们通过回溯法逐一选择数组中的元素,并将其加入当前的排列中。
需要一个 visited 数组来记录每个元素是否已经被使用过,避免重复排列。
每当排列的长度等于原数组长度时,表示当前排列已完成,加入结果集。

核心技巧:
在递归过程中使用 visited 数组来确保每个元素只被使用一次。
递归的终止条件是当当前排列的长度等于数组长度时,说明已经形成一个完整的排列。

class Solution {
public:vector<vector<int>> res;vector<int> path;unordered_set<int> node;void backfind(vector<int>& nums){if(path.size()==nums.size()){res.push_back(path);return;}for(int i=0; i<nums.size(); i++){if(node.find(nums[i])!=node.end()){continue;}node.insert(nums[i]);path.push_back(nums[i]);backfind(nums);node.erase(nums[i]);path.pop_back();}}vector<vector<int>> permute(vector<int>& nums) {backfind(nums);return res;}
};

47. 全排列 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]]

思路:先对数组进行排序,使得相同的元素相邻。使用 visited 数组来标记每个元素是否已经被访问过,同时利用排序后的数组来跳过已经处理过的重复元素。在每次递归时,检查当前元素与前一个元素是否相同,如果相同且前一个元素未被访问,则跳过当前元素。

核心技巧:排序保证了相同元素相邻,从而避免了重复排列。通过回溯的剪枝技巧,避免在同一层的递归中重复访问相同的元素。
47.全排列II1

47.全排列II3

class Solution {
public:vector<vector<int>> res;vector<int> path;void backfind(vector<int>& nums, vector<bool>& visited){if(path.size()==nums.size()){res.push_back(path);return; }for(int i=0; i<nums.size(); i++){if(i>0&&nums[i]==nums[i-1]&&visited[i-1]==false){continue;}//同层树重复的跳过,同层的上一个visited是没访问过的(回溯)//visited[i-1]==true也是可以滴if(visited[i]){continue;}visited[i]=true;path.push_back(nums[i]);backfind(nums,visited);visited[i]=false;path.pop_back();}}vector<vector<int>> permuteUnique(vector<int>& nums) {sort(nums.begin(), nums.end());vector<bool> visited(nums.size(), false);backfind(nums,visited);return res;}
};

51. N 皇后

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。

n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。

给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。

每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q''.' 分别代表了皇后和空位。

示例 1:

img

输入:n = 4
输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]]
解释:如上图所示,4 皇后问题存在两个不同的解法。

思路:使用回溯法逐行放置皇后,每放置一个皇后就递归处理下一行。
在每次尝试放置皇后时,检查该位置是否会与已放置的皇后发生冲突,即检查同列、左斜线和右斜线是否已有皇后。

核心技巧:使用三种标记(列标记、左斜线标记、右斜线标记)来有效判断是否可以放置皇后。
通过递归实现行的逐步尝试,并在放置皇后后继续处理下一行。

51.N皇后

class Solution {
public:vector<vector<string>> res;void find(int n, int row, vector<string>& rowChess){if(row==n){res.push_back(rowChess);return;}for(int col=0; col<n; col++){if(isQ(rowChess,row,col,n)){rowChess[row][col]='Q';find(n, row+1, rowChess);rowChess[row][col]='.';}}}bool isQ(vector<string>& rowChess, int row, int col, int n){//先遍历列for(int i=0; i<row; i++){if(rowChess[i][col]=='Q'){return false;}}//再检查45°线for(int i=row-1, j=col-1; i>=0&&j>=0; i--,j--){if(rowChess[i][j]=='Q'){return false;}}//再检查135°线for(int i=row-1, j=col+1; i>=0&&j<n; i--,j++){if(rowChess[i][j]=='Q'){return false;}}return true;}vector<vector<string>> solveNQueens(int n) {vector<string> rowChess(n, string(n,'.'));find(n, 0, rowChess);return res;}
};

37. 解数独

编写一个程序,通过填充空格来解决数独问题。

数独的解法需 遵循如下规则

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

数独部分空格内已填入了数字,空白格用 '.' 表示。

思路:使用回溯法逐步填充数独中的空格。每次选择一个空格,尝试填入数字 1-9,并检查填入的数字是否合法。如果合法,递归处理下一个空格;如果不合法,回溯并尝试其他数字。

核心技巧:使用一个 isOK 函数来检查当前填入的数字是否符合数独的规则。
回溯的终止条件是所有空格都被填充且合法时,返回解。

class Solution {
public:bool backsolve(vector<vector<char>>& board){for(int i=0; i<board.size(); i++){for(int j=0; j<board[0].size(); j++){if(board[i][j]=='.'){for(char c='1'; c<='9'; c++){if(isOK(board,i,j,c)){board[i][j]=c;if(backsolve(board)) return true;board[i][j]='.';}}return false;}}}return true;}bool isOK(vector<vector<char>>& board, int row, int col, char val){//行里面寻找有没有重复的for(int i=0; i<9; i++){if(board[i][col]==val){return false;}}//列里面寻找有没有重复的for(int j=0; j<9; j++){if(board[row][j]==val){return false;}}int startrow=(row/3)*3;int startcol=(col/3)*3;for(int i=startrow; i<startrow+3; i++){for(int j=startcol; j<startcol+3; j++){if(board[i][j]==val){return false;}}}return true;}void solveSudoku(vector<vector<char>>& board) {backsolve(board);}
};

相关文章:

回溯法经典难题解析

本文将通过几个经典的回溯问题&#xff0c;展示回溯算法的应用及其在解决问题时的核心思想和技巧。这些问题包括全排列、全排列II、N皇后以及数独问题&#xff0c;本文将分别介绍每个问题的思路与实现。 46. 全排列 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有…...

LLM的原理理解6-10:6、前馈步骤7、使用向量运算进行前馈网络的推理8、注意力层和前馈层有不同的功能9、语言模型的训练方式10、GPT-3的惊人性能

目录 LLM的原理理解6-10: 6、前馈步骤 7、使用向量运算进行前馈网络的推理 8、注意力层和前馈层有不同的功能 注意力:特征提取 前馈层:数据库 9、语言模型的训练方式 10、GPT-3的惊人性能 一个原因是规模 大模型GPT-1。它使用了768维的词向量,共有12层,总共有1.…...

Electron开发构建工具electron-vite(alex8088)添加VueDevTools(VitePlugin)

零、介绍 本文章的electron-vite指的是这个项目&#x1f449;electron-vite仓库&#xff0c;electron-vite网站 本文章的VueDevTools指的是VueDevTools的Vite插件版&#x1f449;https://devtools.vuejs.org/guide/vite-plugin 一、有一个用electron-vite创建的项目 略 二、…...

【C++】static修饰的“静态成员函数“--静态成员在哪定义?静态成员函数的作用?

声明为static的类成员称为类的静态成员&#xff0c;用static修饰的成员变量&#xff0c;称之为静态成员变量&#xff1b;用 static修饰的成员函数&#xff0c;称之为静态成员函数。静态成员变量一定要在类外进行初始化 一、静态成员变量 1)特性 所有静态成员为所有类对象所共…...

=computed() =ref()

computed() ref() 在 Vue 中&#xff0c;computed() 和 ref() 是 Vue 3 组合式 API 的核心工具&#xff0c;它们分别用于 计算属性 和 响应式数据。以下是它们的区别和用法&#xff1a; 1. ref() 作用 用于创建响应式的单一数据。可以是基本类型&#xff08;如字符串、数字、…...

webgl threejs 云渲染(服务器渲染、后端渲染)解决方案

云渲染和流式传输共享三维模型场景 1、本地无需高端GPU设备即可提供三维项目渲染 云渲染和云流化媒体都可以让3D模型共享变得简单便捷。配备强大GPU的远程服务器早就可以处理密集的处理工作&#xff0c;而专有应用程序&#xff0c;用户也可以从任何个人设备查看全保真模型并与…...

【shell编程】函数、正则表达式、文本处理工具

函数 系统函数 常见内置命令 echo打印输出 #!/bin/bash # 输出普通文本 echo "Hello, World!"# 输出变量值 name"Alice" echo "Hello, $name"# 输出带有换行符的文本 echo -n "Hello, " # -n 选项不输出换行 echo "World!&quo…...

解决 npm xxx was blocked, reason: xx bad guy, steal env and delete files

问题复现 今天一位朋友说&#xff0c;vue2的老项目安装不老依赖&#xff0c;报错内容如下&#xff1a; npm install 451 Unavailable For Legal Reasons - GET https://registry.npmmirror.com/vab-count - [UNAVAILABLE_FOR_LEGAL_REASONS] vab-count was blocked, reas…...

如何进行高级红队测试:OpenAI的实践与方法

随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;AI模型的安全性和可靠性已经成为业界关注的核心问题之一。为了确保AI系统在实际应用中的安全性&#xff0c;红队测试作为一种有效的安全评估方法&#xff0c;得到了广泛应用。近日&#xff0c;OpenAI发布了两…...

Java:二维数组

目录 1. 二维数组的基础格式 1.1 二维数组变量的创建 —— 3种形式 1.2 二维数组的初始化 \1 动态初始化 \2 静态初始化 2. 二维数组的大小 和 内存分配 3. 二维数组的不规则初始化 4. 遍历二维数组 4.1 for循环 ​编辑 4.2 for-each循环 5. 二维数组 与 方法 5.1…...

Android 天气APP(三十七)新版AS编译、更新镜像源、仓库源、修复部分BUG

上一篇&#xff1a;Android 天气APP&#xff08;三十六&#xff09;运行到本地AS、更新项目版本依赖、去掉ButterKnife 新版AS编译、更新镜像源、仓库源、修复部分BUG 前言正文一、更新镜像源① 腾讯源③ 阿里源 二、更新仓库源三、修复城市重名BUG四、地图加载问题五、源码 前…...

Xilinx IP核(3)XADC IP核

文章目录 1. XADC介绍2.输入要求3.输出4.XADC IP核使用5.传送门 1. XADC介绍 xadc在 所有的7系列器件上都有支持&#xff0c;通过将高质量模拟模块与可编程逻辑的灵活性相结合&#xff0c;可以为各种应用打造定制的模拟接口&#xff0c;XADC 包括双 12 位、每秒 1 兆样本 (MSP…...

计算机网络socket编程(2)_UDP网络编程实现网络字典

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 计算机网络socket编程(2)_UDP网络编程实现网络字典 收录于专栏【计算机网络】 本专栏旨在分享学习计算机网络的一点学习笔记&#xff0c;欢迎大家在评论区交流讨…...

c#窗体列表框(combobox)应用——省市区列表选择实例

效果如下&#xff1a; designer.cs代码如下&#xff1a; using System.Collections.Generic;namespace 删除 {public partial class 省市区选择{private Dictionary<string, List<string>> provinceCityDictionary;private Dictionary<string,List<string&…...

Nginx 架构与设计

Nginx 是一个高性能的 HTTP 和反向代理服务器&#xff0c;同时也可以用作邮件代理和通用的 TCP/UDP 负载均衡器。它的架构设计以高并发、高可扩展性和高性能为目标&#xff0c;充分利用操作系统提供的多路复用机制和事件驱动模型。以下是 Nginx 的架构和设计特点&#xff1a; 1…...

python Flask指定IP和端口

from flask import Flask, request import uuidimport json import osapp Flask(__name__)app.route(/) def hello_world():return Hello, World!if __name__ __main__:app.run(host0.0.0.0, port5000)...

多线程 相关面试集锦

什么是线程&#xff1f; 1、线程是操作系统能够进⾏运算调度的最⼩单位&#xff0c;它被包含在进程之中&#xff0c;是进程中的实际运作单位&#xff0c;可以使⽤多线程对 进⾏运算提速。 ⽐如&#xff0c;如果⼀个线程完成⼀个任务要100毫秒&#xff0c;那么⽤⼗个线程完成改…...

【数据结构】—— 线索二叉树

引入 我们现在提倡节约型杜会&#xff0c; 一切都应该节约为本。对待我们的程序当然也不例外&#xff0c;能不浪费的时间或空间&#xff0c;都应该考虑节省。我们再观察团下图的二叉树&#xff08;链式存储结构)&#xff0c;会发现指针域并不是都充分的利用了&#xff0c;有许…...

uni-app 发布媒介功能(自由选择媒介类型的内容) 设计

1.首先明确需求 我想做一个可以选择媒介的内容&#xff0c;来进行发布媒介的功能 &#xff08;媒介包含&#xff1a;图片、文本、视频&#xff09; 2.原型设计 发布-编辑界面 通过点击下方的加号&#xff0c;可以自由选择添加的媒介类型 但是因为预览中无法看到视频的效果&…...

How to update the content of one column in Mysql

How to update the content of one column in Mysql by another column name? UPDATE egg.eggs_record SET sold 2024-11-21 WHERE id 3 OR id 4;UPDATE egg.eggs_record SET egg_name duck egg WHERE id 2;...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题&#xff0c; 因为搜索范围是有界的&#xff0c;上界最大木板长度补充的全部木料长度&#xff0c;下界最小木板长度&#xff1b; 即left0,right10^6; 我们可以设置一个候选值x(mid)&#xff0c;将木板的长度全部都补充到x&#xff0c;如果成功…...

【Veristand】Veristand环境安装教程-Linux RT / Windows

首先声明&#xff0c;此教程是针对Simulink编译模型并导入Veristand中编写的&#xff0c;同时需要注意的是老用户编译可能用的是Veristand Model Framework&#xff0c;那个是历史版本&#xff0c;且NI不会再维护&#xff0c;新版本编译支持为VeriStand Model Generation Suppo…...