0-1BFS 双端队列 广度优先搜索

news2024/9/22 11:24:49

一. BFS及0-1BFS的简单介绍 

        深度优先搜索DFS和广度优先搜索BFS是经常使用的搜索算法,在各类题目中都有广泛的应用。

        深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次。
        广度优先搜索算法(Breadth-First Search,缩写为 BFS),又称为宽度优先搜索,是一种图形搜索算法。简单的说,BFS 是从根结点开始,沿着树的宽度遍历树的结点。如果所有结点均被访问,则算法中止。

        一般来说,能用DFS的,一般都可以用BFS解决,反过来同理。但是不同的题目,对于DFS和BFS的复杂度可能是有些差别的,对于有些题目,用BFS更容易解决,会有更少的时间复杂度。

        在上文:

BFS (Java) 广度优先搜索 简单介绍、模板、案例(一)

中,给出了BFS的简单介绍,模板和相关案例。那么在本文中,主要来介绍0-1BFS,或者说双端队列BFS。对于简单的BFS类题目,我们在队列尾部进行一直添加即可,但有些题目则不能满足需求,需要在头尾进行添加或者删除元素,我们称作0-1BFS或者双端队列BFS,而对于头尾的操作,可能是不同的,比如头不增加深度,而尾增加深度。

二. 简单模板

class Solution {
    public BFS(TreeNode root) {
        //双端队列,用来存储元素
        Deque<TreeNode> queue = new ArrayDeque<>();
        //添加首个元素
        queue.add(首个元素);
        //当队列不为空一直进行循环,直到队列不再有元素
        while(!queue.isEmpty()){

            if(限制条件){

               头操作,更新深度,或者相反;

            } 

            else{

               尾操作,不更新深度,或者相反;

            }   
    
        }
        返回答案;
    }
}

 

三. 案例

leetcode 1263 推箱子

「推箱子」是一款风靡全球的益智小游戏,玩家需要将箱子推到仓库中的目标位置。

游戏地图用大小为 m x n 的网格 grid 表示,其中每个元素可以是墙、地板或者是箱子。

现在你将作为玩家参与游戏,按规则将箱子 'B' 移动到目标位置 'T' :

玩家用字符 'S' 表示,只要他在地板上,就可以在网格中向上、下、左、右四个方向移动。
地板用字符 '.' 表示,意味着可以自由行走。
墙用字符 '#' 表示,意味着障碍物,不能通行。 
箱子仅有一个,用字符 'B' 表示。相应地,网格上有一个目标位置 'T'。
玩家需要站在箱子旁边,然后沿着箱子的方向进行移动,此时箱子会被移动到相邻的地板单元格。记作一次「推动」。
玩家无法越过箱子。
返回将箱子推到目标位置的最小 推动 次数,如果无法做到,请返回 -1。

输入:grid = [["#","#","#","#","#","#"],
             ["#","T","#","#","#","#"],
             ["#",".",".","B",".","#"],
             ["#",".","#","#",".","#"],
             ["#",".",".",".","S","#"],
             ["#","#","#","#","#","#"]]
输出:3
解释:我们只需要返回推箱子的次数。

class Solution {
    int row;
    int col;
    char[][] grid;
    public int minPushBox(char[][] grid) {
        //初始化
        this.grid = grid;
         row = grid.length;
         col = grid[0].length;
        int pi = 0, pj = 0, bi = 0, bj = 0;
        for(int i = 0; i < row; i++){
            for(int j = 0; j < col; j++){
                if(grid[i][j] == 'S'){
                    pi = i;
                    pj = j;
                }
                if(grid[i][j] == 'B'){
                    bi = i;
                    bj = j;
                }
            }
        }
        int[] dirs = new int[]{-1,0,1,0,-1};
        Deque<int[]> q = new ArrayDeque<>();
        boolean[][] vis = new boolean[row*col][row*col];
        q.offer(new int[]{get(pi, pj), get(bi,bj), 0});
        vis[get(pi,pj)][get(bi,bj)] = true;
        while(!q.isEmpty()){
            var p = q.poll();
            int d = p[2];
            bi = p[1]/col;
            bj = p[1]%col;
            pi = p[0]/col;
            pj = p[0]%col;
            if(grid[bi][bj] == 'T'){
                return d;
            }
            for(int k = 0; k < 4; k++){
                int px = pi + dirs[k];
                int py = pj + dirs[k+1];
                if(!check(px,py)){
                    continue;
                }
                if(px == bi && py == bj){
                    int bx = bi + dirs[k];
                    int by = bj + dirs[k+1];
                    if(!check(bx,by) || vis[get(px,py)][get(bx,by)]){
                        continue;
                    }
                    vis[get(px,py)][get(bx,by)] = true;
                    q.offer(new int[]{get(px,py), get(bx,by), d+1});
                }
                else if(!vis[get(px,py)][get(bi, bj)]){
                    vis[get(px,py)][get(bi, bj)] = true;
                    q.offerFirst(new int[]{get(px,py), get(bi,bj), d});
                }
            }
        }
        return -1;
    }
    public int get(int i, int j){//映射
        return i*col + j;
    }
    public boolean check(int i, int j){//检查坐标是否合规
        return i >= 0 && i < row && j >= 0 && j < col && grid[i][j] != '#';
    }
}

