Perfect Rectangle

The problem asks to determine if the given rectangles exactly cover a rectangular region without any gaps or overlaps.

Here’s the code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class Solution:
    def isRectangleCover(self, rectangles: List[List[int]]) -> bool:
        area = 0
        corners = set()
        for x1, y1, x2, y2 in rectangles:
            area += (x2 - x1) * (y2 - y1)
            for point in ((x1, y1), (x1, y2), (x2, y1), (x2, y2)):
                if point in corners:
                    corners.remove(point)
                else:
                    corners.add(point)

        if len(corners) != 4:
            return False

        corners = sorted(list(corners))
        (x1, y1), (_, _), (_, _), (x2, y2) = corners
        return (x2 - x1) * (y2 - y1) == area

Explanation:

  • We calculate the total area of all the given rectangles, area, by adding the area of each rectangle.
  • We use a set, corners, to store the corners of the rectangles, and remove corners that appear twice, as they would be internal to the overall shape. The corners of the overall shape will be left in the set.
  • We then check if there are exactly 4 corners left in the set. If not, it means that there are gaps or overlaps.
  • Finally, we compare the area of the bounding rectangle formed by the 4 corners with the total area of the given rectangles to ensure that they match exactly. If they do, all rectangles together form an exact cover of a rectangular region.

The code will return True if the given rectangles form an exact cover, and False otherwise.

10 Prerequisite LeetCode Problems

