Code Templates
Master the matrix algorithms and 2D data structure techniques with these optimized code templates. Use them as starting points for solving matrix manipulation, traversal, search, and transformation problems across different programming languages.
1. Matrix Traversal (The Foundation)
Most matrix problems require iterating through every cell or checking neighbors.
Code Breakdown
graph TD
Start["Start Loop i=0 to M-1"] --> Inner["Start Loop j=0 to N-1"]
Inner --> Process["Process matrix[i][j]"]
Process --> CheckNeighbors{"Check Neighbors?"}
CheckNeighbors -- Yes --> Validate["Validate Boundaries:<br>r >= 0, r < M<br>c >= 0, c < N"]
CheckNeighbors -- No --> NextCol
Validate --> NextCol["Next Column j++"]
NextCol --> Inner
Inner -- Done --> NextRow["Next Row i++"]
NextRow --> Start
function traverseMatrix(matrix) {
if (!matrix.length || !matrix[0].length) return;
const rows = matrix.length;
const cols = matrix[0].length;
// Directions: Up, Down, Left, Right
const directions = [[-1, 0], [1, 0], [0, -1], [0, 1]];
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
// Process cell
console.log(`Processing ${matrix[i][j]}`);
// Check neighbors
for (const [di, dj] of directions) {
const ni = i + di;
const nj = j + dj;
// Validate boundaries
if (ni >= 0 && ni < rows && nj >= 0 && nj < cols) {
// Process neighbor matrix[ni][nj]
}
}
}
}
}def traverse_matrix(matrix):
if not matrix or not matrix[0]:
return
rows, cols = len(matrix), len(matrix[0])
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] # Up, Down, Left, Right
for i in range(rows):
for j in range(cols):
# Process cell
print(f"Processing {matrix[i][j]}")
# Check neighbors
for di, dj in directions:
ni, nj = i + di, j + dj
# Validate boundaries
if 0 <= ni < rows and 0 <= nj < cols:
# Process neighbor matrix[ni][nj]
passpublic void traverseMatrix(int[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return;
int rows = matrix.length;
int cols = matrix[0].length;
int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
// Process cell
System.out.println("Processing " + matrix[i][j]);
// Check neighbors
for (int[] dir : directions) {
int ni = i + dir[0];
int nj = j + dir[1];
// Validate boundaries
if (ni >= 0 && ni < rows && nj >= 0 && nj < cols) {
// Process neighbor matrix[ni][nj]
}
}
}
}
}void traverseMatrix(vector<vector<int>>& matrix) {
if (matrix.empty() || matrix[0].empty()) return;
int rows = matrix.size();
int cols = matrix[0].size();
vector<pair<int, int>> directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
// Process cell
// cout << "Processing " << matrix[i][j] << endl;
// Check neighbors
for (auto& dir : directions) {
int ni = i + dir.first;
int nj = j + dir.second;
// Validate boundaries
if (ni >= 0 && ni < rows && nj >= 0 && nj < cols) {
// Process neighbor matrix[ni][nj]
}
}
}
}
}func traverseMatrix(matrix [][]int) {
if len(matrix) == 0 || len(matrix[0]) == 0 {
return
}
rows := len(matrix)
cols := len(matrix[0])
directions := [][]int{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}
for i := 0; i < rows; i++ {
for j := 0; j < cols; j++ {
// Process cell
// fmt.Println("Processing", matrix[i][j])
// Check neighbors
for _, dir := range directions {
ni, nj := i+dir[0], j+dir[1]
// Validate boundaries
if ni >= 0 && ni < rows && nj >= 0 && nj < cols {
// Process neighbor matrix[ni][nj]
}
}
}
}
}def traverse_matrix(matrix)
return if matrix.empty? || matrix[0].empty?
rows = matrix.length
cols = matrix[0].length
directions = [[-1, 0], [1, 0], [0, -1], [0, 1]]
(0...rows).each do |i|
(0...cols).each do |j|
# Process cell
puts "Processing #{matrix[i][j]}"
# Check neighbors
directions.each do |di, dj|
ni, nj = i + di, j + dj
# Validate boundaries
if ni >= 0 && ni < rows && nj >= 0 && nj < cols
# Process neighbor matrix[ni][nj]
end
end
end
end
end2. Matrix Transpose
Matrix transposition swaps rows and columns (MxN -> NxM).
function transpose(matrix) {
const rows = matrix.length;
const cols = matrix[0].length;
const result = Array.from({length: cols}, () => Array(rows).fill(0));
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
result[j][i] = matrix[i][j];
}
}
return result;
}def transpose(matrix):
rows, cols = len(matrix), len(matrix[0])
# List comprehension for concise transposition
return [[matrix[i][j] for i in range(rows)] for j in range(cols)]
# Alternatively using zip:
# return list(map(list, zip(*matrix)))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;
}vector<vector<int>> transpose(vector<vector<int>>& matrix) {
int rows = matrix.size();
int cols = matrix[0].size();
vector<vector<int>> result(cols, vector<int>(rows));
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
result[j][i] = matrix[i][j];
}
}
return result;
}func transpose(matrix [][]int) [][]int {
rows := len(matrix)
cols := len(matrix[0])
result := make([][]int, cols)
for i := range result {
result[i] = make([]int, rows)
}
for i := 0; i < rows; i++ {
for j := 0; j < cols; j++ {
result[j][i] = matrix[i][j]
}
}
return result
}def transpose(matrix)
# Ruby has a built-in method
matrix.transpose
# Manual implementation:
# rows = matrix.length
# cols = matrix[0].length
# Array.new(cols) { |j| Array.new(rows) { |i| matrix[i][j] } }
end3. Matrix Rotation (90° Clockwise)
To rotate 90° clockwise: Transpose then Reverse Rows.
function rotate(matrix) {
const n = matrix.length;
// 1. Transpose
for (let i = 0; i < n; i++) {
for (let j = i; j < n; j++) {
[matrix[i][j], matrix[j][i]] = [matrix[j][i], matrix[i][j]];
}
}
// 2. Reverse Rows
for (let i = 0; i < n; i++) {
matrix[i].reverse();
}
}def rotate(matrix):
n = len(matrix)
# 1. Transpose
for i in range(n):
for j in range(i, n):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
# 2. Reverse Rows
for i in range(n):
matrix[i].reverse()public void rotate(int[][] matrix) {
int n = matrix.length;
// 1. Transpose
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
// 2. Reverse Rows
for (int i = 0; i < n; i++) {
for (int j = 0; j < n / 2; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[i][n - 1 - j];
matrix[i][n - 1 - j] = temp;
}
}
}void rotate(vector<vector<int>>& matrix) {
int n = matrix.size();
// 1. Transpose
for (int i = 0; i < n; ++i) {
for (int j = i; j < n; ++j) {
swap(matrix[i][j], matrix[j][i]);
}
}
// 2. Reverse Rows
for (int i = 0; i < n; ++i) {
reverse(matrix[i].begin(), matrix[i].end());
}
}func rotate(matrix [][]int) {
n := len(matrix)
// 1. Transpose
for i := 0; i < n; i++ {
for j := i; j < n; j++ {
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
}
}
// 2. Reverse Rows
for i := 0; i < n; i++ {
for j, k := 0, n-1; j < k; j, k = j+1, k-1 {
matrix[i][j], matrix[i][k] = matrix[i][k], matrix[i][j]
}
}
}def rotate(matrix)
n = matrix.length
# 1. Transpose
(0...n).each do |i|
(i...n).each do |j|
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
end
end
# 2. Reverse Rows
matrix.each(&:reverse!)
end4. Spiral Traversal
Handling shrinking boundaries: Top++, Bottom–, Left++, Right–.
function spiralOrder(matrix) {
const result = [];
if (!matrix.length) return result;
let top = 0, bottom = matrix.length - 1;
let left = 0, right = matrix[0].length - 1;
while (top <= bottom && left <= right) {
// Right
for (let j = left; j <= right; j++) result.push(matrix[top][j]);
top++;
// Down
for (let i = top; i <= bottom; i++) result.push(matrix[i][right]);
right--;
if (top <= bottom) {
// Left
for (let j = right; j >= left; j--) result.push(matrix[bottom][j]);
bottom--;
}
if (left <= right) {
// Up
for (let i = bottom; i >= top; i--) result.push(matrix[i][left]);
left++;
}
}
return result;
}def spiral_order(matrix):
result = []
if not matrix: return result
top, bottom = 0, len(matrix) - 1
left, right = 0, len(matrix[0]) - 1
while top <= bottom and left <= right:
# Right
for j in range(left, right + 1):
result.append(matrix[top][j])
top += 1
# Down
for i in range(top, bottom + 1):
result.append(matrix[i][right])
right -= 1
if top <= bottom:
# Left
for j in range(right, left - 1, -1):
result.append(matrix[bottom][j])
bottom -= 1
if left <= right:
# Up
for i in range(bottom, top - 1, -1):
result.append(matrix[i][left])
left += 1
return resultpublic 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) {
// Right
for (int j = left; j <= right; j++) result.add(matrix[top][j]);
top++;
// Down
for (int i = top; i <= bottom; i++) result.add(matrix[i][right]);
right--;
if (top <= bottom) {
// Left
for (int j = right; j >= left; j--) result.add(matrix[bottom][j]);
bottom--;
}
if (left <= right) {
// Up
for (int i = bottom; i >= top; i--) result.add(matrix[i][left]);
left++;
}
}
return result;
}vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int> result;
if (matrix.empty()) return result;
int top = 0, bottom = matrix.size() - 1;
int left = 0, right = matrix[0].size() - 1;
while (top <= bottom && left <= right) {
// Right
for (int j = left; j <= right; ++j) result.push_back(matrix[top][j]);
top++;
// Down
for (int i = top; i <= bottom; ++i) result.push_back(matrix[i][right]);
right--;
if (top <= bottom) {
// Left
for (int j = right; j >= left; --j) result.push_back(matrix[bottom][j]);
bottom--;
}
if (left <= right) {
// Up
for (int i = bottom; i >= top; --i) result.push_back(matrix[i][left]);
left++;
}
}
return result;
}func spiralOrder(matrix [][]int) []int {
var result []int
if len(matrix) == 0 { return result }
top, bottom := 0, len(matrix)-1
left, right := 0, len(matrix[0])-1
for top <= bottom && left <= right {
// Right
for j := left; j <= right; j++ { result = append(result, matrix[top][j]) }
top++
// Down
for i := top; i <= bottom; i++ { result = append(result, matrix[i][right]) }
right--
if top <= bottom {
// Left
for j := right; j >= left; j-- { result = append(result, matrix[bottom][j]) }
bottom--
}
if left <= right {
// Up
for i := bottom; i >= top; i-- { result = append(result, matrix[i][left]) }
left++
}
}
return result
}def spiral_order(matrix)
result = []
return result if matrix.empty?
top, bottom = 0, matrix.length - 1
left, right = 0, matrix[0].length - 1
while top <= bottom && left <= right
# Right
(left..right).each { |j| result << matrix[top][j] }
top += 1
# Down
(top..bottom).each { |i| result << matrix[i][right] }
right -= 1
if top <= bottom
# Left
(left..right).to_a.reverse.each { |j| result << matrix[bottom][j] }
bottom -= 1
end
if left <= right
# Up
(top..bottom).to_a.reverse.each { |i| result << matrix[i][left] }
left += 1
end
end
result
endPractice Matches
Check out the Practice Problems to apply these templates to real LeetCode challenges.