~/DHRUVUpskilling
← board/DSA/Sliding Window/dsa-sliding-window-06
Backlog·queued

Maximize Area of Square Hole in Grid

DifficultyMedium
PatternSliding Window
TrackDSA
tl;dr

you can remove limited hbars and vbars return biggest square you can form

full write-up

Maximize Area of Square Hole in Grid

Problem

You are given two integers n and m, and two arrays hBars and vBars.

  • The grid has n + 2 horizontal bars and m + 2 vertical bars.
  • The bars are numbered from 1.
  • Together they make cells of size 1 x 1.

You can remove some bars from hBars (horizontal) and some bars from vBars (vertical). All other bars are fixed and cannot be removed.

Return the maximum area of a square-shaped hole you can make after removing bars (you may remove none).

Examples

Example 1

Input: n = 2, m = 1, hBars = [2,3], vBars = [2]
Output: 4
  • The horizontal bars are [1,2,3,4] and the vertical bars are [1,2,3].
  • Remove horizontal bar 2 and vertical bar 2.
  • The hole is 2 x 2, so the area is 4.

Example 2

Input: n = 1, m = 1, hBars = [2], vBars = [2]
Output: 4
  • Remove horizontal bar 2 and vertical bar 2.
  • The hole is 2 x 2, so the area is 4.

Example 3

Input: n = 2, m = 3, hBars = [2,3], vBars = [2,4]
Output: 4
  • Remove horizontal bar 3 and vertical bar 4.
  • The hole is 2 x 2, so the area is 4.
  • We cannot use both 2 and 4 in vBars together, because they are not next to each other.

Constraints

  • 1 <= n, m <= 10^9
  • 1 <= hBars.length, vBars.length <= 100
  • 2 <= hBars[i] <= n + 1
  • 2 <= vBars[i] <= m + 1
  • All values in hBars are distinct. All values in vBars are distinct.

Main Idea

Removing bars makes a bigger gap

  • Each cell is 1 x 1, so the gap between two neighbor bars is 1.
  • If we remove x bars that sit next to each other (like bars 2, 3, 4), the gap between the two bars around them becomes x + 1.
  • If the removed bars are not next to each other (like 2 and 4), they make separate gaps of size 2. They do not join into one bigger gap.

So only consecutive bars help us grow the hole.

A square needs equal width and height

  • Let hMax be the longest run of consecutive numbers in hBars. The tallest hole we can make has height hMax + 1.
  • Let vMax be the longest run of consecutive numbers in vBars. The widest hole we can make has width vMax + 1.
  • For a square, both sides must be equal. We can always remove fewer bars to make a smaller side.
  • So the biggest square side is min(hMax, vMax) + 1.

The answer is side * side.

Why is n and m not needed? Every bar in hBars and vBars is between 2 and n + 1 (or m + 1). The fixed outer bars 1 and n + 2 are never removed, so the gap always has a bar at each end. The values of n and m do not change the answer.

Solution: Sort and Find the Longest Streak

var maximizeSquareHoleArea = function (n, m, hBars, vBars) {
    // helper: find the longest run of consecutive numbers
    const getMaxConsecutive = (bars) => {
        bars.sort((a, b) => a - b);

        let maxStreak = 1;
        let currentStreak = 1;

        for (let i = 1; i < bars.length; i++) {
            if (bars[i] === bars[i - 1] + 1) {
                // next number in the run
                currentStreak++;
            } else {
                // run is broken, start again
                currentStreak = 1;
            }

            maxStreak = Math.max(maxStreak, currentStreak);
        }

        return maxStreak;
    };

    const hMax = getMaxConsecutive(hBars);
    const vMax = getMaxConsecutive(vBars);

    // the side is (removed bars + 1), and both sides must be equal
    const side = Math.min(hMax, vMax) + 1;

    return side * side;
};

How the Code Works

Step 1: Sort the bars

  • bars.sort((a, b) => a - b) puts the numbers in increasing order.
  • We pass (a, b) => a - b, because the default JavaScript sort compares numbers as text. For example, 10 would come before 2.
  • After sorting, consecutive numbers sit next to each other.

Step 2: Find the longest streak

  • currentStreak is the length of the run we are in now. maxStreak is the best run so far.
  • Both start at 1, because a single bar is a run of length 1.
  • If bars[i] === bars[i - 1] + 1, the run continues, so we add 1.
  • Otherwise, the run is broken, and we reset to 1.

Step 3: Combine both directions

  • hMax and vMax come from the same helper.
  • Math.min(hMax, vMax) + 1 is the biggest square side.
  • We return side * side.

Dry Run

Let us take hBars = [2, 3] and vBars = [2, 4].

Horizontal bars (after sorting [2, 3]):

ibars[i]Is it previous + 1?currentStreakmaxStreak
start--11
13Yes (2 + 1)22

So hMax = 2.

Vertical bars (after sorting [2, 4]):

ibars[i]Is it previous + 1?currentStreakmaxStreak
start--11
14No (2 + 1 = 3)11

So vMax = 1.

Result:

  • side = min(2, 1) + 1 = 2
  • Area = 2 * 2 = 4

This matches the expected output.

Complexity

  • Time Complexity: O(h log h + v log v)
    • h is the length of hBars and v is the length of vBars.
    • Sorting is the biggest cost. The streak loop takes O(h + v).
    • Both arrays have at most 100 items, so it is very fast.
  • Space Complexity: O(1)
    • We use only a few variables. Sorting happens in place.

Note: sort changes the input arrays. This is fine here. If you must keep the original arrays, sort a copy with [...bars].sort(...).

Comparison

ApproachTime ComplexitySpace Complexity
Check all subsets of barsO(2^h * 2^v)O(1)
Sort and longest streakO(h log h + v log v)O(1)

Summary

  • Removing x consecutive bars makes a gap of size x + 1.
  • Bars that are not next to each other do not join into one bigger gap.
  • So we need the longest run of consecutive numbers in hBars and in vBars.
  • A square needs equal sides, so the side is min(hMax, vMax) + 1.
  • The answer is side * side.
  • n and m are not used, because the fixed outer bars always give the gap its two ends.
  • The solution runs in O(h log h + v log v) time and uses O(1) space.