回溯(python)
回溯算法
- 回溯利用递归的性质,从问题的起始点出发,不断地进行尝试,回头一步甚至多步再做选择,直到最终抵达终点的过程。回溯解决问题的所有选项可以形象的用树状结构表示,每一条路径path就是一个栈;
- 树结构的深度优先搜索(DFS)的过程就是回溯,回溯到上一层时通过状态重置的思路实现;
- 回溯算法说白了就是穷举法的升级版。搜索过程中使用剪枝函数,剪去一些不可能到达最终状态的节点,从而减少状态空间树节点的生成,提高了效率;
- 使用场景:要求在二维数组中(可能具体表现为迷宫或者棋盘等)上搜索路径,一般用递归实现;
回溯解题模板(C++)
function backtrack(n, used) { //used用来判断这个数之前有没有选择过// 第一步:判断输入或者状态是否非法if (input/state is invalid) {return;}// 第二步:判读递归是否应当结束,满足结束条件就保存当前结果并返回if (match condition) {return some value;}// 遍历当前所有可能出现的情况for (all possible cases) {// 第三步:尝试下一步的可能性。如果上一步尝试会影响下一步尝试,需要写入状态used.push(case)// 递归进行下一步尝试,搜索该子树result = backtrack(n + 1, used)// 第四步:尝试完毕,状态重置,回溯到上一步used.pop(case)}
}
经典例题
leetcode17. 电话号码的字母组合
class Solution:def letterCombinations(self, digits: str) -> List[str]:phone = {'2': ['a', 'b', 'c'],'3': ['d', 'e', 'f'],'4': ['g', 'h', 'i'],'5': ['j', 'k', 'l'],'6': ['m', 'n', 'o'],'7': ['p', 'q', 'r', 's'],'8': ['t', 'u', 'v'],'9': ['w', 'x', 'y', 'z']}"""回溯函数:先递归入栈(每次调用自身函数,操作系统都会把当时函数参数等信息暂时压入栈中),再出栈(递归终止条件时出栈,再重新使用当时的参数)。后进先出。next_digits为接下来要准备输入的数字,combination为已经产生的组合"""def backtrack(combination, next_digits): if len(next_digits) == 0: #如果没有更多数字需要输入,说明组合已经完成(递归终止条件)output.append(combination)else: #如果还有数字需要被输入,遍历下一个数字所有映射的字母for letter in phone[next_digits[0]]:backtrack(combination + letter, next_digits[1:])#核心部分!!!将当前的字母添加到组合的最后,即combination+letter,并转到下一个数字output = []if digits: #递归终止条件backtrack("", digits) #combination初始值为空字符串return output
leetcode46.全排列
class Solution:def permute(self, nums: List[int]) -> List[List[int]]:""":type nums: List[int]:rtype: List[List[int]]"""def backtrack(first = 0): #first:第几个位置;i:待填数的下标if first == n: #说明已经填完了n个数字,找到一个可行解放入答案组中(递归结束条件)res.append(nums[:])for i in range(first, n):nums[first], nums[i] = nums[i], nums[first]#将nums划分为左右两个部分,左边表示已填过数,右边表示待填的数,递归搜索时我们动态维护这个数组backtrack(first + 1) #继续递归填下一个数nums[first], nums[i] = nums[i], nums[first] #撤销之前填的数(即回溯)n = len(nums) #输入序列长度res = [] #输出结果backtrack()return res #测试用print
leetcode39.组合总和
from typing import List
class Solution:def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:size = len(candidates)if size == 0:return []# 剪枝是为了提速,在本题非必需candidates.sort()# 在遍历的过程中记录路径,它是一个栈path = []res = []# 注意要传入 size ,在 range 中, size 取不到self.__dfs(candidates, 0, size, path, res, target)return resdef __dfs(self, candidates, begin, size, path, res, target):# 先写递归终止的情况if target == 0:# Python 中可变对象是引用传递,因此需要将当前 path 里的值拷贝出来# 或者使用 path.copy()res.append(path[:])returnfor index in range(begin, size):residue = target - candidates[index]# “剪枝”操作,不必递归到下一层,并且后面的分支也不必执行if residue < 0:breakpath.append(candidates[index])# 因为下一层不能比上一层还小,起始索引还从 index 开始self.__dfs(candidates, index, size, path, res, residue)path.pop()
回溯(python)相关推荐
- 迷宫算法之递归回溯python实现
目录 没有目录了,别看了. 0. 概要 上一张我们谈到prim算法,这一张我们使用递归回溯算法来实现迷宫算法,相对于随机prim算法,这个算法更容易理解,并且提出的概念相对较小.但原理不太一样,,这也 ...
- 蓝桥杯 ALGO-1004 无聊的逗 01背包+回溯 python
题目 这逗志芃也太无聊了吧,玩这么一个游戏- 为了这道题能拿个AC我花了三天的时间才搞清楚,感觉这蓝桥杯还是有点难度啊
- python异常处理_Python基础语法案例(Fibonacci):选择结构、循环结构、异常处理结构、代码优化...
推荐图书: <Python程序设计基础(第2版)>,ISBN:9787302490562,董付国,清华大学出版社,第16次印刷,清华大学出版社2019年度畅销图书 图书购买链接(京东):配 ...
- leetcode BFS(python+c++)
1.最小基因变化 思路:bfs搜索回溯 python: class Solution:def minMutation(self, start: str, end: str, bank: List[st ...
- Python的简史:一切从讨厌花括号开始
文章最后有免费的Python资料,获取方式,关注头条号,私信回复资料获取下载链接.资料目录在文章底部,欢迎评论转发收藏下载. 在1991年,荷兰人Guido van Rossum 不喜欢花括号,于是他 ...
- Python编程常见错误表现形式与原因分析
推荐图书: <Python程序设计(第3版)>,(ISBN:978-7-302-55083-9),清华大学出版社,2020年6月第1次印刷,7月第3次印刷 京东购买链接:https://i ...
- Python基础语法案例(Fibonacci):选择结构、循环结构、异常处理结构、代码优化
推荐图书: <Python程序设计基础(第2版)>,ISBN:9787302490562,董付国,清华大学出版社,第16次印刷,清华大学出版社2019年度畅销图书 图书购买链接(京东): ...
- python编程入门与案例详解-quot;Python小屋”免费资源汇总(截至2018年11月28日)...
原标题:"Python小屋"免费资源汇总(截至2018年11月28日) 为方便广大Python爱好者查阅和学习,特整理汇总微信公众号"Python小屋"开通29 ...
- “Python小屋”免费资源汇总(截至2018年11月28日)
为方便广大Python爱好者查阅和学习,特整理汇总微信公众号"Python小屋"开通29个月以来推送过的700多篇文章清单,如果需要本清单的电子版,可以在公众号后台发送消息&quo ...
- 哈佛大学教授亲自操刀,耗时10年整理的152本Python书籍
"Python世界上最好的语言,没有之一" 总体说明: 各分类中的文章是按发布时间逆序排列的,动态更新."Python小屋" 是Python爱好者值得 微搜一下 ...
最新文章
- 用动态实现扩展TVM
- hdu2006 求奇数的乘积【C++】
- 正则表达式的一点奇怪
- 皮一皮:师太请自重...
- 图解设计模式:抽象工厂
- Docker默认网络管理
- Servicehot:混合云泄露四大公有云的秘密
- 如何极速极速搭建个人博客?Copy攻城狮用的这一招很优秀!
- Python--print用法汇总
- 【转】移动客户端测试总结
- STL MAP用法详解
- matlab连接散射点,使用小波散射做信号分类
- U8采购入库单参照到货单查不到内容
- 基于JMF RTP的音视频传输
- 罗永浩是个挺能折腾的人
- 【原生微信小程序】 组件的使用,权限弹窗
- 智慧灯杆(路灯)控制系统平台架构的主要设备有哪些?
- 穆勒的报告显示特朗普没“通俄”后,总统先生开心的像只猴子
- Gartner发布《2021年企业低代码平台魔力象限》低码一体化平台成趋势
- 一个典型的微型计算机绘图系统,机械制图考试理论知识练习题
热门文章
- PS和PL共享DDR
- 【转】委外加工的核算流程
- 2022-01-27 使用liquibase管理mysql执行版本
- 手机qpython3 如何画图_记住这3个功能,一分钟掌握python sns作图
- CSS中的display与visibility
- sql同一张表统计数据生成多个统计列
- 公众号如何运营?我的经验总结
- 手把手教你做时间序列图
- Linux常见错误 “cp: omitting directory/ cp: :Permission denied”解决办法
- 初识linux之vim工具与bdb调试工具