本题小结:(1)判断新位置{px,py}和箱子{bi,bj}位置是否相同,相同则证明能推动箱子

               (2)推动箱子,则深度+1,即对应推动次数,添加至尾部

               (3)未推动箱子,深度不变,添加至头部

练习题目:

leetcode 1368. 使网格图至少有一条有效路径的最小代价
leetcode 2290. 到达角落需要移除障碍物的最小数目

参考来源

 [1] leetcode ylb [Python3/Java/C++/Go/TypeScript] 一题一解:双端队列 BFS(清晰题解)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/708387.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pwn学习day3——函数调用约定

文章目录 x32 cdecl调用约定x64 System V AMD64 ABI调用约定 规定函数调用时如何传递参数&#xff0c;如何返回值&#xff0c;如何进行栈管理 x32 cdecl调用约定 参数从右往左依次压入栈中&#xff0c;返回值存入eax寄存器中,由调用者清理栈上的参数。 测试程序&#xff1a; …

转载-【AI思维空间】Chat2DB 一款开源数据库客户单工具

卸载 Navicat&#xff0c; xxx 又开源了一款数据库神器&#xff0c;太炸了 Chat2DB 是一款有开源免费的多数据库客户端工具&#xff0c;支持windows、mac本地安装&#xff0c;也支持服务器端部署&#xff0c;web网页访问。和传统的数据库客户端软件Navicat、DBeaver 相比Chat2D…

基于JSP+Servlet+Mysql的智能化停车场管理系统(含论文)

TOC 一、系统介绍 项目类型&#xff1a;Java web项目 项目名称&#xff1a;基于JSPServlet的智能智能停车场管理系统 源码作者&#xff1a;未知 项目架构&#xff1a;B/S架构 开发语言&#xff1a;Java语言 前端技术&#xff1a;HTML、CSS、JS等技术 后端技术&#xff…

中国国债发行数据集(2002-2023)

国债是由国家发行的债券&#xff0c;由于国债的发行主体是国家&#xff0c;所以它具有最高的信用度&#xff0c;被公认为是最安全的投资工具。国债按照交易市场的不同分为三类&#xff0c;即银行间市场国债、交易所市场国债和柜台市场国债&#xff1b;按照交易方式的不同分为三…

PCB绘制封装

绘制封装 常见的电阻封装如下&#xff1a; 绘制封装的一般步骤&#xff1a; 丝印不重要&#xff0c;关键是焊盘。 第一步是确认中心(对称中心)&#xff1b;第二步&#xff0c;围绕着对称中心&#xff0c;放置焊盘。直插式的焊盘要放大孔径&#xff0c;贴片式的焊盘要加长&am…

springboot-配置优先级

