数组题目:图像重叠

本文讨论了一道编程题,题目要求找出两个二进制矩阵图像在平移后的最大重叠部分。通过枚举一个图像的所有平移方式,计算与另一个图像的重叠像素数量,找到最大值。算法的时间复杂度为O(n^4),空间复杂度为O(1)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

标题和出处

标题:图像重叠

出处:835. 图像重叠

难度

6 级

题目描述

要求

给出两个图像 img1 \texttt{img1} img1 img2 \texttt{img2} img2,都是大小为 n × n \texttt{n} \times \texttt{n} n×n 的正方形二进制矩阵(二进制矩阵只包含 0 \texttt{0} 0 1 \texttt{1} 1)。

我们转换其中一个图像,向左、右、上、下移动任何数量的单位,并把它放在另一个图像的上面。转换之后,该转换的重叠是指两个图像中都为 1 \texttt{1} 1 的位置的数目。

(请注意,转换不包括任何方向的旋转。)

最大可能的重叠是多少?

示例

示例 1:

示例 1

输入: img1   =   [[1,1,0],[0,1,0],[0,1,0]],   img2   =   [[0,0,0],[0,1,1],[0,0,1]] \texttt{img1 = [[1,1,0],[0,1,0],[0,1,0]], img2 = [[0,0,0],[0,1,1],[0,0,1]]} img1 = [[1,1,0],[0,1,0],[0,1,0]], img2 = [[0,0,0],[0,1,1],[0,0,1]]
输出: 3 \texttt{3} 3
解释:我们将 img1 \texttt{img1} img1 向右移动 1 \texttt{1} 1 个单位,向下移动 1 \texttt{1} 1 个单位。
示例 1 步骤 1
两个图像中都为 1 \texttt{1} 1 的位置的数目是 3 \texttt{3} 3(红色的位置)。
示例 1 步骤 2

示例 2:

输入: img1   =   [[1]],   img2   =   [[1]] \texttt{img1 = [[1]], img2 = [[1]]} img1 = [[1]], img2 = [[1]]
输出: 1 \texttt{1} 1

示例 3:

输入: img1   =   [[0]],   img2   =   [[0]] \texttt{img1 = [[0]], img2 = [[0]]} img1 = [[0]], img2 = [[0]]
输出: 0 \texttt{0} 0

数据范围

  • n = img1.length \texttt{n} = \texttt{img1.length} n=img1.length
  • n = img1[i].length \texttt{n} = \texttt{img1[i].length} n=img1[i].length
  • n = img2.length \texttt{n} = \texttt{img2.length} n=img2.length
  • n = img2[i].length \texttt{n} = \texttt{img2[i].length} n=img2[i].length
  • 1 ≤ n ≤ 30 \texttt{1} \le \texttt{n} \le \texttt{30} 1n30
  • img1[i][j] \texttt{img1[i][j]} img1[i][j] 0 \texttt{0} 0 1 \texttt{1} 1
  • img2[i][j] \texttt{img2[i][j]} img2[i][j] 0 \texttt{0} 0 1 \texttt{1} 1

解法

思路和算法

将一个图像进行转换,等价于将另一个图像以相反方向进行转换,因此只需要考虑转换 img 1 \textit{img}_1 img1 的情况。

在转换 img 1 \textit{img}_1 img1 之后,只有当 img 1 \textit{img}_1 img1 img 2 \textit{img}_2 img2 有至少一个元素重合的时候,重叠才可能大于 0 0 0。由于 img 1 \textit{img}_1 img1 img 2 \textit{img}_2 img2 都是 n n n n n n 列的正方形矩阵,为了在转换之后使得两个图像有重合,转换时在水平方向和竖直方向可以移动的最大单位数都必须小于 n n n,即不能超过 n − 1 n-1 n1

( i , j ) (i, j) (i,j) 表示 img 1 \textit{img}_1 img1 的转换,其中 − ( n − 1 ) ≤ i , j ≤ n − 1 -(n-1) \le i,j \le n-1 (n1)i,jn1

  • 竖直方向, i < 0 i<0 i<0 表示 img 1 \textit{img}_1 img1 向上移动, i > 0 i>0 i>0 表示 img 1 \textit{img}_1 img1 向下移动;

  • 水平方向, j < 0 j<0 j<0 表示 img 1 \textit{img}_1 img1 向左移动, j > 0 j>0 j>0 表示 img 1 \textit{img}_1 img1 向右移动。

转换之后, img 1 [ row − i ] [ column − j ] \textit{img}_1[\textit{row} - i][\textit{column} - j] img1[rowi][columnj] img 2 [ row ] [ column ] \textit{img}_2[\textit{row}][\textit{column}] img2[row][column] 重合,如果这两个值都是 1 1 1,则为一个重叠。

由于行下标和列下标都要满足大于等于 0 0 0 且小于 n n n,因此需要满足以下条件:

  • 0 ≤ row − i < n 0 \le \textit{row} - i < n 0rowi<n

  • 0 ≤ column − j < n 0 \le \textit{column} - j < n 0columnj<n

  • 0 ≤ row < n 0 \le \textit{row} < n 0row<n

  • 0 ≤ column < n 0 \le \textit{column} < n 0column<n

因此枚举行下标和列下标时应满足以下条件:

  • max ⁡ ( 0 , i ) ≤ row < min ⁡ ( n , n + i ) \max(0, i) \le \textit{row} < \min(n, n + i) max(0,i)row<min(n,n+i)

  • max ⁡ ( 0 , j ) ≤ column < min ⁡ ( n , n + j ) \max(0, j) \le \textit{column} < \min(n, n + j) max(0,j)column<min(n,n+j)

对于每组 ( i , j ) (i, j) (i,j),确定 row \textit{row} row column \textit{column} column 的范围之后,即可遍历范围内的全部 ( row , column ) (\textit{row}, \textit{column}) (row,column),计算该组 ( i , j ) (i, j) (i,j) 对应的转换的重叠。

遍历全部 ( i , j ) (i, j) (i,j) 之后即可得到最大可能的重叠。

代码

class Solution {
    public int largestOverlap(int[][] img1, int[][] img2) {
        int maxOverlap = 0;
        int n = img1.length;
        int maxMove = n - 1;
        for (int i = -maxMove; i <= maxMove; i++) {
            for (int j = -maxMove; j <= maxMove; j++) {
                int overlap = 0;
                int rowStart = Math.max(0, i), rowEnd = Math.min(n, n + i);
                int columnStart = Math.max(0, j), columnEnd = Math.min(n, n + j);
                for (int row = rowStart; row < rowEnd; row++) {
                    for (int column = columnStart; column < columnEnd; column++) {
                        if (img1[row - i][column - j] == 1 && img2[row][column] == 1) {
                            overlap++;
                        }
                    }
                }
                maxOverlap = Math.max(maxOverlap, overlap);
            }
        }
        return maxOverlap;
    }
}

复杂度分析

  • 时间复杂度: O ( n 4 ) O(n^4) O(n4),其中 n n n 是矩阵 img 1 \textit{img}_1 img1 img 2 \textit{img}_2 img2 的边长。枚举水平方向和竖直方向的移动单位数各需要 O ( n ) O(n) O(n) 的时间,因此所有可能的转换数为 O ( n 2 ) O(n^2) O(n2),对于每种转换,需要 O ( n 2 ) O(n^2) O(n2) 的时间计算两个图像的重叠,因此总时间复杂度是 O ( n 4 ) O(n^4) O(n4)

  • 空间复杂度: O ( 1 ) O(1) O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟大的车尔尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值