Battleships in a Board(统计战舰数)

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:

  • 题目的中文翻译是本人所作,如有偏差敬请指正。
  • 其中的“个人分析”和“个人解法”均是本人最初的想法和做法,不一定是对的,只是作为一个对照和记录。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值