529. Minesweeper

Description

Let's play the minesweeper game (Wikipedia, online game)!

You are given a 2D char matrix representing the game board. 'M' represents an unrevealed mine, 'E' represents an unrevealed empty square, 'B' represents a revealed blank square that has no adjacent (above, below, left, right, and all 4 diagonals) mines, digit ('1' to '8') represents how many mines are adjacent to this revealed square, and finally 'X' represents a revealed mine.

Now given the next click position (row and column indices) among all the unrevealed squares ('M' or 'E'), return the board after revealing this position according to the following rules:

  1. If a mine ('M') is revealed, then the game is over - change it to 'X'.
  2. If an empty square ('E') with no adjacent mines is revealed, then change it to revealed blank ('B') and all of its adjacent unrevealed squares should be revealed recursively.
  3. If an empty square ('E') with at least one adjacent mine is revealed, then change it to a digit ('1' to '8') representing the number of adjacent mines.
  4. Return the board when no more squares will be revealed.

Example 1:

Input:
[['E', 'E', 'E', 'E', 'E'],
['E', 'E', 'M', 'E', 'E'],
['E', 'E', 'E', 'E', 'E'],
['E', 'E', 'E', 'E', 'E']]

Click : [3,0]

Output:
[['B', '1', 'E', '1', 'B'],
['B', '1', 'M', '1', 'B'],
['B', '1', '1', '1', 'B'],
['B', 'B', 'B', 'B', 'B']]

Explanation:

image

Example 2:

Input:
[['B', '1', 'E', '1', 'B'],
['B', '1', 'M', '1', 'B'],
['B', '1', '1', '1', 'B'],
['B', 'B', 'B', 'B', 'B']]

Click : [1,2]

Output:
[['B', '1', 'E', '1', 'B'],
['B', '1', 'X', '1', 'B'],
['B', '1', '1', '1', 'B'],
['B', 'B', 'B', 'B', 'B']]

Explanation:

image

Note:

  1. The range of the input matrix's height and width is [1,50].
  2. The click position will only be an unrevealed square ('M' or 'E'), which also means the input board contains at least one clickable square.
  3. The input board won't be a stage when game is over (some mines have been revealed).
  4. For simplicity, not mentioned rules should be ignored in this problem. For example, you don't need to reveal all the unrevealed mines when the game is over, consider any cases that you will win the game or flag any squares.

Solution

BFS, time O(m * n), space O(m * n)

出隊列的時候根據(jù)節(jié)點是否挨著雷口锭,來更新節(jié)點的值麸俘。

class Solution {
    public static final int[][] DIRECTIONS
        = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}};
    
    public char[][] updateBoard(char[][] board, int[] click) {
        int x = click[0];
        int y = click[1];
        
        if (board[x][y] == 'M') {
            board[x][y] = 'X';
            return board;
        }
        
        Queue<int[]> queue = new LinkedList<>();
        queue.offer(new int[]{x, y});
        board[x][y] = '*';  // as a middle state
        
        while (!queue.isEmpty()) {
            int[] pos = queue.poll();
            int i = pos[0];
            int j = pos[1];
            int mineCount = getAdjacentMines(board, i, j);
            
            if (mineCount > 0) {
                board[i][j] = (char) ('0' + mineCount);
                continue;
            }
            
            board[i][j] = 'B';
            
            for (int[] direction : DIRECTIONS) {
                i = pos[0] + direction[0];
                j = pos[1] + direction[1];
                
                if (!isValid(board, i, j) || board[i][j] != 'E') {
                    continue;
                }
                
                queue.offer(new int[] {i, j});
                board[i][j] = '*';
            }
        }
        
        return board;
    }
    
    public int getAdjacentMines(char[][] board, int i, int j) {
        int count = 0;
        
        for (int[] direction : DIRECTIONS) {
            int x = i + direction[0];
            int y = j + direction[1];
            if (isValid(board, x, y) && board[x][y] == 'M') {
                ++count;
            }
        }
        
        return count;
    }
    
    public boolean isValid(char[][] board, int i, int j) {
        return i >= 0 && i < board.length && j >= 0 && j < board[0].length;
    }
}
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市喧伞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖吱涉,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異驶乾,居然都是意外死亡邑飒,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門级乐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來疙咸,“玉大人,你說我怎么就攤上這事风科∪雎郑” “怎么了胁编?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵本刽,是天一觀的道長邑狸。 經(jīng)常有香客問我履婉,道長影钉,這世上最難降的妖魔是什么帝簇? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任独令,我火速辦了婚禮赶促,結果婚禮上,老公的妹妹穿的比我還像新娘慨菱。我一直安慰自己焰络,他們只是感情好,可當我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布符喝。 她就那樣靜靜地躺著闪彼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪协饲。 梳的紋絲不亂的頭發(fā)上畏腕,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天,我揣著相機與錄音茉稠,去河邊找鬼描馅。 笑死,一個胖子當著我的面吹牛战惊,可吹牛的內(nèi)容都是我干的流昏。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼吞获,長吁一口氣:“原來是場噩夢啊……” “哼况凉!你這毒婦竟也來了?” 一聲冷哼從身側響起各拷,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤刁绒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后烤黍,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體知市,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年速蕊,在試婚紗的時候發(fā)現(xiàn)自己被綠了嫂丙。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡规哲,死狀恐怖跟啤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情唉锌,我是刑警寧澤隅肥,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站袄简,受9級特大地震影響腥放,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜绿语,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一秃症、第九天 我趴在偏房一處隱蔽的房頂上張望候址。 院中可真熱鬧,春花似錦种柑、人聲如沸宗雇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至泌神,卻和暖如春良漱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背欢际。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工母市, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人损趋。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓患久,卻偏偏與公主長得像,于是被迫代替她去往敵國和親浑槽。 傳聞我的和親對象是個殘疾皇子蒋失,可洞房花燭夜當晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容