地址:
力扣https://leetcode-cn.com/problems/sort-the-matrix-diagonally/
题目:
矩阵对角线 是一条从矩阵最上面行或者最左侧列中的某个元素开始的对角线,沿右下方向一直到矩阵末尾的元素。例如,矩阵 mat 有 6 行 3 列,从 mat[2][0] 开始的 矩阵对角线 将会经过 mat[2][0]、mat[3][1] 和 mat[4][2] 。
给你一个 m * n 的整数矩阵 mat ,请你将同一条 矩阵对角线 上的元素按升序排序后,返回排好序的矩阵。
示例 1:
输入:mat = [[3,3,1,1],[2,2,1,2],[1,1,1,2]]
输出:[[1,1,1,1],[1,2,2,2],[1,2,3,3]]
示例 2:
输入:mat = [[11,25,66,1,69,7],[23,55,17,45,15,52],[75,31,36,44,58,8],[22,27,33,25,68,4],[84,28,14,11,5,50]]
输出:[[5,17,4,1,52,7],[11,11,25,45,8,69],[14,23,25,44,58,15],[22,27,31,36,50,66],[84,28,75,33,55,68]]
提示:
m == mat.length
n == mat[i].length
1 <= m, n <= 100
1 <= mat[i][j] <= 100
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sort-the-matrix-diagonally
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
这道题与 766. 托普利茨矩阵 类似,都是找对角线,但是比较麻烦的是需要对一条线上的数据进行重新排序,那么势必要记录原始的坐标,然后排序完再塞回去
选用另外一种思路觉得相对好操作点:
把二维数组转为一维数组进行操作,挑选坐标进行排序放到临时排序数组然后再塞回去
有两个坐标不需要排序:右上角+左下角
方法一、一维数组转换
先进行第一行的列遍历,再进行行遍历,行列遍历的自增分别是 1 (列),1(行),即 i+=i; i+=col
示例:
1. 二维数组转为一维数组
2. 首先对第一行,每一列开始遍历,对照两个数组来看,可以算出间距就是:列数+1
3. 然后从第 1 行开始进行行遍历,[1][0] 开始,间距也是:列数 + 1
4. 可以看见右上角与左下角坐标元素不参与,数组也可以看见没有标识颜色
5. 每一种颜色就是一个组,进行组内排序(如果下一次是要求升序,想想看怎么改代码)
排序完成后再塞回即可
6. 最后一维数组就是已经各自组内排序好的元素,再依序回填到二维数组即可
int **myMalloc(int r, int c, int *return_r, int **return_c)
{
int **ret = (int **)malloc(sizeof(int *) * r);
*return_r = r;
*return_c =(int *)malloc(sizeof(int) * r);
for(int i=0; i<r; i++)
{
ret[i] = (int *)malloc(sizeof(int) * c);
(*return_c)[i] = c;
}
return ret;
}
int cmp(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
void orderArr(int *arr, int arrLen, int row, int col, int start, int inc)
{
int i,j,k;
int *colArr = (int *)malloc(sizeof(int) * row);
int keepOne = col - 1;
int keepTwo = col * (row -1);
i = start;
memset(colArr, 0, sizeof(int) * row);
while(i != keepOne && i != keepTwo)
{
j = i;
k = 0;
while(j < arrLen)
{
//printf("arr[%d]=%d, k=%d\n", j, arr[j], k);
colArr[k++] = arr[j];
if((j+1)%col == 0)
break;
j += col + 1;
}
if(j > arrLen)
j -= (col+1);
//dispArr(colArr, k);
qsort(colArr, k, sizeof(int), cmp);
//dispArr(colArr, k);
while(k--)
{
//printf("copy back..colArr[%d]=%d, j=%d\n", k, colArr[k], j);
arr[j] = colArr[k];
j -= (col + 1);
}
i += inc;
}
}
void doSort(int *arr, int arrLen, int row, int col)
{
orderArr(arr, arrLen, row, col, 0, 1);
orderArr(arr, arrLen, row, col, col, col);
}
void dispArr(int *arr, int arrLen)
{
printf("Arr: ");
for(int i=0; i<arrLen; i++)
printf("%d ", arr[i]);
printf("\n");
}
void dispRet(int **ret, int row, int col)
{
printf("Ret:\n");
for(int i=0; i<row; i++)
{
for(int j=0; j<col; j++)
printf("%d ", ret[i][j]);
printf("\n");
}
}
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
int** diagonalSort(int** mat, int matSize, int* matColSize, int* returnSize, int** returnColumnSizes){
int i,j,k;
int row = matSize;
int col = matColSize[0];
if(row == 1)
{
*returnSize = matSize;
*returnColumnSizes =(int *)malloc(sizeof(int) * row);
for(int i=0; i<row; i++)
{
(*returnColumnSizes)[i] = col;
}
return mat;
}
int **ret = myMalloc(row, col, returnSize, returnColumnSizes);
// transfer mat[][] to arr[], then do sore by group
int arrLen = row * col;
int *arr = (int *)malloc(sizeof(int) * arrLen);
k = 0;
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
arr[k++] = mat[i][j];
}
}
// dispRet(mat, row, col);
// dispArr(arr, arrLen);
doSort(arr, arrLen, row, col);
//dispArr(arr, arrLen);
// tranfer arr[] back to mat[][]
k = 0;
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
ret[i][j] = arr[k++];
}
}
free(arr);
return ret;
}
其他解题思路待开发