Chapter 08 of 32

2D Arrays in DSA

So far, we've worked with normal arrays that store data in a single sequence:

10  20  30  40  50

But sometimes our data naturally has rows and columns.

For example, think about a classroom where students are sitting in rows:

       Column
       0   1   2   3
     ┌───┬───┬───┬───┐
Row 0│10 │20 │30 │40 │
     ├───┼───┼───┼───┤
Row 1│50 │60 │70 │80 │
     ├───┼───┼───┼───┤
Row 2│90 │15 │25 │35 │
     └───┴───┴───┴───┘

This type of structure is called a 2D array, or two-dimensional array.

In simple words, a 2D array is an array where each element is itself another array.

Creating a 2D Array

In Java, we can create a 2D array like this:

int[][] numbers = new int[3][4];

Here:

3 → number of rows
4 → number of columns

So this creates a structure with 3 rows and 4 columns:

0  0  0  0
0  0  0  0
0  0  0  0

Since these are int values, Java initially fills them with 0.

Initializing a 2D Array

We can also directly provide the values:

int[][] numbers = {
    {10, 20, 30},
    {40, 50, 60},
    {70, 80, 90}
};

You can visualize it as:

       Column
       0   1   2
     ┌───┬───┬───┐
Row 0│10 │20 │30 │
     ├───┼───┼───┤
Row 1│40 │50 │60 │
     ├───┼───┼───┤
Row 2│70 │80 │90 │
     └───┴───┴───┘

The first index represents the row, and the second index represents the column.

Accessing Elements

We can access an element using two indexes:

numbers[row][column]

For example:

int[][] numbers = {
    {10, 20, 30},
    {40, 50, 60},
    {70, 80, 90}
};

System.out.println(numbers[1][2]);

Output:

60

Why?

numbers[1] refers to the second row:

40  50  60

Then [2] refers to the third element:

60

Remember that indexing starts from 0.

Changing an Element

Just like a normal array, we can change an element.

numbers[1][2] = 100;

The array now becomes:

10  20  30
40  50  100
70  80  90

Finding the Number of Rows

We can use:

numbers.length

to get the number of rows.

For example:

int[][] numbers = {
    {10, 20, 30},
    {40, 50, 60},
    {70, 80, 90}
};

System.out.println(numbers.length);

Output:

3

There are three rows.

Finding the Number of Columns

To find the number of columns in a particular row, we use:

numbers[row].length

For example:

System.out.println(numbers[0].length);

Output:

3

So:

numbers.length      → number of rows
numbers[0].length   → number of columns in row 0

Traversing a 2D Array

This is one of the most important things to understand.

Since we have rows and columns, we normally use nested loops.

int[][] numbers = {
    {10, 20, 30},
    {40, 50, 60},
    {70, 80, 90}
};

for (int i = 0; i < numbers.length; i++) {

    for (int j = 0; j < numbers[i].length; j++) {
        System.out.print(numbers[i][j] + " ");
    }

    System.out.println();
}

Output:

10 20 30
40 50 60
70 80 90

The outer loop moves through the rows, while the inner loop moves through the columns.

Think of it like:

Outer loop → Row
Inner loop → Column

Using Enhanced for Loops

We can also use enhanced for loops.

for (int[] row : numbers) {

    for (int value : row) {
        System.out.print(value + " ");
    }

    System.out.println();
}

This is often easier to read when we don't need the row and column indexes.

Finding the Sum of All Elements

Suppose we want to calculate the sum of every value in a 2D array.

int[][] numbers = {
    {10, 20, 30},
    {40, 50, 60},
    {70, 80, 90}
};

int sum = 0;

for (int i = 0; i < numbers.length; i++) {

    for (int j = 0; j < numbers[i].length; j++) {
        sum += numbers[i][j];
    }
}

System.out.println("Sum: " + sum);

Output:

Sum: 450

We're simply visiting every element and adding it to sum.

Finding the Largest Element

We can use the same idea to find the largest value.

int[][] numbers = {
    {10, 25, 30},
    {40, 15, 60},
    {70, 20, 50}
};

int largest = numbers[0][0];

for (int i = 0; i < numbers.length; i++) {

    for (int j = 0; j < numbers[i].length; j++) {

        if (numbers[i][j] > largest) {
            largest = numbers[i][j];
        }
    }
}

System.out.println("Largest: " + largest);

Output:

Largest: 70

Real-World Example

2D arrays are useful whenever data naturally has rows and columns.

For example, imagine a cinema:

      Seat 1  Seat 2  Seat 3  Seat 4
Row 1   O       O       X       O
Row 2   O       X       O       O
Row 3   O       O       O       X

You could represent this using a 2D array:

char[][] seats = {
    {'O', 'O', 'X', 'O'},
    {'O', 'X', 'O', 'O'},
    {'O', 'O', 'O', 'X'}
};

Here, O could represent an available seat and X could represent an occupied seat.

2D arrays are also commonly used to represent matrices, game boards, grids, images, and tables of data.

Jagged Arrays

Here's something interesting about Java: every row of a 2D array doesn't necessarily have to contain the same number of elements.

For example:

int[][] numbers = {
    {10, 20},
    {30, 40, 50},
    {60, 70, 80, 90}
};

This looks like:

10 20
30 40 50
60 70 80 90

This is called a jagged array.

That's why when traversing a 2D array, it's often better to use:

numbers[i].length

rather than assuming every row has the same number of columns.

2D Array in DSA Problems

2D arrays are extremely important in DSA because many problems involve grids.

For example:

Find an element in a matrix
Find the largest value
Calculate row sums
Calculate column sums
Transpose a matrix
Rotate a matrix
Search in a matrix
Traverse a matrix
Count neighboring cells
Find connected cells

Many grid-based problems you'll encounter later are built around the same basic idea of accessing:

grid[row][column]

Time Complexity

Suppose we have a matrix with r rows and c columns.

If we visit every element:

for (int i = 0; i < r; i++) {
    for (int j = 0; j < c; j++) {
        System.out.println(numbers[i][j]);
    }
}

The outer loop runs r times, and the inner loop runs c times for each row.

Therefore, the time complexity is:

O(r × c)

If the matrix is square and has n rows and n columns, then:

O(n²)

A Complete Example

Let's create a small program that calculates the sum of each row:

class Main {
    public static void main(String[] args) {

        int[][] marks = {
            {80, 75, 90},
            {85, 92, 78},
            {70, 88, 95}
        };

        for (int i = 0; i < marks.length; i++) {

            int sum = 0;

            for (int j = 0; j < marks[i].length; j++) {
                sum += marks[i][j];
            }

            System.out.println(
                "Row " + (i + 1) + " total: " + sum
            );
        }
    }
}

Output:

Row 1 total: 245
Row 2 total: 255
Row 3 total: 253

Here, each row could represent a student's marks in three different subjects.

The important thing to understand is that a 2D array is essentially a collection of rows, and each row contains its own elements.

A 2D array is used to organize data in rows and columns, and we usually use nested loops to process all of its elements.

Once you're comfortable with grid[row][column], you'll have the foundation needed for many matrix and grid-based DSA problems.