Sort the Matrix Diagonally

medium array matrix sorting

Problem

You are given an m × n integer matrix. A diagonal here means a line of cells running from the top-left toward the bottom-right: it begins at some cell in the top row or the leftmost column and keeps stepping one row down and one column right until it leaves the grid. Sort the values along every such diagonal in ascending order and return the resulting matrix.

Constraints: 1 ≤ m, n ≤ 100 and 1 ≤ mat[i][j] ≤ 100.

Inputmat = [[3,3,1,1],[2,2,1,2],[1,1,1,2]]
Output[[1,1,1,1],[1,2,2,2],[1,2,3,3]]
The diagonal through (0,0), (1,1), (2,2) holds [3, 2, 1] and becomes [1, 2, 3]; every other ↘ diagonal is sorted the same way.

def diagonal_sort(mat):
    m, n = len(mat), len(mat[0])

    def sort_diag(i, j):
        vals = []
        r, c = i, j
        while r < m and c < n:       # collect the diagonal
            vals.append(mat[r][c])
            r, c = r + 1, c + 1
        vals.sort()                  # sort its values
        r, c = i, j
        for v in vals:               # write them back
            mat[r][c] = v
            r, c = r + 1, c + 1

    for j in range(n):               # diagonals starting on row 0
        sort_diag(0, j)
    for i in range(1, m):            # diagonals starting on column 0
        sort_diag(i, 0)
    return mat
function diagonalSort(mat) {
  const m = mat.length, n = mat[0].length;
  const sortDiag = (i, j) => {
    const vals = [];
    for (let r = i, c = j; r < m && c < n; r++, c++)
      vals.push(mat[r][c]);          // collect the diagonal
    vals.sort((a, b) => a - b);      // sort its values
    let k = 0;
    for (let r = i, c = j; r < m && c < n; r++, c++)
      mat[r][c] = vals[k++];         // write them back
  };
  for (let j = 0; j < n; j++) sortDiag(0, j);
  for (let i = 1; i < m; i++) sortDiag(i, 0);
  return mat;
}
int[][] diagonalSort(int[][] mat) {
    int m = mat.length, n = mat[0].length;
    for (int j = 0; j < n; j++) sortDiag(mat, 0, j);
    for (int i = 1; i < m; i++) sortDiag(mat, i, 0);
    return mat;
}

void sortDiag(int[][] mat, int i, int j) {
    int m = mat.length, n = mat[0].length;
    List<Integer> vals = new ArrayList<>();
    for (int r = i, c = j; r < m && c < n; r++, c++)
        vals.add(mat[r][c]);               // collect the diagonal
    Collections.sort(vals);                // sort its values
    int k = 0;
    for (int r = i, c = j; r < m && c < n; r++, c++)
        mat[r][c] = vals.get(k++);         // write them back
}
vector<vector<int>> diagonalSort(vector<vector<int>>& mat) {
    int m = mat.size(), n = mat[0].size();
    auto sortDiag = [&](int i, int j) {
        vector<int> vals;
        for (int r = i, c = j; r < m && c < n; r++, c++)
            vals.push_back(mat[r][c]);     // collect the diagonal
        sort(vals.begin(), vals.end());    // sort its values
        int k = 0;
        for (int r = i, c = j; r < m && c < n; r++, c++)
            mat[r][c] = vals[k++];         // write them back
    };
    for (int j = 0; j < n; j++) sortDiag(0, j);
    for (int i = 1; i < m; i++) sortDiag(i, 0);
    return mat;
}
Time: O(m·n · log(min(m, n))) Space: O(min(m, n))