解题过程

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

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

  1. /**
  2. * @link https://leetcode.cn/problems/battleships-in-a-board/
  3. * @title 419. 甲板上的战舰
  4. * @description 给你一个大小为 m x n 的矩阵 board 表示甲板,其中,每个单元格可以是一艘战舰 'X' 或者是一个空位 '.' ,返回在甲板 board 上放置的 战舰 的数量。
  5. * 战舰 只能水平或者垂直放置在 board 上。换句话说,战舰只能按 1 x k(1 行,k 列)或 k x 1(k 行,1 列)的形状建造,其中 k 可以是任意大小。两艘战舰之间至少有一个水平或垂直的空位分隔 (即没有相邻的战舰)
  6. * @param {character[][]} board
  7. * @return {number}
  8. */
  9. // 解法一:
  10. // 思路:题目愣是看了十几分钟没搞懂啥意思,确实理解题目成本很大,解题思路一脸懵逼😭
  11. // 这题是看了评论和题解意思在理解做的:【战舰只能按 1 x k(1 行,k 列)或 k x 1(k 行,1 列)的形状建造,也就是说横着或者竖着相连的 'X'都代表同一艘战舰,以此为条件统计不相邻战舰数量】
  12. // 战舰只能以行放置或以列放置为解题突破口
  13. var countBattleships = function (board) {
  14. let count = 0
  15. for (let i = 0; i < board.length; i++) {
  16. for (let j = 0; j < board[i].length; j++) {
  17. if (board[i][j] === 'X') {
  18. // 直接统计战舰数量——战舰的头部:(这里将战舰靠近上侧、靠近左侧的的一个'X' 作为它的头)
  19. count++
  20. if (i > 0 && board[i - 1][j] === 'X') {
  21. // 相邻的行数,但非战舰的头部
  22. count--
  23. }
  24. if (j > 0 && board[i][j - 1] === 'X') {
  25. // 相邻的列数,但非战舰的头部
  26. count--
  27. }
  28. }
  29. }
  30. }
  31. return count
  32. }
  33. // const result = countBattleships([["X",".",".","X"],[".",".",".","X"],[".",".",".","X"]]) // 2
  34. // const result = countBattleships([['.']]) // 0
  35. const result = countBattleships([["X","X","X","X"],[".",".",".","X"],[".",".",".","X"]]) // 1
  36. console.log(result)

解题感受

这道题做的真的痛苦,首先理解题目意思都很费劲,愣是没搞清楚【在甲板 board 上放置的 战舰 的数量】的逻辑,因为说到两个限制条件:

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

整懵了,不过一开始老是以为是战舰是战船上甲板上放置的飞机,哈哈哈哈,看了评论,我好傻,题目都理解错了,把自己整笑了

原来甲板就是为建造战舰(一辆船)的存放地方,所以就是要在这个甲板上统计战舰群的战舰数量,矩阵上相邻的行或列的 ‘X’ 可以作为建造战舰的同一个地方,不相邻的才算新的一个地方,也许这样,统计的时候只需计算全部出现 ‘X’ 的坐标,然后在根据上分或左侧是否出现过 ‘X’ 在进行排除即可

参考答案

宫水三叶