class Solution {
// 方法1
public int[] spiralArray1(int[][] array) {
if (array == null || array.length == 0){
return new int[]{};
}
int m = array.length, n = array[0].length;
int[] xdir = new int[]{0, 1, 0, -1};
int[] ydir = new int[]{1, 0, -1, 0};
int d = 0;
int[] vis = new int[m*n];
int i = 0, j = 0;
int[] ans = new int[m*n];
for (int k = 0; k < m * n; k++){
ans[k] = array[i][j];
vis[i * n + j] = 1;
int ni = i + xdir[d];
int nj = j + ydir[d];
if (ni < 0 || ni >= m || nj < 0 || nj >= n || (vis[ni * n + nj] == 1)){
d = (d + 1) % 4;
ni = i + xdir[d];
nj = j + ydir[d];
}
i = ni;
j = nj;
}
return ans;
}
// 方法2
public int[] spiralArray(int[][] array) {
if (array == null || array.length == 0){
return new int[]{};
}
int m = array.length, n = array[0].length;
int[] ans = new int[m*n];
int idx = 0;
int top = 0, left = 0, right = n-1, down = m - 1;
while (idx < m * n){
// 遍历上层
for (int i = 0; i < right - left + 1; i++){
ans[idx++] = array[top][left+i];
}
// 遍历右层
if (top < down){
for (int i = 0; i < down - top; i++){
ans[idx++] = array[top+i+1][right];
}
}
// 遍历下层
if (left < right && top < down){
for (int i = 0; i < right - left - 1; i++){
ans[idx++] = array[down][right-1-i];
}
}
// 遍历左层
if (left < right && top < down){
for (int i = 0; i < down - top; i++){
ans[idx++] = array[down-i][left];
}
}
// 缩圈继续遍历
top++;
right--;
left++;
down--;
}
return ans;
}
}
class Solution {
public int[] spiralArray(int[][] array) {
if(array==null||array.length==0){
return new int[0];
}
int m = array.length;
int n = array[0].length;
int[] res = new int[m*n];
int up = 0;//上边界
int down = m-1;//下边界
int left = 0;//左边界
int right = n-1;//右边界
int index = 0;
while(up<=down||left<=right){
//往右走
for(int i=left;i<=right;i++){
res[index++] = array[up][i];
}
up++;
if(up>down){
break;
}
//往下走
for(int i=up;i<=down;i++){
res[index++] = array[i][right];
}
right--;
if(right<left){
break;
}
//往左走
for(int i = right;i>=left;i--){
res[index++] = array[down][i];
}
down--;
if(down<up){
break;
}
//往上走
for(int i = down;i>=up;i--){
res[index++] = array[i][left];
}
left++;
if(left>right){
break;
}
}
return res;
}
}
思路:定义左边界、有边界、上边界和下边界,然后可以向右走、向下走、
向左走和向上走,同时创建一个res数组用来保存访问到的数组元素
时间复杂度:O(mn)
空间复杂度:O(1)
“`c++
class Solution {
public:
vector spiralArray(vector>& array) {
if (array.empty()) return {};
int m = array.size(), n = array[0].size();
vector ans(m*n, 0);
int idx = 0;
int l = 0, r = n-1, t = 0, b = m-1;
while (true) {
// top row: t, j = [l -> r]
for (int j=l; j<=r; j++) {
ans[idx++] = array[t][j];
}
// top row is over.
if (++t > b) break;
// right col: i = [t -> b], r
for (int i=t; i<=b; i++) {
ans[idx++] = array[i][r];
}
// right col is over.
if (--r < l) break;
// bottom row: b, j = [r -> l]
for (int j=r; j>=l; j–) {
ans[idx++] = array[b][j];
}
// bottom row is over.
if (–b < t) break;
// left col: i = [b -> l], l
for (int i=b; i>=t; i–) {
ans[idx++] = array[i][l];
}
// left col is over.
if (++l > r) break;
}
return ans;
}
};
“`
class Solution {
public int[] spiralArray(int[][] array) {
if(array.length 0)
return new int[0];
int[] ans = new int[array.length * array[0].length];
ans[0] = array[0][0];
int count = 1;
int left = 0;
int right = array[0].length – 1;
int top = 0;
int bottom = array.length – 1;
int direction = 0;//右 下 左 上
int i = 0, j = 0;
while(left <= right && top <= bottom ){
共以下 6 个回答
// 方法一:模拟
// 解题思路:从起点(0,0)开始,按照右-下-左上的方式遍历数组,遇到边界或者已访问的元素,
// 更换到下一个方向,遍历完所有元素结束
// 时间复杂度 O(mn), 空间复杂度O(mn)
// 方法二:按层遍历
// 解题思路:每层为最外圈数组元素,可分成上右下左四个部分
// 每层上部分起点为[top, left],终点为[top, right]
// 每层右部分起点为[top+1, right],终点为[down, right]
// 每层下部分起点为[down, right-1],终点为[down, left+1]
// 每层左部分起点为[down, left],终点为[up+1, left]
// 遍历时候判断该层的元素长度是否 > 0
// 继续下一层 top++,down–,left++,right–直到遍历完 mn个元素
// 时间复杂度 O(mn), 空间复杂度O(1)
思路:模拟顺时针打印矩阵,需要注意边界情况
“`c++ spiralArray(vector>& array) { ans(m*n, 0);
class Solution {
public:
vector
if (array.empty()) return {};
int m = array.size(), n = array[0].size();
vector
int idx = 0;
int l = 0, r = n-1, t = 0, b = m-1;
while (true) {
// top row: t, j = [l -> r]
for (int j=l; j<=r; j++) { ans[idx++] = array[t][j]; } // top row is over. if (++t > b) break;
// right col: i = [t -> b], r
for (int i=t; i<=b; i++) { ans[idx++] = array[i][r]; } // right col is over. if (--r < l) break; // bottom row: b, j = [r -> l]
for (int j=r; j>=l; j–) {
ans[idx++] = array[b][j];
}
// bottom row is over.
if (–b < t) break; // left col: i = [b -> l], l
for (int i=b; i>=t; i–) {
ans[idx++] = array[i][l];
}
// left col is over.
if (++l > r) break;
}
return ans;
}
};
“`
时间复杂度:O(nm)
额外空间复杂度:O(nm)
死循环中按照右下左上的顺序依次提取元素,每次提取一个元素之后都要判断还能否继续遍历
class Solution {
public int[] spiralArray(int[][] array) {
if(array.length 0)
return new int[0];
int[] ans = new int[array.length * array[0].length];
ans[0] = array[0][0];
int count = 1;
int left = 0;
int right = array[0].length – 1;
int top = 0;
int bottom = array.length – 1;
int direction = 0;//右 下 左 上
int i = 0, j = 0;
while(left <= right && top <= bottom ){
}
//空间复杂度Onm
时间复杂度Onm