73. 矩阵置零/54. 螺旋矩阵

发布于:2024-05-08 ⋅ 阅读:(19) ⋅ 点赞:(0)

73. 矩阵置零

给定一个 m x n 的矩阵,如果一个元素为 ,则将其所在行和列的所有元素都设为 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;
}
};


网站公告

今日签到

点亮在社区的每一天
去签到