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;
    }
};
相关推荐
老鼠只爱大米6 分钟前
LeetCode经典算法面试题 #46:全排列(回溯、交换、剪枝等五种实现方案详细解析)
算法·leetcode·剪枝·回溯·全排列·stj算法
Dovis(誓平步青云)19 分钟前
《滑动窗口算法:从 “暴力遍历” 到 “线性高效” 的思维跃迁》
运维·服务器·数据库·算法
_OP_CHEN1 小时前
【算法基础篇】(五十七)线性代数之矩阵乘法从入门到实战:手撕模板 + 真题详解
线性代数·算法·矩阵·蓝桥杯·c/c++·矩阵乘法·acm/icpc
天天爱吃肉82181 小时前
【跨界封神|周杰伦×王传福(陶晶莹主持):音乐创作与新能源NVH测试,底层逻辑竟完全同源!(新人必看入行指南)】
python·嵌入式硬件·算法·汽车
im_AMBER1 小时前
Leetcode 114 链表中的下一个更大节点 | 删除排序链表中的重复元素 II
算法·leetcode
xhbaitxl1 小时前
算法学习day38-动态规划
学习·算法·动态规划
多恩Stone1 小时前
【3D AICG 系列-6】OmniPart 训练流程梳理
人工智能·pytorch·算法·3d·aigc
历程里程碑1 小时前
普通数组----轮转数组
java·数据结构·c++·算法·spring·leetcode·eclipse
pp起床1 小时前
贪心算法 | part02
算法·leetcode·贪心算法
sin_hielo1 小时前
leetcode 1653
数据结构·算法·leetcode