这道题之前在代码随想录里刷过类似的,还有印象,我就按照当初代码随想录的思路做了一下,结果怎么都做不对,因为按照代码随想录的边界条件设置,当行数和列数都为奇数时,最后一个元素无法被添加到数组中,搞得很伤脑筋,然后我看了下灵神的代码,感觉还是有点太难懂了,我感觉Krahets大佬的代码思想和我的比较贴合,而且也比较好懂,我就直接采用他的思路了。他的思路比较朴素,就是按照上-->右-->下-->左
的顺序遍历矩阵,然后将遍历到的元素添加到数组中,但是这个思路中是遍历一条边后就立刻更新对应的边界,例如,刚刚把上边界的所有元素添加到数组后,就立刻将上边界+1,然后遍历右边的边时,右边是直接从更新后的上边界为起点开始遍历的(这就意味着在同一圈中,上边界添加的元素一定比下边界添加的多,右边界添加的元素一定比左边界添加的多),另外,只要当前的下标值 <=
或者 >=
对应的边界值,我们就无脑添加,为了避免重复添加的问题,我们就需要在更新完边界以后立即判断上下边界有没有交错(up < down
),左右边界有没有交错(left > right
),如果出现了这样的情况,就说明已经打印完了所有元素,无需再继续遍历,直接退出当前的循环。
在退出循环之后,直接返回数组即可。
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
vector<int> result;
int up, right, down, left; //上下左右四个边界
up = 0;
right = matrix[0].size() - 1;
down = matrix.size() - 1;
left = 0;
while(up <= down && left <= right){
//上
for(int i = left; i <= right; ++i)
result.emplace_back(matrix[up][i]);
if(++up > down) break; //添加结束
//右
for(int i = up; i <= down; ++i)
result.emplace_back(matrix[i][right]);
if(--right < left) break; //添加结束
//下
for(int i = right; i >= left; --i)
result.emplace_back(matrix[down][i]);
if(--down < up) break; //添加结束
//左
for(int i = down; i >= up; --i)
result.emplace_back(matrix[i][left]);
if(++left > right) break;
}
return result;
}
};