1329. 将矩阵按对角线排序

地址:

力扣icon-default.png?t=M1L8https://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;
}

其他解题思路待开发

查看更多刷题笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值