Open In App

Maximum image overlap on given binary Matrices

Last Updated : 18 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given two images represented as binary square matrices, matrix1[] and matrix2[] of size n x n, the task is to find the largest possible overlap of 1 in both matrices by translating one matrix over other any number of times to left, right, up, and/or down without any rotation.

Note: Any 1-bit translated outside the matrix borders is erased.

Examples:

Input: matrix1 = { { 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 1, 0, 0 } },

matrix2 = { { 0, 0, 1, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 1, 0 } }
Output: 2

Translation of Matrix

Explanation: Maximum number of overlapping of 1 by translating one matrix over other is 2.

Input: matrix1 = {{0}}, matrix2 = {{0}}
Output: 0

Approach: To solve the problem follow the below idea:

  • Explore all possible translations (left, right, up, and down) of one matrix and calculate the overlap count with the other matrices for each translation.
  • The maximum overlap count obtained from all translations gives us the largest possible overlap between the two matrices.
  • By considering all translations, we ensure that we find the optimal placement of the matrices to get the maximum overlap.

Step-by-step approach:

  • Create a list of directions to explore, where each direction corresponds to a specific shift in x and y directions: dir = {{1, 1}, {-1, 1}, {1, -1}, {-1, -1}}.
  • Loop through each direction d in the direction list.
    • Loop through each cell (i, j) in the matrix1.
      • For each cell (i, j), calculate the overlap count by calling the overlapCount function with the current direction’s shift values.
      • Update the maximum overlap count result by taking the maximum between the current result and the calculated overlap count.
  • Return the final maximum overlap count result.

Below are the implementation of the above approach:

C++




#include <bits/stdc++.h>
using namespace std;
 
// Function to calculate the number of
// overlapping 1s between two matrices
// after a given shift.
int overlapCount(vector<vector<int> >& mat1,
                 vector<vector<int> >& mat2, int shiftX,
                 int shiftY)
{
    int n = mat1.size(), count = 0;
 
    // Loop over each cell in the matrix1 (mat1).
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
 
            // Check if the shifted cell position
            // is within the boundaries of both
            // matrices and if both cells have 1s.
            if (i + shiftX >= 0 && j + shiftY >= 0
                && i + shiftX < n && j + shiftY < n
                && mat1[i][j] * mat2[i + shiftX][j + shiftY]
                       == 1) {
 
                // If the condition is met,
                // increment the count.
                count++;
            }
        }
    }
 
    // Return the total count of overlapping
    // 1s after the given shift.
    return count;
}
 
// Function to find the largest possible overlap
// between two matrices.
int largestOverlap(vector<vector<int> >& mat1,
                   vector<vector<int> >& mat2)
{
    int n = mat1.size(), result = 0;
 
    // Create a list of directions to explore.
    // Each direction corresponds to a specific
    // shift in x and y directions.
    vector<vector<int> > dir
        = { { 1, 1 }, { -1, 1 }, { 1, -1 }, { -1, -1 } };
 
    // Loop through each direction and each cell
    // in the matrix1 (mat1).
    for (int d = 0; d < 4; d++) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
 
                // Calculate the overlap count
                // by applying the given shift
                // in the current direction.
                int res = overlapCount(mat1, mat2,
                                       i * dir[d][0],
                                       j * dir[d][1]);
 
                // Update the maximum overlap
                // count found so far.
                result = max(result, res);
            }
        }
    }
 
    // Return the largest possible overlap found.
    return result;
}
 
// Driver code
int main()
{
 
    // Input matrix
    vector<vector<int> > mat1 = { { 0, 0, 0, 0 },
                                  { 0, 0, 0, 0 },
                                  { 0, 1, 0, 0 },
                                  { 0, 1, 0, 0 } };
 
    vector<vector<int> > mat2 = { { 0, 0, 1, 0 },
                                  { 0, 0, 1, 0 },
                                  { 0, 0, 0, 0 },
                                  { 0, 0, 1, 0 } };
 
    // Function call
    cout << largestOverlap(mat1, mat2);
 
    return 0;
}


Java




import java.util.*;
 
public class MatrixOverlap {
 
