什么是回溯算法?

回溯法是一种系统搜索问题解空间的方法。为了实现回溯,需要给问题定义一个解空间。

说到底它是一种搜索算法。只是这里的搜索是在一个叫做解空间的地方搜索。

而往往所谓的dfs,bfs都是在图或者树这种数据结构上的搜索。

根据定义来看,要实现回溯,需要两点1搜索,2解空间

先看什么是解空间。

就是形如数组的一个向量[a1,a2,....,an]。这个向量的每个元素都是问题的部分解,只有当这个数组的每一个元素都填满(得到全部解)的时候,才表明这个问题得到了解答。

再看搜索。

最简单的就是for循环,上面的向量有n个维度,因此就是n个for循环。

形如:

for(求a1位置上的解)

for(求a2位置上的解)

for(求a3位置上的解)

......

......

for(求an位置上的解)

但是如果n是100?n是100000?那么如何回溯?

当然也可以写n个for循环,但是这样的程序会惨不忍睹。。。而且似乎10000个(不过往往回溯的时间复杂度太大,一般n不会这么大)for循环也很难写出来。。。

因此我们需要一种全新的书写回溯的方法。形如:

void backtrack(int i,int n,other parameters)

{

if( i == n)

{

//get one answer

record answer;

return;

}

//下面的意思是求解空间第i个位置上的下一个解

for(next ans in position i of solution space)

{

backtrack(i+1,n,other parameters);

}

}

就是这么简单!!!

上面的模板适用于所有"解空间确定"的回溯法的问题!!!

上面的i代表解空间的第i个位置,往往从0开始,而n则代表解空间的大小。每一次的backtrack(i,n,other)调用,代表求解空间第i个位置上的解。而当i=n时,代表解空间上的所有位置的解都已经求出。

有了上述模板,我们就解决了搜索的问题。

因此几乎所有回溯的问题的难度都在于如何定义解空间。

下面通过题目,带入模板,然后再看我的解答,来感知一下如何定义解空间。

全排列https://segmentfault.com/a/11...

即对没有重复数字的数组a=[a1,a2,a3,...an]求全排列。

解空间定义为s=[s1,s2,s3,....sn]与数字长度相同。s的每一个元素s【i】(i >= 0&&i < n),都为数组a中的任意元素a【j】(j >= 0&&j < n),不过要保证任意的s【i】不相等。

这里唯一复杂的地方是需要用一个boolean【】数组来表明哪些数已经用过,这样才能保证任意的s【i】不相等。

因此我们看到,回溯本身是很简单的,单纯的模板套用,难的在于需要根据回溯条件来定义各种别的变量,以及最后结果的记录。

探测路径https://leetcode-cn.com/probl... (这个下面给出ac 代码)

这个题很难,但是掌握了如何定义解空间之后再做这个题就会感觉是小儿科了。

这里的解空间s = [s1,s2,s3,....sn]中的每一个元素s【i】代表格子的坐标(x,y),因此从逻辑上来看,s应该是一个类类型的数组。不过,这个题求的是数目,而不是最后的确切路径,因此解空间在这里并没有记录。

java ac代码:

class Solution {

int ans;

public int uniquePathsIII(int[][] grid) {

if(grid.length == 0)return 0;

int num = 0;

int x = 0,y = 0;

for(int i = 0;i < grid.length;i++)

for(int j = 0;j < grid[0].length;j++){

if(grid[i][j] == 1||grid[i][j] == 0)num++;

if(grid[i][j] == 1){x = i;y = j;}

}

backtrack(0,num,x,y,grid,new boolean[grid.length][grid[0].length]);

return ans;

}

void backtrack(int i,int n,int x,int y,int[][]grid,boolean[][]flag)

{

if(!(x >= 0 && x < grid.length && y >= 0 && y < grid[0].length)||flag[x][y]||grid[x][y] == -1)

return;

if(i == n && grid[x][y] == 2)

{

ans++;

return;

}

flag[x][y] = true;

backtrack(i+1,n,x+1,y,grid,flag);

backtrack(i+1,n,x-1,y,grid,flag);

backtrack(i+1,n,x,y+1,grid,flag);

backtrack(i+1,n,x,y-1,grid,flag);

flag[x][y] = false;

}

}

上面这个题的解空间应该有N+1维才对,但是为了方便书写,我只求出前n维位置的解,然后保证最后一维中位置是终点即可。

如果仍然觉得抽象,那么我建议大家把回溯想象成“填格子”游戏。

到leetcode上找回溯的专题,对于每一个回溯法可解的问题,看看这题需要填的格子(格子就是解空间)是什么。

比如n个不重复字母的全排列,不就是填充n个格子,填满并且合法就得到一个解。

再比如在字母矩阵中搜索某个字符串比如"adrsad",那么格子有几维?不就是填充维度是n的格子(字符串s长度n),并且格子的第i(i从0开始到n-1)个维度上必须填s[i],否则都是不合法的。用这种思路再做这个题看看会不会好做很多。

