🧠
Brute Force (Extract and Sort Each Diagonal Separately)
💡 This approach helps beginners understand the problem by directly extracting each diagonal, sorting it, and putting it back, without any optimization.
Intuition
Each diagonal can be identified by its starting point on the first row or first column. Extract all elements along that diagonal, sort them, then write them back.
Algorithm
- Identify all diagonals by their starting points on the first row and first column.
- For each diagonal, extract all elements into a list.
- Sort the list.
- Put the sorted elements back into their diagonal positions in the matrix.
💡 The challenge is correctly identifying and iterating over diagonals, which are not straightforward like rows or columns.
from typing import List
def diagonalSort(mat: List[List[int]]) -> List[List[int]]:
m, n = len(mat), len(mat[0])
# Function to sort one diagonal starting at (r, c)
def sort_diagonal(r, c):
diagonal = []
i, j = r, c
while i < m and j < n:
diagonal.append(mat[i][j])
i += 1
j += 1
diagonal.sort()
i, j = r, c
for val in diagonal:
mat[i][j] = val
i += 1
j += 1
# Sort diagonals starting from first row
for col in range(n):
sort_diagonal(0, col)
# Sort diagonals starting from first column (excluding [0,0])
for row in range(1, m):
sort_diagonal(row, 0)
return mat
# Driver code
if __name__ == '__main__':
matrix = [[3,3,1,1],[2,2,1,2],[1,1,1,2]]
print(diagonalSort(matrix))
Line Notes
m, n = len(mat), len(mat[0])Determine matrix dimensions for boundary checks
def sort_diagonal(r, c):Helper function to isolate and sort one diagonal
while i < m and j < n:Traverse the diagonal until hitting matrix boundary
diagonal.sort()Sort the extracted diagonal elements in ascending order
for val in diagonal:Put sorted values back into the matrix along the diagonal
for col in range(n):Start sorting diagonals from each column in the first row
for row in range(1, m):Start sorting diagonals from each row in the first column, skipping (0,0) to avoid duplication
import java.util.*;
public class Solution {
public int[][] diagonalSort(int[][] mat) {
int m = mat.length, n = mat[0].length;
// Sort one diagonal starting at (r, c)
for (int col = 0; col < n; col++) {
sortDiagonal(mat, 0, col, m, n);
}
for (int row = 1; row < m; row++) {
sortDiagonal(mat, row, 0, m, n);
}
return mat;
}
private void sortDiagonal(int[][] mat, int r, int c, int m, int n) {
List<Integer> diagonal = new ArrayList<>();
int i = r, j = c;
while (i < m && j < n) {
diagonal.add(mat[i][j]);
i++;
j++;
}
Collections.sort(diagonal);
i = r;
j = c;
for (int val : diagonal) {
mat[i][j] = val;
i++;
j++;
}
}
// Driver code
public static void main(String[] args) {
Solution sol = new Solution();
int[][] matrix = {{3,3,1,1},{2,2,1,2},{1,1,1,2}};
int[][] sorted = sol.diagonalSort(matrix);
for (int[] row : sorted) {
System.out.println(Arrays.toString(row));
}
}
}
Line Notes
int m = mat.length, n = mat[0].length;Get matrix dimensions for boundary checks
for (int col = 0; col < n; col++)Iterate over first row columns to start diagonals
for (int row = 1; row < m; row++)Iterate over first column rows to start diagonals, skip (0,0)
while (i < m && j < n)Traverse diagonal until boundary
Collections.sort(diagonal);Sort the diagonal elements
for (int val : diagonal)Write sorted values back into matrix diagonal
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
vector<vector<int>> diagonalSort(vector<vector<int>>& mat) {
int m = mat.size(), n = mat[0].size();
for (int col = 0; col < n; ++col) {
sortDiagonal(mat, 0, col, m, n);
}
for (int row = 1; row < m; ++row) {
sortDiagonal(mat, row, 0, m, n);
}
return mat;
}
private:
void sortDiagonal(vector<vector<int>>& mat, int r, int c, int m, int n) {
vector<int> diagonal;
int i = r, j = c;
while (i < m && j < n) {
diagonal.push_back(mat[i][j]);
i++;
j++;
}
sort(diagonal.begin(), diagonal.end());
i = r; j = c;
for (int val : diagonal) {
mat[i][j] = val;
i++;
j++;
}
}
};
// Driver code
int main() {
Solution sol;
vector<vector<int>> matrix = {{3,3,1,1},{2,2,1,2},{1,1,1,2}};
vector<vector<int>> sorted = sol.diagonalSort(matrix);
for (auto &row : sorted) {
for (int val : row) cout << val << ' ';
cout << '\n';
}
return 0;
}
Line Notes
int m = mat.size(), n = mat[0].size();Get matrix dimensions for boundary checks
for (int col = 0; col < n; ++col)Start diagonals from first row columns
for (int row = 1; row < m; ++row)Start diagonals from first column rows, skip (0,0)
while (i < m && j < n)Traverse diagonal until matrix boundary
sort(diagonal.begin(), diagonal.end());Sort the diagonal elements
for (int val : diagonal)Write sorted values back into matrix diagonal
var diagonalSort = function(mat) {
const m = mat.length, n = mat[0].length;
const sortDiagonal = (r, c) => {
const diagonal = [];
let i = r, j = c;
while (i < m && j < n) {
diagonal.push(mat[i][j]);
i++;
j++;
}
diagonal.sort((a,b) => a - b);
i = r; j = c;
for (const val of diagonal) {
mat[i][j] = val;
i++;
j++;
}
};
for (let col = 0; col < n; col++) {
sortDiagonal(0, col);
}
for (let row = 1; row < m; row++) {
sortDiagonal(row, 0);
}
return mat;
};
// Driver code
const matrix = [[3,3,1,1],[2,2,1,2],[1,1,1,2]];
console.log(diagonalSort(matrix));
Line Notes
const m = mat.length, n = mat[0].length;Get matrix dimensions for boundary checks
const sortDiagonal = (r, c) => {Helper function to extract and sort one diagonal
while (i < m && j < n)Traverse diagonal until matrix boundary
diagonal.sort((a,b) => a - b);Sort diagonal elements numerically ascending
for (const val of diagonal)Write sorted values back into matrix diagonal
for (let col = 0; col < n; col++)Start diagonals from first row columns
for (let row = 1; row < m; row++)Start diagonals from first column rows, skip (0,0)
TimeO(m * n * log(min(m, n)))
SpaceO(min(m, n))
We extract and sort each diagonal. There are roughly m + n diagonals, each up to length min(m, n). Sorting each diagonal costs O(k log k), k ≤ min(m,n). Total is O(m*n*log(min(m,n))).
💡 For a 100x100 matrix, this means sorting about 200 diagonals each up to length 100, which is efficient enough for interviews.
Interview Verdict: Accepted
This approach is straightforward and accepted for the problem constraints, making it a solid first solution.