Given an m x n
matrix board
where each cell is a battleship 'X'
or empty '.'
, return the number of the battleships on board
.
Battleships can only be placed horizontally or vertically on board
. In other words, they can only be made of the shape 1 x k
(1
row, k
columns) or k x 1
(k
rows, 1
column), where k
can be of any size. At least one horizontal or vertical cell separates between two battleships (i.e., there are no adjacent battleships).
For example:
board = [['X','.','.','X'], ['.','.','.','X'], ['.','.','.','X']]
In this case, the output should be 2.
Another example:
board = [['.']]
In this case, the output should be 0.
Constraints:
m == board.length
n == board[i].length
1 <= m, n <= 200
board[i][j]
is either '.'
or 'X'
.Could you do it in one-pass, using only O(1) extra memory and without modifying the values board
?
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
We're given a grid where some cells contain parts of battleships. The brute force method involves carefully examining each cell to find and count these battleships. We need to be thorough and avoid counting the same ship multiple times.
Here's how the algorithm would work step-by-step:
def count_battleships_brute_force(board):
if not board:
return 0
number_of_rows = len(board)
number_of_columns = len(board[0])
battleship_count = 0
for row_index in range(number_of_rows):
for column_index in range(number_of_columns):
if board[row_index][column_index] == 'X':
# Found a potential battleship
battleship_count += 1
sink_battleship(board, row_index, column_index, number_of_rows, number_of_columns)
return battleship_count
def sink_battleship(board, row_index, column_index, number_of_rows, number_of_columns):
# Mark the current cell as visited to avoid double-counting.
board[row_index][column_index] = '.'
# Explore right
if column_index + 1 < number_of_columns and board[row_index][column_index + 1] == 'X':
sink_battleship(board, row_index, column_index + 1, number_of_rows, number_of_columns)
# Explore down
if row_index + 1 < number_of_rows and board[row_index + 1][column_index] == 'X':
# Explore down if there is a ship
sink_battleship(board, row_index + 1, column_index, number_of_rows, number_of_columns)
The goal is to count the number of battleships in a given board. The key idea is to only count the 'head' of each battleship to avoid overcounting and ensure efficiency.
Here's how the algorithm would work step-by-step:
def count_battleships(board):
number_of_rows = len(board)
number_of_columns = len(board[0]) if number_of_rows > 0 else 0
battleship_count = 0
for row_index in range(number_of_rows):
for column_index in range(number_of_columns):
if board[row_index][column_index] == 'X':
# Check if current cell is the 'head' of a battleship.
if (row_index > 0 and board[row_index - 1][column_index] == 'X'):
continue
if (column_index > 0 and board[row_index][column_index - 1] == 'X'):
continue
# Increment battleship_count if it's the 'head'.
battleship_count += 1
return battleship_count
Case | How to Handle |
---|---|
Null or empty board | Return 0 if the board is null or has zero rows/columns. |
Board with zero width or zero height | Return 0 because a battleship cannot exist without at least one cell. |
Board containing only '.' characters | Return 0 as there are no battleships. |
Board containing only 'X' characters representing a single large battleship | Count as one battleship when no adjacent 'X' are present (edge case for naive counting). |
Battleship segments are not connected horizontally or vertically (e.g., diagonal 'X's) | Only count connected horizontal/vertical segments as part of a battleship, ignoring diagonals. |
Invalid board where battleships touch each other | The problem statement implicitly assumes valid boards so this edge case doesn't need to be handled specifically beyond incorrect counts. |
Board with a single row or single column | Handle by iterating through the row or column and counting battleships correctly. |
Integer overflow if board size is extremely large | Ensure data types (e.g., counters) are large enough to handle potential board sizes; if the dimensions are constrained, no special action is needed. |