Open In App

Minimum number of bricks that can be intersected

Improve
Improve
Like Article
Like
Save
Share
Report

Given a 2D array arr[][], representing width of bricks of the same height present on a wall, the task is to find the minimum number of bricks that can be intersected by drawing a straight line from the top to the bottom of the wall. 
Note: A line is said to intersect a brick if it passes through the brick and is non-intersecting if it is touching a brick’s boundary.

Examples:

Input: arr[][] = {{1, 2, 2, 1}, {3, 1, 2}, {1, 3, 2}, {2, 4}, {3, 1, 2}, {1, 3, 1, 1}}

Output: 2
Explanation: Considering the top left corner of the 2D array as the origin, the line is drawn at the coordinate x = 4 on the x-axis, such that it crosses the bricks on the 1st and 4th level, resulting in the minimum number of bricks crossed.

Input: arr[][] = {{1, 1, 1}}
Output: 0
Explanation: The line can be drawn at x = 1 or x = 2 coordinate on the x-axis such that it does not cross any brick resulting in the minimum number of bricks crossed.

Naive Approach: The simplest approach is to consider straight lines that can be drawn on every possible coordinate on the x-axis, along the width of the wall, considering x = 0 at the top left corner of the wall. Then, calculate the number of bricks inserted in each case and print the minimum count obtained. 

Time Complexity: O(N * M) where N is the total number of bricks and M is the total width of the wall
Auxiliary Space: O(1) 

Approach: To optimize the above approach, the idea is to store the number of bricks ending at a certain width on the x-axis in a hashmap, and then find the line where the most number of bricks end. After getting this count, subtract it from the total height of the wall to get the minimum number of bricks crossed. 

Follow the steps below to solve the problem:

  • Initialize a hashmap, M to store the number of bricks ending at a certain width on the x-axis.
  • Traverse the array, arr using the variable i to store row index
    • Initialize a variable, width as 0 to store the ending position.
    • Store the size of the current row in a variable X.
    • Iterate in the range [0, X-2] using the variable j
      • Increment the value of width by arr[i][j] and increment the value of width in M by 1.
      • Also, keep track of the most number of bricks ending at a certain width and store it in a variable, res.
  • Subtract the value of res from the overall height of the wall and store it in a variable, ans.
  • Print the value of ans as the result.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find a line across a wall such
// that it intersects minimum number of bricks
void leastBricks(vector<vector<int> > wall)
{
    // Declare a hashmap
    unordered_map<int, int> map;
 
    // Store the maximum number of
    // brick ending a point on x-axis
    int res = 0;
 
    // Iterate over all the rows
    for (vector<int> list : wall) {
 
        // Initialize width as 0
        int width = 0;
 
        // Iterate over individual bricks
        for (int i = 0; i < list.size() - 1; i++) {
 
            // Add the width of the current
            // brick to the total width
            width += list[i];
 
            // Increment number of bricks
            // ending at this width position
            map[width]++;
 
            // Update the variable, res
            res = max(res, map[width]);
        }
    }
 
    // Print the answer
    cout << wall.size() - res;
}
 
// Driver Code
int main()
{
    // Given Input
    vector<vector<int> > arr{
        { 1, 2, 2, 1 }, { 3, 1, 2 },
        { 1, 3, 2 }, { 2, 4 },
        { 3, 1, 2 }, { 1, 3, 1, 1 }
    };
 
    // Function Call
    leastBricks(arr);
 
    return 0;
}


Java




// Java program for the above approach
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
 
public class GFG
{
 
    // Function to find a line across a wall such
    // that it intersects minimum number of bricks
    static void leastBricks(ArrayList<ArrayList<Integer> > wall)
    {
       
        // Declare a hashmap
        HashMap<Integer, Integer> map = new HashMap<>();
 
        // Store the maximum number of
        // brick ending a point on x-axis
        int res = 0;
 
        // Iterate over all the rows
        for (ArrayList<Integer> list : wall) {
 
            // Initialize width as 0
            int width = 0;
 
            // Iterate over individual bricks
            for (int i = 0; i < list.size() - 1; i++) {
 
                // Add the width of the current
                // brick to the total width
                width += list.get(i);
 
                // Increment number of bricks
                // ending at this width position
                map.put(width,
                        map.getOrDefault(width, 0) + 1);
 
                // Update the variable, res
                res = Math.max(res,
                               map.getOrDefault(width, 0));
            }
        }
 
        // Print the answer
        System.out.println(wall.size() - res);
    }
 
