问题:
Given a matrix of M x N elements (M rows, N columns), return all elements of the matrix in diagonal order as shown in the below image.
Example:
Input:
[ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]Output: [1,2,4,7,5,3,6,8,9]Explanation:
Note:
- The total number of elements of the given matrix will not exceed 10,000.
解决:
①
移动的方向不再是水平或竖直方向,而是对角线方向,那么每移动一次,横纵坐标都要变化,向右上移动的话要坐标加上[-1, 1],向左下移动的话要坐标加上[1, -1],那么难点在于我们如何处理越界情况,越界后遍历的方向怎么变换。
向右上和左下两个对角线方向遍历的时候都会有越界的可能,但是除了左下角和右上角的位置越界需要改变两个坐标之外,其余的越界只需要改变一个。
那么我们就先判断要同时改变两个坐标的越界情况,即在右上角和左下角的位置。如果在右上角位置还要往右上走时,那么要移动到它下面的位置的,那么如果col超过了n-1的范围,那么col重置为n-1,并且row自增2,然后改变遍历的方向。同理如果row超过了m-1的范围,那么row重置为m-1,并且col自增2,然后改变遍历的方向。然后我们再来判断一般的越界情况,如果row小于0,那么row重置0,然后改变遍历的方向。同理如果col小于0,那么col重置0,然后改变遍历的方向。
class Solution { //10ms
public int[] findDiagonalOrder(int[][] matrix) { if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return new int[]{}; int m = matrix.length; int n = matrix[0].length; int row = 0; int col = 0; int k = 0; int[] res = new int[m * n]; int[][] dirs = { {-1,1},{1,-1}}; for (int i = 0;i < m * n;i ++){ res[i] = matrix[row][col]; row += dirs[k][0]; col += dirs[k][1]; if (row >= m){ row = m - 1; col += 2; k = 1 - k; } if (col >= n){ col = n - 1; row += 2; k = 1 - k; } if (row < 0){ row = 0; k = 1 - k; } if (col < 0){ col = 0; k = 1 - k; } } return res; } }② 根据横纵坐标之和的奇偶性来判断遍历的方向,然后对于越界情况再单独处理即可。
class Solution { //8ms
public int[] findDiagonalOrder(int[][] matrix) { if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return new int[]{}; int m = matrix.length; int n = matrix[0].length; int row = 0; int col = 0; int[] res = new int[m * n]; for (int i = 0;i < m * n;i ++){ res[i] = matrix[row][col]; if ((row + col) % 2 == 0){ if (col == n - 1){ row ++; }else if (row == 0){ col ++; }else { row --; col ++; } }else{ if (row == m - 1) { col++; }else if (col == 0){ row ++; }else { row ++; col --; } } } return res; } }