给定一个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;
}
}