在楼梯睡觉被领导抓到了。。
算法题:棋盘上的战舰
思路
解题步骤
遍历棋盘:我们首先需要遍历整个二维数组。每次我们遇到一个‘X’时,都需要判断它是否是一个新的战舰的开始。为了避免重复计数,我们只关心那些位于战舰的起始位置的‘X’。 标记已计算的战舰:为了避免重复统计同一艘战舰,可以采用从上至下、从左至右的扫描方式。这样,当我们遇到一个‘X’时,如果它的上方或左边已经有‘X’,那么它就不是一个新战舰的一部分,可以跳过。 检测新的战舰:为了实现这一点,我们只需要判断当前的‘X’位置的左边和上边是否存在战舰(即‘X’)。如果它们的位置为空(即是海洋‘.’),那么当前的‘X’就是一个新的战舰的起始位置。
Java代码实现
public class Battleship {
public int countBattleships(char[][] board) {
int count = 0;// 遍历每一行
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {// 如果当前位置是战舰的一部分
if (board[i][j] == 'X') {
// 判断当前的'X'是不是一个新的战舰
if (i > 0 && board[i-1][j] == 'X') {
continue; // 上面已经有'X',说明已经属于一个战舰,不算新战舰
}
if (j > 0 && board[i][j-1] == 'X') {
continue; // 左边已经有'X',说明已经属于一个战舰,不算新战舰
}
// 如果当前的'X'没有被上方或左方的'X'覆盖,说明是新战舰的起点
count++;
}
}
}return count;
}public static void main(String[] args) {
Battleship bs = new Battleship();
char[][] board = {
{'X', '.', 'X', 'X'},
{'.', 'X', '.', '.'},
{'.', '.', 'X', 'X'},
{'X', '.', '.', 'X'}
};
System.out.println("战舰数量: " + bs.countBattleships(board)); // 输出应该是3
}
}
解释代码
双重循环遍历棋盘:我们通过双重for循环遍历二维数组 board。board[i][j]代表当前位置。判断新战舰的起始位置:每当遇到一个‘X’,我们检查它的上方和左方是否有‘X’。如果上方或左方已经有‘X’,说明这个‘X’是属于一个已有战舰的部分,不是新战舰。反之,我们就认为这个‘X’是一个新战舰的起点,增加计数。 返回结果:遍历完整个棋盘后, count即为战舰的数量。
优化
可能遇到的坑
ArrayIndexOutOfBoundsException,尤其是在检查上方或左边是否是‘X’时,最好先确保i > 0和j > 0,避免数组越界。