面试算法题之暴力求解

server/2024/10/21 9:09:46/

这里写目录标题

  • 1 回溯
    • 1.1 思路及模板
    • 1.2 例题
      • 1.2.1 全排列
      • 1.2.2 N 皇后
      • 1.2.3 N皇后问题 II

1 回溯

1.1 思路及模板

抽象地说,解决一个回溯问题,实际上就是遍历一棵决策树的过程,树的每个叶子节点存放着一个合法答案。你把整棵树遍历一遍,把叶子节点上的答案都收集起来,就能得到所有的合法答案。

站在回溯树的一个节点上,你只需要思考 3 个问题:
1、路径:也就是已经做出的选择。
2、选择列表:也就是你当前可以做的选择。
3、结束条件:也就是到达决策树底层,无法再做选择的条件。

回溯算法的框架如下:

result = []
def backtrack(路径, 选择列表):if 满足结束条件:result.add(路径)returnfor 选择 in 选择列表:做选择backtrack(路径, 选择列表)撤销选择

更具体的,在下面的例子中,对于遍历到红色节点来说,现在可以解答开头的几个名词:[2] 就是「路径」,记录你已经做过的选择;[1,3] 就是「选择列表」,表示你当前可以做出的选择;「结束条件」就是遍历到树的底层叶子节点,这里也就是选择列表为空的时候。
在这里插入图片描述
如果明白了这几个名词,可以把「路径」和「选择」列表作为决策树上每个节点的属性,比如下图列出了几个蓝色节点的属性:
在这里插入图片描述
函数在树上游走要正确处理节点的属性,那么就要在这两个特殊时间点搞点动作:
在这里插入图片描述
再来理解下回溯框架:

for 选择 in 选择列表:# 做选择将该选择从选择列表移除路径.add(选择)backtrack(路径, 选择列表)# 撤销选择路径.remove(选择)将该选择再加入选择列表

1.2 例题

1.2.1 全排列

给定一个不含重复数字的数组 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]]

思路以及代码
在这里插入图片描述

1、路径:走过的记录在track中。
2、选择列表:used[] 为false表示没走过,可以选择。
3、结束条件:track.size == nums.length 表示到达了叶子节点,可以退出。

class Solution {//存放结果List<List<Integer>> res = new LinkedList();public List<List<Integer>> permute(int[] nums) {List<Integer> track = new LinkedList();boolean[] used = new boolean[nums.length];backtrack(nums,track,used);return res;}// 路径:记录在 track 中// 选择列表:nums 中不存在于 track 的那些元素(used[i] 为 false)// 结束条件:nums 中的元素全都在 track 中出现public void backtrack(int[] nums,List<Integer> track,boolean[] used){//当该条路径的track和nums元素相同,也就是已经走到了叶子节点,退出if(track.size() == nums.length){res.add(new LinkedList(track));return ;}for(int i = 0;i<nums.length;i++){//排除不合法if(used[i]){continue;}//做选择track.add(nums[i]);used[i] = true;//进入下一层决策树backtrack(nums,track,used);//退出track.removeLast();used[i] = false;}}
}

1.2.2 N 皇后

按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。
每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。

示例:
在这里插入图片描述
输入:n = 4
输出:[[“.Q…”,“…Q”,“Q…”,“…Q.”],[“…Q.”,“Q…”,“…Q”,“.Q…”]]
解释:如上图所示,4 皇后问题存在两个不同的解法。

思路以及代码:
这个问题本质上跟全排列问题差不多,决策树的每一层表示棋盘上的每一行;每个节点可以做出的选择是,在该行的任意一列放置一个皇后。
路径:board中小于row的行都已经放置了Q
选择列表:board中第row行的所有列都可以选择
结束条件:当超过了最后一行,也就是row = board.size()

