73. 矩阵置零
给定一个 m x n
的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。
示例 1:
输入:matrix = [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]]
思路:记录当前元素所在行列,然后遍历到处在该行或者该列的元素等于0。
代码:
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
int m=matrix.size();//矩阵行数
int n=matrix[0].size();//矩阵列数
vector<int> row(m),col(n);//记录0元素出现位置的行列数值
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(matrix[i][j]==0){//记录0元素出现位置的行列
row[i]=1;
col[j]=1;
}
}
}
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(row[i]==1||col[j]==1){
matrix[i][j]=0;
}
}
}
}
};
54. 螺旋矩阵
给你一个 m
行 n
列的矩阵 matrix
,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
示例 :
输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]] 输出:[1,2,3,4,8,12,11,10,9,5,6,7]
思路:之前做过n行n列的螺旋矩阵,解决办法就是确定边界,根据边界去调整方向。
代码随想录算法训练营第二天|977. 有序数组的平方、209.长度最小的子数组、 59.螺旋矩阵II-CSDN博客
现在m行n列也不例外,确定边界依然可以做出来。
①边界:边界有上下左右四个边界
上边界:例如例题中,指针从1走到4,这一行就不能再走了(确保从9走到5之后不会再向上走),也就是上边界收缩了一行。
右边界:指针从8走到12,这一列就不能再走了也就是右边界收缩了一列。
剩下:左边界和下边界也是一样。
先对边界初始化,还有初始化一个结果输出数组:
int up=0;//上
int right=matrix[0].size()-1;//右
int down=matrix.size()-1;//下
int left=0;//左
vector<int> ans;
②遍历规则:从左向右时,需要和右边界比较,需要小于等于右边界,该行元素就依次加入到答案数组中;其次该行并不是所有元素都加入,例子中,第一次是从1到4,起点是1,第二次是从6到7,5并没有加入,因为从下向上时候,5就加入了,5加入之后左边界收缩,所以每行的起始位置是左边界;最后我们需要确定是哪一行进行遍历,从例子中可以发现,其实当前遍历的正是上边界所在的一行。
for(int i=left;i<=right;i++) ans.push_back(matrix[up][i]);
确定起始位置,确定结束位置,确定遍历的行或列,这个方法同样适用于其他方向的遍历规则
for(int i=left;i<=right;i++) ans.push_back(matrix[up][i]);//从左到右
for(int i=up;i<=down;i++) ans.push_back(matrix[i][right]);//从上到下
for(int i=right;i>=left;--i) ans.push_back(matrix[down][i]);//从右到左
for(int i=down;i>=up;--i) ans.push_back(matrix[i][left]);//从下到上
注意:从右到左和从下到上,i是递减的,比较也是小于等于。
③确定终止条件:也就是边界碰撞的时候,需要退出,例子中,遍历完外圈元素时,上下边界收缩都等于1,当6遍历到7结束时,上边界收缩,这时候上边界大于下边界,就可以退出循环了。
最后在每次当前行或列遍历完成了,都做一次边界比较。
代码:
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
int up=0;//上
int right=matrix[0].size()-1;//右
int down=matrix.size()-1;//下
int left=0;//左
vector<int> ans;
if(matrix.empty()) return ans;
while(true){
for(int i=left;i<=right;i++) ans.push_back(matrix[up][i]);//从左到右
up+=1;
if(up>down) break;
for(int i=up;i<=down;i++) ans.push_back(matrix[i][right]);//从上到下
right-=1;
if(right<left) break;
for(int i=right;i>=left;--i) ans.push_back(matrix[down][i]);//从右到左
down-=1;
if(down<up) break;
for(int i=down;i>=up;--i) ans.push_back(matrix[i][left]);//从下到上
left+=1;
if(left>right) break;
}
return ans;
}
};