leetcode 419. Battleships in a Board

本文介绍了一种算法,用于计算二维棋盘中战舰的数量。通过遍历棋盘,检查每个'X'是否为战舰的最左侧和顶部,以此来计数独立的战舰。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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'就看看到底是往右还是往下发展的。如果是往右发展的,则j++,一直到结束,把battleship+1;如果是往下发展的,则temp=i,temp++,一直到结束,把battleship+1(注意不能i++,因为后几行的列还等着你遍历呢)

public int countBattleships(char[][] board) {
		int count=0;
		int xLength=board.length;//xLength是行数
		int yLength=board[0].length;//yLength是列数
		int[][] isGoneThroguh = new int[xLength][yLength];
		for(int i=0;i<xLength;i++){
			for(int j=0;j<yLength;j++){
				if(isGoneThroguh[i][j]==1){
					continue;
				}
				if(board[i][j]=='.'){
					isGoneThroguh[i][j]=1;
					continue;
				}
				if(board[i][j]=='X'){
					if(j+1<yLength&&board[i][j+1]=='X'){
						while(j<yLength&&board[i][j]=='X'){
							isGoneThroguh[i][j]=1;
							j++;
						}
						j--;
						count++;
					}
					else if(i+1<xLength&&board[i+1][j]=='X'){
						int temp=i;
						while(temp<xLength&&board[temp][j]=='X'){
							isGoneThroguh[temp][j]=1;
							temp++;
						}
						count++;
					}
					else{
						count++;
					}
				}
			}
		}
		return count;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Battleships_in_a_Board_419 b = new Battleships_in_a_Board_419();
		char[][] a=new char[][]{{'X','.','.','X'},{'.','.','.','X'},{'.','.','.','X'}};
		System.out.println(b.countBattleships(a));	
	}

}

然后大神的思路令我膜拜:

Going over all cells, we can count only those that are the "first" cell of the battleship. First cell will be defined as the most top-left cell. We can check for first cells by only counting cells that do not have an 'X' to the left and do not have an 'X' above them.

只需要数舰队中最上左的那只舰就好了。即你发现了一个'X'之后,如果它上面和左边没'X'的话,它就是最上左的舰,把count+1,反之则不是最上左的舰,直接跳过。

 public int countBattleships(char[][] board) {
        int m = board.length;
        if (m==0) return 0;
        int n = board[0].length;
        
        int count=0;
        
        for (int i=0; i<m; i++) {
            for (int j=0; j<n; 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;
    }
大神的解法多么简洁,多么漂亮。。。这真是智商的差别啊T_T!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值