码迷,mamicode.com
首页 > 其他好文 > 详细

Image Overlap LT835

时间:2019-05-04 09:19:34      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:like   special   position   ase   HERE   style   rom   slide   out   

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. 1 <= A.length = A[0].length = B.length = B[0].length <= 30
  2. 0 <= A[i][j], B[i][j] <= 1

Idea 1. Fix image A, there are 4 directions to move image B, moving up (+rowOffset), moving down (-rowOffset),

moving left(+colOffset), moving right(-colOffset)

For example, moving up and left (1, 1),  for the first cell, i=0, j = 0, A[i][j] -> B[i+1][j+1],

  A[0][0]: B[1][1], A[0][1]: B[1][2], A[1][1]: B[2][2],    A[2][2] -> B[3][3] out of boundary

Time complexity: O(n^4)

Space complexity: O(1)

 1 class Solution {
 2     public int largestOverlap(int[][] A, int[][] B) {
 3         int result = 0;
 4         int aM = A.length;
 5         int aN = A[0].length;
 6         
 7         int bM = B.length;
 8         int bN = B[0].length;
 9         
10         for(int rOffset = -bM; rOffset < bM; ++rOffset) {
11             for(int cOffset = -bN; cOffset < bN; ++cOffset) {
12                 int curr = 0;
13                 for(int i = 0; i < aM; ++i) {
14                     for(int j = 0; j < aN; ++j) {
15                         if(A[i][j] == 1 &&(i + rOffset >= 0 && i + rOffset < bM
16                                           && j + cOffset >=0 && j + cOffset < bN
17                                           && B[i+rOffset][j+cOffset] == 1)) {
18                             ++curr;
19                         }
20                     }
21                 }
22                 result = Math.max(result, curr);
23             }
24         }
25         
26         return result;
27     }
28 }

Idea 2. Instead of doing 2N horizonal sliding, 2N vertical Sliding and counting N^2 overlap areas like idea 1, especially if the matrix is sparse, extracting the positions of all the ones in A and B, doing a pairwise match, if the difference A[i][j] = 1, B[p][q] = 1, moving B[p][q] to A[i][j] needs [p-i, q - j] offset movement, looping all pairs of ones and accumulate the ones with the same offset, how to store the sum by the offset? 2-D array or 1-D array or HashMap?

Note. transfer index from 2D to 1D, normally (i, j) -> (i*N + j), but this does not guarantee uniqueness, different (i, j) pair could map to the same (i*N + j), (1, -1) and (0, 1) to 1 where N = 2, or alternatively, map the range (-N , N) to (0, N), i * 2N + j instead

Time complexity: O(N^4)

Space complexity: O(N^2)

 1 class Solution {
 2     public int largestOverlap(int[][] A, int[][] B) {
 3         int N = A.length;        
 4         
 5         int[][] count = new int[2*N][2*N];
 6         for(int i = 0; i < N; ++i) {
 7             for(int j = 0; j < N; ++j) {
 8                 if(A[i][j] == 1) {
 9                     for(int p = 0; p < N; ++p) {
10                         for(int q = 0; q < N; ++q) {
11                             if(B[p][q] == 1) {
12                                 ++count[i-p + N][j-q + N];
13                             }
14                         }
15                     }
16                 }
17             }
18         }
19         
20         int result = 0;
21         for(int[] row: count) {
22             for(int val: row) {
23                 result = Math.max(result, val);
24             }
25         }
26         return result;
27     }
28 }

Idea 2.b getting all pairs of ones first(N^2), instead of 4 loops (N^4), 1D as key

Time complexity: O(N^2 + La * Lb), worst case, dense matrix La* Lb = O(N^4)

Space complexity: O(N^2)

 1 class Solution {
 2     public int largestOverlap(int[][] A, int[][] B) {
 3         int N = A.length;        
 4         
 5         List<int[]> La = new ArrayList<>();
 6         List<int[]> Lb = new ArrayList<>();
 7         
 8         for(int i = 0; i < N; ++i) {
 9             for(int j = 0; j < N; ++j) {
10                 if(A[i][j] == 1) {
11                     La.add(new int[] {i, j});
12                 }
13                 if(B[i][j] == 1) {
14                     Lb.add(new int[] {i, j});
15                 }
16             }
17         }
18         
19         Map<Integer, Integer> count = new HashMap<>();
20         for(int[] a: La) {
21             for(int[] b: Lb) {
22                 int diff = (a[0] - b[0] + N)* 2*N + (a[1] - b[1] + N);
23                 count.put(diff, count.getOrDefault(diff, 0) + 1);
24             }
25         }
26        
27         int result = 0;
28         for(int val: count.values()) {
29             result = Math.max(result, val);
30         }
31         
32         return result;
33     }
34 }

String : i0 - i1 + " " + j0 - j1

 1 class Solution {
 2     public int largestOverlap(int[][] A, int[][] B) {
 3         int N = A.length;        
 4         
 5         List<int[]> La = new ArrayList<>();
 6         List<int[]> Lb = new ArrayList<>();
 7         
 8         for(int i = 0; i < N; ++i) {
 9             for(int j = 0; j < N; ++j) {
10                 if(A[i][j] == 1) {
11                     La.add(new int[] {i, j});
12                 }
13                 if(B[i][j] == 1) {
14                     Lb.add(new int[] {i, j});
15                 }
16             }
17         }
18         
19         Map<String, Integer> count = new HashMap<>();
20         for(int[] a: La) {
21             for(int[] b: Lb) {
22                 String key = (a[0] - b[0]) + " " + (a[1] - b[1]);
23                 count.put(key, count.getOrDefault(key, 0) + 1);
24             }
25         }
26         
27         int result = 0;
28         for(int val: count.values()) {
29             result = Math.max(result, val);
30         }
31         return result;
32     }
33 }

 

Image Overlap LT835

标签:like   special   position   ase   HERE   style   rom   slide   out   

原文地址:https://www.cnblogs.com/taste-it-own-it-love-it/p/10807475.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!