赞
踩
给你一个大小为 m x n 的矩阵 board 表示甲板,其中,每个单元格可以是一艘战舰 'X' 或者是一个空位 '.' ,返回在甲板 board 上放置的 战舰 的数量。
战舰 只能水平或者垂直放置在 board 上。换句话说,战舰只能按 1 x k(1 行,k 列)或 k x 1(k 行,1 列)的形状建造,其中 k 可以是任意大小。两艘战舰之间至少有一个水平或垂直的空位分隔 (即没有相邻的战舰)。
示例 1:
输入:board = [["X",".",".","X"],[".",".",".","X"],[".",".",".","X"]]
输出:2
示例 2:
输入:board = [["."]]
输出:0
提示:
m == board.length
n == board[i].length
1 <= m, n <= 200
board[i][j] 是 '.' 或 'X'
进阶:你可以实现一次扫描算法,并只使用 O(1) 额外空间,并且不修改 board 的值来解决这个问题吗?
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/battleships-in-a-board
官方题解:
方法一:遍历扫描
题目要求找到矩阵中战舰的数量,战舰用’X’ 表示,空位用 ’.’,而矩阵中的战舰的满足以下两个条件:
战舰只能水平或者垂直放置。战舰只能由子矩阵 1×N(1 行,N 列)组成,或者子矩阵N×1(N 行, 1 列)组成,其中 N 可以是任意大小。
两艘战舰之间至少有一个水平或垂直的空位分隔,没有相邻的战舰。
我们遍历矩阵中的每个位置 (i,j)且满足board[i][j]=’X’,并将以 (i,j)(i,j) 为起点的战舰的所有位置均设置为空位,从而我们即可统计出所有可能的战舰。
- func countBattleships(board [][]byte) int {
- ans := 0
- m, n := len(board), len(board[0])//m:行,n:列
- for i, row := range board{//i为行号,row为每行这个一维切片
- for j, ch := range row{//j为第i行元素的各个元素的索引,ch为第i行的各个元素
- //相当于遍历数组
- if ch == 'X'{//当前位置存在战舰
- //把当前位置所在的行和列的元素都置为空
- row[j] = '.'//将其置为空
- for k := j + 1; k < n && row[k] == 'X'; k++{//当前行有战舰的地方均置为空
- row[k] = '.'
- }
- for k := i + 1; k < m && board[k][j] == 'X'; k++{//当前列有战舰的地方均置为空
- board[k][j] = '.'
- }
- ans++
- }
- }
- }
- return ans
- }

方法二:枚举起点
题目进阶要求一次扫描算法,只使用 O(1) 额外空间,并且不修改甲板的值。因为题目中给定的两艘战舰之间至少有一个水平或垂直的空位分隔,任意两个战舰之间是不相邻的,因此我们可以通过枚举每个战舰的左上顶点即可统计战舰的个数。假设矩阵的行数为 row,矩阵的列数 col,矩阵中的位置 (i, j)为战舰的左上顶点,需满足以下条件:
满足当前位置所在的值board[i][j]=’X’;
满足当前位置的左则为空位,即board[i][j−1]=’.’;
满足当前位置的上方为空位,即board[i−1][j]=’.’;
我们统计出所有战舰的左上顶点的个数即为所有战舰的个数。
- func countBattleships(board [][]byte) (ans int) {
- for i, row := range board {
- for j, ch := range row {
- if ch == 'X' && !(i > 0 && board[i-1][j] == 'X' || j > 0 && board[i][j-1] == 'X') {
- ans++
- }
- }
- }
- return
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。