Each diagonal below the main diagonal is sorted ascending, each diagonal above the main diagonal is sorted descending, and the main diagonal (3, 1, 2, 7) stays unchanged.
[Expected Approach] Using Diagonal Grouping and Sorting - O(n × m × log(min(n, m))) Time and O(min(n, m)) Space
Every cell on the same diagonal shares the same value of row minus column. Grouping all cells by this value separates the matrix into independent diagonals, each of which can be sorted on its own - ascending if it lies below the main diagonal, descending if above, and left untouched if it is the main diagonal itself.
Group every cell's value into a collection keyed by row - col, which identifies its diagonal.
Sort each diagonal's collected values: ascending if the key is positive (below the main diagonal), descending if the key is negative (above the main diagonal), and leave the main diagonal (key equal to 0) untouched.
Walk through the matrix again in the same row-by-row, left-to-right order, placing the sorted values back into their diagonal's positions in sequence.
C++
#include<algorithm>#include<iostream>#include<unordered_map>#include<vector>usingnamespacestd;voiddiagonalSort(vector<vector<int>>&matrix){intn=matrix.size();intm=matrix[0].size();unordered_map<int,vector<int>>diagonals;// Group elements by their diagonal index (row - col)for(inti=0;i<n;i++)for(intj=0;j<m;j++)diagonals[i-j].push_back(matrix[i][j]);// Sort each diagonal: ascending below main, descending above mainfor(auto&[diff,vals]:diagonals){if(diff>0)sort(vals.begin(),vals.end());elseif(diff<0)sort(vals.rbegin(),vals.rend());}// Track how many elements have been placed back per diagonalunordered_map<int,int>pos;for(inti=0;i<n;i++){for(intj=0;j<m;j++){intdiff=i-j;if(diff==0)continue;matrix[i][j]=diagonals[diff][pos[diff]++];}}}intmain(){vector<vector<int>>matrix={{3,6,3,8,2},{4,1,9,5,9},{5,7,2,4,8},{8,3,1,7,6}};diagonalSort(matrix);for(auto&row:matrix){for(intx:row)cout<<x<<" ";cout<<endl;}return0;}
Java
importjava.util.*;classGfG{staticvoiddiagonalSort(int[][]matrix){intn=matrix.length;intm=matrix[0].length;Map<Integer,List<Integer>>diagonals=newHashMap<>();// Group elements by their diagonal index (row -// col)for(inti=0;i<n;i++)for(intj=0;j<m;j++)diagonals.computeIfAbsent(i-j,x->newArrayList<>()).add(matrix[i][j]);// Sort each diagonal: ascending below main,// descending above mainfor(Map.Entry<Integer,List<Integer>>entry:diagonals.entrySet()){intdiff=entry.getKey();List<Integer>vals=entry.getValue();if(diff>0)Collections.sort(vals);elseif(diff<0)Collections.sort(vals,Collections.reverseOrder());}// Track how many elements have been placed back per// diagonalMap<Integer,Integer>pos=newHashMap<>();for(inti=0;i<n;i++){for(intj=0;j<m;j++){intdiff=i-j;if(diff==0)continue;intidx=pos.getOrDefault(diff,0);matrix[i][j]=diagonals.get(diff).get(idx);pos.put(diff,idx+1);}}}publicstaticvoidmain(String[]args){int[][]matrix={{3,6,3,8,2},{4,1,9,5,9},{5,7,2,4,8},{8,3,1,7,6}};diagonalSort(matrix);for(int[]row:matrix)System.out.println(Arrays.toString(row));}}
Python
defdiagonalSort(matrix):n=len(matrix)m=len(matrix[0])diagonals={}# Group elements by their diagonal index (row - col)foriinrange(n):forjinrange(m):diff=i-jdiagonals.setdefault(diff,[]).append(matrix[i][j])# Sort each diagonal: ascending below main, descending above mainfordiffindiagonals:ifdiff>0:diagonals[diff].sort()elifdiff<0:diagonals[diff].sort(reverse=True)# Track how many elements have been placed back per diagonalpos={}foriinrange(n):forjinrange(m):diff=i-jifdiff==0:continueidx=pos.get(diff,0)matrix[i][j]=diagonals[diff][idx]pos[diff]=idx+1if__name__=="__main__":matrix=[[3,6,3,8,2],[4,1,9,5,9],[5,7,2,4,8],[8,3,1,7,6]]diagonalSort(matrix)forrowinmatrix:print(row)
C#
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;classGfG{staticvoiddiagonalSort(int[][]matrix){intn=matrix.Length;intm=matrix[0].Length;Dictionary<int,List<int>>diagonals=newDictionary<int,List<int>>();// Group elements by their diagonal index (row -// col)for(inti=0;i<n;i++){for(intj=0;j<m;j++){intdiff=i-j;if(!diagonals.ContainsKey(diff))diagonals[diff]=newList<int>();diagonals[diff].Add(matrix[i][j]);}}// Sort each diagonal: ascending below main,// descending above mainforeach(vardiffindiagonals.Keys.ToList()){if(diff>0)diagonals[diff].Sort();elseif(diff<0)diagonals[diff].Sort((a,b)=>b.CompareTo(a));}// Track how many elements have been placed back per// diagonalDictionary<int,int>pos=newDictionary<int,int>();for(inti=0;i<n;i++){for(intj=0;j<m;j++){intdiff=i-j;if(diff==0)continue;intidx=pos.ContainsKey(diff)?pos[diff]:0;matrix[i][j]=diagonals[diff][idx];pos[diff]=idx+1;}}}staticvoidMain(){int[][]matrix={newint[]{3,6,3,8,2},newint[]{4,1,9,5,9},newint[]{5,7,2,4,8},newint[]{8,3,1,7,6}};diagonalSort(matrix);foreach(varrowinmatrix)Console.WriteLine(string.Join(" ",row));}}
JavaScript
functiondiagonalSort(matrix){constn=matrix.length;constm=matrix[0].length;constdiagonals=newMap();// Group elements by their diagonal index (row - col)for(leti=0;i<n;i++){for(letj=0;j<m;j++){constdiff=i-j;if(!diagonals.has(diff))diagonals.set(diff,[]);diagonals.get(diff).push(matrix[i][j]);}}// Sort each diagonal: ascending below main, descending// above mainfor(const[diff,vals]ofdiagonals){if(diff>0)vals.sort((a,b)=>a-b);elseif(diff<0)vals.sort((a,b)=>b-a);}// Track how many elements have been placed back per// diagonalconstpos=newMap();for(leti=0;i<n;i++){for(letj=0;j<m;j++){constdiff=i-j;if(diff===0)continue;constidx=pos.get(diff)||0;matrix[i][j]=diagonals.get(diff)[idx];pos.set(diff,idx+1);}}}// Driver codeconstmatrix=[[3,6,3,8,2],[4,1,9,5,9],[5,7,2,4,8],[8,3,1,7,6]];diagonalSort(matrix);matrix.forEach(row=>console.log(row.join(" ")));