算法leetcode|73. 矩阵置零(rust重拳出击)


文章目录


73. 矩阵置零:

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

样例 1:

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

样例 2:

输入:
	
	matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
	
输出:
	
	[[0,0,0,0],[0,4,5,0],[0,3,1,0]]

提示:

  • m == matrix.length
  • n == matrix[0].length
  • 1 <= m, n <= 200
  • -2^31^ <= matrix[i][j] <= 2^31^ - 1

进阶:

  • 一个直观的解决方案是使用 O(mn) 的额外空间,但这并不是一个好的解决方案。
  • 一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。
  • 你能想出一个仅使用常量空间的解决方案吗?

分析:

  • 面对这道算法题目,二当家的再次陷入了沉思。
  • 要遍历整个矩阵是肯定的了,所以时间复杂度上似乎没什么大的技巧,重点在空间复杂度上。
  • 不使用额外空间,直接在遍历中就将行和列置0,会导致还没有遍历到的值丢失。
  • 可以将原矩阵整体拷贝一份作为备份,然后遍历这个备份的矩阵,去直接将原矩阵置0,这样会使用 O(mn) 的额外空间。
  • 一个简单的改进方案是使用两个额外的数组,存储每一行是否出现过0,和每一列是否出现过0,然后再利用这两个额外的标记数组将原矩阵置0,这样会使用 O(m + n) 的额外空间。
  • 可以进一步优化,我们可以用矩阵的第一行和第一列代作为标记数组。但这样会导致原数组的第一行和第一列被修改,无法记录它们是否原本包含 0。因此我们需要额外使用两个标记变量分别记录第一行和第一列是否原本包含 0,这样仅仅需要 O(1) 的额外空间。

题解:

rust:

rust 复制代码
impl Solution {
    pub fn set_zeroes(matrix: &mut Vec<Vec<i32>>) {
        let (m, n) = (matrix.len(), matrix[0].len());
        let (mut flag_row0, mut flag_col0) = (false, false);
        // 第一行是否有0
        for i in 0..n {
            if matrix[0][i] == 0 {
                flag_row0 = true;
                break;
            }
        }
        // 第一列是否有0
        for i in 0..m {
            if matrix[i][0] == 0 {
                flag_col0 = true;
                break;
            }
        }
        // 标记
        (1..m).for_each(|i| {
            (1..n).for_each(|j| {
                if matrix[i][j] == 0 {
                    matrix[i][0] = 0;
                    matrix[0][j] = 0;
                }
            });
        });
        // 置0
        (1..m).for_each(|i| {
            (1..n).for_each(|j| {
                if matrix[i][0] == 0 || matrix[0][j] == 0 {
                    matrix[i][j] = 0;
                }
            });
        });
        // 第一行置0
        if flag_row0 {
            for i in 0..n {
                matrix[0][i] = 0;
            }
        }
        // 第一列置0
        if flag_col0 {
            for i in 0..m {
                matrix[i][0] = 0;
            }
        }
    }
}

go:

go 复制代码
func setZeroes(matrix [][]int)  {
    m, n := len(matrix), len(matrix[0])
	row0, col0 := false, false
	// 第一行是否有0
	for _, v := range matrix[0] {
		if v == 0 {
			row0 = true
			break
		}
	}
	// 第一列是否有0
	for _, r := range matrix {
		if r[0] == 0 {
			col0 = true
			break
		}
	}
	// 标记
	for i := 1; i < m; i++ {
		for j := 1; j < n; j++ {
			if matrix[i][j] == 0 {
				matrix[i][0] = 0
				matrix[0][j] = 0
			}
		}
	}
	// 置0
	for i := 1; i < m; i++ {
		for j := 1; j < n; j++ {
			if matrix[i][0] == 0 || matrix[0][j] == 0 {
				matrix[i][j] = 0
			}
		}
	}
	// 第一行置0
	if row0 {
		for i := 0; i < n; i++ {
			matrix[0][i] = 0
		}
	}
	// 第一列置0
	if col0 {
		for _, r := range matrix {
			r[0] = 0
		}
	}
}

c++:

