Knowledge Guide
HomeDSACompany Practice

medium Number of Islands

Problem Statement

Given a 2D array (i.e., a matrix) containing only 1s (land) and 0s (water), count the number of islands in it.

An island is a connected set of 1s (land) and is surrounded by either an edge or 0s (water). Each cell is considered connected to other cells horizontally or vertically (not diagonally).

Example 2

Input: matrix =

Image
Image

Output: 3
Explanation: The matrix has three islands. See the highlighted cells below.

Image
Image

Example 1

Input: matrix =

Image
Image

Output: 1
Explanation: The matrix has only one island. See the highlighted cells below.

Image
Image

Constraints:

Try it yourself

Try solving this question here:

✅ Solution Number of Islands

Problem Statement

Given a 2D array (i.e., a matrix) containing only 1s (land) and 0s (water), count the number of islands in it.

An island is a connected set of 1s (land) and is surrounded by either an edge or 0s (water). Each cell is considered connected to other cells horizontally or vertically (not diagonally).

Example 1

Input: matrix =

Image
Image

Output: 3
Explanation: The matrix has three islands. See the highlighted cells below.

Image
Image

Example 2

Input: matrix =

Image
Image

Output: 1
Explanation: The matrix has only one island. See the highlighted cells below.

Image
Image

Constraints:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m, n <= 300
  • matrix[i][j] is '0' or '1'.

Solution

We can traverse the matrix linearly to find islands.

Whenever we find a cell with the value '1' (i.e., land), we have found an island. Using that cell as the root node, we will perform a Depth First Search (DFS) or Breadth First Search (BFS) to find all of its connected land cells. During our DFS or BFS traversal, we will find and mark all the horizontally and vertically connected land cells. 

We need to have a mechanism to mark each land cell to ensure that each land cell is visited only once. To mark a cell visited, we have two options:

  1. We can update the given input matrix. Whenever we see a '1', we will make it '0'.
  2. A separate boolean matrix can be used to record whether or not each cell has been visited. 

Following is the DFS or BFS traversal of the example-2 mentioned above:

Image
Image

By following the above algorithm, every time DFS or BFS is triggered, we are sure that we have found an island. We will keep a running count to calculate the total number of islands.

Below, we will see three solutions based on:

  1. DFS
  2. BFS
  3. BFS with visited matrix

Code  (DFS)

Here is what our DFS algorithm will look like. We will update the input matrix to mark cells visited.

java
import java.util.*;

class Solution {

  public int countIslands(int[][] matrix) {
    int rows = matrix.length;
    int cols = matrix[0].length;
    int totalIslands = 0;

    for (int i = 0; i < rows; i++) {
      for (int j = 0; j < cols; j++) {
        if (matrix[i][j] == 1) { // only if the cell is a land
          // we have found an island
          totalIslands++;
          visitIslandDFS(matrix, i, j);
        }
      }
    }
    return totalIslands;
  }

  private static void visitIslandDFS(int[][] matrix, int x, int y) {
    if (x < 0 || x >= matrix.length || y < 0 || y >= matrix[0].length) return; // return, if it is not a valid cell
    if (matrix[x][y] == 0) return; // return, if it is a water cell

    matrix[x][y] = 0; // mark the cell visited by making it a water cell

    // recursively visit all neighboring cells (horizontally & vertically)
    visitIslandDFS(matrix, x + 1, y); // lower cell
    visitIslandDFS(matrix, x - 1, y); // upper cell
    visitIslandDFS(matrix, x, y + 1); // right cell
    visitIslandDFS(matrix, x, y - 1); // left cell
  }

  public static void main(String[] args) {
    Solution sol = new Solution();
    System.out.println(
      sol.countIslands(
        new int[][] {
          { 1, 1, 1, 0, 0 },
          { 0, 1, 0, 0, 1 },
          { 0, 0, 1, 1, 0 },
          { 0, 0, 1, 0, 0 },
          { 0, 0, 1, 0, 0 },
        }
      )
    );

    System.out.println(
      sol.countIslands(
        new int[][] {
          { 0, 1, 1, 1, 0 },
          { 0, 0, 0, 1, 1 },
          { 0, 1, 1, 1, 0 },
          { 0, 1, 1, 0, 0 },
          { 0, 0, 0, 0, 0 },
        }
      )
    );
  }
}

Time Complexity
Time complexity of the above algorithm will be , where ‘M’ is the number of rows and 'N' is the number of columns of the input matrix. This is due to the fact that we have to traverse the whole matrix to find the islands.

Space Complexity
DFS recursion stack can go deep when the whole matrix is filled with '1's. Hence, the space complexity will be , where ‘M’ is the number of rows and 'N' is the number of columns of the input matrix.

Code  (BFS)

Here is what our BFS algorithm will look like. We will update the input matrix to mark cells visited.

java
import java.util.*;

class Solution {
  public static int countIslands(int[][] matrix) {

    int rows = matrix.length;
    int cols = matrix[0].length;
    int totalIslands = 0;

    for (int i = 0; i < rows; i++) {
      for (int j = 0; j < cols; j++) {
        if (matrix[i][j] == 1) { // only if the cell is a land
          // we have found an island
          totalIslands++;
          visitIslandBFS(matrix, i, j);
        }
      }
    }
    return totalIslands;
  }

