给定一个m x n大小的矩阵(m行,n列),按螺旋的顺序返回矩阵中的所有元素。
数据范围:
,矩阵中任意元素都满足
要求:空间复杂度
,时间复杂度 )
public ArrayList<Integer> spiralOrder (int[][] matrix) { // 顺时针返回一个矩阵 ArrayList<Integer> ans=new ArrayList<>(); if(matrix==null||matrix.length==0) return ans;//这里一定要判空,否则无法通过 //设置矩阵的四个边界值,截至条件为:左右边界/上下边界重合 //从左到右,上边界下移一行 判断上下边界是否重合 //从上到下,右边界左移一行 判断左右边界是否重合 //从右到左,下边界上移一行 判断上下边界是否重合 //从下到上,左边界右移一行 判断左右边界是否重合 //循环判断这四步,直至循环结束 int left=0;//左边界 int right=matrix[0].length-1;//右边界(有效边界) int up=0;//上边界 int down=matrix.length-1;//下边界(有效边界) while(left<=right&&up<=down){ for(int i=left;i<right+1;i++){ ans.add(matrix[up][i]); } up++; if(up>down) break; for(int i=up;i<down+1;i++){ ans.add(matrix[i][right]); } right--; if(right<left) break; for(int i=right;i>=left;i--){ ans.add(matrix[down][i]); } down--; if(down<up) break; for(int i=down;i>=up;i--){ ans.add(matrix[i][left]); } left++; if(left>right) break; } return ans; }
import java.util.ArrayList; public class Solution { public ArrayList<Integer> spiralOrder(int[][] matrix) { ArrayList<Integer> result = new ArrayList<>(); if (matrix == null || matrix.length == 0) { return result; } int i = 0, iDirect = 0; int j = 0, jDirect = 0; int circle = 0; result.add(matrix[0][0]); while (result.size() <= (matrix.length * matrix[0].length)) { int totalNum = getCircleNods(matrix.length, matrix[0].length, circle); int jRange = (matrix[i].length - (circle + 1)); int iRange = (matrix.length - (circle + 1)); int up = (totalNum + (matrix.length - 2 * circle)); int right = (up + ((matrix[0].length - 2 * circle) - 2)); int down = (right + (matrix.length - 2 * circle)); int left = (down + ((matrix[0].length - 2 * circle) - 2)); if (totalNum <= result.size() && result.size() < up) { iDirect = 0; jDirect = 1; i = i + iDirect; if (j < jRange) { j = j + jDirect; } result.add(matrix[i][j]); } else if (up <= result.size() && result.size() <= right ) { iDirect = 1; jDirect = 0; if (i < iRange) { i = i + iDirect; } j = j + jDirect; result.add(matrix[i][j]); } else if (right < result.size() && result.size() < down) { iDirect = 0; jDirect = -1; i = i + iDirect; if (j >= (circle + 1)) { j = j + jDirect; } result.add(matrix[i][j]); } else if (down <= result.size() && result.size() < left) { iDirect = -1; jDirect = 0; if (i >= (circle + 1)) { i = i + iDirect; } j = j + jDirect; result.add(matrix[i][j]); } if (right < up || down < right || left < down) { break; } if (result.size() == left) { circle++; } } return result; } public static int getCircleNods(int m, int n, int circle) { int totalNum = 0; for (int idx = 0; idx < circle; idx++) { totalNum += 2 * (m - 2 * idx) + 2 * ((n - 2 * idx) - 2); } return totalNum; } }
import java.util.ArrayList; public class Solution { public ArrayList<Integer> spiralOrder(int[][] matrix) { ArrayList<Integer> list = new ArrayList<>(); if (matrix.length == 0) { return list; } int res = matrix.length * matrix[0].length; int x = 0; int y = 0; int minx = 0; int maxx = matrix[0].length - 1; int miny = 0; int maxy = matrix.length - 1; if (maxx == 0 || maxy == 0) { for (int i = 0; i <= maxy; i++) { for (int j = 0; j <= maxx; j++) { list.add(matrix[i][j]); } } return list; } for (int i = 0; i < res; i++) { list.add(matrix[y][x]); if (x == minx && y == (miny + 1)) { minx ++; maxx --; miny ++; maxy --; x ++; continue; } if (x == minx && y == miny && x < maxx && y <= maxy) { x++; } else if (x < maxx && y < maxy && x > minx) { x++; } else if (x == maxx && y < maxy) { y++; } else if (x > minx && y == maxy && y > miny) { x--; } else if (x == minx && y <= maxy && y > miny) { y--; } } return list; } }
import java.util.ArrayList; public class Solution { public ArrayList<Integer> spiralOrder(int[][] matrix) { ArrayList<Integer> res = new ArrayList<>(); if (matrix.length == 0) return res; int[][] posmat = new int[][] {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; int[] pos = new int[] {1, 0}; int count = 0; int i = 0, j = 0; while (count < matrix.length * matrix[0].length) { if (j < matrix.length && j >= 0 && i < matrix[0].length && i >= 0 && matrix[j][i] != -999) { res.add(matrix[j][i]); matrix[j][i] = -999; count++; i += pos[0]; j += pos[1]; } else { i -= pos[0]; j -= pos[1]; if (pos[0] == 1 && pos[1] == 0) pos = posmat[1]; else if (pos[0] == 0 && pos[1] == 1) pos = posmat[2]; else if (pos[0] == -1 && pos[1] == 0) pos = posmat[3]; else pos = posmat[0]; i += pos[0]; j += pos[1]; } } return res; } }
import java.util.ArrayList; public class Solution { int[][] log; int n; int m; ArrayList<Integer> res=new ArrayList<>(); public ArrayList<Integer> spiralOrder(int[][] matrix) { if(matrix.length==0){ return res; } n=matrix.length; m=matrix[0].length; log=new int[n][m]; int len=n*m; int i=0,j=0; while(res.size()<len){ //右走 while(j<m&&log[i][j]!=1){ log[i][j]=1; res.add(matrix[i][j]); j++; } j--; i++; //下走 while(i<n&&log[i][j]!=1){ log[i][j]=1; res.add(matrix[i][j]); i++; } i--; j--; //左走 while(j>=0&&log[i][j]!=1){ log[i][j]=1; res.add(matrix[i][j]); j--; } j++; i--; //上走 while(i>=0&&log[i][j]!=1){ log[i][j]=1; res.add(matrix[i][j]); i--; } i++; j++; } return res; } }
import java.util.ArrayList; import java.util.*; public class Solution { public ArrayList<Integer> spiralOrder(int[][] matrix) { int m=matrix.length;//row ArrayList<Integer> path=new ArrayList<Integer>(); if(m==0){//空即没有行也没有列---即没有行 return path; } int n=matrix[0].length;//col //最开始的转圈位置 int start_x=0,start_y=0; //转几圈 int loop=Math.min(m,n)/2; int temp=loop;//备份后面用 //如果min是奇数---会出现中间有一列或中间有一行---mid是起始位置 int mid=Math.min(m,n)/2;; //用来控制遍历的边界 int offset=1; while(loop>0){ int i,j; for(i=start_x,j=start_y;j<=n-offset-1;j++){ path.add(matrix[i][j]); } for(;i<=m-offset-1;i++){ path.add(matrix[i][j]); } for(;j>=start_y+1;j--){ path.add(matrix[i][j]); } for(;i>=start_x+1;i--){ path.add(matrix[i][j]); } start_x=start_x+1; start_y=start_y+1; loop--; offset++; } if(Math.min(m,n)%2==1){ int a,b; if(m>=n){//行多列少---中间剩下列 //从mid开始的列 for(a=mid,b=mid;a<=mid+m-temp*2-1;a++){ path.add(matrix[a][b]); } } if(n>m){//列多行少---中间剩下行 //从mid开始的行 for(a=mid,b=mid;b<=mid+n-temp*2-1;b++){ path.add(matrix[a][b]); } } } return path; } }
import java.util.ArrayList; public class Solution { public ArrayList<Integer> spiralOrder(int[][] matrix) { ArrayList<Integer> res = new ArrayList<Integer>(); if (matrix.length == 0) return res; int top = 0, left = 0, right = matrix[0].length - 1, down = matrix.length - 1; while (left <= right && top <= down) { for (int i = left; i <= right; i ++) res.add(matrix[top][i]); top ++; if (top > down) break; for (int i = top; i <= down; i ++) res.add(matrix[i][right]); right --; if (left > right) break; for (int i = right; i >= left; i --) res.add(matrix[down][i]); down --; if (top > down) break; for (int i = down; i >= top; i --) res.add(matrix[i][left]); left ++; if (left > right) break; } return res; } }
import java.util.ArrayList; public class Solution { public ArrayList<Integer> spiralOrder(int[][] matrix) { ArrayList<Integer> res = new ArrayList<>(); if(matrix==null || matrix.length==0) return new ArrayList<Integer>(); int m = matrix.length, n = matrix[0].length; int up = 0, down = m-1, left = 0, right = n-1; while(up < down && left < right){ for (int i = left; i < right; i++) res.add(matrix[up][i]); for (int i = up; i < down; i++) res.add(matrix[i][right]); for (int i = right; i > left; i--) res.add(matrix[down][i]); for (int i = down; i > up ; i--) res.add(matrix[i][left]); up++; right--; down--; left++; } if(up==down) for (int i = left; i <= right; i++) res.add(matrix[up][i]); else if(left==right) for (int i = up; i <= down; i++) res.add(matrix[i][left]); return res; } }
public ArrayList<Integer> spiralOrder(int[][] matrix) { ArrayList<Integer> res = new ArrayList<Integer>(); if(matrix.length<1){ return res; } int s1 = 0 ,e1 = matrix.length-1 ,s2 =0 ,e2 = matrix[0].length-1; while(s1<=e1 && s2<=e2){ for(int i=s2;i<=e2;i++){ res.add(matrix[s1][i]); } s1++; for(int i=s1;i<=e1;i++){ res.add(matrix[i][e2]); } e2--; if(s1<=e1 && s2<=e2){ for(int i=e2;i>=s2;i--){ res.add(matrix[e1][i]); } e1--; for(int i=e1;i>=s1;i--){ res.add(matrix[i][s2]); } s2++; } } return res; }
import java.util.ArrayList; import java.util.*; public class Solution { public ArrayList<Integer> spiralOrder(int[][] matrix) { ArrayList<Integer> list = new ArrayList<Integer>(); //如果数据组的长度为0,则直接返回空数组 if(matrix.length == 0) return list; //定义四个方向的指针 int top = 0,bottom = matrix.length - 1; int left = 0,right = matrix[0].length - 1; //当 while( top < (matrix.length + 1)/2 && left < (matrix[0].length + 1)/2){ //从左到右 for(int i = left; i <= right; i++){ list.add(matrix[top][i]); } //从上到下 for(int i = top + 1; i <= bottom; i++){ list.add(matrix[i][right]); } //从有到左 for(int i = right - 1; top != bottom && i >= left; i--){ list.add(matrix[bottom][i]); } //从下到上 for(int i = bottom - 1; left != right && i >= top +1; i--){ list.add(matrix[i][left]); } ++top; --bottom; ++left; --right; } return list; } }
import java.util.ArrayList; public class Solution { public ArrayList<Integer> spiralOrder(int[][] matrix) { ArrayList<Integer> res = new ArrayList<>(); if(matrix == null || matrix.length == 0) return res; int m = matrix.length, n = matrix[0].length; int minIdx = Math.min(m, n); int loop = minIdx / 2; // 模拟次数 int startx = 0, starty = 0; int offset = 1; // 控制边界的偏移量 int i, j; // 参考代码随想录:区间[起点,终点),左闭右开 while(0 < loop--){ // 新的起点 i = starty; j = startx; // 模拟上 for(; j < startx + n - offset; j++) res.add(matrix[i][j]); //模拟右 for(; i < starty + m - offset; i++) res.add(matrix[i][j]); // 模拟下 for(; j > startx; j--) res.add(matrix[i][j]); // 模拟左 for(; i > starty; i--) res.add(matrix[i][j]); startx++; starty++; offset += 2; //因为startx和starty也加了1,所以计算边界时需要将加的1减掉 } if(minIdx % 2 == 1){ // 每次走2行2列,所以奇数行或奇数列最后会剩下一行或一列 // while循环终止导致i和j没有更新 i = starty; j = startx; if(m <= n){ //模拟剩下的一行 while(j <= startx + n - offset){ res.add(matrix[i][j]); j++; } } else { // 模拟剩下的一列 while(i <= starty + m - offset){ res.add(matrix[i][j]); i++; } } } return res; } }
//类似于蛇形矩阵问题 import java.util.ArrayList; public class Solution { public ArrayList<Integer> spiralOrder(int[][] matrix) { ArrayList<Integer> list = new ArrayList<>(); int n = matrix.length; if(n == 0) return list; int m = matrix[0].length; int[] dx = {0,1,0,-1}; int[] dy = {1,0,-1,0}; boolean[][] st = new boolean[n][m]; int d = 0;//表示刚开始是向右的方向 int i = 0; int j = 0;//初始出发时的坐标 for(int k = 0;k<n * m;k++){ //先朝着一个方向一直走,走到头再换方向 list.add(matrix[i][j]); st[i][j] = true; //尝试朝当前方向走一步 int x = i + dx[d]; int y = j + dy[d]; if(x >= 0 && x < n && y >= 0 && y < m && !st[x][y]){ i = x; j = y;//如果可以继续走那就继续走,不用换方向 }else{ d = (d + 1) % 4;//走不了时换方向 i = i + dx[d]; j = j + dy[d]; } } return list; } }
import java.util.ArrayList; public class Solution { public ArrayList<Integer> spiralOrder(int[][] matrix) { int[][] next = {{0,1},{1,0},{0,-1},{-1,0}}; int i = 0; int j = 0; int direct = 0; ArrayList<Integer> list = new ArrayList<>(); while(matrix.length != 0){ list.add(matrix[i][j]); matrix[i][j] = -123; if(list.size() == matrix.length * matrix[0].length) break; if( i + next[direct][0] > matrix.length - 1 || j + next[direct][1] > matrix[0].length - 1 || j + next[direct][1] < 0 || i + next[direct][0] < 0 || matrix[i + next[direct][0]][j + next[direct][1]] == -123 ){ direct = (direct + 1) % 4; } i += next[direct][0]; j += next[direct][1]; } return list; } }
解题思路:通过四个数(代表上下左右)来构建边界,再按照左->右;上->下;右->左;下->上的次序完成遍历;
注意:开始遍历前判断数组是为为空可提升效率
import java.util.*; public class Solution { public ArrayList<Integer> spiralOrder(int[][] matrix) { //通过四个指针不断收缩来限制顺时针遍历的范围 ArrayList<Integer> res = new ArrayList<>(); if(matrix.length==0) return res; int hang = matrix.length; //行数 int lie = matrix[0].length; //列数 int top=0,left=0,bot=hang-1,right=lie-1; //上左下右四个边界 int i=0,j=0; //元素 matrix[i][j] int index=0; //index记录矩阵中元素的个数 while(index < hang*lie){ //向列表中添加数据 res.add(matrix[i][j]); //边界变更时,上下边界、左右边界不能重合, //所以添加判断 top+1<bot; left+1<right; if(i==top&&j<right){ //从左往右遍历 j++; if(j==right&&top+1<bot){ //修改上边界 top++; } }else if(j==right&&i<bot){ //从上往下遍历 i++; if(i==bot&&right-1>left){ //修改右边界 right--; } }else if(i==bot&&j>left){ //从右往左遍历 j--; if(j==left&&bot-1>top){ //修改下边界 bot--; } }else if(j==left&&i>top){ //从下往上遍历 i--; if(i==top&&left+1<right){ //修改左边界 left++; } } index++; } return res; } }
// 这题很容易写错,四个指针不断收缩 import java.util.ArrayList; public class Solution { public ArrayList<Integer> spiralOrder(int[][] matrix) { ArrayList<Integer> res = new ArrayList<>(); if (matrix.length == 0) return res; int top = 0, left = 0, right = matrix[0].length-1, bot = matrix.length-1; while (left <= right && top <= bot) { for (int i = left; i <= right; i++) { res.add(matrix[top][i]); } for (int i = top+1; i <= bot; i++) { res.add(matrix[i][right]); } if (top < bot && left < right) { for (int i = right-1; i >= left; i--) { res.add(matrix[bot][i]); } for (int i = bot-1; i >= top+1; i--) { res.add(matrix[i][left]); } } left++; right--; top++; bot--; } return res; } }
import java.util.ArrayList; public class Solution { public ArrayList<Integer> spiralOrder(int[][] matrix) { ArrayList<Integer> list = new ArrayList<>(); if (matrix.length == 0) return list; int result = 0; if (matrix.length >= matrix[0].length){ result = matrix[0].length; }else { result = matrix.length; } for (int i = 0; i < (result+1) / 2; i++) { test(matrix, i, i, matrix.length - i - 1, matrix[0].length - i - 1, list); } return list; } public void test(int[][] matrix,int m, int n, int l, int r,ArrayList<Integer> list){ for (int i = n; i <= r; i++) { list.add(matrix[m][i]); } m++; for (int i = m; i <= l; i++) { list.add(matrix[i][r]); } r--; for (int i = r; i >= n && l >= m; i--) { list.add(matrix[l][i]); } l--; for (int i = l; i >= m && r >= n; i--) { list.add(matrix[i][n]); } n++; } }