LeetCode 835.图像重叠:暴力模拟O(n^4)

【LetMeFly】835.图像重叠:暴力模拟O(n^4)

力扣题目链接:https://leetcode.cn/problems/image-overlap/

给你两个图像 img1img2 ,两个图像的大小都是 n x n ,用大小相同的二进制正方形矩阵表示。二进制矩阵仅由若干 0 和若干 1 组成。

转换 其中一个图像,将所有的 1 向左,右,上,或下滑动任何数量的单位;然后把它放在另一个图像的上面。该转换的 重叠 是指两个图像 具有 1 的位置的数目。

请注意,转换 不包括 向任何方向旋转。越过矩阵边界的 1 都将被清除。

最大可能的重叠数量是多少?

 

示例 1:

输入:img1 = [[1,1,0],[0,1,0],[0,1,0]], img2 = [[0,0,0],[0,1,1],[0,0,1]]
输出:3
解释:将 img1 向右移动 1 个单位,再向下移动 1 个单位。

两个图像都具有 1 的位置的数目是 3(用红色标识)。

示例 2:

输入:img1 = [[1]], img2 = [[1]]
输出:1

示例 3:

输入:img1 = [[0]], img2 = [[0]]
输出:0

 

提示:

  • n == img1.length == img1[i].length
  • n == img2.length == img2[i].length
  • 1 <= n <= 30
  • img1[i][j]01
  • img2[i][j]01

解题方法:暴力模拟

img1最多往上移动 n − 1 n-1 n1格,最多往下移动 n − 1 n-1 n1格,于是我们第一层循环使用dx − ( n − 1 ) -(n-1) (n1) n − 1 n-1 n1表示img1往下移动的格数;左右移动同理,第二层循环使用dy − ( n − 1 ) -(n-1) (n1) n − 1 n-1 n1表示img1往右移动的格数。

两层循环枚举了img1的所有可能移动方式,由于img1向下移动了dx格向右移动了dy格,所以img1[i][j]就会移动到img2[i+dx][j+dy]的位置。由 0 ≤ i < n 0\leq i\lt n 0i<n 0 ≤ i + d x < n 0\leq i+dx\lt n 0i+dx<n可以得出竖直方向的有效重叠范围是 0 ≤ i < n − d x 0\leq i\lt n-dx 0i<ndx,同理水平方向有 0 ≤ j < n − d y 0\leq j\lt n-dy 0j<ndy

第三层第四层循环则可分别使用变量i max ⁡ ( 0 , − d x ) \max(0,-dx) max(0,dx) min ⁡ ( n , n − d x ) \min(n,n-dx) min(n,ndx)和变量j max ⁡ ( 0 , − d y ) \max(0,-dy) max(0,dy) min ⁡ ( n , n − d y ) \min(n,n-dy) min(n,ndy),一个格子一个格子地计算在前两层循环的移动方式下,重叠的1有多少个。

  • 时间复杂度 O ( n 4 ) O(n^4) O(n4)
  • 空间复杂度 O ( 1 ) O(1) O(1)

AC代码

C++
/*
 * @LastEditTime: 2026-09-13 11:32:09
 */
class Solution {
public:
    int largestOverlap(vector<vector<int>>& img1, vector<vector<int>>& img2) {
        int ans = 0;
        int n = img1.size();
        for (int dx = 1 - n; dx < n; dx++) {  // [-(n-1), n-1]
            for (int dy = 1 - n; dy < n; dy++) {
                int this_ans = 0;
                // img1[i][j] -> img2[i+dx][j+dy]
                // 0≤i<n 且 0≤i+dx<n 得出 0≤i -dx≤i i<n i<n-dx
                for (int i = max(0, -dx); i < min(n, n-dx); i++) {
                    for (int j = max(0, -dy); j < min(n, n-dy); j++) {
                        this_ans += img1[i][j] * img2[i+dx][j+dy];
                    }
                }
                ans = max(ans, this_ans);
            }
        }
        return ans;
    }
};

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

千篇源码题解已开源

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Tisfy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值