您的位置:首页 > 其它

Battleships in a Board(统计战舰数)

2016-11-07 16:39 274 查看
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:

题目的中文翻译是本人所作,如有偏差敬请指正。

其中的“个人分析”和“个人解法”均是本人最初的想法和做法,不一定是对的,只是作为一个对照和记录。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: