题目描述
题目来源于leetcode
给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素,对角线遍历如下图所示。
示例:
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,4,7,5,3,6,8,9]
说明:
给定矩阵中的元素总数不会超过 100000 。
简要分析
一共需要遍历M+N层,每一层的元素索引之和=层数。
2种遍历方式,一种是右上,一种是左下,可以根据当前层数来判断选用那种方式。
右上遍历的第一个元素是上一层末尾元素的下方
左下遍历的第一个元素是上一层末尾元素的右方
代码
class Solution {
public void action(int[][] matrix,List<Integer> list,int[] end,int k,int m,int n,int all) {//end是每一层的最后一个元素的索引,k是当前正在遍历层数,m是M行,n是N列,all是m+n的值,也就是最终需要遍历的层数
if(k>all) {//如果遍历的层数>最终层数,结束
return;
}
/*
*遍历有2个方向,一个是右上,一个是左下,可以根据k的值发现往哪个
*方向进行遍历
*/
if(k%2==1) {//左下方
int a;
for(a=end[0];a<=k;a++) {//这一层的第一个元素在上一层最后一个元素的右方,遍历得到的元素的索引之和=k
if(a<m && k-a<n) {
list.add(matrix[a][k-a]);
end = new int[]{a,k-a};//将end重置为当前层数最后一个元素的索引
}
}
action(matrix, list, end, k+1, m, n, all);//当前层数+1,继续遍历
}
if(k%2==0) {//右上方
int b;
for(b=end[1];b<=k;b++) {这一层的第一个元素在上一层最后一个元素的下方,遍历得到的元素的索引之和=k
if(b<n && k-b<m) {
list.add(matrix[k-b][b]);
end = new int[] {k-b,b};
}
}
action(matrix, list, end, k+1, m, n, all);
}
}
public int[] findDiagonalOrder(int[][] matrix) {
if(matrix==null || matrix.length==0) {
int[] x= {};
return x;
}
int M = matrix.length;
int N = matrix[0].length;
/*
*只有一行或一列得情况
*/
if(M==1) {
return matrix[0];
}
if(N==1) {
int[] result = new int[M];
for(int i=0;i<M;i++) {
result[i] = matrix[i][0];
}
return result;
}
int[] end = {0,0};
List<Integer> list = new ArrayList<>();
list.add(matrix[0][0]);
action(matrix, list, end, 1,M,N,M+N);//从第一层开始
return list.stream().mapToInt(Integer::intValue).toArray();//将list转换为数组返回
}
}