力扣对应题目链接:54. 螺旋矩阵 - 力扣(LeetCode)
牛客对应题目链接:顺时针打印矩阵_牛客题霸_牛客网 (nowcoder.com)
一、《剑指 Offer》内容
二、分析题目
写法二解法:
可以将矩阵看成若干层,首先输出最外层的元素,其次输出次外层的元素,直到输出最内层的元素。
定义矩阵的第 k 层是到最近边界距离为 k 的所有顶点。
对于每层,从左上方开始以顺时针的顺序遍历所有元素。假设当前层的左上角位于 (top, left),右下角位于 (bottom, right),按照如下顺序遍历当前层的元素:
- 从左到右遍历上侧元素,依次为 (top, left) 到 (top, right)。
- 从上到下遍历右侧元素,依次为 (top+1, right) 到 (bottom, right)。
- 如果 left < right 且 top < bottom,则从右到左遍历下侧元素,依次为 (bottom, right−1) 到 (bottom, left+1),以及从下到上遍历左侧元素,依次为 (bottom,left) 到 (top+1,left)。
遍历完当前层的元素之后,将 left 和 top 分别增加 1,将 right 和 bottom 分别减少 1,进入下一层继续遍历,直到遍历完所有元素为止。
三、代码
1、写法一
//力扣
class Solution {
private:
vector<int> res;
public:
void printCircle(vector<vector<int>>& matrix, int n, int m, int st)
{
int endX=n-1-st, endY=m-1-st;
//左->右
for(int j=st; j<=endY; j++)
res.push_back(matrix[st][j]);
//上->下
if(st<endX)
for(int i=st+1; i<=endX; i++)
res.push_back(matrix[i][endY]);
//右->左
if(st<endX && st<endY)
for(int j=endY-1; j>=st; j--)
res.push_back(matrix[endX][j]);
//下->上
if(st<endY && st<endX-1)
for(int i=endX-1; i>=st+1; i--)
res.push_back(matrix[i][st]);
}
vector<int> spiralOrder(vector<vector<int>>& matrix) {
//n行m列
int n=matrix.size();
if(n==0) return res;
int m=matrix[0].size();
int st=0;
while(n>st*2 && m>st*2)
{
//一圈一圈打印
printCircle(matrix, n, m, st);
st++;
}
return res;
}
};
//牛客
class Solution {
private:
vector<int> res;
public:
void printCircle(vector<vector<int>>& matrix, int n, int m, int st)
{
int endX=n-1-st, endY=m-1-st;
//左->右
for(int j=st; j<=endY; j++)
res.push_back(matrix[st][j]);
//上->下
if(st<endX)
for(int i=st+1; i<=endX; i++)
res.push_back(matrix[i][endY]);
//右->左
if(st<endX && st<endY)
for(int j=endY-1; j>=st; j--)
res.push_back(matrix[endX][j]);
//下->上
if(st<endY && st<endX-1)
for(int i=endX-1; i>=st+1; i--)
res.push_back(matrix[i][st]);
}
vector<int> printMatrix(vector<vector<int> > matrix) {
int n=matrix.size();
if(n==0) return {};
int m=matrix[0].size();
int st=0;
while(n>st*2 && m>st*2)
{
//一圈一圈打印
printCircle(matrix, n, m, st);
st++;
}
return res;
}
};
2、写法二
//力扣
class Solution {
private:
vector<int> res;
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int n=matrix.size();
if(n==0) return res;
int m=matrix[0].size();
int left=0, right=m-1;
int top=0, bottom=n-1;
while(left<=right && top<=bottom)
{
for(int j=left; j<=right; j++)
res.push_back(matrix[top][j]);
for(int i=top+1; i<=bottom; i++)
res.push_back(matrix[i][right]);
if(left<right && top<bottom)
{
for(int j=right-1; j>=left; j--)
res.push_back(matrix[bottom][j]);
for(int i=bottom-1; i>top; i--)
res.push_back(matrix[i][left]);
}
left++;
right--;
top++;
bottom--;
}
return res;
}
};