Address:
Force bucklehttps://leetcode-cn.com/problems/sort-the-matrix-diagonally/
Title:
A matrix diagonal is a diagonal line starting from an element in the topmost row or leftmost column of the matrix, along the lower right direction to the end of the matrix. For example, the matrix mat has 6 rows and 3 columns. The diagonal of the matrix starting from mat[2][0] will pass through mat[2][0], mat[3][1] and mat[4][2].
Give you an integer matrix {mat of {m * n}. Please sort the elements on the diagonal of the same matrix in ascending order and return to the ordered matrix.
Example 1:
Input: mat = [[3,3,1,1], [2,2,1,2], [1,1,2]]
Output: [1,1,1,1], [1,2,2,2], [1,2,3,3]]
Example 2:
Input: 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]]
Output: [[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]]
Tips:
m == mat.length
n == mat[i].length
1 <= m, n <= 100
1 <= mat[i][j] <= 100
Source: LeetCode
Link: https://leetcode-cn.com/problems/sort-the-matrix-diagonally
The copyright belongs to Lingkou network. For commercial reprint, please contact the official authorization, and for non-commercial reprint, please indicate the source.
Idea:
This question is related to 766. Toplitz matrix Similarly, they all find diagonals, but the trouble is that the data on a line needs to be reordered, so it is necessary to record the original coordinates, and then insert them back after sorting
Choose another idea and feel that it is relatively good to operate:
Convert the two-dimensional array into one-dimensional array for operation, select the coordinates for sorting, put them into the temporary sorting array, and then plug them back
There are two coordinates that do not need to be sorted: upper right corner + lower left corner
Method 1: one dimensional array conversion
First perform the column traversal of the first row, and then the row traversal. The self increment of row and column traversal is 1 (column) and 1 (row), that is, i+=i; i+=col
Example:
1. Convert two-dimensional array to one-dimensional array
2. First, for the first row, start traversing each column. Compared with the two arrays, you can calculate the spacing: the number of columns + 1
3. Then start the row traversal from the first row, starting from [1] [0], and the spacing is also: number of columns + 1
4. It can be seen that the coordinate elements in the upper right corner and the lower left corner are not involved, and the array can also be seen that there is no identification color
5. Each color is a group. Sort within the group (if ascending order is required next time, think about how to change the code)
Insert it back after sorting
6. The last one-dimensional array is the elements that have been sorted in their respective groups, and then backfill them to the two-dimensional array in order
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; }
Other problem solving ideas to be developed