代码题(38)— 旋转图像矩阵置零

Posted eilearn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了代码题(38)— 旋转图像矩阵置零相关的知识,希望对你有一定的参考价值。

1、48. 旋转图像

给定一个 × n 的二维矩阵表示一个图像。

将图像顺时针旋转 90 度。

说明:

你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。

示例 1:

给定 matrix = 
[
  [1,2,3],
  [4,5,6],
  [7,8,9]
],

原地旋转输入矩阵,使其变为:
[
  [7,4,1],
  [8,5,2],
  [9,6,3]
]

示例 2:

给定 matrix =
[
  [ 5, 1, 9,11],
  [ 2, 4, 8,10],
  [13, 3, 6, 7],
  [15,14,12,16]
], 

原地旋转输入矩阵,使其变为:
[
  [15,13, 2, 5],
  [14, 3, 4, 1],
  [12, 6, 8, 9],
  [16, 7,10,11]
]

  这种方法首先对原数组取其转置矩阵,然后把每行的数字翻转可得到结果,如下所示(其中蓝色数字表示翻转轴):

1  2  3       1  4  7       7  4  1

4  5  6  -->   2  5  8   -->     8  5  2  

7  8  9       3  6  9          9  6  3

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        if(matrix.empty())
            return;
        int n = matrix.size();
        for(int i=0;i<n;++i)
        {
            for(int j=i+1;j<n;++j)
            {
                swap(matrix[i][j], matrix[j][i]); //首先转置矩阵,以左对角线旋转
            }
            reverse(matrix[i].begin(),matrix[i].end());//对转置后矩阵每一行翻转
        }
        
    }
};

2、73. 矩阵置零

给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。

示例 1:

输入: 
[
  [1,1,1],
  [1,0,1],
  [1,1,1]
]
输出: 
[
  [1,0,1],
  [0,0,0],
  [1,0,1]
]

  这道题中说的空间复杂度为O(mn)的解法自不用多说,直接新建一个和matrix等大小的矩阵,然后一行一行的扫,只要有0,就将新建的矩阵的对应行全赋0,行扫完再扫列,然后把更新完的矩阵赋给matrix即可,这个算法的空间复杂度太高。将其优化到O(m+n)的方法是,用一个长度为m的一维数组记录各行中是否有0,用一个长度为n的一维数组记录各列中是否有0,最后直接更新matrix数组即可。这道题的要求是用O(1)的空间,那么我们就不能新建数组,我们考虑就用原数组的第一行第一列来记录各行各列是否有0.

  1. - 先扫描第一行第一列,如果有0,则将各自的flag设置为true
  2. - 然后扫描除去第一行第一列的整个数组,如果有0,则将对应的第一行和第一列的数字赋0
  3. - 再次遍历除去第一行第一列的整个数组,如果对应的第一行和第一列的数字有一个为0,则将当前值赋0
  4. - 最后根据第一行第一列的flag来更新第一行第一列
class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        if(matrix.empty())
            return ;
        int m = matrix.size();
        int n = matrix[0].size();
        bool rowZero = false;
        bool colZero = false;
        for(int i=0;i<m;++i)
        {
            if(matrix[i][0] == 0)
                colZero = true;
        }
        for(int i=0;i<n;++i)
        {
            if(matrix[0][i] == 0)
                rowZero = true;
        }
        for (int i = 1; i < m; ++i) {
            for (int j = 1; j < n; ++j) {
                if (matrix[i][j] == 0) {
                    matrix[0][j] = 0;
                    matrix[i][0] = 0;
                }
            }
        }
        for (int i = 1; i < m; ++i) {
            for (int j = 1; j < n; ++j) {
                if (matrix[0][j] == 0 || matrix[i][0] == 0) {
                    matrix[i][j] = 0;
                }
            }
        }
        if (rowZero) {
            for (int i = 0; i < n; ++i) matrix[0][i] = 0;
        }
        if (colZero) {
            for (int i = 0; i < m; ++i) matrix[i][0] = 0;
        }
    }
};

 

以上是关于代码题(38)— 旋转图像矩阵置零的主要内容,如果未能解决你的问题,请参考以下文章

精选力扣500题 第68题 48. 旋转图像 寻找两个正序数组的中位数c++/java详细题解

48. 旋转图像

#leetcode刷题之路48-旋转图像

面试题 01.07. 旋转矩阵

旋转图像--力扣

48. 旋转图像