荒废好久了,临近毕业都没什么时间更新博客,希望入职以后能更多的关注自身技术的提升。先刷点算法题吧~
描述
给一个 2D 板, 计数上面有多少战舰. 战舰用 'X'
表示,空地用 '.'
表示。你可以假设有一下规则:
- 你会得到一个有效的板,上面只有战舰跟空地。
- 战舰只能横着或者竖着放。换句话说,它们的大小只能是
1xN
(1 行, N 列) 或者Nx1
(N 行, 1 列), N 可以是任意数。 - 在两艘战舰之间至少有一个横向的或者纵向的格子分隔 - 没有相邻的战舰
样例
样例1
输入:
X..X
...X
...X
输出: 2
解释:
在上述板上有两艘战舰。
样例2
输入:
...X
XXXX
...X
解释:
这是一个你不会得到的无效输入 - 因为战舰之间始终会有一个单元格分隔。
挑战
你可以只遍历一遍,并且值使用O(1)的额外空间且不修改板上的值来解决这个问题吗
思路:要求只能遍历一次,并且对于每个单位的位置有特殊要求。。我们可以通过找每个单位的左上角来计数,其特点无非是board[i][j-1] =='.' &&board[i-1][j]=='.' && board[i][j]=='X'.
注意这里对于无效图形的判定规则。
AC代码如下:
class Solution { public: /** * @param board: the given 2D board * @return: the number of battle ships */ int countBattleships(vector<vector<char>> &board) { // Write your code here int res = 0; if(board.size() == 0) return res; 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] == '.':true) && (j>0?board[i][j-1] == '.':true)){//左上角计数,注意边界 ++res; } if(board[i][j] == 'X' && i>0 && j>0){//判断图形是否有效! int temp = 0; board[i][j-1] == 'X'?temp+=1:0; board[i-1][j-1] == 'X'?temp+=1:0; board[i-1][j] == 'X'?temp+=1:0; if(temp == 2) return -1; } } } return res; } };