Talentd
FleetCode
Make and follow sheets.Sign in

Battleships in a Board solution and explanation

MediumArrayDepth-First SearchMatrix4 min read77.4% acceptanceUpdated 9 Apr 2026
Battleships in a BoardKevin Naughton Jr. · 10:31 · 40K viewsWatch on YouTube
9 more videos on this problem
  1. Battleships in a BoardKevin Naughton Jr. · 10:31 · 40K views
  2. LeetCode 419. Battleships in a BoardHappy Coding · 21:21 · 3K views
  3. Leetcode 419 Battleships in a Board| Better than DFS| Explanation and Code Walkthrough| Interview|Seemant Aggarwal · 10:32 · 2K views
  4. 419. Battleships In A Board (Leetcode Medium)Programming Live with Larry · 9:05 · 1K views
  5. LeetCode 419 Battleships in a Board - Lintcode 986 Battleships in a Board - DFS Java SolutionAlgorithmicIQ · 8:37 · 895 views
  6. META INTERVIEW QUESTION | Battleships in a Board (LeetCode problem 419)MCCOMP · 5:56 · 727 views
  7. Google Programming Interview Question | Battleships in a Board | Java | O(N) solutionCodingForFAANGJobs · 4:30 · 324 views
  8. LeetCode 419 - Battleships in a Board | Clean & Optimal Approach | Grid & Matrix DSA ExplainedAslam Coding · 10:42 · 249 views
  9. Battleships in a Board | Top Google Coding Interview QuestionCoding Courses · 6:14 · 217 views
  10. LeetCode 419. Battleships in a Board Solution Explained - JavaAlgorithms and Data Structures Course · 6:21 · 199 views

The problem

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).

Example 1:

Input: board = [["X",".",".","X"],[".",".",".","X"],[".",".",".","X"]]
Output: 2

Example 2:

Input: board = [["."]]
Output: 0

Constraints:

  • m == board.length
  • n == board[i].length
  • 1 <= m, n <= 200
  • board[i][j] is either '.' or 'X'.

Follow up: Could you do it in one-pass, using only O(1) extra memory and without modifying the values board?

Approach overview

Problem Overview: You are given an m x n grid representing a battleship board. Cells contain either 'X' (part of a ship) or '.' (empty). Ships are placed only horizontally or vertically and never touch each other. The task is to count how many distinct battleships exist on the board.

Approach 1: Brute Force DFS Traversal (O(m*n) time, O(m*n) space)

Treat the board as a graph and explore each ship using Depth-First Search. Iterate through every cell of the matrix. When you encounter an 'X' that hasn't been visited, start a DFS and mark all connected 'X' cells belonging to that ship. Because ships are guaranteed to be straight lines, the DFS will only extend horizontally or vertically. Maintain a visited structure (array or hash set) to avoid revisiting cells. Each DFS traversal corresponds to exactly one battleship, so increment the count when a new traversal begins. This approach is straightforward and mirrors typical Depth-First Search problems on grids.

Approach 2: Optimized Linear Scan (O(m*n) time, O(1) space)

A more efficient observation eliminates the need for DFS or extra memory. Instead of exploring entire ships, count only the starting cell of each battleship. A cell is the start of a ship if it contains 'X' and there is no 'X' directly above it and no 'X' directly to its left. Iterate through the grid once using simple array indexing. When a cell satisfies this condition, it must represent the top-left segment of a battleship, so increment the count. All other segments belong to ships already counted. This works because ships never touch and are always straight lines.

Recommended for interviews: The optimized linear scan is what interviewers expect. It shows you can recognize structural constraints in the grid and reduce the problem to a single pass with O(1) extra space. Explaining the DFS approach first demonstrates understanding of grid traversal, but identifying the start-cell trick highlights stronger problem-solving skills.

Approach 1: Brute Force Approach

This approach involves iterating over all possible pairs in the list and checking each possible solution. It's not the most efficient but lays a good groundwork to understand the problem.

def brute_force_solution(arr):
    n = len(arr)
    for i in range(n - 1):
        for j in range(i + 1, n):
            # Check your condition here and process the pair (arr[i], arr[j])
            pass

