2D Arrays
2D Arrays in Java
A 2D array is essentially an array of arrays. Each element is another array.
Declaration and Initialization
// Declare and create 2D array
int[][] matrix = new int[3][4]; // 3 rows, 4 columns
// Static initialization
int[][] grid = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// Alternative syntax
int[][] grid2 = new int[][] {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
Accessing Elements
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// Access element at row 1, column 2
int value = matrix[1][2]; // 6
// Modify element
matrix[0][1] = 10; // matrix is now {{1, 10, 3}, {4, 5, 6}, {7, 8, 9}}
// Get dimensions
int rows = matrix.length; // 3
int cols = matrix[0].length; // 4
Memory Model
// 2D array is array of arrays
int[][] arr = new int[3][4];
// arr[0] is reference to first row array
// arr[1] is reference to second row array
// arr[2] is reference to third row array
// Each row is separate object in memory
// Rows can have different lengths (jagged array)
Common Initialization Patterns
// Fill with specific value
int[][] matrix = new int[3][3];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
matrix[i][j] = i * 3 + j + 1;
}
}
// matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
// Identity matrix
int[][] identity = new int[3][3];
for (int i = 0; i < 3; i++) {
identity[i][i] = 1;
}
// identity = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}
Traversal
2D Array Traversal
Row-Major Traversal (Standard)
int[][] matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
// Standard row-major order
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
// Output:
// 1 2 3
// 4 5 6
// 7 8 9
Column-Major Traversal
// Traverse by columns first
for (int j = 0; j < matrix[0].length; j++) {
for (int i = 0; i < matrix.length; i++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
// Output:
// 1 4 7
// 2 5 8
// 3 6 9
Enhanced For Loop
int[][] matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
for (int[] row : matrix) {
for (int val : row) {
System.out.print(val + " ");
}
System.out.println();
}
Diagonal Traversal
// Main diagonal (top-left to bottom-right)
for (int i = 0; i < matrix.length; i++) {
System.out.print(matrix[i][i] + " ");
}
// Output: 1 5 9
// Anti-diagonal (top-right to bottom-left)
for (int i = 0; i < matrix.length; i++) {
System.out.print(matrix[i][matrix[0].length - 1 - i] + " ");
}
// Output: 3 5 7
Spiral Order
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> result = new ArrayList<>();
if (matrix.length == 0) return result;
int top = 0, bottom = matrix.length - 1;
int left = 0, right = matrix[0].length - 1;
while (top <= bottom && left <= right) {
for (int i = left; i <= right; i++)
result.add(matrix[top][i]);
top++;
for (int i = top; i <= bottom; i++)
result.add(matrix[i][right]);
right--;
if (top <= bottom) {
for (int i = right; i >= left; i--)
result.add(matrix[bottom][i]);
bottom--;
}
if (left <= right) {
for (int i = bottom; i >= top; i--)
result.add(matrix[i][left]);
left++;
}
}
return result;
}
Jagged Arrays
Jagged Arrays
Jagged arrays are arrays of arrays where each row can have different length.
Declaration
// Create jagged array
int[][] jagged = new int[3][];
// Each row must be initialized separately
jagged[0] = new int[]{1, 2, 3}; // 3 elements
jagged[1] = new int[]{4, 5}; // 2 elements
jagged[2] = new int[]{6, 7, 8, 9}; // 4 elements
// Direct initialization
int[][] jagged2 = {
{1, 2, 3},
{4, 5},
{6, 7, 8, 9}
};
Accessing Jagged Arrays
int[][] jagged = {{1, 2, 3}, {4, 5}, {6, 7, 8, 9}};
// Get row length
int row0Length = jagged[0].length; // 3
int row1Length = jagged[1].length; // 2
int row2Length = jagged[2].length; // 4
// Access elements
int val = jagged[1][0]; // 4
// Safe traversal
for (int i = 0; i < jagged.length; i++) {
for (int j = 0; j < jagged[i].length; j++) {
System.out.print(jagged[i][j] + " ");
}
System.out.println();
}
Use Cases
// 1. Adjacency list for graphs
int[][] graph = {
{1, 2}, // Node 0 connects to 1, 2
{2, 3}, // Node 1 connects to 2, 3
{3}, // Node 2 connects to 3
{} // Node 3 has no connections
};
// 2. Triangle/pascal's triangle
int[][] triangle = {
{1},
{1, 1},
{1, 2, 1},
{1, 3, 3, 1},
{1, 4, 6, 4, 1}
};
// 3. Sparse data representation
int[][] sparse = {
{0, 0, 5},
{1, 2, 3},
{2, 1, 7}
};
// Each row: [row, col, value]
Memory Considerations
// Regular 2D array: contiguous block
int[][] regular = new int[3][4]; // 12 ints contiguous
// Jagged array: scattered references
int[][] jagged = new int[3][];
jagged[0] = new int[2]; // Separate allocation
jagged[1] = new int[5]; // Separate allocation
jagged[2] = new int[3]; // Separate allocation
// Jagged arrays use more memory due to reference overhead
// But can be more memory-efficient for sparse data
Matrix Operations
Matrix Operations
Matrix Transpose
public int[][] transpose(int[][] matrix) {
int rows = matrix.length;
int cols = matrix[0].length;
int[][] result = new int[cols][rows];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
result[j][i] = matrix[i][j];
}
}
return result;
}
// In-place for square matrix
public void transposeInPlace(int[][] matrix) {
int n = matrix.length;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
}
Matrix Rotation (90 degrees clockwise)
// Method 1: Transpose + Reverse rows
public void rotate(int[][] matrix) {
int n = matrix.length;
// Transpose
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
// Reverse each row
for (int i = 0; i < n; i++) {
int left = 0, right = n - 1;
while (left < right) {
int temp = matrix[i][left];
matrix[i][left] = matrix[i][right];
matrix[i][right] = temp;
left++;
right--;
}
}
}
// Method 2: Direct rotation
public void rotateDirect(int[][] matrix) {
int n = matrix.length;
for (int i = 0; i < n / 2; i++) {
for (int j = i; j < n - 1 - i; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[n - 1 - j][i];
matrix[n - 1 - j][i] = matrix[n - 1 - i][n - 1 - j];
matrix[n - 1 - i][n - 1 - j] = matrix[j][n - 1 - i];
matrix[j][n - 1 - i] = temp;
}
}
}
Matrix Multiplication
public int[][] multiply(int[][] a, int[][] b) {
int rowsA = a.length, colsA = a[0].length;
int rowsB = b.length, colsB = b[0].length;
if (colsA != rowsB) throw new IllegalArgumentException("Incompatible dimensions");
int[][] result = new int[rowsA][colsB];
for (int i = 0; i < rowsA; i++) {
for (int j = 0; j < colsB; j++) {
for (int k = 0; k < colsA; k++) {
result[i][j] += a[i][k] * b[k][j];
}
}
}
return result;
}
Matrix Addition
public int[][] add(int[][] a, int[][] b) {
int rows = a.length, cols = a[0].length;
int[][] result = new int[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
result[i][j] = a[i][j] + b[i][j];
}
}
return result;
}
Practice Problems
Rotate an n x n 2D matrix 90 degrees clockwise in-place.
Example:
Input: [[1,2,3],[4,5,6],[7,8,9]]
Output: [[7,4,1],[8,5,2],[9,6,3]]
Transpose then reverse each row
Optimal Solution — O(n^2) time, O(1) space
Transpose the matrix, then reverse each row.
public void rotate(int[][] matrix) {
int n = matrix.length;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
for (int i = 0; i < n; i++) {
int left = 0, right = n - 1;
while (left < right) {
int temp = matrix[i][left];
matrix[i][left] = matrix[i][right];
matrix[i][right] = temp;
left++;
right--;
}
}
}Edge Cases:
- 1x1 matrix
- 2x2 matrix
Return all elements of a matrix in spiral order.
Example:
Input: [[1,2,3],[4,5,6],[7,8,9]]
Output: [1,2,3,6,9,8,7,4,5]
Traverse in spiral pattern
Optimal Solution — O(m * n) time, O(1) space
Use four boundaries (top, bottom, left, right) and shrink them as we traverse.
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> result = new ArrayList<>();
int top = 0, bottom = matrix.length - 1;
int left = 0, right = matrix[0].length - 1;
while (top <= bottom && left <= right) {
for (int i = left; i <= right; i++) result.add(matrix[top][i]);
top++;
for (int i = top; i <= bottom; i++) result.add(matrix[i][right]);
right--;
if (top <= bottom) {
for (int i = right; i >= left; i--) result.add(matrix[bottom][i]);
bottom--;
}
if (left <= right) {
for (int i = bottom; i >= top; i--) result.add(matrix[i][left]);
left++;
}
}
return result;
}Edge Cases:
- Single row
- Single column
- 1x1 matrix
If an element is 0, set its entire row and column to 0.
Example:
Input: [[1,1,1],[1,0,1],[1,1,1]]
Output: [[1,0,1],[0,0,0],[1,0,1]]
Row 1 and column 1 become zeros
Optimal Solution — O(m * n) time, O(1) space
Use first row and column as markers to avoid extra space.
public void setZeroes(int[][] matrix) {
boolean firstRow = false, firstCol = false;
int m = matrix.length, n = matrix[0].length;
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
if (matrix[i][j] == 0) {
if (i == 0) firstRow = true;
if (j == 0) firstCol = true;
matrix[i][0] = 0;
matrix[0][j] = 0;
}
for (int i = 1; i < m; i++)
for (int j = 1; j < n; j++)
if (matrix[i][0] == 0 || matrix[0][j] == 0)
matrix[i][j] = 0;
if (firstRow) for (int j = 0; j < n; j++) matrix[0][j] = 0;
if (firstCol) for (int i = 0; i < m; i++) matrix[i][0] = 0;
}Edge Cases:
- No zeros
- Entire matrix zeros
- Single element
Quiz
1. How do you declare a 2D array in Java?
2. What is a jagged array?
3. How do you get the number of rows in a 2D array?
4. What is the primary purpose of Multidimensional Arrays?
Flashcards
Question
How do you traverse a 2D array in Java?
Click to reveal answer
Answer
Use nested for loops: for (int i = 0; i < matrix.length; i++) for (int j = 0; j < matrix[i].length; j++)
Question
What is the difference between matrix.length and matrix[0].length?
Click to reveal answer
Answer
matrix.length is the number of rows. matrix[0].length is the number of columns in the first row.
Question
How do you transpose a matrix?
Click to reveal answer
Answer
Swap matrix[i][j] with matrix[j][i] for all i < j. For non-square matrices, create new array with swapped dimensions.
Question
What is Multidimensional Arrays?
Click to reveal answer
Answer
Multidimensional Arrays is a key concept in Java programming.
Question
When to use Multidimensional Arrays?
Click to reveal answer
Answer
Use Multidimensional Arrays when building production systems that require reliability, scalability, and maintainability.
Revision Notes
Key Takeaways
- 1.2D arrays are arrays of arrays
- 2.Each row can have different length (jagged arrays)
- 3.Use nested loops for traversal
- 4.Matrix operations often require O(n²) time
Interview Tips
- •Always check bounds before accessing elements
- •Consider in-place operations to save space
- •Practice spiral order and diagonal traversal
- •Know how to handle non-square matrices
Cheat Sheet
Cheat Sheet
- Declaration:
int[][] arr = new int[3][4]; - Access:
arr[row][col] - Rows:
arr.length - Columns:
arr[0].length - Transpose: swap [i][j] with [j][i]
- Rotate 90°: transpose + reverse rows