文章目录

  • 前言
  • bfs类问题
  • 双向bfs
  • 例题实战

前言

文章若有疏忽还请指正,更多精彩还请关注公众号:bigsai

在搜索问题中,以迷宫问题最具有代表性,无论是八皇后的回溯问题,还是dfs找出口,bfs找最短次数等等题目的问题。在我们刚开始ac的时候、可能有着很多满足感!感觉是个迷宫问题咱么都可以给他这么搜出来 !!

然而,当数据达到一定程度,我们使用简单的方法肯定会爆炸的,****。就可能需要一些特殊的巧妙方法处理,比如各种剪枝优先队列A*dfs套bfs,又或者利用一些非常厉害的数学方法比如康托展开(逆展开)等等。而今天,我们谈谈双向bfs

bfs类问题

bfs又称广度优先搜索

  • 估计大部分人第一次接触bfs的时候是在学习数据结构的二叉树的层序遍历!借助一个队列一层一层遍历。
  • 第二次估计就是在学习图论的时候,给你一个图,让你写出一个bfs遍历的顺序。

此后再无bfs…

而很多笔试面试还是其他机试其实对bfs的要求远远不止那么低的,需要能够处理一些小问题、写出对应代码。而事bfs可以处理很多问题,很多dfs搜索能够解决的问题bfs也能解决很多(相反也成立),并且很多跟状态有些关系的用bfs更好控制,因为bfs借助的是一个队列实现,队列中储存节点就可以保存一些节点的状态。

不过bfs并不是万能的,具体问题要看迷宫的大小的,迷宫长宽没增加一个数,那么这个数量级增加是非常大的,因为搜索次数大概和边长的指数级别有关系。当然这里不详细介绍bfs了,大家可以看以前的一篇文章。数据结构与算法—图论之dfs、bfs(深度优先搜索、宽度优先搜索)。

双向bfs

什么样的情况可以使用双向bfs来优化呢?其实双向bfs的主要思想是问题的拆分吧,比如在一个迷宫中可以往下往右行走,问你有多少种方式从左上到右下。

  • 正常情况下,我们就是搜索遍历,如果迷宫边长为n,那么这个复杂度大概是2n级别.
  • 但是实际上我们可以将迷宫拆分一下,比如根据对角线(比较多),将迷宫一分为二。其实你的结果肯定必然经过对角线的这些点对吧!我们只要分别计算出各个对角线各个点的次数然后相加就可以了!
  • 怎么算? 就是从(0,0)到中间这个点mid的总次数为n1,然后这个mid到(n,n)点的总次数为n2,然后根据排列组合总次数就是n1*n2(n1和n2正常差不多大)这样就可以通过乘法减少加法的运算次数啦!
  • 简单的说,从数据次数来看如果直接搜索全图经过下图的那个点的次数为n1*n2次,如果分成两个部分相乘那就是n1+n2次。两者差距如果n1,n2=1000左右,那么这么一次差距是平方(根号)级别的。从搜索图形来看其实这么一次搜索是本来一个n*n大小的搜索转变成n次(每次大概是(n/2)*(n/2)大小的迷宫搜索两次)。也就是如果18*18的迷宫如果使用直接搜索,那么大概2^18次方量级,而如果采用双向bfs,那么就是2^9这个量级。

例题实战

题目链接:http://oj.hzjingma.com/contest/problem?id=20&pid=8#problem-anchor


分析:对于题目的要求还是很容易理解的,就是找到所有的路径种类,再判断其中是对称路径的有几个输出即可!

对于一个普通思考是这样的,首先是进行dfs,然后动态维护一个字符串,每次跑到最后判断这个路径字符串是否满足对称要求,如果满足那么就添加到容器中进行判断。可惜很遗憾这样是超时的,仅能通过40%的样例。

接着用普通bfs进行尝试,维护一个node节点,每次走的时候路径储存起来其实这个效率跟dfs差不多依然超时。只能通过40%数据。