    // Driver code
    public static void main(String[] args)
    {
      // Given Input
        ArrayList<ArrayList<Integer> > arr
            = new ArrayList<>();
        arr.add(new ArrayList<>(Arrays.asList(1, 2, 2, 1)));
        arr.add(new ArrayList<>(Arrays.asList(3, 1, 2)));
        arr.add(new ArrayList<>(Arrays.asList(1, 3, 2)));
        arr.add(new ArrayList<>(Arrays.asList(2, 4)));
        arr.add(new ArrayList<>(Arrays.asList(3, 1, 2)));
        arr.add(new ArrayList<>(Arrays.asList(1, 3, 1, 1)));
 
        // Function Call
        leastBricks(arr);
    }
}
 
// This code is contributed by abhinavjain194


Python3




# Python 3 program for the above approach
from collections import defaultdict
 
# Function to find a line across a wall such
# that it intersects minimum number of bricks
def leastBricks(wall):
 
    # Declare a hashmap
    map = defaultdict(int)
 
    # Store the maximum number of
    # brick ending a point on x-axis
    res = 0
 
    # Iterate over all the rows
    for list in wall:
 
        # Initialize width as 0
        width = 0
 
        # Iterate over individual bricks
        for i in range(len(list) - 1):
 
            # Add the width of the current
            # brick to the total width
            width += list[i]
 
            # Increment number of bricks
            # ending at this width position
            map[width] += 1
 
            # Update the variable, res
            res = max(res, map[width])
 
    # Print the answer
    print(len(wall) - res)
 
 
# Driver Code
if __name__ == "__main__":
 
    # Given Input
    arr = [
        [1, 2, 2, 1], [3, 1, 2],
        [1, 3, 2], [2, 4],
        [3, 1, 2], [1, 3, 1, 1]
    ]
 
    # Function Call
    leastBricks(arr)
 
    # This code is contributed by ukasp.


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
  
// Function to find a line across a wall such
// that it intersects minimum number of bricks
static void leastBricks(List<List<int>> wall)
{
     
    // Declare a hashmap
    Dictionary<int,
               int> map = new Dictionary<int,
                                         int>();
 
    // Store the maximum number of
    // brick ending a point on x-axis
    int res = 0;
 
    // Iterate over all the rows
    foreach (List<int> subList in wall)
    {
         
        // Initialize width as 0
        int width = 0;
        for(int i = 0; i < subList.Count - 1; i++)
        {
             
            // Add the width of the current
            // brick to the total width
            width += subList[i];
             
            // Increment number of bricks
            // ending at this width position
            if (map.ContainsKey(width))
                map[width]++;
            else
                map.Add(width, 1);
             
            // Update the variable, res
            res = Math.Max(res, map[width]);
        }
    }
 
    // Print the answer
    Console.Write(wall.Count-res);
}
 
// Driver Code
public static void Main()
{
     
    // Given Input
    List<List<int>> myList = new List<List<int>>();
    myList.Add(new List<int>{ 1, 2, 2, 1 });
    myList.Add(new List<int>{ 3, 1, 2 });
    myList.Add(new List<int>{ 1, 3, 2 });
    myList.Add(new List<int>{ 2, 4 });
    myList.Add(new List<int>{ 3, 1, 2 });
    myList.Add(new List<int>{ 1, 3, 1, 1 });
     
    // Function Call
    leastBricks(myList);
}
}
 
// This code is contributed by bgangwar59


Javascript




<script>
 
// JavaScript program for the above approach
 
 
// Function to find a line across a wall such
// that it intersects minimum number of bricks
function leastBricks(wall) {
    // Declare a hashmap
    let map = new Map();
 
    // Store the maximum number of
    // brick ending a point on x-axis
    let res = 0;
 
    // Iterate over all the rows
    for (let list of wall) {
 
        // Initialize width as 0
        let width = 0;
 
        // Iterate over individual bricks
        for (let i = 0; i < list.length - 1; i++) {
 
            // Add the width of the current
            // brick to the total width
            width += list[i];
 
            // Increment number of bricks
            // ending at this width position
            if (map.has(width)) {
                map.set(width, map.get(width) + 1);
            } else {
                map.set(width, 1)
            }
 
            // Update the variable, res
            res = Math.max(res, map.get(width));
        }
    }
 
    // Print the answer
    document.write(wall.length - res);
}
 
// Driver Code
 
// Given Input
let arr = [
    [1, 2, 2, 1], [3, 1, 2],
    [1, 3, 2], [2, 4],
    [3, 1, 2], [1, 3, 1, 1]
];
 
// Function Call
leastBricks(arr);
 
</script>


Output: 

2

 

Time Complexity: O(N) where N is the total number of bricks on the wall
Auxiliary Space: O(M) where M is the total width of the wall



Last Updated : 30 Jun, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads