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]
                    pass
public 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
end

2. 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] } }
end

3. 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!)
end

4. 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 result
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) {
        // 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
end

Practice Matches

Check out the Practice Problems to apply these templates to real LeetCode challenges.