Skip to content

Commit ec22f9e

Browse files
Update solution for Problem 1329: Sort Matrix by Diagonals - use correct in-place algorithm with direct diagonal access
1 parent 2471727 commit ec22f9e

File tree

4 files changed

+189
-0
lines changed

4 files changed

+189
-0
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Sort Matrix by Diagonals - Problem #1329
2+
3+
## Problem Description
4+
A matrix diagonal is a diagonal line of cells starting from some cell in either the topmost row or leftmost column and going in the southwest direction until reaching the matrix's end. For example, the matrix diagonal starting from `mat[2][0]`, where `mat` is a 6 x 3 matrix, includes cells `mat[2][0]`, `mat[3][1]`, and `mat[4][2]`.
5+
6+
Given an `m x n` matrix `mat`, return a matrix of the same size where all the diagonals are sorted in ascending order.
7+
8+
## Examples
9+
```
10+
Input: mat = [[3,3,1,1],[2,2,1,2],[1,1,1,2]]
11+
Output: [[1,1,1,1],[1,2,2,2],[1,2,3,3]]
12+
Explanation:
13+
The diagonals are:
14+
- [3] (from mat[0][0])
15+
- [2,3] (from mat[1][0])
16+
- [1,2,1] (from mat[2][0])
17+
- [1,1,2] (from mat[0][1])
18+
- [2,2] (from mat[1][1])
19+
- [1] (from mat[2][1])
20+
21+
After sorting each diagonal:
22+
- [3] → [3]
23+
- [2,3] → [2,3]
24+
- [1,2,1] → [1,1,2]
25+
- [1,1,2] → [1,1,2]
26+
- [2,2] → [2,2]
27+
- [1] → [1]
28+
29+
The final matrix is [[1,1,1,1],[1,2,2,2],[1,2,3,3]]
30+
```
31+
32+
## Approach
33+
This is a matrix traversal problem that requires identifying diagonals and sorting them. The key insight is that elements on the same diagonal have the same difference between their row and column indices.
34+
35+
## Algorithm
36+
1. **Identify diagonal groups**: Elements on the same diagonal have `row - col = constant`
37+
2. **Group by diagonal**: Use a map or array to group elements by their diagonal difference
38+
3. **Sort each diagonal**: Sort the elements in each diagonal group
39+
4. **Reconstruct matrix**: Place the sorted elements back into the matrix in diagonal order
40+
41+
## Key Implementation Details
42+
- **Diagonal Identification**: Use `row - col` to identify which diagonal an element belongs to
43+
- **Diagonal Grouping**: Collect all elements from each diagonal into separate arrays
44+
- **Sorting**: Sort each diagonal array in ascending order
45+
- **Matrix Reconstruction**: Place sorted elements back into the matrix following diagonal patterns
46+
47+
## Mathematical Intuition
48+
The diagonal pattern follows this rule:
49+
- **Diagonal Difference**: Elements on diagonal `i` have `row - col = i`
50+
- **Diagonal Order**: Diagonals are processed from top-left to bottom-right
51+
- **Element Placement**: After sorting, elements are placed back in their original diagonal positions
52+
53+
## Time Complexity
54+
- **Time**: O(mn × log(min(m,n))) where m and n are the dimensions of the matrix
55+
- O(mn) to collect elements from all diagonals
56+
- O(log(min(m,n))) to sort each diagonal (worst case when diagonal length is min(m,n))
57+
- **Space**: O(mn) for storing diagonal elements
58+
59+
## Example Walkthrough
60+
For input `[[3,3,1,1],[2,2,1,2],[1,1,1,2]]`:
61+
- Diagonal 0 (row-col=0): [3,2,1] → sorted: [1,2,3]
62+
- Diagonal -1 (row-col=-1): [3,2,1] → sorted: [1,2,3]
63+
- Diagonal -2 (row-col=-2): [1,2] → sorted: [1,2]
64+
- Diagonal -3 (row-col=-3): [1] → sorted: [1]
65+
- Diagonal 1 (row-col=1): [2,1] → sorted: [1,2]
66+
- Diagonal 2 (row-col=2): [1] → sorted: [1]
67+
68+
## Key Insights
69+
- **Diagonal Property**: Elements on the same diagonal have constant `row - col` difference
70+
- **Grouping Strategy**: Collect all elements from each diagonal before sorting
71+
- **Reconstruction Order**: Place sorted elements back in diagonal order
72+
- **Boundary Handling**: Handle edge cases for rectangular matrices
73+
74+
## Alternative Approaches
75+
- **In-place Sorting**: Sort diagonals directly in the matrix (more complex)
76+
- **Priority Queue**: Use min-heap for each diagonal
77+
- **Bucket Sort**: Use counting sort for small integer ranges
78+
- **Two-pass**: First collect, then reconstruct
79+
80+
## Edge Cases
81+
- **Empty Matrix**: Return empty matrix
82+
- **Single Row/Column**: Handle 1D matrices
83+
- **Rectangular Matrix**: Handle non-square matrices
84+
- **Single Element**: Handle 1×1 matrices
85+
- **All Same Values**: Handle matrices with identical elements
86+
87+
## Applications
88+
- **Image Processing**: Sort pixel values along diagonal lines
89+
- **Data Analysis**: Organize data by diagonal patterns
90+
- **Matrix Operations**: Preprocessing for matrix algorithms
91+
- **Pattern Recognition**: Analyze diagonal structures
92+
- **Game Development**: Sort game board elements diagonally
93+
94+
## Optimization Opportunities
95+
- **Early Termination**: Stop when all diagonals are processed
96+
- **Memory Access**: Optimize matrix traversal patterns
97+
- **Sorting Algorithm**: Choose appropriate sorting method based on data
98+
- **In-place Operations**: Minimize extra memory usage
99+
100+
## Related Problems
101+
- **Diagonal Traverse**: Traverse matrix in diagonal order
102+
- **Rotate Image**: Rotate matrix by 90 degrees
103+
- **Matrix Sorting**: Various matrix sorting problems
104+
- **Grid Operations**: Other grid-based algorithms
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import java.util.*;
2+
3+
class Solution {
4+
public int[][] sortMatrix(int[][] grid) {
5+
int n = grid.length;
6+
7+
// Sort diagonals starting from top row (excluding main diagonal)
8+
for (int d = n - 2; d >= 0; d--) {
9+
List<Integer> diag = new ArrayList<>();
10+
for (int i = 0; i < n - d; i++) {
11+
diag.add(grid[i][i + d]);
12+
}
13+
Collections.sort(diag);
14+
for (int i = 0; i < n - d; i++) {
15+
grid[i][i + d] = diag.get(i);
16+
}
17+
}
18+
19+
// Sort diagonals starting from left column (including main diagonal)
20+
for (int d = 0; d < n; d++) {
21+
List<Integer> diag = new ArrayList<>();
22+
for (int j = 0; j < n - d; j++) {
23+
diag.add(grid[j + d][j]);
24+
}
25+
Collections.sort(diag, Collections.reverseOrder());
26+
for (int j = 0; j < n - d; j++) {
27+
grid[j + d][j] = diag.get(j);
28+
}
29+
}
30+
31+
return grid;
32+
}
33+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* @param {number[][]} grid
3+
* @return {number[][]}
4+
*/
5+
var sortMatrix = function(grid) {
6+
const n = grid.length;
7+
8+
// Sort diagonals starting from top row (excluding main diagonal)
9+
for (let d = n - 2; d >= 0; d--) {
10+
const diag = [];
11+
for (let i = 0; i < n - d; i++) {
12+
diag.push(grid[i][i + d]);
13+
}
14+
diag.sort((a, b) => a - b);
15+
for (let i = 0; i < n - d; i++) {
16+
grid[i][i + d] = diag[i];
17+
}
18+
}
19+
20+
// Sort diagonals starting from left column (including main diagonal)
21+
for (let d = 0; d < n; d++) {
22+
const diag = [];
23+
for (let i = 0; i < n - d; i++) {
24+
diag.push(grid[i + d][i]);
25+
}
26+
diag.sort((a, b) => b - a); // reverse sort
27+
for (let i = 0; i < n - d; i++) {
28+
grid[i + d][i] = diag[i];
29+
}
30+
}
31+
32+
return grid;
33+
};
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from typing import List
2+
3+
class Solution:
4+
def sortMatrix(self, grid: List[List[int]]) -> List[List[int]]:
5+
n = len(grid)
6+
7+
# Sort diagonals starting from top row (excluding main diagonal)
8+
for d in range(n-2, -1, -1):
9+
diag = sorted(grid[i][i+d] for i in range(n-d))
10+
for i in range(n-d):
11+
grid[i][i+d] = diag[i]
12+
13+
# Sort diagonals starting from left column (including main diagonal)
14+
for d in range(n):
15+
diag = sorted((grid[j+d][j] for j in range(n-d)), reverse=True)
16+
for j in range(n-d):
17+
grid[j+d][j] = diag[j]
18+
19+
return grid

0 commit comments

Comments
 (0)