力扣对应题目链接: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; } };