cpp 复制代码
class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        const int m = matrix.size(), n = matrix[0].size();
        bool flag_row0 = false, flag_col0 = false;
        // 第一行是否有0
        for (int i = 0; i < n; ++i) {
            if (!matrix[0][i]) {
                flag_row0 = true;
                break;
            }
        }
        // 第一列是否有0
        for (int i = 0; i < m; ++i) {
            if (!matrix[i][0]) {
                flag_col0 = true;
                break;
            }
        }
        // 标记
        for (int i = 1; i < m; ++i) {
            for (int j = 1; j < n; ++j) {
                if (!matrix[i][j]) {
                    matrix[i][0] = matrix[0][j] = 0;
                }
            }
        }
        // 置0
        for (int i = 1; i < m; ++i) {
            for (int j = 1; j < n; ++j) {
                if (!matrix[i][0] || !matrix[0][j]) {
                    matrix[i][j] = 0;
                }
            }
        }
        // 第一行置0
        if (flag_row0) {
            for (int i = 0; i < n; ++i) {
                matrix[0][i] = 0;
            }
        }
        // 第一列置0
        if (flag_col0) {
            for (int i = 0; i < m; ++i) {
                matrix[i][0] = 0;
            }
        }
    }
};

python:

python 复制代码
class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        m, n = len(matrix), len(matrix[0])
        # 第一行是否有0
        flag_row0 = any(matrix[0][i] == 0 for i in range(n))
        # 第一列是否有0
        flag_col0 = any(matrix[i][0] == 0 for i in range(m))
        # 标记
        for i in range(1, m):
            for j in range(1, n):
                if matrix[i][j] == 0:
                    matrix[i][0] = matrix[0][j] = 0
        # 置0
        for i in range(1, m):
            for j in range(1, n):
                if matrix[i][0] == 0 or matrix[0][j] == 0:
                    matrix[i][j] = 0
        # 第一行置0
        if flag_row0:
            for j in range(n):
                matrix[0][j] = 0
        # 第一列置0
        if flag_col0:
            for i in range(m):
                matrix[i][0] = 0

java:

java 复制代码
class Solution {
    public void setZeroes(int[][] matrix) {
        final int m        = matrix.length, n = matrix[0].length;
        boolean   flagRow0 = false, flagCol0 = false;
        // 第一行是否有0
        for (int i = 0; i < m; ++i) {
            if (matrix[i][0] == 0) {
                flagCol0 = true;
                break;
            }
        }
        // 第一列是否有0
        for (int i = 0; i < n; ++i) {
            if (matrix[0][i] == 0) {
                flagRow0 = true;
                break;
            }
        }
        // 标记
        for (int i = 1; i < m; ++i) {
            for (int j = 1; j < n; ++j) {
                if (matrix[i][j] == 0) {
                    matrix[i][0] = matrix[0][j] = 0;
                }
            }
        }
        // 置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
        if (flagRow0) {
            for (int i = 0; i < n; ++i) {
                matrix[0][i] = 0;
            }
        }
        // 第一列置0
        if (flagCol0) {
            for (int i = 0; i < m; ++i) {
                matrix[i][0] = 0;
            }
        }
    }
}

非常感谢你阅读本文~

欢迎【点赞】【收藏】【评论】三连走一波~

放弃不难,但坚持一定很酷~

希望我们大家都能每天进步一点点~

本文由 二当家的白帽子:https://le-yi.blog.csdn.net/ 博客原创~


相关推荐
小芒果_011 分钟前
P11229 [CSP-J 2024] 小木棍
c++·算法·信息学奥赛
qq_434085902 分钟前
Day 52 || 739. 每日温度 、 496.下一个更大元素 I 、503.下一个更大元素II
算法
Beau_Will3 分钟前
ZISUOJ 2024算法基础公选课练习一(2)
算法
XuanRanDev5 分钟前
【每日一题】LeetCode - 三数之和
数据结构·算法·leetcode·1024程序员节
gkdpjj7 分钟前
C++优选算法十 哈希表
c++·算法·散列表
代码猪猪傻瓜coding7 分钟前
力扣1 两数之和
数据结构·算法·leetcode
小码农<^_^>1 小时前
优选算法精品课--滑动窗口算法(一)
算法
羊小猪~~1 小时前
神经网络基础--什么是正向传播??什么是方向传播??
人工智能·pytorch·python·深度学习·神经网络·算法·机器学习
假装我不帅1 小时前
asp.net framework从webform开始创建mvc项目
后端·asp.net·mvc