▶ 扫雷的扩展判定。已知棋盘上所有点的情况(雷区 'M',已翻开空白区 'B',未翻开空白区 'E',数字区 '1' ~ '8'),现在给定一个点击位置(一定在空白区域),若命中雷区则将被命中的 M 改为 X,若命中空白区则将点击位置扩展为带有数字边界的安全区。

● 自己的解法,28 ms,深度优先遍历。改善了边界判定的方法,以后写类似的矩阵函数的时候可以借鉴。实际上可以在 extend 开头判定 click 是否在棋盘范围内,以后就可以强行 8 个方向搜索(见后面大佬的代码)

 class Solution
{
public:
vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click)
{
if (board[click[]][click[]] == 'M')
{
board[click[]][click[]] = 'X';
return board;
}
extend(board, click);
return board;
}
void extend(vector<vector<char>>& board, vector<int>& click)
{
const int row = board.size(), col = board[].size(), rowClick = click[], colClick = click[];
char location = ~;
int count = ;
vector<int> tempClick;
// 计算当前位置的相邻情况,location从左边起 8 位分别表示 右,右上,上,左上,左,左下,下,右下 是否有相邻块
if (colClick % col == col - ) // 右,11000001
location &= ~;
if (rowClick == ) // 上,01110000
location &= ~;
if (colClick % col == ) // 左,00011100
location &= ~;
if (rowClick == row - ) // 下,00000111
location &= ~;
// 统计周围雷数计数,从右开始,逆时针方向搜索
if (location & << && board[rowClick][colClick + ] == 'M')
count++;
if (location & << && board[rowClick - ][colClick + ] == 'M')
count++;
if (location & << && board[rowClick - ][colClick] == 'M')
count++;
if (location & << && board[rowClick - ][colClick - ] == 'M')
count++;
if (location & << && board[rowClick][colClick - ] == 'M')
count++;
if (location & << && board[rowClick + ][colClick - ] == 'M')
count++;
if (location & << && board[rowClick + ][colClick] == 'M')
count++;
if (location & << && board[rowClick + ][colClick + ] == 'M')
count++;
if (count)// 周围有雷,本地为数字,停止搜索
{
board[rowClick][colClick] = count + '';
return;
}
board[rowClick][colClick] = 'B';// 周围无雷,本地为安全区,继续搜索
if (location & << && board[rowClick][colClick + ] == 'E')
extend(board, tempClick = { rowClick, colClick + });
if (location & << && board[rowClick - ][colClick + ] == 'E')
extend(board, tempClick = { rowClick - , colClick + });
if (location & << && board[rowClick - ][colClick] == 'E')
extend(board, tempClick = { rowClick - , colClick });
if (location & << && board[rowClick - ][colClick - ] == 'E')
extend(board, tempClick = { rowClick - , colClick - });
if (location & << && board[rowClick][colClick - ] == 'E')
extend(board, tempClick = { rowClick, colClick - });
if (location & << && board[rowClick + ][colClick - ] == 'E')
extend(board, tempClick = { rowClick + , colClick - });
if (location & << && board[rowClick + ][colClick] == 'E')
extend(board, tempClick = { rowClick + , colClick });
if (location & << && board[rowClick + ][colClick + ] == 'E')
extend(board, tempClick = { rowClick + , colClick + });
return;
}
};

● 大佬的代码,38 ms,深度优先遍历,与后面的广度优先遍历在格式上保持一致

 class Solution
{
public:
vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click)
{
int m = board.size(), n = board[].size(), row = click[], col = click[];
int count, i, j, r, c;
vector<int>tempClick;
if (board[row][col] == 'M')
{
board[row][col] = 'X';
return board;
}
for (count = , i = -; i < ; i++)
{
for (j = -; j < ; j++)
{
if (i == && j == )
continue;
r = row + i, c = col + j;
if (r < || r >= m || c < || c < || c >= n)
continue;
if (board[r][c] == 'M' || board[r][c] == 'X')
count++;
}
}
if (count)
{
board[row][col] = (char)(count + '');
return board;
}
for (board[row][col] = 'B', i = -; i < ; i++)
{
for (j = -; j < ; j++)
{
if (i == && j == )
continue;
r = row + i, c = col + j;
if (r < || r >= m || c < || c < || c >= n)
continue;
if (board[r][c] == 'E')
updateBoard(board, tempClick = { r, c });
}
}
return board;
}
};

