lecode59
class Solution {
public:
vector<vector
std::vector<vector<int>> ve(n,vector<int>(n,0)); //vector初始化,第一位是元素个数,第二位是内容
int count=1; //填充数值
int num=n/2; //循环圈数
int begin=0; //每圈开始的位置
int left=0; //左界限 //注意遵循左闭右开原则,每次处理不处理最后一位,交给下一部分处理,保证逻辑连贯
int right=n-1; //右界限
int high=0; //上界限
int low=n-1; //下界限
while(num>0){
for(int i=left;i<right;i++){
ve[high][i]=count++; //从左到右
}
for(int i=high;i<low;i++){
ve[i][right]=count++; //从上到下
}for(int i=right;i>left;i--){
ve[low][i]=count++; //从右到左
}for(int i=low;i>high;i--){
ve[i][left]=count++; //从下到上
}
num--;
left++;
right--;
high++;
low--;
}
if(n%2){
ve[n/2][n/2]=count; //注意如果是单数点,比如3,最中间的要单独处理
}
return ve;
}
};
lecode54
class Solution {
public:
vector
std::vector
int left=0;
int right=matrix[0].size()-1; //c++vector长度是size()
int high=0;
int low=matrix.size()-1;
while(true){ //这个和上题不一样,这个直接处理角点
for(int i=left;i<=right;i++){
ve.push_back(matrix[high][i]);
}
if(++high>low) break;
for(int i=high;i<=low;i++){
ve.push_back(matrix[i][right]);
}
if(--right<left) break;
for(int i=right;i>=left;i--){
ve.push_back(matrix[low][i]);
}
if(--low<high) break;
for(int i=low;i>=high;i--){
ve.push_back(matrix[i][left]);
}
if(++left>right) break;
}
return ve;
}
};
螺旋矩阵 (LeetCode 54) 与你刚才做的 螺旋矩阵 II (LeetCode 59) 最大的区别在于:LC 59 是正方形 nn,而 LC 54 是长方形 mn。
正方形可以完美地一圈圈往里缩,中心要么是一个点(奇数),要么没有(偶数)。
但长方形可能会剩下一行,或者剩下一列,甚至是一个非正方形的“芯”。
因此,对于 LC 54,“设定四个边界并不断向内收缩” 的模拟法通常比 LC 59 那种“计算转几圈(loop)”的方法更直观,也不容易在长宽不一致时出错。
核心代码思路:“撞墙转向,缩减边界”
在做 LC 54 时,还是使用我们上一轮讨论出的 “设定四边界 (up, down, left, right) + while(true) + 立即检查 break” 的方法。
因为它不需要计算圈数,也不需要单独处理中心(中心的那一行/列会被当作最后一次正常的边界收缩自然处理掉)。
一句话总结:正方形用“圈数法”(LC 59),长方形用“四边界收缩法”(LC 54)。
浙公网安备 33010602011771号