LeetCode 热题 100 | 矩阵

目录

[1 73. 矩阵置零](#1 73. 矩阵置零)

[2 54. 螺旋矩阵](#2 54. 螺旋矩阵)

[3 48. 旋转图像](#3 48. 旋转图像)

[4 240. 搜索二维矩阵 II](#4 240. 搜索二维矩阵 II)


菜鸟做题第二周,语言是 C++

1 73. 矩阵置零

解题思路:

  1. 遍历矩阵,寻找等于 0 的元素,记录对应的行和列
  2. 将被记录的行的元素全部置 0
  3. 将被记录的列的元素全部置 0
cpp 复制代码
class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int n = matrix.size(), m = matrix[0].size();
        unordered_set<int> row, col;

        // 寻找0
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                if (matrix[i][j] == 0) {
                    row.insert(i);
                    col.insert(j);
                }
            }
        }
        
        // 行置0
        for (auto &r:row) {
            for (int j = 0; j < m; ++j) {
                matrix[r][j] = 0;
            }
        }

        // 列置0
        for (auto &c:col) {
            for (int i = 0; i < n; ++i) {
                matrix[i][c] = 0;
            }
        }
    }
};

2 54. 螺旋矩阵

解题思路:

  • 定义 right,down,left,up 来标志四个方向
  • 根据不同的方向设置不同的坐标加减策略
  • 将被遍历过的元素置为 101,用于指示能否继续前进
  • 借助 ans.size() 计数,用于指示是否继续循环

为什么将被遍历过的元素置为 101?

如上图所示,101 是矩阵元素绝对不会取到的数值。

如果题目对取值范围没有限制的话,那可能真的需要定义另一个矩阵来记录遍历情况了。

cpp 复制代码
class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        int right = 1, down = 0, up = 0, left = 0;
        vector<int> ans;
        int n = matrix.size(), m = matrix[0].size();

        int i = 0, j = 0;
        while (ans.size() != n * m) {
            if (right) {
                while (j < m && matrix[i][j] != 101) {
                    ans.push_back(matrix[i][j]);
                    matrix[i][j] = 101;
                    ++j;
                }
                --j;
                ++i;
                right = 0;
                down = 1;
            }

            if (down) {
                while (i < n && matrix[i][j] != 101) {
                    ans.push_back(matrix[i][j]);
                    matrix[i][j] = 101;
                    ++i;
                }
                --i;
                --j;
                down = 0;
                left = 1;
            }

            if (left) {
                while (j >= 0 && matrix[i][j] != 101) {
                    ans.push_back(matrix[i][j]);
                    matrix[i][j] = 101;
                    --j;
                }
                ++j;
                --i;
                left = 0;
                up = 1;
            }

            if (up) {
                while (i >= 0 && matrix[i][j] != 101) {
                    ans.push_back(matrix[i][j]);
                    matrix[i][j] = 101;
                    --i;
                }
                ++i;
                ++j;
                up = 0;
                right = 1;
            }
        }
        return ans;
    }
};

3 48. 旋转图像

报一丝,还是用了新的矩阵,以后想想其他办法。。。

cpp 复制代码
class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        auto temp = matrix;
        int n = matrix.size();
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                temp[i][j] = matrix[n - 1 - j][i];
            }
        }
        matrix = temp;
    }
};

4 240. 搜索二维矩阵 II

笨办法,但意外的是没超时

cpp 复制代码
class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {

        int n = matrix.size(), m = matrix[0].size();

        int i = 0, j = 0;
        while (i < n && j < m && matrix[i][j] <= target) {
            if (matrix[i][j] == target) return true;
            ++i;
            ++j;
        }

        // 针对n<m且找到头的情况
        if (i == n) {
            --i;
            while (j < m && matrix[i][j] <= target) {
                if (matrix[i][j] == target) return true;
                ++j;
            }
            if (j == m) return false;

            for (int y = j; y < m; ++y) {
                for (int x = i; x >= 0; --x) {
                    if (matrix[x][y] == target) return true;
                }
            }
        }

        // 针对n>m的情况且找到头的情况
        if (j == m) {
            --j;
            while (i < n && matrix[i][j] <= target) {
                if (matrix[i][j] == target) return true;
                ++i;
            }
            if (i == n) return false;

            for (int x = i; x < n; ++x) {
                for (int y = j; y >= 0; --y) {
                    if (matrix[x][y] == target) return true;
                }
            }
        }

        for (int x = i; x < n; ++x) {
            for (int y = j; y >= 0; --y) {
                if (matrix[x][y] == target) return true;
            }
        }

        for (int y = j; y < m; ++y) {
            for (int x = i; x >= 0; --x) {
                if (matrix[x][y] == target) return true;
            }
        }
        
        return false;
    }
};
相关推荐
仙俊红7 分钟前
快速运行openMMOCR
深度学习·算法
-Max-静-23 分钟前
Paddle Inference部署推理(十八)
人工智能·windows·深度学习·算法·paddle·推理 部署
PaLu-LI1 小时前
ORB-SLAM2源码学习:Initializer.cc:Initializer::CheckFundamental地图初始化——检查基础矩阵F并评分
c++·opencv·学习·线性代数·ubuntu·计算机视觉·矩阵
qq_485668991 小时前
算法习题--蓝桥杯
算法·职场和发展·蓝桥杯
waves浪游1 小时前
类和对象(中)
c语言·开发语言·数据结构·c++·算法·链表
做人不要太理性1 小时前
【算法一周目】滑动窗口(2)
c++·算法·leetcode·哈希算法·散列表·滑动窗口
青い月の魔女1 小时前
数据结构初阶---复杂度
c语言·数据结构·笔记·学习·算法
汤姆和杰瑞在瑞士吃糯米粑粑1 小时前
【优先算法学习】双指针--结合题目讲解学习
c++·学习·算法
m0_547486661 小时前
数据结构试题库1
java·数据结构·算法
多多*1 小时前
后端并发编程操作简述 Java高并发程序设计 六类并发容器 七种线程池 四种阻塞队列
java·开发语言·前端·数据结构·算法·状态模式