参考资料:左程云算法课
54. Spiral Matrix
Given an m x n matrix, return all elements of the matrix in spiral order.
Example 1:
Input: matrix = [[1,2,3],[4,5,6],[7,8,9]]
Output: [1,2,3,6,9,8,7,4,5]
思路:用矩阵的左上角点和右下角点确定一个框(最外层),然后一圈一圈的地打印,先打印最外层,借助矩阵的左上角点和右下角点的坐标分别对角线方向向内收缩一步,可以到达新的框(也就是次外层),再打印次外层,……
注:要考虑到 最后一圈可能出现的情况,即
最后一圈可能是空;可能是一个数,可能是一行数,也可能是一列数。
class Solution {
public List<Integer> spiralOrder1(int[][] m) {
List<Integer> ans = new ArrayList<>();
if(m==null||m.length==0||m[0]==null||m[0].length==0)
{
return ans;
}
int a=0;
int b=0;
int c = m.length-1;
int d=m[0].length-1;
while(a<=c && b<=d)
{
addEdge(m,a++,b++,c--,d--,ans);
}
return ans;
}
public static void addEdge(int[][] m, int a,int b, int c, int d, List<Integer> ans)
{
int curR=a;
int curC=b;
if(a==c)
{
for(int i=b;i<=d;i++)
{
ans.add(m[a][i]);
}
return;
}
if(b==d)
{
for(int i=a;i<=c;i++ )
{
ans.add(m[i][b]);
}
return;
}
for(;curC<d;curC++)
{
ans.add(m[curR][curC]);
}
for(;curR<c;curR++)
{
ans.add(m[curR][curC]);
}
for(;curC>b;curC--)
{
ans.add(m[curR][curC]);
}
for(;curR>a;curR--)
{
ans.add(m[curR][curC]);
}
}
}
上面是老师写的;
下面是自己写的;思路差不多
public List<Integer> spiralOrder(int[][] ma) {
int m = ma.length;
int n = ma[0].length;
List<Integer> prep = new ArrayList<>();
int r1=0,c1=0;
int r2=m-1,c2=n-1;
while(r1<=r2 && c1<=c2) // ,,
{
spiral(ma,r1,c1,r2,c2,prep);
r1++;
c1++;
r2--;
c2--;
}
return prep;
}
void spiral(int[][] ma, int r1, int c1, int r2, int c2, List<Integer> prep)
{
if(r1==r2 && c1==c2)
{
prep.add(ma[r1][c1]);
return;
}else if(r1==r2)
{
for(int i=c1;i<=c2;i++)
{
prep.add(ma[r1][i]);
}
return;
}else if(c1==c2)
{
for(int i=r1;i<=r2;i++)
{
prep.add(ma[i][c1]);
}
return;
}
int r=r1;
int c=c1;
while(c<c2) // right
{
prep.add(ma[r][c]);
c++;
}
// r1,c2
while(r<r2)
{
prep.add(ma[r][c]);
r++;
}
// r2,c2
while(c>c1)
{
prep.add(ma[r][c]);
c--;
}
// r2,c1
while(r>r1)
{
prep.add(ma[r][c]);
r--;
}
}
官网给出的迭代解法
public int[] spiralOrder(int[][] matrix) {
if(matrix==null||matrix.length==0||matrix[0].length==0){
return new int[0];
}
int rows = matrix.length,cols = matrix[0].length;
// int left=0,right=cols-1,up=0,bottom=rows-1;
int index=0;
int[] res = new int[rows*cols];
int x1=0,y1=0,x2=rows-1,y2=cols-1;
while(x1<=x2 && y1<=y2){
for(int j=y1;j<=y2;j++){
res[index++]=matrix[x1][j];
}
for(int i=x1+1;i<=x2;i++){
res[index++]=matrix[i][y2];
}
if(x1<x2 && y1<y2){ // !! 这个判断条件很重要,如果y1==y2那么就没必要向左遍历记录框的下边界了
for(int j=y2-1;j>=y1;j--){
res[index++]=matrix[x2][j];
}
for(int i=x2-1;i>x1;i--){
res[index++]=matrix[i][y1];
}
}
x1++;
y1++;
x2--;
y2--;
}
return res;
}