QUESTION:
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) orNx1
(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?
EXPLANATION:
其实一开始想到的逻辑就是:
1.碰到一个x,那么就将他后面的所有x都换成。同时将他这一列的所有x都换成。
这样就相当于所有的ship都缩成了一个点,那么就很容易可以算出来了。
紧接着的followup就更容易了,不要缩成点。因为每次计算的时候,如果达到一个x,如果他的上一列这也是x,或者这一列前面也是x,那么说明这个x已经被计算过了。具体的可以看代码逻辑。
SOLUTION:
public class Solution {
public int countBattleships(char[][] board) {
int count = 0;
for(int i = 0;i<board.length;i++){
char[] tmp = board[i];
for(int j = 0;j<tmp.length;j++){
char value = tmp[j];
if(value == 'X'){
int x = j+1;
while (x<tmp.length && tmp[x]=='X'){
tmp[x] = '.';
x = x+1;
}
x = i+1;
while (x <board.length && board[x][j]== 'X'){
board[x][j] = '.';
x = x+1;
}
count++;
}
}
}
return count;
}
}
public class Solution {
public int countBattleships(char[][] board) {
if(board == null || board.length == 0 || board[0].length == 0) {
return 0;
}
int count = 0;
for(int i = 0; i < board.length; i++) {
for(int j = 0; j < board[0].length; 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;
}
}