▶ 扫雷的扩展判定。已知棋盘上所有点的情况(雷区 '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异常处理机制分析(上)

    过去曾有一段时间关于java的异常处理机制曾经让我吃尽苦头,异常机制看似简单,原理,用法也仅仅如此,但是,用起来或是在使用一些框架的时候总会因为使用不当,造成灾难性后果. jdk异常处理机制     ...

  2. gcd 与 扩gcd 总结

    gcd 定理的证明: 模板: ll gcd(ll a,ll b) { ) return a; else return gcd(b,a%b); } 扩gcd证明: 模板: ll extgcd(ll a, ...

  3. Holt-Winters模型原理分析

    Holt-Winters模型原理分析及代码实现(python) from:https://blog.csdn.net/u010665216/article/details/78051192 引言 最近 ...

  4. C#读写配置文件Config

    应用程序配置文件是标准的XML文件,XML标记和属性是区分大小写的.它是可以按需要更改的,开发人员可以使用配置文件来更改设置,而不必重编译应用程序.配置文件的根节点是configuration.我们经 ...

  5. UML类图中的各种箭头代表的含义(转自:http://www.cnblogs.com/damsoft/archive/2016/10/24/5993602.html)

    1.UML简介Unified Modeling Language (UML)又称统一建模语言或标准建模语言. 简单说就是以图形方式表现模型,根据不同模型进行分类,在UML 2.0中有13种图,以下是他 ...

  6. Servlet不是线程安全的。

    要解释为什么Servlet为什么不是线程安全的,需要了解Servlet容器(即Tomcat)使如何响应HTTP请求的. 当Tomcat接收到Client的HTTP请求时,Tomcat从线程池中取出一个 ...

  7. 手机dp和px的转换

    1dp   0.75px  ----> 320*240 1dp   1px      ----->480*320 1dp   1.5px   ----->800*480      4 ...

  8. CF-1055E:Segments on the Line (二分&背包&DP优化)(nice problem)

    You are a given a list of integers a 1 ,a 2 ,…,a n  a1,a2,…,an and s s of its segments [l j ;r j ] [ ...

  9. 《DSP using MATLAB》Problem 3.2

    1.用x1序列的DTFT来表示x2序列的DTFT 2.代码: %% ------------------------------------------------------------------ ...

  10. flow flow-typed 定义简单demo

    flow-typed 安装 全局 npm install -g flow-typed 测试代码 一个简单全局函数 目录根目录 flow-typed userLibDef.js declare func ...