  private static void visitIslandBFS(int[][] matrix, int x, int y) {
    Queue<int[]> neighbors = new LinkedList<>();
    neighbors.add(new int[] { x, y });
    while (!neighbors.isEmpty()) {
      int row = neighbors.peek()[0];
      int col = neighbors.peek()[1];
      neighbors.remove();

      if (row < 0 || row >= matrix.length || col < 0 || col >= matrix[0].length)
        continue; // continue, if it is not a valid cell
      if (matrix[row][col] == 0)
        continue; // continue if it is a water cell

      matrix[row][col] = 0; // mark the cell visited by making it a water cell

      // insert all neighboring cells to the queue for BFS
      neighbors.add(new int[] { row + 1, col }); // lower cell
      neighbors.add(new int[] { row - 1, col }); // upper cell
      neighbors.add(new int[] { row, col + 1 }); // right cell
      neighbors.add(new int[] { row, col - 1 }); // left cell
    }
  }

  public static void main(String[] args) {
    System.out.println(Solution.countIslands(
        new int[][] {
            { 1, 1, 1, 0, 0 },
            { 0, 1, 0, 0, 1 },
            { 0, 0, 1, 1, 0 },
            { 0, 0, 1, 0, 0 },
            { 0, 0, 1, 0, 0 }
        }));
        
    System.out.println(Solution.countIslands(
        new int[][] {
            { 0, 1, 1, 1, 0 },
            { 0, 0, 0, 1, 1 },
            { 0, 1, 1, 1, 0 },
            { 0, 1, 1, 0, 0 },
            { 0, 0, 0, 0, 0 }
        }));

  }
}

Time Complexity
Time complexity of the above algorithm will be , where ‘M’ is the number of rows and 'N' is the number of columns.

Space Complexity
Space complexity of the above algorithm will be . In the worst case, when the matrix is completely filled with land cells, the size of the queue can grow up to .

Code  (BFS with visited matrix)

Here is what our BFS algorithm will look like. We will keep a separate boolean matrix to record whether or not each cell has been visited.

java
import java.util.*;

class Solution {
  public static int countIslands(int[][] matrix) {
    int rows = matrix.length;
    int cols = matrix[0].length;
    boolean[][] visited = new boolean[rows][cols];
    int totalIsland = 0;

    for (int i = 0; i < rows; i++) {
      for (int j = 0; j < cols; j++) {
        // if the cell has not been visited before and is a land
        if (!visited[i][j] && matrix[i][j] == 1) {
          // we have found an island
          totalIsland++;
          visitIslandBFS(matrix, visited, i, j);
        }
      }
    }
    return totalIsland;
  }

  private static void visitIslandBFS(int[][] matrix, boolean[][] visited, int x, int y) {
    Queue<int[]> neighbors = new LinkedList<>();
    neighbors.add(new int[] { x, y });
    while (!neighbors.isEmpty()) {
      int row = neighbors.peek()[0];
      int col = neighbors.peek()[1];
      neighbors.remove();

      if (row < 0 || col < 0 || row >= matrix.length || col >= matrix[0].length)
        continue; // continue, if it is not a valid cell
      if (matrix[row][col] == 0 || visited[row][col])
        continue; // continue if the cell is water or visited

      visited[row][col] = true; // mark the visited array

      // insert all neighboring cells to the queue for BFS
      neighbors.add(new int[] { row + 1, col }); // lower cell
      neighbors.add(new int[] { row - 1, col }); // upper cell
      neighbors.add(new int[] { row, col + 1 }); // right cell
      neighbors.add(new int[] { row, col - 1 }); // left cell
    }
  }

  public static void main(String[] args) {
    System.out.println(Solution.countIslands(
        new int[][] {
            { 1, 1, 1, 0, 0 },
            { 0, 1, 0, 0, 1 },
            { 0, 0, 1, 1, 0 },
            { 0, 0, 1, 0, 0 },
            { 0, 0, 1, 0, 0 }
        }));
        
    System.out.println(Solution.countIslands(
        new int[][] {
            { 0, 1, 1, 1, 0 },
            { 0, 0, 0, 1, 1 },
            { 0, 1, 1, 1, 0 },
            { 0, 1, 1, 0, 0 },
            { 0, 0, 0, 0, 0 }
        }));
  }
}

Time Complexity
Time complexity of the above algorithm will be , where ‘M’ is the number of rows and 'N' is the number of columns.

Space Complexity
Because of the visited array and max size of the queue, the space complexity will be , where ‘M’ is the number of rows and 'N' is the number of columns of the input matrix.

🤖 Don't fully get this? Learn it with Claude

Stuck on Number of Islands? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🪜 Hint ladder (no spoilers)

Progressively stronger hints — you still solve it.

I'm working on the problem **Number of Islands** (DSA). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🎨 Explain the approach visually

See the technique, not just code.

Explain the optimal approach to **Number of Islands** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔍 Review my solution

Catch bugs, edge cases, sub-optimality.

I'll paste my solution to **Number of Islands**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🔁 Drill the pattern

Lock in recognition with look-alikes.

Give me 2 problems that use the SAME underlying pattern as **Number of Islands**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes