一、题目描述
给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素,对角线遍历如下图所示。

二、解题思路
对角线遍历:根据题目给定一个矩阵(如下),


我们可以发现遍历的顺序分为斜上走和斜下走,分别有不同的特点:

考虑边界条件:
条件一:假如,下面这个先斜上走,遍历完1之后,下一个遍历的元素根据上面斜上走的条件,发现超出边界,此时应该调转方向:row<0:row=0,col不变,换方向表示当row小于0时,将row设置为0,col不变,换方向。

条件二:同理,斜下走满足条件也要换方向:col<0:row不变,col=0,换方向表示此时row保持不变,col设置为0,换方向:

条件三:一直到主对角线下面的斜下走遍历完,此时的位置处于第一列元素9的下面,此时换方向从最后一行元素11开始,需要新的边界条件,那么这时你会发现超出边界的条件是row>=m:row=m-1,col+=2,换方向意思是,当row大于等于行数m时,此时row从m-1开始,col从col+=2列开始:

条件四:继续斜上走,此时斜上走当col大于等于n列时,位置在第一行4的后面,此时也要换方向:col>=n:row+=2,col=n-1,换方向

最终:

特殊条件一:此时边界条件还没有考虑完,斜上和斜下也有可能同时存在两个边界条件,假如有一个n*n的矩阵:当走到主对角线时,发现条件一和条件四都符合,此时该怎么重新换方向走呢,使用哪个条件的逻辑呢?

这种情况,此时先执行条件四的逻辑,主对角线走完3之后再往上走,此时坐标应该是(-1,3)col>=n,先将row+=2,col=n-1,这时下一个遍历的元素就跑到了6这个位置:

特殊情况二:再来看下面这种情况,发现越界符合条件二和三,这时怎么继续遍历执行呢?

此时执行条件三,row>=m,row = m-1,col+=2,就来到我想要的位置,也就是斜上走的位置:

三、代码演示
class Solution {
public int[] findDiagonalOrder(int[][] mat) {
//假设矩阵元素个数为0的话,返回一个空数组
if (mat.length==0){
return new int[0];
}
//求出行列的长度
int m = mat.length;
int n = mat[0].length;
//定义一个二维数组来确定是往斜上还是斜下走,斜上:row-1,col+1;斜下:row+1,col-1
int[][] dirs = {{-1,1},{1,-1}};
//存放结果集
int[] result = new int[m*n];
//di是用来标识方向的
int row = 0, col = 0, di=0;
for (int i=0; i<m*n; i++){
result[i] = mat[row][col];
row = row + dirs[di][0];
col = col + dirs[di][1];
/**
* 这里先考虑同时满足两个越界条件的情况,最开始是斜上走,假如最开始的斜上走就出现了特殊情况一呢?
* 这时解决特殊情况一的情况(执行条件四)
*/
if (col>=n){
col = n-1;
row += 2;
//换方向,di取0和1,0是斜上,1是斜下,通过下面的公式计算下一个方向
di = 1-di;
}
//特殊情况二(执行条件三)
if (row>=m){
row = m-1;
col += 2;
di = 1-di;
}
//条件二
if (col<0){
col = 0;
di = 1-di;
}
//条件一
if (row<0){
row = 0;
di = 1-di;
}
}
return result;
}
}

1103

被折叠的 条评论
为什么被折叠?



