Battleships in a Board战列舰队问题解法分析
2017-03-24 21:05
357 查看
问题详见:Battleships in a Board
Given an 2D board, count how many 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.
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?
解题思路:
由题目可知该问题中战列舰队是有在同一行或者同一列的X战舰组成的舰队,而且两个战列舰队之间不会重复和毗邻。所以我们可以用DFS和BFS的方法对其进行查找。下面是两种算法的C++代码和提交结果图。DFS:
class Solution { public: int m, n; vector<vector<bool>> flag; int go[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; void dfs(vector<vector<char>>& board, int i, int j) { if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] == '.' || flag[i][j]) return; flag[i][j] = true; for (int d = 0; d < 4; ++d) dfs(board, i+go[d][0], j+go[d][1]); } int countBattleships(vector<vector<char>>& board) { if (board.empty()) return 0; m = board.size(), n = board[0].size(); flag.resize(m, vector<bool>(n, false)); int result = 0; for (int i = 0; i < m; ++i) for (int j = 0; j < n; ++j) if (board[i][j] == 'X' && !flag[i][j]) { ++result; dfs(board, i, j); } return result; } };
BFS:
class Solution { public: int go[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; int countBattleships(vector<vector<char>>& board) { if (board.empty()) return 0; int m = board.size(), n = board[0].size(); vector<vector<bool>> flag(m, vector<bool>(n, false)); int result = 0; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (board[i][j] == 'X' && !flag[i][j]) { ++result; queue<pair<int, int>> q; q.push({i, j}); while (!q.empty()) { auto t = q.front(); q.pop(); flag[t.first][t.second] = true; for (int d = 0; d < 4; ++d) { int ni = t.first+go[d][0], nj = t.second+go[d][1]; if (ni < 0 || ni >= m || nj < 0 || nj >= n || board[ni][nj] == '.' || flag[ni][nj]) continue; q.push({ni, nj}); } } } } } return result; } };
然而我们发现还有一种更加简单的方法可以得出结果。那就是根据题目中对战列舰队的严格限制的规则的利用。我们可以判断搜索到的点是属于已经查找到的战列舰队还是一个新的战列舰队中的一个战舰,只需要判断这个点在2D空间的上一个和左一个位置是否存在战舰(搜索按照从上往下从左到右的顺序),如果存在说明该战舰属于已经查找到的战列舰队,否则就是新的战列舰队(根据题意即使只有一个战舰也能构成战列舰队)。所以我们得出如下的简单算法:
class Solution { public: int countBattleships(vector<vector<char>>& board) { int count = 0; for(int i=0;i<board.size();i++) for(int j=0;j<board[0].size();j++) if(board[i][j]=='X' && (i==0 || board[i-1][j]!='X') && (j==0 || board[i][j-1]!='X')) count++; return count; } };
提交运行结果:
相关文章推荐
- Battleships in a Board问题及解法
- Knight Probability in Chessboard问题及解法
- 分析in和exists的区别与执行效率的问题 (3)
- 分析in和exists的区别与执行效率的问题
- LeetCode[419] Battleships in a Board
- Battleships in a Board
- LeetCode 419 Battleships in a Board (DFS 或 模拟)
- 分析in和exists的区别与执行效率的问题
- Battleships in a Board
- mybatis异常:Improper inline parameter map format. Should be: #{propName,attr1=val1,attr2=val2}问题分析及解决
- IMP-00008: unrecognized statement in the export file: string的问题分析
- leetcode oj java Battleships in a Board
- 出现java.lang.UnsupportedClassVersionError: Bad version number in .class file问题的解决方法分析
- Populating Next Right Pointers in Each Node问题另一种解法
- 关于Address already in use: connect问题分析及解决方案
- battleships-in-a-board
- ACL控制icmp数据包问题分析(ACL挂法IN,OUT分析)
- 八皇后问题解法及算法分析
- mybatis异常:Improper inline parameter map format. Should be: #{propName,attr1=val1,attr2=val2}问题分析及解决
- Spark 2.0 DataFrame map操作中Unable to find encoder for type stored in a Dataset.问题的分析与解决