解题过程
:::info
题目链接
给你一个大小为 m x n 的矩阵 board 表示甲板,其中,每个单元格可以是一艘战舰 ‘X’ 或者是一个空位 ‘.’ ,返回在甲板 board 上放置的 战舰 的数量。
战舰 只能水平或者垂直放置在 board 上。换句话说,战舰只能按 1 x k(1 行,k 列)或 k x 1(k 行,1 列)的形状建造,其中 k 可以是任意大小。两艘战舰之间至少有一个水平或垂直的空位分隔 (即没有相邻的战舰) :::
/**
* @link https://leetcode.cn/problems/battleships-in-a-board/
* @title 419. 甲板上的战舰
* @description 给你一个大小为 m x n 的矩阵 board 表示甲板,其中,每个单元格可以是一艘战舰 'X' 或者是一个空位 '.' ,返回在甲板 board 上放置的 战舰 的数量。
* 战舰 只能水平或者垂直放置在 board 上。换句话说,战舰只能按 1 x k(1 行,k 列)或 k x 1(k 行,1 列)的形状建造,其中 k 可以是任意大小。两艘战舰之间至少有一个水平或垂直的空位分隔 (即没有相邻的战舰)
* @param {character[][]} board
* @return {number}
*/
// 解法一:
// 思路:题目愣是看了十几分钟没搞懂啥意思,确实理解题目成本很大,解题思路一脸懵逼😭
// 这题是看了评论和题解意思在理解做的:【战舰只能按 1 x k(1 行,k 列)或 k x 1(k 行,1 列)的形状建造,也就是说横着或者竖着相连的 'X'都代表同一艘战舰,以此为条件统计不相邻战舰数量】
// 战舰只能以行放置或以列放置为解题突破口
var countBattleships = function (board) {
let count = 0
for (let i = 0; i < board.length; i++) {
for (let j = 0; j < board[i].length; j++) {
if (board[i][j] === 'X') {
// 直接统计战舰数量——战舰的头部:(这里将战舰靠近上侧、靠近左侧的的一个'X' 作为它的头)
count++
if (i > 0 && board[i - 1][j] === 'X') {
// 相邻的行数,但非战舰的头部
count--
}
if (j > 0 && board[i][j - 1] === 'X') {
// 相邻的列数,但非战舰的头部
count--
}
}
}
}
return count
}
// const result = countBattleships([["X",".",".","X"],[".",".",".","X"],[".",".",".","X"]]) // 2
// const result = countBattleships([['.']]) // 0
const result = countBattleships([["X","X","X","X"],[".",".",".","X"],[".",".",".","X"]]) // 1
console.log(result)
解题感受
这道题做的真的痛苦,首先理解题目意思都很费劲,愣是没搞清楚【在甲板 board 上放置的 战舰 的数量】的逻辑,因为说到两个限制条件:
- 战舰只能水平或者垂直放置在 board 上。换句话说,战舰只能按 1 x k(1 行,k 列)或 k x 1(k 行,1 列)的形状建造,其中 k 可以是任意大小
- 两艘战舰之间至少有一个水平或垂直的空位分隔 (即没有相邻的战舰)
整懵了,不过一开始老是以为是战舰是战船上甲板上放置的飞机,哈哈哈哈,看了评论,我好傻,题目都理解错了,把自己整笑了
原来甲板就是为建造战舰(一辆船)的存放地方,所以就是要在这个甲板上统计战舰群的战舰数量,矩阵上相邻的行或列的 ‘X’ 可以作为建造战舰的同一个地方,不相邻的才算新的一个地方,也许这样,统计的时候只需计算全部出现 ‘X’ 的坐标,然后在根据上分或左侧是否出现过 ‘X’ 在进行排除即可