LeetCode419 Battleships in a Board

文章目录
  1. 1. 描述
  2. 2. 样例
  3. 3. 思路
  4. 4. 代码

描述

Given an 2D board, count how many different battleships are in it. The battleships are represented with 'X's, empty slots are represented with '.'s. You may assume the following rules:

  • You receive a valid board, made of only battleships or empty slots.
  • Battleships can only be placed horizontally or vertically. In other words, they can only be made of the shape 1xN (1 row, N columns) or Nx1 (N rows, 1 column), where N can be of any size.
  • At least one horizontal or vertical cell separates between two battleships - there are no adjacent battleships.

样例

1
2
3
X..X
...X
...X

In the above board there are 2 battleships.

Invalid Example:

1
2
3
...X
XXXX
...X

This is an invalid board that you will not receive - as battleships will always have a cell separating between them.

Follow up:
Could you do it in one-pass, using only O(1) extra memory and without modifying the value of the board?

思路

给一个n*m的棋盘,上面有一些N×1或者是1×N的战舰(N可以为任意数,只要非零且不超过棋盘大小),其中任意两个战舰之间有一个空方块隔开,问有多少艘战舰。

这题直观的想法是求有多少个连通分量,dfs一下即可。但是这没用到”N×1或者是1×N”这个性质,思考之后发现,其实只需判断一个 ‘X’ 的左边或者是上边是否也有 ‘X’ 即可,若没有,这就说明这个 X 是属于一个新的战舰,答案加1。扫一遍棋盘即可,不用额外的数组,也不需要修改棋盘(dfs的做法则需要)。

代码

DFS版:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Solution {
public:
int r, c;

void dfs(vector<vector<char>>& board, int x, int y) {
board[x][y] = '.';
int dir[4][2] = {{0, 1}, {0, -1}, {-1, 0}, {1, 0}};
for (int k = 0; k < 4; ++k) {
int nx = x + dir[k][0], ny = y + dir[k][1];
if (nx < 0 || nx >= r || ny < 0 || ny >= c || board[nx][ny] == '.') continue;
dfs(board, nx, ny);
}
}

int countBattleships(vector<vector<char>>& board) {
int ans = 0;
r = board.size();
c = board[0].size();
for (int i = 0; i < r; ++i) {
for (int j = 0; j < c; ++j) {
if (board[i][j] == 'X') {
dfs(board, i, j);
ans++;
}
}
}
return ans;
}
};

扫一遍即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public:
int countBattleships(vector<vector<char>>& board) {
int r = board.size(), c = board[0].size();
int ans = 0;
for (int i = 0; i < r; ++i) {
for (int j = 0; j < c; ++j) {
if (board[i][j] == 'X') {
if ((i - 1 < 0 || i - 1 >= 0 && board[i - 1][j] != 'X') &&
(j - 1 < 0 || j - 1 >= 0 && board[i][j - 1] != 'X')) ans++;
}
}
}
return ans;
}
};

分享到 评论