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.
(给定一个二维平面,计算在该平面上战舰的数目。用一系列’x’来表示战舰,用’.’来表示空位,规则如下:
● 给你一个由战舰或空位组成的有效平面
● 战舰只能水平或垂直放置,也就是说它们由一行N列或者N行一列组成,N可以为任何大小。
● 在俩战舰之间至少要有一个水平或垂直位置的间隔,没有相邻的。
)
Example:
X..X
…X
…X
In the above board there are 2 battleships.
Invalid Example:
…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?
1.参考思路
由战舰组成的示例可以看出,构成一艘战舰的最左上角字符’x’在它位置上的左上角是没有其他’x’的,所以可以统计二维数组中所有’x’左上角相邻位置没有其他’x’的数目,该统计结果就是战舰的数目。
2.参考解法
(1)
int countBattleships(vector<vector<char>>& board)
{
int row = board.size();
if(row == 0)
return 0;
int col = board[0].size();
int count = 0;
for (int i=0; i < row; ++i)
{
for (int j=0; j<col; ++j)
{
if(board[i][j] == '.') continue;
if(i > 0 && board[i-1][j] == 'X') continue;
if(j > 0 && board[i][j-1] == 'X') continue;
++count;
}
}
return count;
}
该算法的时间复杂度为O(m*n),空间复杂度为O(1)。
(2)洪泛填充(flood fill)
int countBattleships(vector<vector<char>>& board) {
int ret = 0;
for (int i = 0; i < board.size(); ++i) {
for (int j = 0; j < board[0].size(); ++j) {
if (board[i][j] == '.') continue;
dfs(board, i, j);
++ret;
}
}
return ret;
}
void dfs(vector<vector<char>> &board, int x, int y) {
if (board[x][y] == '.') return;
board[x][y] = '.';
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
for (int i = 0; i < 4; ++i) {
int xx = x + dx[i];
int yy = y + dy[i];
if (xx < 0 || xx == board.size() || yy < 0 || yy == board[0].size()) continue;
dfs(board, xx, yy);
}
}
该算法的时间复杂度为O(m*n)
3.总结
上面的解法一简单易懂,但实际上能想出这种巧妙的方法需要较强的观察分析能力。解法二则采用了DFS,由于涉及到递归,所以效率上远低于解法一。
PS:
- 题目的中文翻译是本人所作,如有偏差敬请指正。
- 其中的“个人分析”和“个人解法”均是本人最初的想法和做法,不一定是对的,只是作为一个对照和记录。