1. 程式人生 > >Leetcode:835. 圖像重疊

Leetcode:835. 圖像重疊

註意 時間 .com 變化 出了 return 什麽 urn res

直接找出所有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;
}

Leetcode:835. 圖像重疊