    // Function to calculate the number of overlapping 1s
    // between two matrices after a given shift.
    static int overlapCount(int[][] mat1, int[][] mat2,
                            int shiftX, int shiftY)
    {
        int n = mat1.length;
        int count = 0;
 
        // Loop over each cell in the matrix1 (mat1).
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
 
                // Check if the shifted cell position is
                // within the boundaries of both matrices
                // and if both cells have 1s.
                if (i + shiftX >= 0 && j + shiftY >= 0
                    && i + shiftX < n && j + shiftY < n
                    && mat1[i][j]
                               * mat2[i + shiftX]
                                     [j + shiftY]
                           == 1) {
 
                    // If the condition is met, increment
                    // the count.
                    count++;
                }
            }
        }
 
        // Return the total count of overlapping 1s after
        // the given shift.
        return count;
    }
 
    // Function to find the largest possible overlap between
    // two matrices.
    static int largestOverlap(int[][] mat1, int[][] mat2)
    {
        int n = mat1.length;
        int result = 0;
 
        // Create a list of directions to explore. Each
        // direction corresponds to a specific shift in x
        // and y directions.
        int[][] dir = {
            { 1, 1 }, { -1, 1 }, { 1, -1 }, { -1, -1 }
        };
 
        // Loop through each direction and each cell in the
        // matrix1 (mat1).
        for (int d = 0; d < 4; d++) {
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
 
                    // Calculate the overlap count by
                    // applying the given shift in the
                    // current direction.
                    int res = overlapCount(mat1, mat2,
                                           i * dir[d][0],
                                           j * dir[d][1]);
 
                    // Update the maximum overlap count
                    // found so far.
                    result = Math.max(result, res);
                }
            }
        }
 
        // Return the largest possible overlap found.
        return result;
    }
 
    // Driver code
    public static void main(String[] args)
    {
 
        // Input matrix
        int[][] mat1 = { { 0, 0, 0, 0 },
                         { 0, 0, 0, 0 },
                         { 0, 1, 0, 0 },
                         { 0, 1, 0, 0 } };
 
        int[][] mat2 = { { 0, 0, 1, 0 },
                         { 0, 0, 1, 0 },
                         { 0, 0, 0, 0 },
                         { 0, 0, 1, 0 } };
 
        // Function call
        System.out.println(largestOverlap(mat1, mat2));
    }
}


Python3




# Function to calculate the number of overlapping 1s
# between two matrices after a given shift.
def overlapCount(mat1, mat2, shiftX, shiftY):
    n = len(mat1)
    count = 0
 
    # Loop over each cell in matrix1 (mat1).
    for i in range(n):
        for j in range(n):
 
            # Check if the shifted cell position is within the boundaries
            #  of both matrices and if both cells have 1s.
            if (
                i + shiftX >= 0
                and j + shiftY >= 0
                and i + shiftX < n
                and j + shiftY < n
                and mat1[i][j] * mat2[i + shiftX][j + shiftY] == 1
            ):
 
                # If the condition is met, increment the count.
                count += 1
 
    # Return the total count of
    # overlapping 1s after the given shift.
    return count
 
# Function to find the largest
# possible overlap between two matrices.
def largestOverlap(mat1, mat2):
    n = len(mat1)
    result = 0
 
    # Create a list of directions to explore.
    # Each direction corresponds to a specific shift in x and y directions.
    dir = [(1, 1), (-1, 1), (1, -1), (-1, -1)]
 
    # Loop through each direction
    # and each cell in matrix1 (mat1).
    for d in range(4):
        for i in range(n):
            for j in range(n):
 
                # Calculate the overlap count by
                # applying the given shift in the current direction.
                res = overlapCount(mat1, mat2, i * dir[d][0], j * dir[d][1])
 
                # Update the maximum overlap count found so far.
                result = max(result, res)
 
    # Return the largest possible overlap found.
    return result
 
# Driver code
if __name__ == "__main__":
    # Input matrix
    mat1 = [
        [0, 0, 0, 0],
        [0, 0, 0, 0],
        [0, 1, 0, 0],
        [0, 1, 0, 0],
    ]
 
    mat2 = [
        [0, 0, 1, 0],
        [0, 0, 1, 0],
        [0, 0, 0, 0],
        [0, 0, 1, 0],
    ]
 
    # Function call
    print(largestOverlap(mat1, mat2))
# This code is contributed by 2302adityaprakash


C#




using System;
using System.Collections.Generic;
 
