IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> LeetCode算法题10:DFS/BFS-扫雷游戏 -> 正文阅读

[数据结构与算法]LeetCode算法题10:DFS/BFS-扫雷游戏


前言

??????DFS 和 BFS,可参考之前的一篇文章:https://blog.csdn.net/Little_ant_/article/details/123415889?spm=1001.2014.3001.5501 介绍了二者的伪代码实现和关于 BFS 实现时需要注意的地方。

扫雷游戏

??????题目链接:https://leetcode-cn.com/problems/minesweeper/

??????题目描述:
让我们一起来玩扫雷游戏!

给你一个大小为 m x n 二维字符矩阵 board ,表示扫雷游戏的盘面,其中:

‘M’ 代表一个 未挖出的 地雷,
‘E’ 代表一个 未挖出的 空方块,
‘B’ 代表没有相邻(上,下,左,右,和所有4个对角线)地雷的 已挖出的 空白方块,
数字(‘1’ 到 ‘8’)表示有多少地雷与这块 已挖出的 方块相邻,
‘X’ 则表示一个 已挖出的 地雷。
给你一个整数数组 click ,其中 click = [clickr, clickc] 表示在所有 未挖出的 方块(‘M’ 或者 ‘E’)中的下一个点击位置(clickr 是行下标,clickc 是列下标)。

根据以下规则,返回相应位置被点击后对应的盘面:

如果一个地雷(‘M’)被挖出,游戏就结束了- 把它改为 ‘X’ 。
如果一个 没有相邻地雷 的空方块(‘E’)被挖出,修改它为(‘B’),并且所有和其相邻的 未挖出 方块都应该被递归地揭露。
如果一个 至少与一个地雷相邻 的空方块(‘E’)被挖出,修改它为数字(‘1’ 到 ‘8’ ),表示相邻地雷的数量。
如果在此次点击中,若无更多方块可被揭露,则返回盘面。

DFS :

??????思路为:1,如果当前位置元素为’M’,修改其为’X‘并返回;如果为’E’的话,这里注意和简单的 DFS 有点差异,区别在于简单的 DFS 这时便可以对当前位置元素做访问或修改,但是本题中需要首先判断当前位置周围 8 个元素的状态,然后根据结果来对当前位置进行修改。2,根据题意,DFS 递归的情况仅针对于当前位置为’B’的情况,相对的是如果当前位置为数字的话,不需要进行递归了。参考代码如下:

    int[] xi={1,0,0,-1,1,1,-1,-1};
    int[] yi={0,1,-1,0,-1,1,-1,1};
    public char[][] updateBoard(char[][] board, int[] click) {
        int x=click[0],y=click[1];
        if(board[x][y]=='M'){
            board[x][y]='X';
            return board;
        }
        solve(board,x,y);
        return board;
    }
    public void solve(char[][] board,int x,int y){
        //和一般 DFS 不一样的是:当前位置的判断依赖于其周围位置元素的状态
        int count=0;
        for(int i=0;i<8;i++){
            int newX=x+xi[i],newY=y+yi[i];
            if(newX<0||newY<0||newX>=board.length||newY>=board[0].length)
                continue;
            if(board[newX][newY]=='M')
                count++;
        }
        if(count!=0)
            board[x][y]=(char)('0'+count);
        else{
            board[x][y]='B';
            for(int i=0;i<8;i++){
                int newX=x+xi[i],newY=y+yi[i];
                if(newX<0||newY<0||newX>=board.length||newY>=board[0].length)
                    continue;
                if(board[newX][newY]=='E')//这里注意仅对未翻开的格子进行递归判断。
                    solve(board,newX,newY);
            }
        }
    } 

BFS

?????? BFS 中,为了避免相同元素重复入队有两种解决方法:1,在入队时修改其值,2,采用标记数组。本题没法在入队时修改其值,所以采用标记数组的方法(在入队时标记)。此问题在博客https://blog.csdn.net/Little_ant_/article/details/123415889?spm=1001.2014.3001.5501有提到过。参考代码如下:

public char[][] updateBoard(char[][] board, int[] click) {
        int[] xi={1,0,0,-1,1,1,-1,-1};
        int[] yi={0,1,-1,0,-1,1,-1,1};
        int x=click[0],y=click[1];
        LinkedList<int[]> queue=new LinkedList<>();
        queue.add(new int[]{x,y});
        if(board[x][y]=='M'){
            queue.remove();
            board[x][y]='X';
        }
        int count;
        boolean[][] flag=new boolean[board.length][board[0].length];
        flag[x][y]=true;
        while(!queue.isEmpty()){
            int[] tmp=queue.poll();
            x=tmp[0];
            y=tmp[1];
            count=0;
            for(int i=0;i<8;i++){
                int newX=x+xi[i],newY=y+yi[i];
                if(newX<0||newY<0||newX>=board.length||newY>=board[0].length)
                    continue;
                if(board[newX][newY]=='M')
                    count++;
            }
            if(count!=0)
                board[x][y]=(char)('0'+count);
            else{
                board[x][y]='B';
                for(int i=0;i<8;i++){
                    int newX=x+xi[i],newY=y+yi[i];
                    if(newX<0||newY<0||newX>=board.length||newY>=board[0].length||flag[newX][newY])
                        continue;
                    if(board[newX][newY]=='E'){
                        queue.add(new int[]{newX,newY});//没法在入队时更改其值,因为现在还不确定其状态。
                        flag[newX][newY]=true;
                    }
                }
            }
        }
        return board;
    }

总结

??????完

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-04-01 00:19:45  更:2022-04-01 00:23:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 9:33:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码