arr = [1, 2, 3, 4, 5]
brute_force_solution(arr)
public class BruteForceSolution {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};
        bruteForceSolution(arr);
    }

    public static void bruteForceSolution(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {
                // Check your condition here and process the pair (arr[i], arr[j])
            }
        }
    }
}
#include <iostream>
#include <vector>

void bruteForceSolution(std::vector<int> &arr) {
    for(size_t i = 0; i < arr.size() - 1; i++) {
        for(size_t j = i + 1; j < arr.size(); j++) {
            // Check your condition here and process the pair (arr[i], arr[j])
        }
    }
}

int main() {
    std::vector<int> arr = {1, 2, 3, 4, 5};
    bruteForceSolution(arr);
    return 0;
}
function bruteForceSolution(arr) {
    for (let i = 0; i < arr.length - 1; i++) {
        for (let j = i + 1; j < arr.length; j++) {
            // Check your condition here and process the pair (arr[i], arr[j])
        }
    }
}

const arr = [1, 2, 3, 4, 5];
bruteForceSolution(arr);
#include <stdio.h>

void bruteForceSolution(int arr[], int n) {
    for(int i = 0; i < n - 1; i++) {
        for(int j = i + 1; j < n; j++) {
            // Check your condition here and process the pair (arr[i], arr[j])
        }
    }
}

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int n = sizeof(arr) / sizeof(arr[0]);
    bruteForceSolution(arr, n);
    return 0;
}
using System;

class Program
{
    static void Main()
    {
        int[] arr = { 1, 2, 3, 4, 5 };
        BruteForceSolution(arr);
    }

    static void BruteForceSolution(int[] arr)
    {
        int n = arr.Length;
        for (int i = 0; i < n - 1; i++)
        {
            for (int j = i + 1; j < n; j++)
            {
                // Check your condition here and process the pair (arr[i], arr[j])
            }
        }
    }
}

The Python solution uses two nested loops to iterate over pairs in the array. Any specific condition related to the problem is handled in the nested loop.

Complexity

Time Complexity: O(n^2)
Space Complexity: O(1)

Try this approach in the editor

Approach 2: Optimized Hash Map Approach

This approach uses a hash map to store and track information about the elements, allowing us to reduce the number of comparisons by enabling constant time lookups. It leverages the hash map to quickly determine if another element needed to meet the condition exists.

def optimized_solution(arr):
    hash_table = {}
    for num in arr:
        # Use hash_table to implement the condition (like finding pairs)
        hash_table[num] = True
        # Your logic here

arr = [1, 2, 3, 4, 5]
optimized_solution(arr)
import java.util.HashMap;

public class OptimizedSolution {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};
        optimizedSolution(arr);
    }

    public static void optimizedSolution(int[] arr) {
        HashMap<Integer, Boolean> hashMap = new HashMap<>();
        for (int num : arr) {
            // Use hashMap to implement the condition (like finding pairs)
            hashMap.put(num, true);
            // Your logic here
        }
    }
}
#include <iostream>
#include <unordered_map>
#include <vector>

void optimizedSolution(std::vector<int> &arr) {
    std::unordered_map<int, bool> hashTable;
    for(int num : arr) {
        // Use hashTable to implement the condition (like finding pairs)
        hashTable[num] = true;
        // Your logic here
    }
}

int main() {
    std::vector<int> arr = {1, 2, 3, 4, 5};
    optimizedSolution(arr);
    return 0;
}
function optimizedSolution(arr) {
    const hashTable = {};
    for (const num of arr) {
        // Use hashTable to implement the condition (like finding pairs)
        hashTable[num] = true;
        // Your logic here
    }
}

const arr = [1, 2, 3, 4, 5];
optimizedSolution(arr);
#include <stdio.h>
#include <stdlib.h>

#define TABLE_SIZE 1000

int hashFunction(int key) {
    return abs(key) % TABLE_SIZE;
}

void optimizedSolution(int arr[], int n) {
    int hashTable[TABLE_SIZE] = {0};
    for (int i = 0; i < n; i++) {
        // Use hashTable to implement the condition (like finding pairs)
        int key = hashFunction(arr[i]);
        // Your logic here
        hashTable[key] = 1;
    }
}

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int n = sizeof(arr) / sizeof(arr[0]);
    optimizedSolution(arr, n);
    return 0;
}
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        int[] arr = { 1, 2, 3, 4, 5 };
        OptimizedSolution(arr);
    }

    static void OptimizedSolution(int[] arr)
    {
        Dictionary<int, bool> hashTable = new Dictionary<int, bool>();
        foreach (int num in arr)
        {
            // Use hashTable to implement the condition (like finding pairs)
            hashTable[num] = true;
            // Your logic here
        }
    }
}

