返回

零矩阵:动态编程的典范

后端

引言
在leetcode面试题01.08 零矩阵中,我们给定一个二维矩阵,需要将所有与0相邻的元素都置为0。动态规划是一种解决这类问题的有效方法,它将问题分解成更小的问题,逐个求解,最终得到全局最优解。

Java实现

class Solution {
    public void setZeroes(int[][] matrix) {
        int m = matrix.length, n = matrix[0].length;
        boolean[] row = new boolean[m];
        boolean[] col = new boolean[n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == 0) {
                    row[i] = true;
                    col[j] = true;
                }
            }
        }
        for (int i = 0; i < m; i++) {
            if (row[i]) {
                Arrays.fill(matrix[i], 0);
            }
        }
        for (int j = 0; j < n; j++) {
            if (col[j]) {
                for (int i = 0; i < m; i++) {
                    matrix[i][j] = 0;
                }
            }
        }
    }
}

在这个Java解法中,我们首先用两个布尔数组row和col来记录哪些行和列包含0。然后,我们遍历整个矩阵,如果遇到一个0,就将对应的行和列标记为True。最后,我们再遍历一次矩阵,将所有被标记为True的行和列中的元素全部置为0。

C++实现

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int m = matrix.size(), n = matrix[0].size();
        vector<bool> row(m, false);
        vector<bool> col(n, false);
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (matrix[i][j] == 0) {
                    row[i] = true;
                    col[j] = true;
                }
            }
        }
        for (int i = 0; i < m; i++) {
            if (row[i]) {
                for (int j = 0; j < n; j++) {
                    matrix[i][j] = 0;
                }
            }
        }
        for (int j = 0; j < n; j++) {
            if (col[j]) {
                for (int i = 0; i < m; i++) {
                    matrix[i][j] = 0;
                }
            }
        }
    }
};

在C++实现中,我们使用了vector来代替布尔数组,并对代码进行了相应调整。其余逻辑与Java实现基本相同。

Rust实现

pub fn set_zeroes(matrix: &mut Vec<Vec<i32>>) {
    let m = matrix.len();
    let n = matrix[0].len();
    let mut row = vec![false; m];
    let mut col = vec![false; n];
    for i in 0..m {
        for j in 0..n {
            if matrix[i][j] == 0 {
                row[i] = true;
                col[j] = true;
            }
        }
    }
    for i in 0..m {
        if row[i] {
            for j in 0..n {
                matrix[i][j] = 0;
            }
        }
    }
    for j in 0..n {
        if col[j] {
            for i in 0..m {
                matrix[i][j] = 0;
            }
        }
    }
}

在Rust实现中,我们使用了Vec来代替布尔数组,并对代码进行了相应调整。其余逻辑与Java和C++实现基本相同。

总结

通过leetcode面试题01.08 零矩阵,我们学习了动态规划这一强大的算法范式,并用Java、C++和Rust三种语言分别实现了该问题。通过对这三种语言的比较,我们可以发现,它们在语法和风格上存在一些差异,但都能够很好地解决这个问题。动态规划是一种非常重要的算法,在解决许多实际问题中都有着广泛的应用。