Two images A
and B
are given, 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: A = [[1,1,0], [0,1,0], [0,1,0]] B = [[0,0,0], [0,1,1], [0,0,1]] Output: 3 Explanation: We slide A to right by 1 unit and down by 1 unit.
Notes:
1 <= A.length = A[0].length = B.length = B[0].length <= 30
0 <= A[i][j], B[i][j] <= 1
图像重叠。题意是给两个尺寸相同的二维矩阵A和B,转换其中一个图像,转换的方式是只能上下左右平移,不能旋转。请问如何平移,能使两个矩阵重叠。重叠的定义是两个图像重叠的部分都是由1组成。
我这里提供一个比较朴素的思路。因为两个矩阵A和B的尺寸是相同的,所以可以把两个矩阵分别扫描一遍,把两个矩阵内所有是1的坐标拿出来存在一个list中。然后用一个O(n^2)级别的循环,两两比较从A拿出来的每个1的坐标和从B拿出来的每个1的坐标的坐标差。坐标差用一个string表示(横坐标差 + "" + 纵坐标差),把这个string当做key放入hashmap,同时统计这个坐标差出现的次数。出现次数最多的坐标差就是能重叠的1的个数。
时间O(n^2)
空间O(n) - hashmap + list
Java实现
1 class Solution { 2 public int largestOverlap(int[][] A, int[][] B) { 3 int rows = A.length; 4 int cols = A[0].length; 5 // two lists to save pixel coordinates 6 List<int[]> la = new ArrayList<>(); 7 List<int[]> lb = new ArrayList<>(); 8 for (int r = 0; r < rows; r++) { 9 for (int c = 0; c < cols; c++) { 10 if (A[r][c] == 1) { 11 la.add(new int[] { r, c }); // save the pixel coordinates 12 } 13 if (B[r][c] == 1) { 14 lb.add(new int[] { r, c }); 15 } 16 } 17 } 18 // map to map the vector (from a pixel in A to a pixel in B) to its count 19 HashMap<String, Integer> map = new HashMap<>(); 20 for (int[] pa : la) { 21 for (int[] pb : lb) { 22 // get the vector from a pixel in A to a pixel in B 23 String s = (pa[0] - pb[0]) + " " + (pa[1] - pb[1]); 24 // count the number of same vectors 25 map.put(s, map.getOrDefault(s, 0) + 1); 26 } 27 } 28 int max = 0; 29 for (int count : map.values()) { 30 max = Math.max(max, count); 31 } 32 return max; 33 } 34 }