Python uses a dictionary to act as a hash table, efficiently implementing lookup and storage operations necessary for solving the problem optimally.

Complexity

Time Complexity: O(n) on average
Space Complexity: O(n)

Try this approach in the editor

Approach 3: Direct Iteration

We can iterate through the matrix, find the top-left corner of each battleship, i.e., the position where the current position is X and both the top and left are not X, and increment the answer by one.

After the iteration ends, return the answer.

The time complexity is O(m times n), where m and n are the number of rows and columns of the matrix, respectively. The space complexity is O(1).

function countBattleships(board: string[][]): number {
    const m = board.length;
    const n = board[0].length;
    let ans = 0;
    for (let i = 0; i < m; ++i) {
        for (let j = 0; j < n; ++j) {
            if (board[i][j] === '.') {
                continue;
            }
            if (i && board[i - 1][j] === 'X') {
                continue;
            }
            if (j && board[i][j - 1] === 'X') {
                continue;
            }
            ++ans;
        }
    }
    return ans;
}
func countBattleships(board [][]byte) (ans int) {
	for i, row := range board {
		for j, c := range row {
			if c == '.' {
				continue
			}
			if i > 0 && board[i-1][j] == 'X' {
				continue
			}
			if j > 0 && board[i][j-1] == 'X' {
				continue
			}
			ans++
		}
	}
	return
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
Brute Force Approach

Time Complexity: O(n^2)
Space Complexity: O(1)

Optimized Hash Map Approach

Time Complexity: O(n) on average
Space Complexity: O(n)

Direct Iteration–

Complexity analysis

ApproachTimeSpaceWhen to Use
Brute Force DFS TraversalO(m*n)O(m*n)When learning grid traversal or when ships could have arbitrary shapes requiring full exploration
Optimized Linear Scan (Start Cell Detection)O(m*n)O(1)Best approach when ships are guaranteed to be straight and non-touching

Frequently asked questions

Is Battleships in a Board easy or hard?

Battleships in a Board is classified as a Medium difficulty problem. The challenge lies in recognizing the constraint that ships never touch and are always straight lines. Once that observation is made, the optimized O(m*n) constant-space solution becomes straightforward.

Battleships in a Board Python/Java solution

In Python or Java, iterate through the board using nested loops. When a cell contains 'X', check the cell above and to the left. If neither contains 'X', increment the ship count. This implementation keeps the complexity at O(m*n) time and O(1) space.

How to solve Battleships in a Board in O(n)?

Treat the board as a grid and scan each cell exactly once. Count a battleship only when the current cell is 'X' and both the top neighbor and left neighbor are not 'X'. This ensures you only count the first segment of each ship. The algorithm therefore runs in O(m*n) time with constant space.

What is the best approach for Battleships in a Board?

The best approach is a single-pass linear scan that counts only the starting cell of each battleship. A cell represents a new ship if it contains 'X' and there is no 'X' above it or to its left. This guarantees each ship is counted exactly once. The solution runs in O(m*n) time with O(1) extra space.

Is Battleships in a Board asked at Google/Amazon/Meta?

Battleships in a Board is a common matrix scanning problem used in interviews at large tech companies. Variations involving grid traversal, counting connected components, or DFS on matrices appear frequently at companies like Amazon, Google, and Meta.

What data structure is used in Battleships in a Board?

The problem primarily uses a 2D array (matrix). The brute force solution may also use recursion or a visited set during DFS traversal. The optimized approach relies only on simple index checks within the matrix, avoiding additional data structures.

What is the time complexity of Battleships in a Board?

The optimal solution runs in O(m*n) time because every cell in the grid is checked once. No nested exploration or repeated scanning is required. Space complexity is O(1) since the algorithm only uses a few variables while iterating through the board.

Comments

Now write it yourselfClose this page and solve Battleships in a Board in the editor, without looking.
Practise Battleships in a Board