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$格,于是我们第一层循环使用dx从$-(n-1)$到$n-1$表示img1往下移动的格数;左右移动同理,第二层循环使用dy从$-(n-1)$到$n-1$表示img1往右移动的格数。

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

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

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

AC代码

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
* @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和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

千篇源码题解已开源


835.图像重叠:暴力模拟O(n^4)
https://blog.letmefly.xyz/2026/09/13/LeetCode 0835.图像重叠/
作者
发布于
2026年9月13日
许可协议