public class GFG
{
    // Function to calculate the number of overlapping 1s between two matrices after a given shift.
    static int OverlapCount(List<List<int>> mat1, List<List<int>> mat2, int shiftX, int shiftY)
    {
        int n = mat1.Count, count = 0;
 
        // Loop over each cell in the matrix1 (mat1).
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                // Check if the shifted cell position is within the boundaries of
                // both matrices and if both cells have 1s.
                if (i + shiftX >= 0 && j + shiftY >= 0 &&
                    i + shiftX < n && j + shiftY < n &&
                    mat1[i][j] * mat2[i + shiftX][j + shiftY] == 1)
                {
                    // If the condition is met, increment the count.
                    count++;
                }
            }
        }
 
        // Return the total count of overlapping 1s after the given shift.
        return count;
    }
 
    // Function to find the largest possible overlap between two matrices.
    static int LargestOverlap(List<List<int>> mat1, List<List<int>> mat2)
    {
        int n = mat1.Count, result = 0;
 
        // Create a list of directions to explore. Each direction corresponds to a specific shift in x and y directions.
        List<List<int>> dir = new List<List<int>> { new List<int> { 1, 1 }, new List<int> { -1, 1 }, new List<int> { 1, -1 }, new List<int> { -1, -1 } };
 
        // Loop through each direction and each cell in the matrix1 (mat1).
        for (int d = 0; d < 4; d++)
        {
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    // Calculate the overlap count by applying the given shift in the current direction.
                    int res = OverlapCount(mat1, mat2, i * dir[d][0], j * dir[d][1]);
 
                    // Update the maximum overlap count found so far.
                    result = Math.Max(result, res);
                }
            }
        }
 
        // Return the largest possible overlap found.
        return result;
    }
 
    // Driver code
    public static void Main()
    {
        // Input matrices
        List<List<int>> mat1 = new List<List<int>> {
            new List<int> { 0, 0, 0, 0 },
            new List<int> { 0, 0, 0, 0 },
            new List<int> { 0, 1, 0, 0 },
            new List<int> { 0, 1, 0, 0 }
        };
 
        List<List<int>> mat2 = new List<List<int>> {
            new List<int> { 0, 0, 1, 0 },
            new List<int> { 0, 0, 1, 0 },
            new List<int> { 0, 0, 0, 0 },
            new List<int> { 0, 0, 1, 0 }
        };
 
        // Function call
        Console.WriteLine(LargestOverlap(mat1, mat2));
    }
}


Javascript




// Function to calculate the number of
// overlapping 1s between two matrices
// after a given shift.
function overlapCount(mat1, mat2, shiftX, shiftY) {
    const n = mat1.length;
    let count = 0;
 
    // Loop over each cell in the matrix1 (mat1).
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < n; j++) {
 
            // Check if the shifted cell position
            // is within the boundaries of both
            // matrices and if both cells have 1s.
            if (
                i + shiftX >= 0 && j + shiftY >= 0 &&
                i + shiftX < n && j + shiftY < n &&
                mat1[i][j] * mat2[i + shiftX][j + shiftY] === 1
            ) {
 
                // If the condition is met,
                // increment the count.
                count++;
            }
        }
    }
 
    // Return the total count of overlapping
    // 1s after the given shift.
    return count;
}
 
// Function to find the largest possible overlap
// between two matrices.
function largestOverlap(mat1, mat2) {
    const n = mat1.length;
    let result = 0;
 
    // Create a list of directions to explore.
    // Each direction corresponds to a specific
    // shift in x and y directions.
    const dir = [
        [1, 1], [-1, 1], [1, -1], [-1, -1]
    ];
 
    // Loop through each direction and each cell
    // in the matrix1 (mat1).
    for (let d = 0; d < 4; d++) {
        for (let i = 0; i < n; i++) {
            for (let j = 0; j < n; j++) {
 
                // Calculate the overlap count
                // by applying the given shift
                // in the current direction.
                const res = overlapCount(mat1, mat2,
                    i * dir[d][0],
                    j * dir[d][1]);
 
                // Update the maximum overlap
                // count found so far.
                result = Math.max(result, res);
            }
        }
    }
 
    // Return the largest possible overlap found.
    return result;
}
 
// Driver code
// Input matrices
const mat1 = [
    [0, 0, 0, 0],
    [0, 0, 0, 0],
    [0, 1, 0, 0],
    [0, 1, 0, 0]
];
 
const mat2 = [
    [0, 0, 1, 0],
    [0, 0, 1, 0],
    [0, 0, 0, 0],
    [0, 0, 1, 0]
];
 
// Function call
console.log(largestOverlap(mat1, mat2));


Output

2

Time Complexity: O(n4)
Auxiliary Space: O(1)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads