leetcode
leetcode 651 ~ 700
角矩形的数量

角矩形的数量

难度:

标签:

题目描述

代码结果

运行时间: 77 ms, 内存: 17.2 MB


/*
 * 思路:
 * 1. 使用Java Stream API简化代码。
 * 2. 遍历每一对行,计算每一列中同时为1的个数。
 * 3. 使用组合数学计算每一对行之间形成的矩形的数量。
 */
import java.util.stream.IntStream;

public class CornerRectangles {
    public int countCornerRectangles(int[][] grid) {
        int m = grid.length;
        int n = grid[0].length;
        return IntStream.range(0, m)
                .mapToObj(i -> i)
                .flatMap(i -> IntStream.range(i + 1, m)
                        .mapToObj(j -> new int[]{i, j}))
                .mapToInt(pair -> {
                    int i = pair[0];
                    int j = pair[1];
                    long pairCount = IntStream.range(0, n)
                            .filter(k -> grid[i][k] == 1 && grid[j][k] == 1)
                            .count();
                    return (int) (pairCount * (pairCount - 1) / 2);
                })
                .sum();
    }

    public static void main(String[] args) {
        CornerRectangles solution = new CornerRectangles();
        int[][] grid = {
            {1, 0, 0, 1},
            {0, 0, 1, 0},
            {1, 0, 0, 1},
            {1, 1, 1, 1}
        };
        System.out.println(solution.countCornerRectangles(grid)); // 输出: 1
    }
}

解释

方法:

该题解使用了位运算和组合计数的思路。首先对每一行进行预处理,用一个整数 mask 记录该行哪些位置是1。然后利用位与运算,对于当前行 r,计算它与之前每一行 masks[i] (0<=i

时间复杂度:

O(m^2)

空间复杂度:

O(m)

代码细节讲解

🦆
在处理每一行的数据时,为什么选择使用整数掩码来表示行中1的位置,而不是直接使用行数组本身?
使用整数掩码表示行中1的位置而不是使用行数组本身,主要是出于效率和空间优化的考虑。整数掩码可以将一行中的信息压缩到一个整数中,这样可以极大地减少数据处理的空间复杂度,特别是在行宽较小于整数位数(如32位或64位)的情况下。此外,整数运算(如位与、位或和位计数)通常比数组操作更快,这使得在算法中使用位运算处理掩码比逐个检查数组元素更有效率。
🦆
你提到利用位与运算来找出两行之间共同的1的位置,这种方法在哪些情况下可能会有性能瓶颈?
利用位与运算来找出两行之间共同的1的位置虽然在许多情况下都很有效,但在矩阵的宽度非常大时,特别是超过常规整数位数(如32位或64位)的情况下,可能会遇到性能瓶颈。在这种情况下,每行的掩码可能需要多个整数来表示,增加了位运算的复杂度和处理时间。此外,如果矩阵中1的密度非常高,位运算操作的结果仍然是较大的数,这意味着后续的计算,如位计数,需要更多时间来处理更多的1位,也可能导致效率降低。
🦆
在计算角矩形的数量时,使用了组合计数公式,能否解释为什么选择组合计数来计算两行中公共1的位置可以形成的矩形数目?
在计算角矩形时,每一对公共1的位置(即同列的两个1)都可以看作是矩形的两个角。因此,问题转化为在每对行的交集中找到所有可能的1对的组合。组合计数公式`C(n, 2)`,即从n个元素中选择2个的方式数,正好用于计算这种情况。这是因为每两个公共1的位置可以唯一确定一个角矩形。因此,对于每一对行,我们只需要计算其交集中1的个数,然后使用组合公式来计算这些1可以组成多少个矩形。
🦆
算法中的`temp &= allMask`操作是如何帮助优化计算的?这里的`allMask`变量具体起到了什么作用?
在算法中,`temp &= allMask`操作用于限制`temp`仅包含到当前行为止所有行中共同存在的1的位置。`allMask`是一个累积的掩码,它通过位或操作`|=`跟踪了到当前行为止,哪些列至少有一个1。这样,使用`temp &= allMask`确保我们只考虑那些在之前至少出现过一次的列,这有助于减少后续运算的不必要计算,优化整体的计算效率。通过这种方式,我们可以快速且准确地找到两个行之间可能形成角矩形的列对,提升算法性能。

相关问题