419.甲板上的戰艦(dfs, 沉沒戰艦)

無聲有寒發表於2020-10-08

給定一個二維的甲板, 請計算其中有多少艘戰艦。 戰艦用 'X'表示,空位用 '.'表示。 你需要遵守以下規則:

給你一個有效的甲板,僅由戰艦或者空位組成。
戰艦隻能水平或者垂直放置。換句話說,戰艦隻能由 1xN (1 行, N 列)組成,或者 Nx1 (N 行, 1 列)組成,其中N可以是任意大小。
兩艘戰艦之間至少有一個水平或垂直的空位分隔 - 即沒有相鄰的戰艦。
示例 :

X..X
...X
...X
在上面的甲板中有2艘戰艦。

無效樣例 :

...X
XXXX
...X
你不會收到這樣的無效甲板 - 因為戰艦之間至少會有一個空位將它們分開。

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/battleships-in-a-board
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。


思考

我們打算遍歷這個二維陣列,然後遇到X就開始就記個數。但這樣有個問題,比如又變那一列,3個X其實是一艘戰艦,如果遇上了都數一遍,就會重複數。

所以數過的戰艦需要“沉沒”掉,把"X"變為"."

怎樣探索一艘戰艦包含哪些X呢,注意到戰艦隻能橫向或者縱向成一豎。

首先檢查點有沒有越界,是不是在甲板上(X),不是的話直接返回。

符合條件的話:

我們就先將這個點變成".",然後對這個點進行深度優先搜尋,向四周探索。

探索到下一個X點,就繼續dfs.

下圖註釋

遍歷二維陣列,到(0,0),發現是X。船數+1

就dfs(0,0)

    將board[0][0] = "."

    然後dfs四周的點。發現左邊和上邊的點越界了,右邊和下邊的點不是X,所以直接返回。

 

然後遍歷(0,1),  (0,2), 都不是X,沒事

 

到(0,3)了,它是X,船數+1. dfs(0,3)

 首先將board[0][3]置為"."

dfs四周的點。

左邊不是X,上和右邊越界了,直接返回。

dfs(1,3)

沒有越界,且是X

board[1][3] 置為"."

dfs四周

這個時候,左邊上邊都不是X,右邊越界,直接返回。

 

dfs(2,3)

沒有越界,且是X

board[2][3] 置為"."

左邊,上邊都不是X,下邊和右邊越界,直接返回。

 

回到主遍歷線,遍歷(1,0), (1,1)......     (2,3),都沒找到X,所以返回戰艦數2


程式碼實現 

/**
 * @param {character[][]} board
 * @return {number}
 */
var countBattleships = function(board) {
    let result = 0
    for (let row = 0; row < board.length; row++) {
        for (let col = 0; col < board[0].length; col++) {
            if (board[row][col] === 'X') {
                result++
                dfs(row, col)
            }
        }
    }

    function dfs(row, col) {
        //當前點條件判斷
        //越界或不在甲板上直接返回
        if (row < 0 || row >= board.length || col < 0 || col >= board[0].length ||
        board[row][col] !== 'X') {
            return
        }

        //沉默當前點
        board[row][col] = '.'
        //對四個方向進行深度優先搜尋
        dfs(row-1, col)
        dfs(row+1, col)
        dfs(row, col-1)
        dfs(row, col+1)
    }

    return result

}; 

 

相關文章