54.螺旋矩阵
- 题号:54
- 知识点:矩阵
- 目标完成度:1/150
- 总结
题干:给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
思路:
- 1.首先得到矩阵的宽和高,并将宽和高减一,防止容器访问越界。
- 2.以方形矩阵为例,按照题干提示的箭头从左到右,从上到下,从右到左,从下到上遍历。写出四个while循环,注意不要访问越界!
- 3.外环遍历完成,然后缩圈,指示矩阵宽的左指针(
w_first_flag
)加1,右指针(w_last_flag
)减1,指示高的顶指针(h_top_flag
)加1 ,低指针(h_bot_flag
)减1;(用指针描述可能不太准确,理解就好),然后重置计数器w_first,w_last,h_top,h_bot
- 4.缩圈终止条件(也就是外层while遍历的条件)?左指针始终>=右指针,上指针始终<=下指针。或者理解为左指针-右指针>=0;下指针-上指针>=0。解决方形矩阵。
- 5.再解决长>宽的矩阵:提交测试发现中间的那一行会从左到右输出一次,也会从右到左输出一次;所以会多输出。并且,遍历到中间这一行时,
上指针==下指针
,发现这个特点之后,只需要加一个if判断当上指针==下指针
时屏蔽掉从左到右的输出即可。 - 6.对于宽>长的矩阵,解决方法与5相同
- 7.对于行矩阵(形如[[6,7,8]]),只需要一次遍历即可完成,行矩阵的特点第一次遍历时下指针就是0,并且第一次遍历时下指针就是0的一定是行矩阵。所以解决方法是加if判断
下指针==0
,进而判断是否为行矩阵,如果是行矩阵,完成一次遍历后就可以return。 - 8.列矩阵与7相似。至此通过全部测试用例
- 9.示意图(画技拙劣,希望表示明白了)
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int init_w = matrix[0].size()-1;
int init_h = matrix.size()-1;
int w_first = 0;
int w_last = init_w;
int h_top = 0;
int h_bot = init_h;
int w_first_flag = 0;
int w_last_flag = init_w;
int h_top_flag = 0;
int h_bot_flag = init_h;
vector<int> ret;
while(w_last_flag>=w_first_flag && h_top_flag<=h_bot_flag){ //one loop
while(w_first<=w_last_flag){
ret.push_back(matrix[h_top][w_first]);
w_first += 1;
}
while(h_top+1<=h_bot_flag){
ret.push_back(matrix[h_top+1][w_last_flag]);
h_top += 1;
}
if(h_bot_flag != h_top_flag){
while(w_last-1>=w_first_flag){
ret.push_back(matrix[h_bot_flag][w_last-1]);
w_last -= 1;
}
}
if(w_first_flag != w_last_flag){
while(h_bot-1>=h_top_flag+1){
ret.push_back(matrix[h_bot-1][w_first_flag]);
h_bot -= 1;
}
}
if(h_bot_flag == 0){
return ret;
}
if(w_last_flag == 0){
return ret;
}
w_first_flag += 1;
w_last_flag -= 1;
h_top_flag += 1;
h_bot_flag -= 1;
w_first = w_first_flag;
w_last = w_last_flag;
h_top = h_top_flag;
h_bot = h_bot_flag;
}
return ret;
}
};