Skip to content

3月19日报(矩阵)

约 1395 字大约 5 分钟

日报leetcode

2026-03-19

  • 完成一道 mid 数组相关,添加至昨天日报了
  • 看了矩阵

矩阵置零

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

思路解析

如果要是遍历到 0 直接将十字交叉线上的所有值全部变为 0 明显是不合适的,在接下来的遍历中就会分不清是原本就存在的 0 还是修改后的 0 ,最终导致整个矩阵都变成 0 为了解决以上问题,我们需要新建一个布尔值记录 是否要将第零行、列全部改为 0 接下来实现第一关 从 1 开始遍历矩阵,如果遇到 0 ,就将他的上方和左方改为 0 继续执行下一步, 再次遍历矩阵,查看上方和左边是否还有 0 ,有的话就将其也修改为 0 最后如果第 0 行、列有 0 直接将其全部修改

代码实现

class Solution {  
    public void setZeroes(int[][] matrix) {  
        int m = matrix.length;  
        int n = matrix[0].length;  
		// 记录第 0 行是否有 0
        boolean firstRowHasZero = false;  
        for (int x : matrix[0]) {  
            if (x == 0) {  
                firstRowHasZero = true;  
                break;  
            }  
        }  
        // 记录第 0 列是否有 0
        boolean firstColHasZero = false;  
        for (int i = 0; i < m; i++) {  
            if (matrix[i][0] == 0) {  
                firstColHasZero = true;  
                break;  
            }  
        }  
        // 跳过 第 0 行,留到最后修改
        for (int i = 1; i < m; i++) {  
            for (int j = 1; j < n; j++) {  
                if (matrix[i][j] == 0) {  
                    matrix[i][0] = 0;  
                    matrix[0][j] = 0;  
                }  
            }  
        }  
  
        for (int i = 1; i < m; i++) {  
            for (int j = 1; j < n; j++) {  
                if (matrix[i][0] == 0 || matrix[0][j] == 0) {  
                    matrix[i][j] = 0;  
                }  
            }  
        }  
		  // 如果包含 0 直接全部修改为 0
        if (firstColHasZero) {  
            for (int[] row : matrix) {  
                row[0] = 0;  
            }  
        }  
        // 如果包含 0 直接全部修改为 0
        if (firstRowHasZero) {  
            Arrays.fill(matrix[0], 0);  
        }  
    }  
}

螺旋矩阵

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

思路解析

观察图片 ,由此的得知,顺时针螺旋顺序其实是依次 “从左向右、从上向下、从右向左、从下向上” 循环

于是我们有以下流程 使用图表来辅助理解

打印方向1. 根据边界打印2. 边界向内收缩3. 是否打印完毕
从左向右左边界 l,右边界 r上边界 t 加 1是否 t > b
从上向下上边界 t,下边界 b右边界 r 减 1是否 l > r
从右向左右边界 r,左边界 l下边界 b 减 1是否 t > b
从下向上下边界 b,上边界 t左边界 l 加 1是否 l > r

代码实现

class Solution {  
    public List<Integer> spiralOrder(int[][] matrix) {  
        if (matrix.length == 0)  
            return new ArrayList<Integer>();  
        int l = 0, r = matrix[0].length - 1;  
        int t = 0, b = matrix.length - 1, x = 0;  
  
        Integer[] res = new Integer[(r + 1) * (b + 1)];  
        while (true) {  
            for (int i = l; i <= r; i++) res[x++] = matrix[t][i];  
            if (++t > b) break;  
            for (int i = t; i <= b; i++) res[x++] = matrix[i][r];  
            if (l > --r) break;  
            for (int i = r; i >= l; i--) res[x++] = matrix[b][i];  
            if (t > --b) break;  
            for (int i = b; i >= t; i--) res[x++] = matrix[i][l];  
            if (++l > r) break;  
        }  
        return Arrays.asList(res);  
  
    }  
}

旋转图像

给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

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

思路解析

先看图,以此获得映射公式

之后按照公式来进行代码的实现即可

代码实现

class Solution {  
    public void rotate(int[][] matrix) {  
        int n = matrix.length;  
        for (int i = 0; i < n; i++) {  
            for (int j = 0; j < i; j++) {  
                int tmp = matrix[i][j];  
                matrix[i][j] = matrix[j][i];  
                matrix[j][i] = tmp;  
            }  
        }  
        for (int[] row : matrix) {  
            for (int j = 0; j < n / 2; j++) {  
                int tmp = row[j];  
                row[j] = row[n - 1 -j];  
                row[n - 1 - j] = tmp;  
            }  
        }  
    }  
}

合并为同一个循环

class Solution {  
    public void rotate(int[][] matrix) {  
        int n = matrix.length;  
        for (int i = 0; i < n; i++) {  
            int[] row = matrix[i];  
            for (int j = i + 1; j < n; j++) {  
                int tmp = row[j];  
                row[j] = matrix[j][i];  
                matrix[j][i] = tmp;  
            }  
            for (int j = 0; j < n / 2; j++) {  
                int tmp = row[j];  
                row[j] = row[n - 1 - j];  
                row[n - 1 - j] = tmp;  
            }  
        }  
    }  
}

搜索二维矩阵 Ⅱ

编写一个高效的算法来搜索 _m_ x _n_ 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:

  • 每行的元素从左到右升序排列。
  • 每列的元素从上到下升序排列。

思路解析

for for return true(bushi 将矩阵逆时针旋转 45 度,并将其转化为图形式,发现其类似于 二叉搜索树 ,即对于每个元素,其左分支元素更小、右分支元素更大。因此,通过从 “根节点” 开始搜索,遇到比 target 大的元素就向左,反之向右,即可找到目标值 target

根结点 即为 左下角和右上角的数字,在此用 flag 表示,以左下角元素开始则有:

  • flag > target 则证明 target 一定在 flag 所在行的上方,即 flag 所在行可以被消除
  • flag < target 则证明 target 一定在 flag 所在列的右方,即 flag 所在列可以被消除

代码实现

class Solution {  
    public boolean searchMatrix(int[][] matrix, int target) {  
        int i = matrix.length - 1, j = 0;  
        while (i >= 0 && j < matrix[0].length) {  
            if(matrix[i][j] > target) i--;  
            else if(matrix[i][j] < target) j++;  
            else return true;  
        }  
        return false;  
    }  
}