Backtrack 算法思路
Backtrack 算法思路
1.引言
黄色的树林里分出两条路,可惜我不能同时去涉足,我选择了人迹稀少的一条,从此决定了我一生的道路
2.什么是回溯算法?
Backtrack算法,中译回溯算法,是一个非常实用的一个算法,如果用一个谚语来形容回溯算法,我愿意称之为“不撞南墙不回头”的一种算法。
为什么这么说呢?因为回溯算法实质上就是一种不断尝试,通过不断的“试错”不断更改信息的一种算法。
“不撞南墙”说明了当回溯算法不遇到错误的时候,“不回头”就是不返回上一步重新尝试。
从引言的那首罗伯特.弗罗斯特的诗里,“可惜我不能同时去涉足”,可是对于回溯算法来说不是这样的,回溯算法看到路走错了就不会继续走了,它会折返到最近的一个分岔口,重新选择一条道路行走。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FIvQYVnT-1652531632747)(https://tse1-mm.cn.bing.net/th/id/R-C.91867e276501f596a4802b67aea756f6?rik=T2H1qdJZGAQe7g&riu=http%3a%2f%2fimg95.699pic.com%2fphoto%2f50123%2f6755.jpg_wh300.jpg!%2ffh%2f300%2fquality%2f90&ehk=6ZJzrS%2bT3A%2fCApII9W0nWQRrSgaCGaU1C3o6wI7aRLs%3d&risl=&pid=ImgRaw&r=0&sres=1&sresct=1)]
回溯算法可以用来解数独,进行排列组合,解决N皇后等问题
3.回溯算法的实现
让我们来看一看79. 单词搜索 这道题
这道题要求我们从board里面查找某一个单词(例如:ABCDE),如果查找到单词,我们就返回True,否则返回False。
如上所示,黄色的路径就代表我们成功找到了“ABCDE”这个连续的单词。我们可以从上、下、左、右四个方向进行单词查找。
这里有一点需要注意,单词并不需要第一行第一列的数字来开始,我们可以从任何点上开始单词。
回溯算法的基本思路
1.确定Base case,即考虑一些越界情况,结果实现的情况。
2.在选择列表中进行选择
3.迭代下一个情况
4.撤销选择
这个回溯算法可以如下定义:
def backtrack(x,y,index)
x,y就是我们传进去的board的行数和列数,index为单词的索引
def dfs(x,y,index):#base caseif x<0 or x>=row or y<0 or y>=col: 、return Falseif board[x][y]!=word[index]:return Falseif index ==len(word)-1:return True#做选择board[x][y] = '#' #进行迭代for i in [[0,1],[1,0],[0,-1],[-1,0]]:next_x = x+i[0]next_y = y+i[1]if dfs(next_x,next_y,index+1):return True#撤销选择board[x][y] = word[index]return False#开始点,可以从任一行任一列开始for i in range(row):for j in range(col):if dfs(i,j,0):return Truereturn False
如上,按照思路,第一步:确立Base case,当索引为index的单词字符刚刚和board的x行y列的字符相同时,继续走下去,如果不是,则return,程序返回上一步(即返回上一次for循环,进行下一个循环),如果继续走下去,就再次执行刚刚的内容,如此循环,直至我们可以找到一个序列和给出的单词一致,即index的长度达到了单词的长度。
让我们来看下一道一个比较简单的题目, 全排列
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
代码如下:
class Solution:def permute(self, nums: List[int]) -> List[List[int]]:res = []track = []def backtrack():if len(track) == len(nums): #base caseres.append(track[:])returnfor i in range(0,len(nums)):if nums[i] in track:continuetrack.append(nums[i]) #选择backtrack() #迭代track.pop()#撤销选择backtrack()return res
还是惯常的思路,确立一个Base case,然后进行选择,进行迭代,撤销选择。
其实从回溯算法里面,我们也能发现一件事,那就是所谓“智能”的计算机,实际上是因为计算机拥有巨大的“计算能力",它能不厌其烦的进行大量的数据处理,并从这些数据中根据我们所确立的“basecase”进行选择。
如果你跟一个不知道计算机怎么运行的人演示这个全排列算法(如果你去演示一个N皇后,解数独的例子可能更好),他们会纠结于为什么你跟电脑说:“给我一个数组[1,2,3]的全排列输出。”电脑就会如实的做到,电脑他难道是因为知道全排列的含义而去思考吗?实际上是你给他一个指令,让他去遍历这些数组组成的所有有用序列,然后返回而已。
不过,这样也可以说明,电脑是可以拥有“学习能力”的,比如你给计算机一百万个数据,让他去处理这之间的关系(而不需要你告诉它关系是什么),然后你再丢给它一个不是数据里数字,他能返回给你一个“最接近结果”的一个值,当然,这就是另一种事情了。
Backtrack 算法思路相关推荐
- ML:从0到1 机器学习算法思路实现全部过程最强攻略
ML:从0到1 机器学习算法思路实现全部过程最强攻略 目录 思维导图 设计思路 思维导图 设计思路 相关文章 ML之FE:结合Kaggle比赛的某一案例细究Feature Engineering思路框 ...
- DL之GANDCGNNcGAN:GANDCGNNcGAN算法思路、关键步骤的相关配图和论文集合
DL之GAN&DCGNN:GAN&DCGNN&cGAN算法思路.关键步骤的相关配图和论文集合 目录 GAN&DCGNN&cGAN相关论文推荐 1.GAN论文 2 ...
- 浅谈最小生成树的算法思路(二)Kruskal算法
Kruskal算法是另外一种最小生成树的常见算法,理解起来,笔者觉得是比Prim算法要简单的. 算法思路 定义2个集合,集合P代表已经确定的边的集合,初始为空集.集合Q代表还未确定的边的集合,初始化为 ...
- 浅谈最小生成树的算法思路(一)Prim算法
Prim算法是求最小生成树的一种常见算法,简单谈一下笔者自己的理解. 算法思路 设已经确定的点集为P,初始为空.设还未确定的点集为Q,初始为该图所有点的集合.设已经确定的边为X,初始为空. 选取任意一 ...
- 图的最小生成树和最短路径算法思路总结(Prim,Kruskal,Dijkstra,Floyd)
带权无向图->最小生成树算法->Prim算法: 思路: 首先,我们先设置两个集合,U_{}:一个用来放最小生成树的顶点,T_{}:一个用来放最小生成树的边.选取最开始的点V_0,将V_0放 ...
- Java——打印九宫格的算法思路(任意维奇数行方阵)
九宫格算法口诀: 一居下行正中央,依次斜填切莫忘:下出框时向上放,右出框时向左放:排重便在上格填,右下排重一个样. 3 X 3 九宫格的算法思路: 1.始终将数字1放置在最后一行的中间位置: 2.数字 ...
- POJ前面的题目算法思路【转】
1000 A+B Problem 送分题 49% 2005-5-7 1001 Exponentiation 高精度 85% 2005-5-7 1002 487-3279 n/a 90% 2005-5- ...
- 二叉树结构与算法思路解析
二叉树 介绍 主要内容 二叉树的概念和性质 二叉树的存储结构 遍历二叉树 递归遍历 非递归遍历 线索二叉树 哈夫曼树 树和森林 树和森林的存储 树和森林与二叉树的转换 树和森林的遍历 树型结构特点 一 ...
- 中国软件杯 公共地点人流量计算的云监管平台 算法思路分享
赛题名称:公共地点人流量计算的云监管平台 获奖名次:二等奖 项目主要分工: 周泽淼 云端全部业务 张宗浩 边缘端核心业务与算法部分 杨帆 前端框架 部分业务逻辑及宣传视频 针对比赛我们想了很多点子,只 ...
- java斗地主游戏开发 算法思路讲解
上学期刚开学的时候我特别沉迷于斗地主 充了6块钱赢了30万豆 然后一夜之间破产 越想越气 然后我就有一个大胆的想法开发一个斗地主现在这个斗地主能在控制台上运行 本文主要讲解我在开发斗地主时研究的算法思 ...
最新文章
- LeetCode简单题之分糖果 II
- oracle取两个小时内的数据,【求解】一个时间条件,查两个不同时间段数据怎么查...
- SpringBoot 统一异常处理 ControllerAdvice
- C语言计算一个数的平方根立方根,怎样快速计算出一个数的平方根立方根?
- python查看CNN训练模型参数
- ArrayList基操
- 简单的SQL注入学习
- 没有显示屏怎么启动服务器,中关村xp系统提示“没有启动服务器服务”如何解决...
- Error: docker-ce conflicts with 2:docker-1.13.1-208.git7d71120.el7_9.x86_64
- java j2se1.5_Java教程 用J2SE1.5建立多任务的Java应用程序
- 05 ansible剧本编写
- Moods of Norway扩大RFID系统使用范围,保证库存准确率
- 量子计算机与GIS,量子计算机系列---开篇,原理
- 笔记本电脑显示打印机服务器关闭,电脑打印机服务能设定自动关闭吗
- MindManager 2021授权许可密钥思维导图软件
- python sample函数取样,python sample函数取样_Pytorch各种取样器sample
- 计算机用户帐号 MAC地址怎么查,mac地址怎么查
- latch 深入理解(转载)
- 物联网卡和流量卡相比哪个信号强
- 机器学习——科学计算库(Numpy,Matplotlib,Pandas)