529. Minesweeper
▶ 扫雷的扩展判定。已知棋盘上所有点的情况(雷区 '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的更多相关文章
- LN : leetcode 529 Minesweeper
lc 529 Minesweeper 529 Minesweeper Let's play the minesweeper game! You are given a 2D char matrix r ...
- Week 5 - 529.Minesweeper
529.Minesweeper Let's play the minesweeper game (Wikipedia, online game)! You are given a 2D char ma ...
- 529. Minesweeper扫雷游戏
[抄题]: Let's play the minesweeper game (Wikipedia, online game)! You are given a 2D char matrix repre ...
- LeetCode 529. Minesweeper
原题链接在这里:https://leetcode.com/problems/minesweeper/description/ 题目: Let's play the minesweeper game ( ...
- leetcode笔记(七)529. Minesweeper
题目描述 Let's play the minesweeper game (Wikipedia, online game)! You are given a 2D char matrix repres ...
- 529 Minesweeper 扫雷游戏
详见:https://leetcode.com/problems/minesweeper/description/ C++: class Solution { public: vector<ve ...
- [LeetCode] 529. Minesweeper 扫雷
Let's play the minesweeper game (Wikipedia, online game)! You are given a 2D char matrix representin ...
- LC 529. Minesweeper
Let's play the minesweeper game (Wikipedia, online game)! You are given a 2D char matrix representin ...
- 【LeetCode】529. Minesweeper 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS 日期 题目地址:https://leetco ...
随机推荐
- Java Spring-注解进行属性注入
2017-11-06 21:19:43 一.Spring的注解装配BeanSpring2.5 引入使用注解去定义Bean @Component 描述Spring框架中Bean Spring的框架中提供 ...
- wikioi 1035 火车停留 裸费用流
链接:http://wikioi.com/problem/1035/ 怎么说呢,只能说这个建图很有意思.因为只有m条道,然后能互相接在一起的连通,对每个点进行拆点,很有意思的一道裸费用留题. 代码: ...
- MVC3 之asp.net 与vb.net 互转练习
vb.net mvc3相关教程http://www.asp.net/mvc/overview/older-versions/getting-started-with-aspnet-mvc3/vb/ad ...
- spring boot与spring mvc的区别
Spring 框架就像一个家族,有众多衍生产品例如 boot.security.jpa等等.但他们的基础都是Spring 的 ioc和 aop ioc 提供了依赖注入的容器 aop ,解决了面向横切面 ...
- 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_ ...
- java.io.File中的 pathSeparator 与separator 的区别
先总的说一下区别: File.pathSeparator指的是分隔连续多个路径字符串的分隔符,例如: java -cp test.jar;abc.jar HelloWorld 就是指“;” ...
- memcache+php实现页面访问的加速
一.什么是memcache memcache是目前主流的一个高性能的分布式内存对象缓存系统:它以key-value形式在内存中存储数据.由于数据缓存在内存中,所以相比操作DB而言,它不需要解析SQL. ...
- 一个简单的观察者模式的JS实现
这不是原创文章,主要是写给自己看的.原文比较详细容易让人,我提取最简单最好理解的部分,便于我以后用到.参考http://www.cnblogs.com/TomXu/archive/2012/03/02 ...
- 关键词提取算法-TextRank
今天要介绍的TextRank是一种用来做关键词提取的算法,也可以用于提取短语和自动摘要.因为TextRank是基于PageRank的,所以首先简要介绍下PageRank算法. 1.PageRank算法 ...
- linux 服务器性能调优总结
1.性能分析的几个方面 https://blog.csdn.net/w174504744/article/details/53894127 2.cpu 性能分析工具 perf https://blog ...