529.掃雷游戲
https://leetcode-cn.com/problems/minesweeper/
題目描述
讓我們一起來玩掃雷游戲!
給定一個代表游戲板的二維字符矩陣, 'M' 代表一個未挖出的地雷,'E' 代表一個未挖出的空方塊,'B' 代表沒有相鄰(上,下,左,右,和所有4個對角線)地雷的已挖出的空白方塊,數字('1' 到 '8')表示有多少地雷與這塊已挖出的方塊相鄰,'X' 則表示一個已挖出的地雷,
現在給出在所有未挖出的方塊中('M'或者'E')的下一個點擊位置(行和列索引),根據以下規則,回傳相應位置被點擊后對應的面板:
- 如果一個地雷('M')被挖出,游戲就結束了- 把它改為 'X',
- 如果一個沒有相鄰地雷的空方塊('E')被挖出,修改它為('B'),并且所有和其相鄰的未挖出方塊都應該被遞回地揭露,
- 如果一個至少與一個地雷相鄰的空方塊('E')被挖出,修改它為數字('1'到'8'),表示相鄰地雷的數量,
- 如果在此次點擊中,若無更多方塊可被揭露,則回傳面板,
示例 1:
輸入:
[['E', 'E', 'E', 'E', 'E'],
['E', 'E', 'M', 'E', 'E'],
['E', 'E', 'E', 'E', 'E'],
['E', 'E', 'E', 'E', 'E']]
Click : [3,0]
輸出:
[['B', '1', 'E', '1', 'B'],
['B', '1', 'M', '1', 'B'],
['B', '1', '1', '1', 'B'],
['B', 'B', 'B', 'B', 'B']]
示例 2:
輸入:
[['B', '1', 'E', '1', 'B'],
['B', '1', 'M', '1', 'B'],
['B', '1', '1', '1', 'B'],
['B', 'B', 'B', 'B', 'B']]
Click : [1,2]
輸出:
[['B', '1', 'E', '1', 'B'],
['B', '1', 'X', '1', 'B'],
['B', '1', '1', '1', 'B'],
['B', 'B', 'B', 'B', 'B']]
注意:
- 輸入矩陣的寬和高的范圍為 [1,50],
- 點擊的位置只能是未被挖出的方塊 ('M' 或者 'E'),這也意味著面板至少包含一個可點擊的方塊,
- 輸入面板不會是游戲結束的狀態(即有地雷已被挖出),
- 簡單起見,未提及的規則在這個問題中可被忽略,例如,當游戲結束時你不需要挖出所有地雷,考慮所有你可能贏得游戲或標記方塊的情況,
題解:
-
當前點擊的是【未挖出來的雷】,我們將其改為X即可,表示點到了雷,然后結束,
-
當前點擊的是【為挖出的空方塊】,我們需要統計他周圍相鄰(八個)的方塊里的地雷的數量cnt(即M的數量),
如果cnt>0,就將當前方塊改為cnt的數字(附近的雷數)
如果cnt為0,則將其改為B,并遞回計算周圍八個未挖出的方塊,如果沒有更多方塊可以被揭露,則回傳面板,
實作:
public char[][] UpdateBoard (char[][] board, int[] click) {
int x = click[0], y = click[1];
//如果當前坐標位置處為M,則點中了“雷”,則Game over
if (board[x][y] == 'M') {
board[x][y] = 'X';
} else {
dfs (board, x, y);
}
return board;
}
//左、左上、上、右上、右、右下、下、左下
int[] vx = new int[] {-1, -1, 0, 1, 1, 1, 0, -1 };
int[] vy = new int[] { 0, -1, -1, -1, 0, 1, 1, 1 };
private void dfs (char[][] board, int x, int y) {
//計算當前點[x,y]周圍M(雷)的數量
int cnt = 0;
for (int i = 0; i < 8; i++) {
int currentX = x + vx[i];
int currentY = y + vy[i];
//跳過不符合遞回條件的塊
//1.如果坐標超出范圍
if (currentX < 0 || currentX >= board.Length || currentY < 0 || currentY >= board[0].Length) {
continue;
}
if (board[currentX][currentY] == 'M') {
cnt++;
}
}
//周圍M個數不為0時,將[x,y]處的值設定成cnt數字
if (cnt > 0) {
board[x][y] = (char) (cnt + '0');
}
//如果周圍沒有M(雷)時
else {
//將[x,y]初的值設定成B
board[x][y] = 'B';
//遞回周圍8個點
for (int i = 0; i < 8; i++) {
int currentX = x + vx[i];
int currentY = y + vy[i];
//跳過不符合遞回條件的塊
//1.如果坐標超出范圍
//2.或者當前坐標處值不為E,表示當前坐標已經處理過
if (currentX < 0 || currentX >= board.Length || currentY < 0 || currentY >= board[0].Length || board[currentX][currentY] != 'E') {
continue;
}
dfs (board, x + vx[i], y + vy[i]);
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/2199.html
標籤:其他
