今天我们来研究leetcode的螺旋矩阵问题,下面请看原题:
然后先看简单一点的方法:
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> res = new LinkedList<>();
if (matrix.length == 0) {
return res;
}
int up = 0, down = matrix.length - 1, left = 0, right = matrix[0].length - 1;
while (true) {
for (int col = left; col <= right; ++col) {
res.add(matrix[up][col]);
}
if (++up > down) {
break;
}
for (int row = up; row <= down; ++row) {
res.add(matrix[row][right]);
}
if (--right < left) {
break;
}
for (int col = right; col >= left; --col) {
res.add(matrix[down][col]);
}
if (--down < up) {
break;
}
for (int row = down; row >= up; --row) {
res.add(matrix[row][left]);
}
if (++left > right) {
break;
}
}
return res;
}
}
上面这道题传入一个矩阵进入我们的函数,我们为了让他能够正常跑,所以我们需要设立上下左右4个边界。他的左边界为0,他的右边界为matrix[0].length-1,他的上边界为0,他的下边界为matrix.length-1.上下左右4个边界设好之后我们开始简单的遍历操作就可以了,首先从第一行来将第一行中的所有元素加入到我们的链表中去之后,我们的上边界,也就是我们的up值给他加一个1,然后做一个判断,如果上边届++之后我们的边界值大于下边界的话,证明我们的二维数组已经遍历完毕了,所以我们直接就退出循环。然后我们开始循环遍历列。如果列的长度小于左边界的话,我们退出循环,然后重新开始遍历行,再重新开始遍历列,当我们的左边界大于又边界或者下边界小于下边界的时候,我们就退出循环,然后将杂自循环过程中得到的list返回给主函数。
然后我们来看官方对这一到题的解法:
package medium.spiralOrder;
import java.util.ArrayList;
import java.util.List;
public class Main {
private static Integer[][] matrix;
private static List<Integer> spiralOrder(int [][] matrix){
List<Integer> order =new ArrayList<Integer>();
if(matrix==null||matrix.length==0||matrix[0].length==0){
return order;
}
int rows= matrix.length,columns=matrix[0].length;
boolean[][] visited=new boolean[rows][columns];
int total=rows*columns;
int row=0,column=0;
int[][] directions={{0,1},{1,0},{0,-1},{-1,0}};
int directionIndex=0;
for(int i=0;i<total;i++){
order.add(matrix[row][column]);
visited[row][column]=true;
int nextRow=row+directions[directionIndex][0],nextColumn=column+directions[directionIndex][1];
if(nextRow<0||nextRow>=rows||nextColumn<0||nextColumn>=columns||visited[nextRow][nextColumn]){
directionIndex=(directionIndex+1)%4;
}
row+=directions[directionIndex][0];
column+=directions[directionIndex][1];
}
return order;
}
public static void main(String[] args) {
}
}
官方的这个题解就晦涩难懂很多了。但是大致的思路还是一样的。首先你做一个空List列表,然后定义这个列表为ArrayList,再在对这个数组进行螺旋矩阵之前先判断这个数组是否为空,如果为空的话,直接就返回这样一个空队列回去,如果不为空的话我们再接着往下面走,首先定义两个变量,一个为行数,一个为列数,他们两个变量用来存放我们的这个二维数组的最大行下标和最大列下标。然后再定义一个辅助数组,用来保存我们遍历过的路径,再定义一个总数total为行数*列数。然后设置当前行下标和当期列下标。再定义一个方向二维数组,用来存放上下左右需要走过的方向。循环体中做整体判断。首先将每个当前遍历到的结点都加到那个一开始定义好的数组里面去。然后在辅助数组中设置当前访问过的结点为真,代表这个结点已经被存放到数组里面去了。