直接找出所有1的位置,然后对两个矩阵的所有这些位置进行求差。然后统计这些差出现最多的次数是多少。
两个坐标的差是什么含义?就是把其中一个坐标移动到另一个坐标需要移动的向量。因此,在遍历过程中,我们找出了A中所有值为1的坐标移动到B中所有值为1的坐标需要移动的向量。那么,在这些向量中出现次数最多的向量就是我们要求的整个矩阵应该移动的向量。这个向量出现的次数,就是我们向该向量方向移动了之后,能重叠的1的个数。
寒神的做法的优点:第一,注意到了题目给的A和B是大小相等的正方形!第二,遍历正方形的方式使用的是i在[0,NN]区间里,然后 [i/N][i%N] 这个求位置方法,可以把两重循环简写成一重(但是时间复杂没有变化)。第三,使用了数字表示向量,即把一个向量的行数100+列数,比如第13行第19列,可以用一个数字表示1319。寒神告诉我们,这个100的选择是因为太小的话不能有效区分,应该最小是2N。
public int largestOverlap(int[][] A, int[][] B) {
int N = A.length;
List<Integer> LA = new ArrayList<>();
List<Integer> LB = new ArrayList<>();
HashMap<Integer, Integer> count = new HashMap<>();
for (int i = 0; i < N * N; ++i) if (A[i / N][i % N] == 1) LA.add(i / N * 100 + i % N);
for (int i = 0; i < N * N; ++i) if (B[i / N][i % N] == 1) LB.add(i / N * 100 + i % N);
for (int i : LA) for (int j : LB)
count.put(i - j, count.getOrDefault(i - j, 0) + 1);
int res = 0;
for (int i : count.values()) res = Math.max(res, i);
return res;
}
转载于:https://blog.51cto.com/f1yinsky/2376421