回溯算法

  • 回溯利用递归的性质,从问题的起始点出发,不断地进行尝试,回头一步甚至多步再做选择,直到最终抵达终点的过程。回溯解决问题的所有选项可以形象的用树状结构表示,每一条路径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)相关推荐

  1. 迷宫算法之递归回溯python实现

    目录 没有目录了,别看了. 0. 概要 上一张我们谈到prim算法,这一张我们使用递归回溯算法来实现迷宫算法,相对于随机prim算法,这个算法更容易理解,并且提出的概念相对较小.但原理不太一样,,这也 ...

  2. 蓝桥杯 ALGO-1004 无聊的逗 01背包+回溯 python

    题目 这逗志芃也太无聊了吧,玩这么一个游戏- 为了这道题能拿个AC我花了三天的时间才搞清楚,感觉这蓝桥杯还是有点难度啊

  3. python异常处理_Python基础语法案例(Fibonacci):选择结构、循环结构、异常处理结构、代码优化...

    推荐图书: <Python程序设计基础(第2版)>,ISBN:9787302490562,董付国,清华大学出版社,第16次印刷,清华大学出版社2019年度畅销图书 图书购买链接(京东):配 ...

  4. leetcode BFS(python+c++)

    1.最小基因变化 思路:bfs搜索回溯 python: class Solution:def minMutation(self, start: str, end: str, bank: List[st ...

  5. Python的简史:一切从讨厌花括号开始

    文章最后有免费的Python资料,获取方式,关注头条号,私信回复资料获取下载链接.资料目录在文章底部,欢迎评论转发收藏下载. 在1991年,荷兰人Guido van Rossum 不喜欢花括号,于是他 ...

  6. Python编程常见错误表现形式与原因分析

    推荐图书: <Python程序设计(第3版)>,(ISBN:978-7-302-55083-9),清华大学出版社,2020年6月第1次印刷,7月第3次印刷 京东购买链接:https://i ...

  7. Python基础语法案例(Fibonacci):选择结构、循环结构、异常处理结构、代码优化

    推荐图书: <Python程序设计基础(第2版)>,ISBN:9787302490562,董付国,清华大学出版社,第16次印刷,清华大学出版社2019年度畅销图书 图书购买链接(京东): ...

  8. python编程入门与案例详解-quot;Python小屋”免费资源汇总(截至2018年11月28日)...

    原标题:"Python小屋"免费资源汇总(截至2018年11月28日) 为方便广大Python爱好者查阅和学习,特整理汇总微信公众号"Python小屋"开通29 ...

  9. “Python小屋”免费资源汇总(截至2018年11月28日)

    为方便广大Python爱好者查阅和学习,特整理汇总微信公众号"Python小屋"开通29个月以来推送过的700多篇文章清单,如果需要本清单的电子版,可以在公众号后台发送消息&quo ...

  10. 哈佛大学教授亲自操刀,耗时10年整理的152本Python书籍

    "Python世界上最好的语言,没有之一" 总体说明: 各分类中的文章是按发布时间逆序排列的,动态更新."Python小屋" 是Python爱好者值得 微搜一下 ...

最新文章

  1. 用动态实现扩展TVM
  2. hdu2006 求奇数的乘积【C++】
  3. 正则表达式的一点奇怪
  4. 皮一皮:师太请自重...
  5. 图解设计模式:抽象工厂
  6. Docker默认网络管理
  7. Servicehot:混合云泄露四大公有云的秘密
  8. 如何极速极速搭建个人博客?Copy攻城狮用的这一招很优秀!
  9. Python--print用法汇总
  10. 【转】移动客户端测试总结
  11. STL MAP用法详解
  12. matlab连接散射点,使用小波散射做信号分类
  13. U8采购入库单参照到货单查不到内容
  14. 基于JMF RTP的音视频传输
  15. 罗永浩是个挺能折腾的人
  16. 【原生微信小程序】 组件的使用,权限弹窗
  17. 智慧灯杆(路灯)控制系统平台架构的主要设备有哪些?
  18. 穆勒的报告显示特朗普没“通俄”后,总统先生开心的像只猴子
  19. Gartner发布《2021年企业低代码平台魔力象限》低码一体化平台成趋势
  20. 一个典型的微型计算机绘图系统,机械制图考试理论知识练习题

热门文章

  1. PS和PL共享DDR
  2. 【转】委外加工的核算流程
  3. 2022-01-27 使用liquibase管理mysql执行版本
  4. 手机qpython3 如何画图_记住这3个功能,一分钟掌握python sns作图
  5. CSS中的display与visibility
  6. sql同一张表统计数据生成多个统计列
  7. 公众号如何运营?我的经验总结
  8. 手把手教你做时间序列图
  9. Linux常见错误 “cp: omitting directory/ cp: :Permission denied”解决办法
  10. 初识linux之vim工具与bdb调试工具