● 大佬的广度优先遍历,31 ms,最快的解法算法与之相同,但维护一个 unordered_set<int> 用于保存已经访问过的点来防止重复访问

 class Solution
{
public:
vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click)
{
const int m = board.size(), n = board[].size();
queue<vector<int>> q;
vector<int> cell;
int row, col, count, i, j, r, c;
for (q.push(click); !q.empty();)
{
cell = q.front(),q.pop();
row = cell[], col = cell[];
if (board[row][col] == 'M')
{
board[row][col] = 'X';
continue;
}
for (count = , i = -; i < ; i++)
{
for (j = -; j < ; j++)
{
if (i == && j == )
continue;
r = row + i, c = col + j;
if (r < || r >= m || c < || c < || c >= n)
continue;
if (board[r][c] == 'M' || board[r][c] == 'X')
count++;
}
}
if (count)
{
board[row][col] = (char)(count + '');
continue;
}
for (board[row][col] = 'B', i = -; i < ; i++)
{
for (j = -; j < ; j++)
{
if (i == && j == )
continue;
r = row + i, c = col + j;
if (r < || r >= m || c < || c < || c >= n)
continue;
if (board[r][c] == 'E')
{
q.push(vector<int>{r, c});
board[r][c] = 'B';
}
}
}
}
return board;
}
};

529. Minesweeper的更多相关文章

  1. LN : leetcode 529 Minesweeper

    lc 529 Minesweeper 529 Minesweeper Let's play the minesweeper game! You are given a 2D char matrix r ...

  2. Week 5 - 529.Minesweeper

    529.Minesweeper Let's play the minesweeper game (Wikipedia, online game)! You are given a 2D char ma ...

  3. 529. Minesweeper扫雷游戏

    [抄题]: Let's play the minesweeper game (Wikipedia, online game)! You are given a 2D char matrix repre ...

  4. LeetCode 529. Minesweeper

    原题链接在这里:https://leetcode.com/problems/minesweeper/description/ 题目: Let's play the minesweeper game ( ...

  5. leetcode笔记(七)529. Minesweeper

    题目描述 Let's play the minesweeper game (Wikipedia, online game)! You are given a 2D char matrix repres ...

  6. 529 Minesweeper 扫雷游戏

    详见:https://leetcode.com/problems/minesweeper/description/ C++: class Solution { public: vector<ve ...

  7. [LeetCode] 529. Minesweeper 扫雷

    Let's play the minesweeper game (Wikipedia, online game)! You are given a 2D char matrix representin ...

  8. LC 529. Minesweeper

    Let's play the minesweeper game (Wikipedia, online game)! You are given a 2D char matrix representin ...

  9. 【LeetCode】529. Minesweeper 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS 日期 题目地址:https://leetco ...

随机推荐

  1. Java Spring-注解进行属性注入

    2017-11-06 21:19:43 一.Spring的注解装配BeanSpring2.5 引入使用注解去定义Bean @Component 描述Spring框架中Bean Spring的框架中提供 ...

  2. wikioi 1035 火车停留 裸费用流

    链接:http://wikioi.com/problem/1035/ 怎么说呢,只能说这个建图很有意思.因为只有m条道,然后能互相接在一起的连通,对每个点进行拆点,很有意思的一道裸费用留题. 代码: ...

  3. MVC3 之asp.net 与vb.net 互转练习

    vb.net mvc3相关教程http://www.asp.net/mvc/overview/older-versions/getting-started-with-aspnet-mvc3/vb/ad ...

  4. spring boot与spring mvc的区别

    Spring 框架就像一个家族,有众多衍生产品例如 boot.security.jpa等等.但他们的基础都是Spring 的 ioc和 aop ioc 提供了依赖注入的容器 aop ,解决了面向横切面 ...

  5. WIN8.1 PRO RTM VOL.Enterprise.2013.10.17

    Windows 8.1 Pro VL (x64) - DVD (Chinese-Simplified)ISO|Chinese - Simplified|发布日期: 2013/10/17文件名: cn_ ...

  6. java.io.File中的 pathSeparator 与separator 的区别

    先总的说一下区别: File.pathSeparator指的是分隔连续多个路径字符串的分隔符,例如: java   -cp   test.jar;abc.jar   HelloWorld 就是指“;” ...

  7. memcache+php实现页面访问的加速

    一.什么是memcache memcache是目前主流的一个高性能的分布式内存对象缓存系统:它以key-value形式在内存中存储数据.由于数据缓存在内存中,所以相比操作DB而言,它不需要解析SQL. ...

  8. 一个简单的观察者模式的JS实现

    这不是原创文章,主要是写给自己看的.原文比较详细容易让人,我提取最简单最好理解的部分,便于我以后用到.参考http://www.cnblogs.com/TomXu/archive/2012/03/02 ...

  9. 关键词提取算法-TextRank

    今天要介绍的TextRank是一种用来做关键词提取的算法,也可以用于提取短语和自动摘要.因为TextRank是基于PageRank的,所以首先简要介绍下PageRank算法. 1.PageRank算法 ...

  10. linux 服务器性能调优总结

    1.性能分析的几个方面 https://blog.csdn.net/w174504744/article/details/53894127 2.cpu 性能分析工具 perf https://blog ...