Minimum Rectangles to Cover Points

Med
#2764Time: O(N^2). The initial sort takes O(N log N). The nested loops for the DP calculation result in a quadratic time complexity, which is the dominant factor.Space: O(N), where N is the number of points. This is for storing the DP array. Additional space might be required for sorting, typically O(log N) or O(N).
Patterns
Algorithms
Data structures

Prompt

You are given a 2D integer array points, where points[i] = [xi, yi]. You are also given an integer w. Your task is to cover all the given points with rectangles.

Each rectangle has its lower end at some point (x1, 0) and its upper end at some point (x2, y2), where x1 <= x2, y2 >= 0, and the condition x2 - x1 <= w must be satisfied for each rectangle.

A point is considered covered by a rectangle if it lies within or on the boundary of the rectangle.

Return an integer denoting the minimum number of rectangles needed so that each point is covered by at least one rectangle.

Note: A point may be covered by more than one rectangle.

 

Example 1:

Input: points = [[2,1],[1,0],[1,4],[1,8],[3,5],[4,6]], w = 1

Output: 2

Explanation:

The image above shows one possible placement of rectangles to cover the points:

  • A rectangle with a lower end at (1, 0) and its upper end at (2, 8)
  • A rectangle with a lower end at (3, 0) and its upper end at (4, 8)

Example 2:

Input: points = [[0,0],[1,1],[2,2],[3,3],[4,4],[5,5],[6,6]], w = 2

Output: 3

Explanation:

The image above shows one possible placement of rectangles to cover the points:

  • A rectangle with a lower end at (0, 0) and its upper end at (2, 2)
  • A rectangle with a lower end at (3, 0) and its upper end at (5, 5)
  • A rectangle with a lower end at (6, 0) and its upper end at (6, 6)

Example 3:

Input: points = [[2,3],[1,2]], w = 0

Output: 2

Explanation:

The image above shows one possible placement of rectangles to cover the points:

  • A rectangle with a lower end at (1, 0) and its upper end at (1, 2)
  • A rectangle with a lower end at (2, 0) and its upper end at (2, 3)

 

Constraints:

  • 1 <= points.length <= 105
  • points[i].length == 2
  • 0 <= xi == points[i][0] <= 109
  • 0 <= yi == points[i][1] <= 109
  • 0 <= w <= 109
  • All pairs (xi, yi) are distinct.

Approaches

2 approaches with complexity analysis and trade-offs.

This approach uses dynamic programming to find the minimum number of rectangles. After sorting the points by their x-coordinate, it builds a solution for the first i points by leveraging the solutions for smaller subproblems. It systematically checks all possible groupings for the last rectangle.

Algorithm

    1. Sort the points array by x-coordinate. - 2. Create a dp array of size n, where dp[i] is the minimum rectangles to cover points 0 to i. - 3. Iterate i from 0 to n-1. - 4. For each i, iterate j from i down to 0. - 5. If points[i][0] - points[j][0] <= w, update dp[i] with min(dp[i], (j > 0 ? dp[j-1] : 0) + 1). - 6. If the condition fails, break the inner loop as further points won't satisfy it. - 7. The final answer is dp[n-1].

Walkthrough

The problem can be solved using dynamic programming after an initial sorting step. The key observation is that the y-coordinates of the points are irrelevant for determining the minimum number of rectangles; only the x-coordinates matter. The width constraint w is the deciding factor for grouping points. The algorithm proceeds as follows:

  1. Sort: First, we sort the points array based on the x-coordinates in non-decreasing order. This allows us to process points from left to right.
  2. DP State: We define a DP array, dp, where dp[i] stores the minimum number of rectangles required to cover the first i+1 points (i.e., points[0] to points[i]).
  3. DP Transition: To calculate dp[i], we consider the i-th point. We must place it in a rectangle. This rectangle can potentially cover previous points as well. We iterate backwards from point i with an index j. As long as points[i][0] - points[j][0] <= w, all points from j to i can be covered by a single new rectangle. The total cost would be 1 (for this new rectangle) plus the cost to cover points up to j-1, which is dp[j-1]. We take the minimum over all valid j. The recurrence relation is: dp[i] = min(dp[j-1] + 1) for all j from 0 to i such that points[i][0] - points[j][0] <= w (with dp[-1] being 0). The final answer is dp[n-1]. Here is the Java implementation:
import java.util.Arrays;import java.util.Comparator; class Solution {    public int minRectanglesToCoverPoints(int[][] points, int w) {        int n = points.length;        if (n == 0) {            return 0;        }         Arrays.sort(points, Comparator.comparingInt(p -> p[0]));         int[] dp = new int[n];        // dp[i] = min rectangles to cover points 0...i         for (int i = 0; i < n; i++) {            // Initialize with the case where point i starts a new rectangle            // covering only itself, adding to the solution for points 0...i-1.            dp[i] = (i > 0 ? dp[i-1] : 0) + 1;             // Try to group with previous points            for (int j = i; j >= 0; j--) {                if (points[i][0] - points[j][0] <= w) {                    // Points from j to i can be in one rectangle.                    // The cost is 1 (for this rectangle) + cost to cover points up to j-1.                    int prevCost = (j > 0) ? dp[j-1] : 0;                    dp[i] = Math.min(dp[i], prevCost + 1);                } else {                    // Since sorted, no point before j will satisfy the condition                    break;                }            }        }        return dp[n-1];    }}

Complexity

Time

O(N^2). The initial sort takes O(N log N). The nested loops for the DP calculation result in a quadratic time complexity, which is the dominant factor.

Space

O(N), where N is the number of points. This is for storing the DP array. Additional space might be required for sorting, typically O(log N) or O(N).

Trade-offs

Pros

  • Provides a structured way to arrive at the correct solution.

  • Guaranteed to be correct if implemented properly.

Cons

  • Inefficient for large inputs due to its O(N^2) time complexity, which will likely time out on larger constraints.

  • Requires O(N) extra space for the DP table.

Solutions

public class Solution {    public int MinRectanglesToCoverPoints(int[][] points, int w) {        Array.Sort(points, (a, b) => a[0] - b[0]);        int ans = 0, x1 = -1;        foreach(int[] p in points) {            int x = p[0];            if (x > x1) {                ans++;                x1 = x + w;            }        }        return ans;    }}

Video walkthrough

Newsletter

One sharp idea, every week

System design and interview prep — short enough to finish.

No spam. Unsubscribe anytime.

Practice

Same difficulty — related problems to reinforce the pattern.