返回

Java&C++ 题解与拓展:LeetCode 1582. 二进制矩阵中的特殊位置

后端

引言

在计算机科学领域,二进制矩阵是一种常见的的数据结构,它由 0 和 1 的元素组成,用来表示二进制数据。LeetCode 1582. 二进制矩阵中的特殊位置 问题要求我们找到一个二进制矩阵中所有满足特定条件的特殊位置,这些位置的上下左右四个方向上必须至少有一个 0。

题解

要解决这个问题,我们可以采用遍历的思路,逐个检查矩阵中的每个位置。对于每个位置,我们可以检查其上下左右四个方向上的元素,统计满足条件的 0 的数量。如果这个数量大于 0,则该位置就是特殊位置。

Java 解法

class Solution {
    public int numSpecial(int[][] mat) {
        int m = mat.length;
        int n = mat[0].length;
        int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
        int count = 0;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (mat[i][j] == 1) {
                    int zeroCount = 0;
                    for (int[] dir : dirs) {
                        int x = i + dir[0];
                        int y = j + dir[1];
                        if (x >= 0 && x < m && y >= 0 && y < n && mat[x][y] == 0) {
                            zeroCount++;
                        }
                    }
                    if (zeroCount > 0) {
                        count++;
                    }
                }
            }
        }
        return count;
    }
}

C++ 解法

class Solution {
public:
    int numSpecial(vector<vector<int>>& mat) {
        int m = mat.size();
        int n = mat[0].size();
        vector<vector<int>> dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
        int count = 0;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (mat[i][j] == 1) {
                    int zeroCount = 0;
                    for (auto& dir : dirs) {
                        int x = i + dir[0];
                        int y = j + dir[1];
                        if (x >= 0 && x < m && y >= 0 && y < n && mat[x][y] == 0) {
                            zeroCount++;
                        }
                    }
                    if (zeroCount > 0) {
                        count++;
                    }
                }
            }
        }
        return count;
    }
};

拓展:使用 Rust 语言解决

Rust 是一种系统编程语言,以其内存安全性和高性能而著称。我们可以使用 Rust 的迭代器和模式匹配功能来简洁地解决这个问题。

fn num_special(mat: &Vec<Vec<i32>>) -> usize {
    let (m, n) = (mat.len(), mat[0].len());
    let dirs = [(-1, 0), (1, 0), (0, -1), (0, 1)];
    let mut count = 0;
    for (i, row) in mat.iter().enumerate() {
        for (j, &val) in row.iter().enumerate() {
            if val == 1 {
                let zero_count = dirs
                    .iter()
                    .filter(|&(di, dj)| {
                        let (ni, nj) = (i as i32 + di, j as i32 + dj);
                        ni >= 0 && ni < m as i32 && nj >= 0 && nj < n as i32 && mat[ni as usize][nj as usize] == 0
                    })
                    .count();
                if zero_count > 0 {
                    count += 1;
                }
            }
        }
    }
    count
}

类和方法学习

  • Java 中的流处理: Java 提供了强大的流处理 API,允许我们对数据集合进行各种操作,如过滤、映射和归约。在 Java 解法中,我们使用了流来统计满足条件的 0 的数量。
  • C++ 中的 lambda 表达式: C++ 中的 lambda 表达式提供了一种便捷的方式来定义匿名函数,用于执行特定的操作。在 C++ 解法中,我们使用了 lambda 表达式来对方向数组进行遍历。
  • Rust 中的迭代器和模式匹配: Rust 语言提供了强大的迭代器和模式匹配功能,使我们可以简洁地处理数据集合。在 Rust 解法中,我们使用了迭代器和模式匹配来过滤满足条件的元素。

总结

LeetCode 1582. 二进制矩阵中的特殊位置 问题是一个经典的遍历问题,可以通过检查每个位置的上下左右四个方向上的元素来解决。我们使用 Java、C++ 和 Rust 三种语言提供了详细的解决方案,并对所涉及的类和方法进行了深入的学习和记录。通过这篇文章,读者可以全面了解如何解决此问题以及如何应用各种编程语言中的高级特性。