再比如括号生成,这里的格子的数量是括号对数乘以2,格子上填的就是左括号或者右括号,这里的剪枝条件是,当前右括号数量超过了左括号,或左括号数量超过了一半。当然为了剪枝需要在函数参数中维护左右括号数这两个变量。

最后,为什么要掌握回溯法???

因为懂了回溯法之后笔试里的很多题就算AC不了,起码成功运行70%到90%之间是没问题的。

而且如果笔试题里有的数据集设计的不够好,那么回溯甚至可以比动态规划运行的还快。

而这对于获得面试机会已经足够了!!!

并且回溯很优美,很容易理解,因为说到底它不过就是个填格子的游戏罢了。

java回溯算法_回溯算法讲解--适用于leetcode绝大多数回溯题目相关推荐

  1. 回溯算法讲解--适用于leetcode绝大多数回溯题目

    什么是回溯算法? 回溯法是一种系统搜索问题解空间的方法.为了实现回溯,需要给问题定义一个解空间. 说到底它是一种搜索算法.只是这里的搜索是在一个叫做解空间的地方搜索. 而往往所谓的dfs,bfs都是在 ...

  2. cb32a_c++_STL_算法_查找算法_(5)adjacent_find

    cb32a_c++_STL_算法_查找算法_(5)adjacent_find adjacent_find(b,e),b,begin(),e,end() adjacent_find(b,e,p),p-p ...

  3. 回溯java算法_聊聊算法——回溯算法

    "递归只应天上有,迭代还须在人间",从这句话我们可以看出递归的精妙,确实厉害,递归是将问题规模逐渐减小, 然后再反推回去,但本质上是从最小的规模开始,直到目标值,思想就是数学归纳法 ...

  4. java寻优算法_模拟退火算法SA原理及python、java、php、c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径...

    模拟退火算法SA原理及python.java.php.c++语言代码实现TSP旅行商问题,智能优化算法,随机寻优算法,全局最短路径 模拟退火算法(Simulated Annealing,SA)最早的思 ...

  5. java调度问题的贪心算法_贪心算法——换酒问题

    知识回顾 贪心算法 (greedy algorithm),又称贪婪算法. 是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法. 贪心算法在 有最优子 ...

  6. python序列模式的关联算法_关联算法

    以下内容来自刘建平Pinard-博客园的学习笔记,总结如下: 1 Apriori算法原理总结 Apriori算法是常用的用于挖掘出数据关联规则的算法,它用来找出数据值中频繁出现的数据集合,找出这些集合 ...

  7. ls路由算法_路由算法详解

    路由算法详解1. 引言 2. 路由器基础知识 3. LS算法 4. 示例:Dijkstra算法 5. DV算法 6. 分级路由 如果您已经阅读过博闻网中的路由器工作原理一文,您会了解到路由器的作用是管 ...

  8. 层次聚类算法 算法_聚类算法简介

    层次聚类算法 算法 Take a look at the image below. It's a collection of bugs and creepy-crawlies of different ...

  9. 接受拒绝算法_通过算法拒绝大学学位

    接受拒绝算法 数据科学 (Data Science) Nina was close to tears when she accused Nick Gibb of ruining her life. N ...

最新文章

  1. 艺街开放平台开源计划
  2. Zabbix Server端配置文件说明
  3. jpa内网mysql_mysql+jpa简单实现步骤
  4. Android scroller控件,Android Scroller完全解析
  5. java计算时间的秒数差,去掉周末和节假日
  6. 密钥可以永久激活吗?
  7. Linux下重启MYSQL的命令
  8. C#面向对象三大特性(重要)
  9. MIMIC申请失败问题及其他问题答复
  10. 猫学习IOS(四)UI半小时就搞定Tom猫
  11. 微信小程序开发类似微博回复功能自带云开发数据库(无限回复)
  12. ORACLE学习笔记(6)(分析函数)
  13. 挡土墙lisp程序_挡土墙设计程序说明
  14. MATLAB数据预处理——导入,插补,绘图
  15. Castor XML
  16. 如何运用AI聊天机器人,助推内容营销活动取得成功?
  17. 大数据用户画像之基本概念(一)
  18. Linux学习手册(命令大全)
  19. Android系统架构原理
  20. python资料全集

热门文章

  1. 骑士 cms宝塔环境配置问题
  2. 爬虫清洗:python strip()函数 去空格\n\r\t函数的用法
  3. 4.3.1 求绝对值
  4. php创蓝253四要素认证_创蓝253配置
  5. Java输出英语字母对应的数字
  6. ♂【超全超详细】2W字零基础小白黑客学习路线,知识体系(附学习路线图)♂
  7. 工厂方法模式-----女娃造人的故事
  8. 数据结构(python) —— 【34: 动态规划之钢条切割问题】
  9. 呵呵,原来梦醒后一切这么美好(KK记)
  10. 指标波动的原因很头疼?不妨试试“问诊”法!