面试题29. 顺时针打印矩阵
难度:简单 2020/6/5每日一题打卡√
题目描述
解题思路
1、按层模拟
把整个矩阵想象乘一圈一圈的圆形⚪,先遍历最外面那层,然后往里遍历一层。不知道为什么我一开始想到的就是用递归写,实际上不用递归也可以的
用level记录层数,也即是偏移量
/*
* 面试题29. 顺时针打印矩阵
* 2020/6/5每日一题打卡
*/
public int[] spiralOrder(int[][] matrix) {
int m = matrix.length;
if(m == 0)
return new int[] {};
int n = matrix[0].length;
int[] re = new int[m*n];
int index = 0;
spiralHelper(matrix,0,re,index,m,n) ;
return re;
}
public void spiralHelper(int[][] matrix,int level,int[] re,int index,int m,int n) {
if(index == m*n)
return;
for (int i = level; i < n-level; i++) { //从左上往右上
if(index == m*n) return;
re[index++] = matrix[level][i];
}
for (int i = level+1; i < m-level; i++) { //从右上往右下
if(index == m*n) return;
re[index++] = matrix[i][n-level-1];
}
for (int i = n-level-2; i >= level; i--) { //从右下往左下
if(index == m*n) return;
re[index++] = matrix[m-level-1][i];
}
for (int i = m-level-2; i > level; i--) { //从左下往左上
if(index == m*n) return;
re[index++] = matrix[i][level];
}
spiralHelper(matrix,level+1,re,index,m,n) ;
}
2、不是递归的写法
就设置上下左右四个边界值,每次遍历完一层,收缩边界值
public int[] spiralOrder(int[][] matrix) {
int m = matrix.length;
if(m == 0)
return new int[] {};
int n = matrix[0].length;
int[] re = new int[m*n];
int a = 0,b = m-1,c = 0,d = n-1,index = 0; //上下左右边界
while(true) {
if(index == m*n) break;
for (int i = c; i <= d; i++) { //从左上往右上
re[index++] = matrix[a][i];
}
if(index == m*n) break;
for (int i = a+1; i <= b; i++) { //从右上往右下
re[index++] = matrix[i][d];
}
if(index == m*n) break;
for (int i = d-1; i >= c; i--) { //从右下往左下
re[index++] = matrix[b][i];
}
if(index == m*n) break;
for (int i = b-1; i > a; i--) { //从左下往左上
re[index++] = matrix[i][c];
}
a++;
b--;
c++;
d--;
}
return re;
}
边界下标绕得人头晕