接下来就开始双向bfs进行分析

  • 既然只能右下,那么对角线的那个位置的肯定是中间的那个字符串的!它的存在不影响是否对称的(n*n的迷宫路径长度为n-1 + n为奇数).
  • 我们判断路径是否对称,只需要判断从(1,1)到对角节点k(设为k节点)的路径有没有和(n,n)到k相同的。如果有路径相同的那么就说明这一对构成对称路径
  • 在具体实现上,我们对每个对角线节点可以进行两次bfs(一次左上到(1,1),一次右下到(n,n)).并且将路径放到两个hashset(set1,set2)中,跑完之后用遍历其中一个hashset中的路径,看看另一个set是否存在该路径,如果存在就说明这个是对称路径放到 总的hashset(set) 中。对角线每个位置都这样判断完最后只需要输出总的hashset(set)的集合大小即可!

ac代码如下:

import java.util.ArrayDeque;
import java.util.HashSet;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;public class test2 {   static class node{int x;int y;String path="";public node() {}public node(int x,int y,String team){this.x=x;this.y=y;this.path=team;}}public static void main(String[] args) {Scanner sc=new Scanner(System.in);Set<String>set=new HashSet<String>();//储存最终结果int n=Integer.parseInt(sc.nextLine());char map[][]=new char[n][n];for(int i=0;i<n;i++){String string=sc.nextLine();map[i]=string.toCharArray();}Queue<node>q1=new ArrayDeque<node>();//左上的队列Queue<node>q2=new ArrayDeque<node>();//右下的队列for(int i=0;i<n;i++){q1.clear();q2.clear();Set<String>set1=new HashSet<String>();//储存zuoshangSet<String>set2=new HashSet<String>();//储右下q1.add(new node(i,n-1-i,""+map[i][n-1-i]));q2.add(new node(i,n-1-i,""+map[i][n-1-i]));while(!q1.isEmpty()&&!q2.isEmpty()){node team=q1.poll();node team2=q2.poll();if(team.x==n-1&&team.y==n-1)//到终点,将路径储存{//System.out.println(team2.path); set1.add(team.path);set2.add(team2.path);}else {if(team.x<n-1)//可以向下{q1.add(new node(team.x+1, team.y, team.path+map[team.x+1][team.y]));}if(team.y<n-1)//可以向右{q1.add(new node(team.x, team.y+1, team.path+map[team.x][team.y+1]));}if(team2.x>0)//上{q2.add(new node(team2.x-1, team2.y, team2.path+map[team2.x-1][team2.y]));}if(team2.y>0)//左{q2.add(new node(team2.x, team2.y-1, team2.path+map[team2.x][team2.y-1]));}}}for(String va:set1){if(set2.contains(va)){set.add(va);}}}System.out.println(set.size());        }
}


浅谈迷宫搜索类的双向bfs问题(例题解析)相关推荐

  1. 数据结构实验之图论四:迷宫探索_迷宫搜索类的双向bfs问题(例题详解)

    前言 文章若有疏忽还请指正! 更多精彩还请关注公众号:bigsai 头条号:一直码农一直爽 在搜索问题中,以迷宫问题最具有代表性,无论是八皇后的回溯问题,还是dfs找出口,bfs找最短次数等等题目的问 ...

  2. 广度优先搜索解决欧拉回路时间复杂度_迷宫搜索类的双向bfs问题(例题详解)

    前言 文章若有疏忽还请指正! 更多精彩还请关注公众号:bigsai 头条号:一直码农一直爽 在搜索问题中,以迷宫问题最具有代表性,无论是八皇后的回溯问题,还是dfs找出口,bfs找最短次数等等题目的问 ...

  3. python新式类和旧式类的区别_浅谈python新式类和旧式类区别

    python的新式类是2.2版本引进来的,我们可以将之前的类叫做经典类或者旧式类. 为什么要在2.2中引进new style class呢?官方给的解释是: 为了统一类(class)和类型(type) ...

  4. 浅谈ipad阅读类应用设计

    自古以来,人们从阅读中了解最新资讯,学习知识,陶冶情操.随着社会和科技的发展,新的阅读设备,阅读方式,丰富的多媒体展示,让阅读这一人类行为更加高效化和多样化.对于平板电脑这个较新的媒介,我们如何能进一 ...

  5. 计算机方面的文献在哪里找,最新浅谈计算机参考文献 浅谈计算机专著类参考文献哪里找...

    [100个]关于最新浅谈计算机参考文献汇总,作为大学生的毕业生应该明白了浅谈计算机专著类参考文献哪里找,收集好参考文献后的浅谈计算机论文写作起来会更轻松! 一.浅谈计算机论文参考文献范文 [1]浅谈计 ...

  6. 浅谈Perl的类、包、模块与面对对象编程

    http://blog.chinaunix.net/uid-27464093-id-3308003.html Perl面向对象Perl面向对象学习例子实例代码教程 - 在我们了解perl的面向对象的概 ...

  7. 浅谈淘宝类目属性体系:商品搜索背后的逻辑架构

    转载自:http://www.geekpark.net/news/205894 摘要 淘宝拥有百万家商户和超过10亿的商品数,它如何让用户精准地找到想要的商品呢?其背后有着强大的技术支撑. 淘宝目前在 ...

  8. 浅谈京东搜索关键词排名规则

    本人在没有参加京东 搜索训练 营培训以前,一直从事的都是搜索引擎的优化工作.毫不吹嘘的说,对中文分词.以及用户的需求分析有一点自己的心得的.刚参加 完 上海站的培训,有点战战兢兢的,毕竟到上海的前一天 ...

  9. 浅谈 深度优先搜索与广度优先搜索

    文章目录 深度优先搜索(DFS) 广度优先搜索(BFS) 区别 DFS例题:八皇后问题 AC代码 思路整理 BFS例题:奇怪的电梯 AC代码 思路整理 深度优先搜索(DFS) 深搜在无减枝的情况下,一 ...

最新文章

  1. 利用memcached做缓存服务器,为后端tomcat服务器做会话保持,利用httpd的jk模块模块做负载均衡...
  2. 淮北师范大学计算机学院在哪个校区,2021年淮北师范大学信息学院有几个校区,大一新生在哪个校区...
  3. 重写equals就必须重写hashCode的原理分析
  4. Leetcode 22.括号生成 (每日一题 20210623)
  5. 你真的懂select Socket模型吗?
  6. video标签 添加视频
  7. android+note2+分辨率,魅蓝Note2的屏幕尺寸是多少?魅蓝Note2的分辨率是多少?
  8. 【Java】异常处理的目的
  9. GNU/Linux下有多少是GNU的?
  10. 联想杨元庆:未来五年研发总投入将会超过1000亿人民币
  11. python怎样连续输入两个数字_在python中生成连续的数字,同时输入不变
  12. 如何在Java客户端调用RESTful服务
  13. Python 系统管理利器Fabric
  14. python 使用 ipx协议_肝了三天,万字长文教你玩转 tcpdump,从此抓包不用愁
  15. vue+nodejs+element 实现drawio绘图效果
  16. MicroSIP编译完全手册
  17. UI设计中有哪些常见的风格?
  18. 对手游渠道商的一些看法
  19. 使用yguard混淆,名字出现超长字符 map=“ooooooooooooooo”
  20. 如何将摄像机拍摄信号采集到直播软件

热门文章

  1. SAGE(SAGEMATH)密码学基本使用方法
  2. 【Pygame小游戏】这款休闲游戏你肯定了解过《开心消消乐》更新版本上线,好土好喜欢
  3. 【Flask】flask入门以及第一个flask项目的创建
  4. python——面向对象进阶之新增属性和方法
  5. 主机信息收集技术 -Nmap
  6. Android的AlertDialog详解
  7. Debian部署postgresql并允许远程连接
  8. EPROCESS ETHREAD简介
  9. 【安全漏洞】某CMS后台防护逻辑漏洞导致GETSHELL
  10. 挖掘 OSINT 金矿——实习生和社交媒体