给你一个m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
分析:
先不考虑特殊情况, 螺旋输出可以看为每次按顺时针顺序
输出边界框上的元素, 然后逐渐缩小边框,最后输出所有元素。其逻辑如下图。
因此, 只需要维护边框的四个参数:
u
p
,
d
o
w
n
,
l
e
f
t
,
r
i
g
h
t
up ,down ,left,right
up,down,left,right
且更新公式为:
l
e
f
t
n
e
w
=
l
e
f
t
+
1
left_{new} = left +1
leftnew=left+1
r
i
g
h
t
n
e
w
=
r
i
g
h
t
−
1
right_{new} = right-1
rightnew=right−1
u
p
n
e
w
=
u
p
+
1
up_{new}=up+1
upnew=up+1
d
o
w
n
n
e
w
=
d
o
w
n
−
1
down_{new}= down-1
downnew=down−1
因此伪代码有:
循环判断输出结束
遍历比边框
更新边框
这里需要特别注意许纳泽的遍历方式能否应对特殊情况,如下图:
为了避免重复遍历,必须保证选择的单行,或单列的特殊情况下能够一次性遍历完成。
方式3 只需要遍历完顶行+右列,判断当前边框是否为特殊情况,是否继续进行就能应该对所有情况。
代码如下:
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
// answer
vector<int> answer;
//四角边框
int up = 0;
int down = matrix.size()-1;
int left = 0;
int right = matrix[0].size()-1;
//循环处理
while(up<=down && left<=right) {
//up row left to right
for(int ind = left; ind<=right; ind++){
answer.push_back(matrix[up][ind]);
}
//right col up to down
for(int ind = up+1; ind<=down; ind ++){
answer.push_back(matrix[ind][right]);
}
//down row right to left
if ( left < right && up < down){
for(int ind = right-1; ind >left; ind--){
answer.push_back(matrix[down][ind]);
}
//left colunm down to up
for(int ind = down; ind>up; ind--){
answer.push_back(matrix[ind][left]);
}
}
// update pox
up ++;
down --;
left ++;
right --;
}
return answer;
}
};
其他的需要设定针对性的判断条件,比较麻烦。
总结:
公式思路确实回将问题抽象的简单点,模拟方法可能还相对难思考想象。