A topic in the Open Knowledge Graph — a free, open map of 15,495 topics and the order to learn them in.
A two-dimensional array stores values in a grid of rows and columns, and each element is reached with two indexes: `grid[row][col]`. In Java and Python it is built as an array whose elements are themselves arrays (rows). Grids model game boards, images, seating charts, spreadsheets and matrices. Processing them almost always uses nested loops, with the outer loop choosing a row and the inner loop walking across its columns.
Draw the grid on paper with row and column numbers before writing any code, and have students label `grid[1][2]` on the drawing. Practice the standard traversals in order: row-major (row by row), column-major (column by column), one row, one column, and the whole grid for a sum or maximum. In Python, show the shared-row bug from `[[0] * cols] * rows` on screen so students see why each row must be created separately.
You already know that an array stores a sequence of values reached by one index. Many problems need two directions instead of one. A tic-tac-toe board has 3 rows and 3 columns. A grayscale image has rows and columns of pixel brightness values. A two-dimensional array models these grids directly.
In Java you write `int[][] board = new int[3][4];`. This creates 3 rows with 4 columns each, and every `int` starts at 0. You reach one element with two indexes, row first: `board[1][2]` is row 1, column 2, counting from 0. In Python the usual form is a list of lists, such as `board = [[0, 0, 0, 0] for _ in range(3)]`, and access looks the same: `board[1][2]`.
It helps to know how the grid is built. A Java `int[][]` is really an array of row arrays. That explains the length rules. `board.length` is the number of rows, 3. `board[0].length` is the length of row 0, which is the number of columns, 4. Because rows are separate arrays, Java even allows rows of different lengths, called ragged arrays, though most problems use rectangles.
Processing a grid uses the nested loops you have already met. The standard row-major traversal is:
```java
for (int r = 0; r < board.length; r++) {
for (int c = 0; c < board[r].length; c++) {
// use board[r][c]
}
}
```
The outer loop chooses a row. The inner loop walks across it. Swap the loops and you get column-major order, which visits all of column 0 first. To work on just one row, fix `r` and loop over `c`. To work on one column, fix `c` and loop over `r`.
Common tasks follow directly from these patterns. A total adds every element. A row sum resets an accumulator at the start of each row. Finding the largest value tracks a running maximum. Checking a tic-tac-toe win looks at one row, one column, or a diagonal, where the diagonal elements are `board[i][i]`.
Watch the indexes carefully. The most common bug is swapping row and column. The second is using `board.length` as the column bound, which works only when the grid happens to be square. In Python, the third is building rows with `[[0] * cols] * rows`, which stores one row object several times.