之前刷LeetCode都是直接进题库刷题,今天点开探索才发现还有这种模块化的入门教程,就打开数组与字符串那块开始学习。到二维数组的时候,有一道练习题是这样的:
给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素,对角线遍历如下图所示。
样例输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,4,7,5,3,6,8,9]
之前没有做过二维数组的题,上来一下就给我搞蒙了,后来仔细想想,这道题其实难点就在于遍历方向的判定和边界点的处理。
首先,对于遍历方向,我将其分为两类:左下和右上。在代码中设置一个标志位flag,就可以分别来对这两种情况进行处理。
其次,对于边界点的处理。先判断当前点是否是二维矩阵的最后一个点(即右下角),如果是,则遍历结束。对于遍历方向为右上的,先判定矩形的右边界,因为这个边界上的点的下一个遍历点只能是它正下方的那个点(已经排除了右下角的结束点),并在遍历下一个点的时候遍历方向改变。然后再判定是否是矩形的上边界,在排除了右边界的情况下,上边界的点的下一个遍历点只能是它正右方的那个点,并在遍历下一个点的时候遍历方向改变。不在这两个边界上的点的下一个遍历点均为它右上方的那个点。对于遍历方向为左下的,先判定矩形的下边界,因为在下边界上的点的下一个遍历点只能是它正右方的那个点,并在遍历下一个点的时候遍历方向改变。再判定矩形的左边界,因为在左边界上的点的下一个遍历点只能是它正下方的那个点,并在遍历下一个点的时候遍历方向改变。
这样一来,整个代码的逻辑就非常清晰了,代码如下:
class Solution {
public int[] findDiagonalOrder(int[][] matrix) {
if(matrix.length==0||matrix==null){
return new int[]{};
}//如果是空数组直接返回一个空数组
int m=matrix.length,n=matrix[0].length;
int[] ans=new int[m*n];//新建数组,大小为二维数组元素个数
int flag=0,a=0,b=0;//flag是标志位,0代表右上,1代表左下。a、b是当前遍历点的行列坐标,a为行,b为列
for(int i=0;i<m*n;i++){
ans[i]=matrix[a][b];//每一次遍历先保存该点的数值
if(a==m-1&&b==n-1){
break;
}//遍历到了最后一个点,就退出循环
if(flag==0){//方向是右上
if(b==n-1){//当前遍历点在右边界上
++a;
flag=1;
}
else if(a==0){//当前点在上边界且不在右边界上
++b;
flag=1;
}
else{//当前点不在边界上
--a;
++b;
}
}
else{//方向是左下
if(a==m-1){//当前点在下边界上
++b;
flag=0;
}
else if(b==0){//当前点在左边界上且不在下边界上
++a;
flag=0;
}
else{//当前点不在边界上
++a;
--b;
}
}
}
return ans;
}
}
这道题可能算是一道基础题,但是对于初学者来说,可以培养一种解决问题的思路。把一个看起来复杂的问题划分为几个步骤,将大问题划分为小问题,逻辑思路一下就清楚了。