class Solution {
public://存放结果vector<vector<string>> res;vector<vector<string>> solveNQueens(int n) {// vector<string> 代表一个棋盘// '.' 表示空,'Q' 表示皇后,初始化空棋盘vector<string> board(n, string(n, '.'));backtrack(board, 0);return res;}//路径:board中小于row的行都已经放置了Q//选择列表:board中第row行的所有列都可以选择//结束条件:当超过了最后一行,也就是row = board.size()void backtrack(vector<string>& board,int row){if(board.size() == row){res.push_back(board);return;}int n = board[row].size();for(int col = 0;col<n;col++){// 排除不合法选择if (!isValid(board, row, col)) {continue;}// 做选择board[row][col] = 'Q';// 进入下一行决策backtrack(board, row + 1);// 撤销选择board[row][col] = '.';}}//输入棋盘board,判断第row行的第col列是否可以放Q?bool isValid(vector<string> board,int row,int col){int n = board.size();//检查同一列是否有冲突for(int i = 0;i<=row;i++){if(board[i][col] == 'Q'){return false;}}//检查右上for(int i = row - 1,j = col + 1;i >= 0 && j < n;i--,j++){if(board[i][j] == 'Q'){return false;}}//检查左上for(int i = row - 1,j = col - 1;i>=0 && j>=0;i--,j--){if(board[i][j] == 'Q'){return false;}}return true;}
};

1.2.3 N皇后问题 II

n 皇后问题 研究的是如何将 n 个皇后放置在 n × n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给你一个整数 n ,返回 n 皇后问题 不同的解决方案的数量。
在这里插入图片描述
输入:n = 4
输出:2
解释:如上图所示,4 皇后问题存在两个不同的解法。

思路以及代码:
这道题和N皇后几乎一样,只需要将N皇后的退出返回数组改为退出res++即可,如下所示:

        if(board.size() == row){res++;return;}

http://www.ppmy.cn/server/4009.html

相关文章

ssm420基于JavaEE的企业人事管理信息系统的设计与实现论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本企业人事管理信息系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据…

Ubuntu如何给tar.gz文件创建桌面快捷方式

在Ubuntu中&#xff0c;给.tar.gz文件创建URL桌面图标快捷方式或者是启动脚本桌面图标快捷方式可以通过创建一个.desktop文件来实现。.desktop文件是Linux系统中用于定义应用程序启动器的文件格式&#xff0c;它们通常包含图标、名称和执行命令等信息。以下是创建.tar.gz文件的…

javascript模块化学习

Js模块化 【成长期】原始的js模块化 // 使用立即执行函数 var的方式 // 例如 有base.js 和 main.js两个文件 // 其中main.js需要调用base.js中的函数 可以这样写/** base.js */ var baseModule (function () {var a 1;var b 11;var c 22;console.log(a, b, c)…

static+单例模式+类的复合继承

汇编语言 汇编语言是最靠谱的验证“编程语言相关知识点”正确性的方式 汇编语言与机器语言一一对应&#xff0c;每一条机器语言都有与之对应的汇编指令 机器语言是计算机使用的语言&#xff0c;它是一串二进制数字 汇编语言可以通过汇编得到机器语言机器语言可以通过反汇编得到…

FILE类与IO流

目录 File类的实例化与常用方法 File类的理解 文件路径的表示方式&#xff1a; API的使用 IO流概述与流的分类 I/O流中的是Input/Output的缩写 IO流的分类&#xff08;不同角度&#xff09; Java程序中的IO流涉及40多个&#xff0c;但实际上都是由4个抽象类衍生出来的。 F…

【教程】ubuntu20.04 下配置 Charm-crypto 0.5 实验环境

目录 前言先决条件基本依赖安装准备好 gcc&#xff0c;make 和 perl准备好 m4&#xff0c;flex&#xff0c;bison 和 libssl-dev安装 Python3.x&#xff0c;pip3 和 pyparsing 安装 OpenSSL安装 GMP5.x安装 PBC安装 Charm-crypto5.0安装开发环境检验 Charm-crypto5.0 安装成功主…

《综合品酒师》培训中FENDI CLUB精酿啤酒掀起品质生活新浪潮

近日&#xff0c;云仓酒庄的《综合品酒师》培训活动成功刷新了世界纪录&#xff0c;这一壮举不仅彰显了云仓酒庄在人才培养方面的专业实力&#xff0c;更以其与众不同的FENDI CLUB精酿啤酒掀起了酒水行业的新风尚。作为一名业内专业人士&#xff0c;我深入剖析了此次培训对酒水…

《深入浅出多模态》: 多模态经典模型:BLIP

🎉AI学习星球推荐: GoAI的学习社区 知识星球是一个致力于提供《机器学习 | 深度学习 | CV | NLP | 大模型 | 多模态 | AIGC 》各个最新AI方向综述、论文等成体系的学习资料,配有全面而有深度的专栏内容,包括不限于 前沿论文解读、资料共享、行业最新动态以、实践教程、求职…