← Static tasks

835. Image Overlap

leetcode

#array#bit-manipulation#csharp#leetcode#math#matrix#two-pointers

Task

С

ложность:

Вам даны два изображения, img1 и img2, представленные как бинарные квадратные матрицы размером n x n. Бинарная матрица содержит только 0 и 1 в качестве значений.

Мы можем сдвигать одно изображение как угодно, перемещая все биты 1 влево, вправо, вверх и/или вниз на любое количество единиц. Затем мы помещаем его поверх другого изображения. После этого мы можем вычислить перекрытие, подсчитав количество позиций, на которых в обоих изображениях есть 1.

Также обратите внимание, что при сдвиге не допускается никакое вращение. Любые биты 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 translate img1 to right by 1 unit and down by 1 unit.

C# solution

matched/original
public class Solution {
    public int ShiftAndCount(int xShift, int yShift, int[][] M, int[][] R) {
        int leftShiftCount = 0, rightShiftCount = 0;
        int rRow = 0;
        for (int mRow = yShift; mRow < M.Length; ++mRow) {
            int rCol = 0;
            for (int mCol = xShift; mCol < M.Length; ++mCol) {
                if (M[mRow][mCol] == 1 && M[mRow][mCol] == R[rRow][rCol])
                    leftShiftCount++;
                if (M[mRow][rCol] == 1 && M[mRow][rCol] == R[rRow][mCol])
                    rightShiftCount++;
                rCol++;
            }
            rRow++;
        }
        return Math.Max(leftShiftCount, rightShiftCount);
    }
    public int LargestOverlap(int[][] A, int[][] B) {
        int maxOverlaps = 0;
        for (int yShift = 0; yShift < A.Length; ++yShift) {
            for (int xShift = 0; xShift < A.Length; ++xShift) {
                maxOverlaps = Math.Max(maxOverlaps, ShiftAndCount(xShift, yShift, A, B));
                maxOverlaps = Math.Max(maxOverlaps, ShiftAndCount(xShift, yShift, B, A));
            }
        }
        return maxOverlaps;
    }
}

C++ solution

auto-draft, review before submit
#include <bits/stdc++.h>
using namespace std;

// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
class Solution {
public:
    public int ShiftAndCount(int xShift, int yShift, int[][] M, int[][] R) {
        int leftShiftCount = 0, rightShiftCount = 0;
        int rRow = 0;
        for (int mRow = yShift; mRow < M.size(); ++mRow) {
            int rCol = 0;
            for (int mCol = xShift; mCol < M.size(); ++mCol) {
                if (M[mRow][mCol] == 1 && M[mRow][mCol] == R[rRow][rCol])
                    leftShiftCount++;
                if (M[mRow][rCol] == 1 && M[mRow][rCol] == R[rRow][mCol])
                    rightShiftCount++;
                rCol++;
            }
            rRow++;
        }
        return max(leftShiftCount, rightShiftCount);
    }
    public int LargestOverlap(int[][] A, int[][] B) {
        int maxOverlaps = 0;
        for (int yShift = 0; yShift < A.size(); ++yShift) {
            for (int xShift = 0; xShift < A.size(); ++xShift) {
                maxOverlaps = max(maxOverlaps, ShiftAndCount(xShift, yShift, A, B));
                maxOverlaps = max(maxOverlaps, ShiftAndCount(xShift, yShift, B, A));
            }
        }
        return maxOverlaps;
    }
}

Java solution

matched/original
class Solution {
    protected int shiftAndCount(int xShift, int yShift, int[][] M, int[][] R) {
        int leftShiftCount = 0, rightShiftCount = 0;
        int rRow = 0;
        for (int mRow = yShift; mRow < M.length; ++mRow) {
            int rCol = 0;
            for (int mCol = xShift; mCol < M.length; ++mCol) {
                if (M[mRow][mCol] == 1 && M[mRow][mCol] == R[rRow][rCol])
                    leftShiftCount += 1;
                if (M[mRow][rCol] == 1 && M[mRow][rCol] == R[rRow][mCol])
                    rightShiftCount += 1;
                rCol += 1;
            }
            rRow += 1;
        }
        return Math.max(leftShiftCount, rightShiftCount);
    }

    public int largestOverlap(int[][] A, int[][] B) {
        int maxOverlaps = 0;

        for (int yShift = 0; yShift < A.length; ++yShift)
            for (int xShift = 0; xShift < A.length; ++xShift) {
                maxOverlaps = Math.max(maxOverlaps, shiftAndCount(xShift, yShift, A, B));
                maxOverlaps = Math.max(maxOverlaps, shiftAndCount(xShift, yShift, B, A));
            }

        return maxOverlaps;
    }

Python solution

matched/original
class Solution:
    def shiftAndCount(self, xShift, yShift, M, R):
        leftShiftCount = 0
        rightShiftCount = 0
        rRow = 0
        for mRow in range(yShift, len(M)):
            rCol = 0
            for mCol in range(xShift, len(M)):
                if M[mRow][mCol] == 1 and M[mRow][mCol] == R[rRow][rCol]:
                    leftShiftCount += 1
                if M[mRow][rCol] == 1 and M[mRow][rCol] == R[rRow][mCol]:
                    rightShiftCount += 1
                rCol += 1
            rRow += 1
        return max(leftShiftCount, rightShiftCount)

    def largestOverlap(self, A: List[List[int]], B: List[List[int]]) -> int:
        maxOverlaps = 0
        for yShift in range(len(A)):
            for xShift in range(len(A)):
                maxOverlaps = max(maxOverlaps, self.shiftAndCount(xShift, yShift, A, B))
                maxOverlaps = m

Go solution

matched/original
func shiftAndCount(xShift, yShift int, M, R [][]int) int {
    leftShiftCount, rightShiftCount := 0, 0
    rRow := 0
    for mRow := yShift; mRow < len(M); mRow++ {
        rCol := 0
        for mCol := xShift; mCol < len(M); mCol++ {
            if M[mRow][mCol] == 1 && M[mRow][mCol] == R[rRow][rCol] {
                leftShiftCount++
            }
            if M[mRow][rCol] == 1 && M[mRow][rCol] == R[rRow][mCol] {
                rightShiftCount++
            }
            rCol++
        }
        rRow++
    }
    return max(leftShiftCount, rightShiftCount)
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

func largestOverlap(A [][]int, B [][]int) int {
    maxOverlaps := 0
    for yShift := 0; yShift < len(A); yShift++ {
        for xShift := 0; xShift < len(A); xShift++ {
            maxOverlaps = max(maxOverlaps, shiftAndCount(xShift, yShift, A, B))
            maxOverlaps = max(maxOverlaps, shiftAndCount(xShift, yShift, B, A))
        }
    }
    return maxOverlaps
}

Explanation

Algorithm

Определите функцию shiftAndCount(xShift, yShift, M, R), которая смещает матрицу M относительно матрицы R на координаты (xShift, yShift) и подсчитывает количество единиц в зоне перекрытия.

Организуйте цикл по всем возможным комбинациям координат смещения (xShift, yShift).

На каждой итерации вызывайте функцию shiftAndCount() дважды для обоих направлений смещения и обновляйте максимальное количество перекрытий.

😎