LeetCode 419.甲板上的战舰

619 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天,点击查看活动详情.

LeetCode 419.甲板上的战舰

题目描述

给你一个大小为 m x n 的矩阵 board 表示甲板,其中,每个单元格可以是一艘战舰 'X' 或者是一个空位 '.' ,返回在甲板 board 上放置的 战舰 的数量。

战舰 只能水平或者垂直放置在 board 上。换句话说,战舰只能按 1 x k(1 行,k 列)或 k x 1(k 行,1 列)的形状建造,其中 k 可以是任意大小。两艘战舰之间至少有一个水平或垂直的空位分隔 (即没有相邻的战舰)。

示例 进阶:你可以实现一次扫描算法,并只使用 O(1) 额外空间,并且不修改 board 的值来解决这个问题吗?

解题思路

思路一:DFS(深度优先搜索)

先不考虑空间复杂度, 那么这道题跟LeetCode 200. 岛屿数量 - 掘金 (juejin.cn)解法一样,实现代码如下:

/**
 * @param {character[][]} board
 * @return {number}
 */
var countBattleships = function(board) {
    let count = 0, rowLen = board.length, colLen = board[0].length;

    const dfs = function (row, col) {
        if (row < 0 || row >= rowLen || col < 0 || col >= colLen || board[row][col] === '.') {
            return;
        }
        board[row][col] = '.'; // 沉没
        dfs(row - 1, col);
        dfs(row + 1, col);
        dfs(row, col + 1);
        dfs(row, col - 1);
    }

    for (let row = 0; row < rowLen; row++) {
        for (let col = 0; col < colLen; col++) {
            if (board[row][col] === 'X') {
                count++;
                dfs(row, col);
            }
        }
    }

    return count; 
};

但如何只使用 O(1) 额外空间,并且不修改 board 的值来解决这个问题呢?

思路二:枚举起点

根据题意, 我们已知两艘战舰不会相邻,且战舰只能是1xk或者kx1的形式;所以,我们搜索的时候其实不用搜索四个方向,只需要查找每个战舰的左上顶点即可统计战舰的个数。及满足以下条件即可:

  • 满足当前位置所在的值 board[row][col] === 'X';
  • 满足当前位置的左则为空位,即 board[row][col−1] === '.';
  • 满足当前位置的上方为空位,即 board[row−1][col] === '.';

实现代码如下:

/**
 * @param {character[][]} board
 * @return {number}
 */
var countBattleships = function(board) {
    let count = 0, rowLen = board.length, colLen = board[0].length;

    for (let row = 0; row < rowLen; row++) {
        for (let col = 0; col < colLen; col++) {
            if (board[row][col] === 'X') {
                if (row > 0 && board[row - 1][col] === 'X') {
                    continue;
                }
                if (col > 0 && board[row][col - 1] === 'X') {
                    continue;
                }
                count++; 
            }
        }
    }

    return count; 
};
  • 时间复杂度:O(m×n),其中 m 是矩阵的行数,n 是矩阵的列数,我们只需要遍历一遍矩阵中每个位置即可。

  • 空间复杂度: O(1)

参考资料

LeetCode 419.甲板上的战舰 - 力扣(LeetCode)