配置文件 类型 1.properties(三者同时存在&#xff0c;优先级最高) 2.yml 3.yaml&#xff08;最低&#xff09; 除此之外&#xff0c;可以在启动配置处修改 //java系统属性配置, -Dserver.port8080&#xff0c;优先级高于以上三种 //命令行参数 --server.port10010&#xff0…

【SQL应知应会】行列转换(一)• MySQL版

欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 本文收录于SQL应知应会专栏,本专栏主要用于记录对于数据库的一些学习&#xff0c;有基础也有进阶&#xff0c;有MySQL也有Oracle 行列转换 • Mysql版 一、MySQL行列转换1.准备操作…

kafka入门,数据去重(九)

数据传递语义 至少一次&#xff1a;ACK级别设置为-1分区副本大于等于2ISR里应答的最小副本数量大于等于2 最多一次&#xff1a;ACK级别设置为0 总结&#xff1a; At Least Once&#xff1a;可以保证数据不丢失&#xff0c;但是不能保证数据不重复 At Most Once&#xff1a;可以…

智慧园区运营管理平台解决方案

智慧园区运营管理平台是当今现代城市发展中的一项重要工具。随着城市人口不断增长&#xff0c;对城市基础设施和服务的需求也不断增加。为了有效管理和优化园区内的各项运营活动&#xff0c;智慧园区运营管理平台应运而生。 智慧园区运营管理平台是基于现代信息技术和互联网技术…

10W+前端面试题面试资料八股文

点击下方链接获取全部内容文档题目及其答案: 10W前端面试题&面试资料&八股文题目及其答案 https://m.tb.cn/h.5a7v237?tkQeVPdsoKwr4 CZ3457 部分题目如下&#xff1a; 1. call丶apply丶bind区别及源码实现&#xff08;手写&#xff09; 不同点&#xff1a; call…

HTML 编辑器的介绍及推荐

HTML 编辑器 HTML 编辑器是用于编写 HTML 的工具&#xff0c;使用 HTML 编辑器时以编辑主题&#xff0c;索引&#xff0c;自定义窗口&#xff0c;选择添加搜索页。 使用 Notepad 或 TextEdit 来编写 HTML 下列是三种专门用于编辑 HTML 的 HTML 编辑器&#xff1a; Adobe Dream…

ChatGPT实战:高考志愿填报

近期&#xff0c;随着各地陆续发布高考成绩&#xff0c;高考志愿填报市场随之升温&#xff0c;“高报师”再次成为“香饽饽”。填报志愿对中学生来说太难&#xff0c;在一个懵懂的年纪做这样一个决策&#xff0c;份量是比较重的。当普通人没很多的信息做参考的时候&#xff0c;…

【测试效率提升技巧】xmind测试用例转换为excel工具使用手册

【测试效率提升技巧】xmind测试用例转换为excel工具使用手册 一、前置环境配置二、执行Xmind2testcase的转换方法1.在控制台输入xmind2testcase [path/xmind文件路径] [-csv] [-xml] [-json]&#xff0c;例&#xff1a;xmind2testcase /root/homin/XX测试点.xmind -csv ##在当前…

HBase(14):HBase架构

1 系统架构 1.1 Client 客户端,例如:发出HBase操作的请求。例如:之前我们编写的Java API代码、以及HBase shell,都是CLient 1.2 Master Server 在HBase的Web UI中,可以查看到Master的位置。 监控RegionServer处理RegionServer故障转移处理元数据的变更处理region的分配或…

【Python 随练】学用 circle 函数画圆形。

题目&#xff1a; 画图&#xff0c;学用circle函数画圆形。 简介&#xff1a; 在本篇博客中&#xff0c;我们将介绍如何使用Python的绘图库来画圆形。我们将使用circle函数来绘制圆形&#xff0c;并提供一个完整的代码示例来演示其用法。 绘制圆形&#xff1a; 要绘制圆形…

使用Megascans,Blender和Substance 3D画家创建渔人旅馆(p1)

今天瑞云渲染小编给大家带来一篇Polina Tarakanova分享的Fishermans Inn项目背后的工作流程&#xff0c;展示了如何完成水分效果&#xff0c;并解释了照明的设置方式。 介绍 你好! 我叫Polina Tarakanova&#xff0c;今年30岁&#xff0c;是一名来自莫斯科的初级环境艺术家。从…

ISE软件基本使用

ISE软件基本使用 基本设置 关联notepad的操作&#xff1a;选择notepad的exe文件路径&#xff0c;并且加 { } 符号&#xff0c;并在结尾加$1。ISE可以设置程序运行的速度等级&#xff0c;该速度等级会影响程序从外部SPI Flash启动的启动速度。JTAG 接口的作用是将编译好的程 序…

pikache靶场通关——CSRF攻击

文章目录 前言使用工具第一关&#xff08;host&#xff1a;192.168.1.107&#xff09;、CSRF(get) loginStep.1、以受害者身份登录账号Step.2、以受害者身份点击修改个人信息的按钮Step.3、以黑客身份使用burp进行抓包&#xff08;查看对面修改格式&#xff09;Step4、以黑客身…

文件打包解包的方法

文件打包 前言 在很多情况下&#xff0c;软件需要隐藏一些图片&#xff0c;防止用户对其更改&#xff0c;替换。例如腾讯QQ里面的资源图片&#xff0c;哪怕你用Everything去搜索也搜索不到&#xff0c;那是因为腾讯QQ对这些资源图片进行了打包&#xff0c;当软件运行的时候解…

在SpringBoot中的Jackson使用笔记

在SpringBoot中的Jackson使用笔记 常用的java转json&#xff0c;json反序列化为java等方法&#xff0c;这里定义成一个工具类来用jackson package cn.ath.knowwikibackend.util;import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.Jso…