好的我们今天来做题,链接如下:
力扣419 甲板上的战舰https://leetcode-cn.com/problems/battleships-in-a-board/题目挺让人感兴趣的,题目本身还是蛮简单的。
题目最后要求:“你可以实现一次扫描算法,并只使用 O(1)
额外空间,并且不修改 board
的值来解决这个问题吗?”
那么我们就尽量只扫描一遍,只使用1个临时的变量,不修改board值来完成~
其实第一时间感觉这题跟前两天CSDN上那道最佳路径II的题目很像,思考过后确实有几分相似。
思路:
我们需要解决的问题就是当我们遍历到X的时候需要判断这艘战舰是否长度大于1,最初的想法是遍历到1个点为X后向其他3个方向判断,但很快否定掉,这样麻烦不说,而且横向遍历的情况下,还需要越过纵向的战舰,按照前面的要求肯定无法实现。
之后观察题目的示意图,很快敲定了想法:
我们需要求战舰总数,其实就在求连续的X构成的块的数量,如果我们从左往右从上往下(按照二维数组正常遍历的顺序)遍历的话,当碰到1个格为X的时候,该格的上方和左方都不是X的话,便能确认该格为当前X构成的块的左上角格。我们只需要统计这种X的总数即是最终战舰的总数。需要额外考虑的特殊情况则是起点,第一行,第一列(就是这些地方让我觉得跟之前最佳路径II那题很像)
代码如下:
class Solution {
public int countBattleships(char[][] board) {
int res = 0;
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if(board[i][j] == 'X'){
if(i==0 && j==0){ //从左上角开始判断:不存在左格和上格。
res++;
}else if(i==0){ //如果是第一行:上格不是X
if(board[i][j-1] != 'X'){
res++;
}
}else if(j==0){ // 第零列的情况:左格不是X
if(board[i-1][j] !='X'){
res++;
}
}else{ // 通常情况:左格和上格都不是X
if(board[i-1][j] !='X' && board[i][j-1]!='X'){
res++;
}
}
}
}
}
return res;
}
}