题目主要信息:
- 题目给定一个的矩阵,需要将其螺旋输出
举一反三:
学习完本题的思路你可以解决类似的矩阵遍历的问题。
方法:边界模拟法(推荐使用)
思路:
这道题就是一个简单的模拟,我们想象有一个矩阵,从第一个元素开始,往右到底后再往下到底后再往左到底后再往上,结束这一圈,进入下一圈螺旋。
具体做法:
- step 1:首先排除特殊情况,即矩阵为空的情况。
- step 2:设置矩阵的四个边界值,开始准备螺旋遍历矩阵,遍历的截止点是左右边界或者上下边界重合。
- step 3:首先对最上面一排从左到右进行遍历输出,到达最右边后第一排就输出完了,上边界相应就往下一行,要判断上下边界是否相遇相交。
- step 4:然后输出到了右边,正好就对最右边一列从上到下输出,到底后最右边一列已经输出完了,右边界就相应往左一列,要判断左右边界是否相遇相交。
- step 5:然后对最下面一排从右到左进行遍历输出,到达最左边后最下一排就输出完了,下边界相应就往上一行,要判断上下边界是否相遇相交。
- step 6:然后输出到了左边,正好就对最左边一列从下到上输出,到顶后最左边一列已经输出完了,左边界就相应往右一列,要判断左右边界是否相遇相交。
- step 7:重复上述3-6步骤直到循环结束。
图示:
Java代码实现:
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 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; i++)
res.add(matrix[up][i]);
//上边界向下
up++;
if(up > down)
break;
//右边界的从上到下
for(int i = up; 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(up > down)
break;
//左边界的从下到上
for(int i = down; i >= up; i--)
res.add(matrix[i][left]);
//左边界向右
left++;
if(left > right)
break;
}
return res;
}
}
C++代码实现
class Solution {
public:
vector<int> spiralOrder(vector<vector<int> > &matrix) {
vector<int> res;
int n = matrix.size();
//先排除特殊情况
if(n == 0)
return res;
//左边界
int left = 0;
//右边界
int right = matrix[0].size() - 1;
//上边界
int up = 0;
//下边界
int down = n - 1;
//直到边界重合
while(left <= right && up <= down){
//上边界的从左到右
for(int i = left; i <= right; i++)
res.push_back(matrix[up][i]);
//上边界向下
up++;
if(up > down)
break;
//右边界的从上到下
for(int i = up; i <= down; i++)
res.push_back(matrix[i][right]);
//右边界向左
right--;
if(left > right)
break;
//下边界的从右到左
for(int i = right; i >= left; i--)
res.push_back(matrix[down][i]);
//下边界向上
down--;
if(up > down)
break;
//左边界的从下到上
for(int i = down; i >= up; i--)
res.push_back(matrix[i][left]);
//左边界向右
left++;
if(left > right)
break;
}
return res;
}
};
Python实现代码:
class Solution:
def spiralOrder(self , matrix: List[List[int]]) -> List[int]:
res = list()
n = len(matrix)
#先排除特殊情况
if n == 0:
return res
#左边界
left = 0
#右边界
right = len(matrix[0]) - 1
#上边界
up = 0
#下边界
down = n - 1
#直到边界重合
while left <= right and up <= down:
#上边界的从左到右
for i in range(left, right+1):
res.append(matrix[up][i])
#上边界向下
up += 1
if up > down:
break
#右边界的从上到下
for i in range(up,down+1):
res.append(matrix[i][right])
#右边界向左
right -= 1
if left > right:
break
i = right
#下边界的从右到左
while i >= left:
res.append(matrix[down][i])
i -= 1
#下边界向上
down -= 1
if up > down:
break
i = down
#左边界的从下到上
while i >= up:
res.append(matrix[i][left])
i -= 1
#左边界向右
left += 1
if left > right:
break
return res
复杂度分析:
- 时间复杂度:,相当于遍历整个矩阵
- 空间复杂度:,res属于必要空间,没有使用额外辅助空间