The Perfect Rectangle involves geometrical calculations, hashmaps, and sorting. Here are 10 simpler problems to prepare for it:

  1. Merge Intervals (LeetCode #56): This problem will help you understand how to work with intervals, which is similar to working with rectangles in your target problem.

  2. Insert Interval (LeetCode #57): This is another problem that helps you deal with intervals, which can be applied to rectangles as well.

  3. Meeting Rooms II (LeetCode #253): This problem also involves interval handling but adds an additional complexity of overlapping intervals which will be beneficial.

  4. Contains Duplicate (LeetCode #217): This problem will help you understand how to utilize a Hashmap/Set to track duplicates, which is a crucial part of the Perfect Rectangle problem.

  5. Two Sum (LeetCode #1): This problem involves the use of a Hashmap to store and retrieve data, which is an important technique for the Perfect Rectangle problem.

  6. Rectangle Area (LeetCode #223): This problem directly involves rectangles and will help you understand how to calculate and compare areas.

  7. Sort Colors (LeetCode #75): This problem will help you understand the concept of sorting in linear time, which can be useful in your target problem.

  8. Find the Duplicate Number (LeetCode #287): This problem, like the Contains Duplicate problem, helps with understanding the use of Hashmap for duplicate tracking.

  9. Number of Islands (LeetCode #200): This problem is helpful to understand how to traverse a grid, which is an essential part of your target problem.

  10. Maximal Rectangle (LeetCode #85): This problem, although a bit more complex, will give you good practice in dealing with problems related to rectangles.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Solution:
    def isRectangleCover(self, rectangles: List[List[int]]) -> bool:
        area = 0
        corners = set()
        a = lambda: (Y-y) * (X-x)

        for x, y, X, Y in rectangles:
            area += a()
            corners ^= {(x,y), (x,Y), (X,y), (X,Y)}

        if len(corners) != 4: return False
        x, y = min(corners, key=lambda x: x[0] + x[1])
        X, Y = max(corners, key=lambda x: x[0] + x[1])
        return a() == area

Given an array rectangles where rectangles[i] = [xi, yi, ai, bi] represents an axis-aligned rectangle. The bottom-left point of the rectangle is (xi, yi) and the top-right point of it is (ai, bi).

Return true if all the rectangles together form an exact cover of a rectangular region.

Example 1:

Input: rectangles = [[1,1,3,3],[3,1,4,2],[3,2,4,4],[1,3,2,4],[2,3,3,4]] Output: true Explanation: All 5 rectangles together form an exact cover of a rectangular region. Example 2:

Input: rectangles = [[1,1,2,3],[1,3,2,4],[3,1,4,2],[3,2,4,4]] Output: false Explanation: Because there is a gap between the two rectangular regions. Example 3:

Input: rectangles = [[1,1,3,3],[3,1,4,2],[1,3,2,4],[2,2,4,4]] Output: false Explanation: Because two of the rectangles overlap with each other.

Constraints:

1 <= rectangles.length <= 2 * 104 rectangles[i].length == 4 -105 <= xi, yi, ai, bi <= 105

Perfect Rectangle - This problem requires checking if some rectangles can perfectly form another large rectangle. This is a Shape Formation Verification Problem.

Language Agnostic Coding Drills

Let’s break down this problem into several smaller concepts, arrange them in increasing level of difficulty, and then integrate them into the final solution. Remember, each concept should be learned independently before combining them. The programming language used here is Python, but these concepts are language-independent and can be applied to most modern programming languages.

  1. Understanding Lists and Basic List Operations: This is fundamental to most programming languages. Here, we have a list of lists, each inner list containing four integers. Understanding how to access and manipulate lists is key.

  2. Understanding Sets and Basic Set Operations: In Python, a set is an unordered collection of unique items. They are used in this problem to keep track of the rectangle’s corners. You should understand how to add and remove elements from a set, and how the XOR (^=) operator works with sets.

  3. Lambdas (Anonymous Functions): A lambda function is a small anonymous function. A lambda function can take any number of arguments, but can only have one expression. In this problem, it’s used to calculate the area of the rectangle.

  4. Loops: Looping is used here to iterate over the list of rectangles, to both calculate the total area and update the corners set.

  5. Conditional Statements: Conditional statements (if) are used here to determine whether the rectangles can form a perfect rectangle.

  6. Sorting and Min/Max Functions: Understanding how to find the minimum and maximum values in a collection is important. Here, min and max functions are used to find the left-bottom and right-top corners of the bounding rectangle.

To solve this problem, you’d first calculate the total area of all small rectangles and update the corners set. Then, you’d check whether the number of corners is 4 (which should be the case for a perfect rectangle). Finally, you’d find the left-bottom and right-top corners of the bounding rectangle, and check whether the area of the bounding rectangle is equal to the total area. If all these conditions are met, the rectangles can form a perfect rectangle.

Targeted Drills in Python

  1. Understanding Lists and Basic List Operations:

    Here is a drill for understanding and manipulating lists.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    list_example = [1, 2, 3, 4]
    print("Original List: ", list_example)
    
    # Accessing list elements
    print("First Element: ", list_example[0])
    
    # Adding to a list
    list_example.append(5)
    print("List after appending 5: ", list_example)
    
  2. Understanding Sets and Basic Set Operations:

    Below is a drill for understanding and manipulating sets, including using XOR with sets.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    set_example = {1, 2, 3}
    print("Original Set: ", set_example)
    
    # Adding to a set
    set_example.add(4)
    print("Set after adding 4: ", set_example)
    
    # XOR operation
    set_example ^= {4, 5}
    print("Set after XOR with {4, 5}: ", set_example)
    
  3. Lambdas (Anonymous Functions):

    Here is a drill for creating and using lambda functions.

    1
    2
    3
    
    # A lambda function to add two numbers
    add_func = lambda x, y: x + y
    print("Sum of 5 and 7: ", add_func(5, 7))
    
  4. Loops:

    Below is a simple loop drill.

    1
    2
    3
    
    # Print square of each number from 1 to 5
    for i in range(1, 6):
        print(f"Square of {i}: ", i**2)
    
  5. Conditional Statements:

    Here is a drill for understanding conditional statements.

    1
    2
    3
    4
    5
    
    num = 10
    if num > 5:
        print(f"{num} is greater than 5.")
    else:
        print(f"{num} is not greater than 5.")
    
  6. Sorting and Min/Max Functions:

    Below is a drill for using sorting and min/max functions.

    1
    2
    3
    4
    5
    
    list_example = [4, 2, 9, 6, 1]
    print("Min: ", min(list_example))
    print("Max: ", max(list_example))
    list_example.sort()
    print("Sorted List: ", list_example)
    

These drills can be practiced separately and once understood, can be integrated to solve the final problem.