You are given two images img1 and img2 both of size n x n, represented as binary, square matrices of the same size. (A binary matrix has only 0s and 1s as values.)
We translate one image however we choose (sliding it left, right, up, or down any number of units), and place it on top of the other image. After, the overlap of this translation is the number of positions that have a 1 in both images.
(Note also that a translation does not include any kind of rotation.)
What is the largest possible overlap?
Example 1:
Input: img1 = [[1,1,0],[0,1,0],[0,1,0]], img2 = [[0,0,0],[0,1,1],[0,0,1]]
Output: 3
Explanation: We slide img1 to right by 1 unit and down by 1 unit.
求两个image的overlap,overlap是指重叠到一块的时候相同位置都是1的个数。
img1和img2都可上下左右移动,但不能翻转。
思路:
普通的img shift一般是往右移一格一格移,移到边界的时候下移一行再右移。暂且称为右下移动。
但是这里img可以4个方向shift,左上,左下,右上,右下
粗暴的方法就是每个方向写一个循环,每个循环里找最大的overlap,但是可以思考一下,
img1和img2叠在一起的时候,img1向上移动就相当于img2向下移动,同理左右移动。所以img1循环右下的时候,(1) img1和img2调换一下位置(img2右下),就变成了img1左上。这样就解决了2个方向。
同时,(2) img1循环右下的时候,比如走到了(0,1)位置,第一个overlap的位置是看img1[0][1]和img2[0][0]是否相等,把两个img的列换一下,img1[0][0]和img2[0][1]就相当于img2右移,也就是img1左移。那么循环右下的时候同时解决了左下和右下两个方向。
(2) (1)结合,img1循环右下,调换列,解决了左下和右下两个方向,再调换img1和img2的位置,就在一个循环里解决了四个方向。在4个方向里找最大的overlap。
但是时间复杂度是不变的,都是O(N4)
class Solution {
int row = 0;
int col = 0;
public int largestOverlap(int[][] img1, int[][] img2) {
row = img1.length;
col = img1[0].length;
int result = 0;
for(int i = 0; i < row; i++) { //row shift
for(int j = 0; j < col; j++) { //col shift
result = Math.max(result, count(i, j, img1, img2));
result = Math.max(result, count(i, j, img2, img1));
}
}
return result;
}
int count(int sr, int sc, int[][] img1, int[][] img2) {
int overlap1 = 0;
int overlap2 = 0;
for(int i = sr; i < row; i++) {
for(int j = sc; j < col; j++) {
overlap1 += img1[i-sr][j-sc] & img2[i][j]; //right shift
overlap2 += img1[i-sr][j] & img2[i][j-sc]; //left shift
}
}
return Math.max(overlap1, overlap2);
}
}