面试算法问题:每次查询后求最大矩形面积的解法与优化
Hey there! Let's break down your problem and questions clearly:
1. Is your solution correct?
Absolutely! Your core logic is spot-on. Here's why:
Every query splits the current rectangle along either the x or y axis, and the largest possible rectangle after each split will always be the product of the maximum gap between consecutive x-split lines and the maximum gap between consecutive y-split lines.
Let's verify with your example:
- Initial state: x splits are [0,6], maxX=6; y splits are [0,6], maxY=6. Area = 6*6=36.
- After
x=2: x splits become [0,2,6], maxX=6-2=4. maxY remains 6. Area=4*6=24 (matches your example). - After
y=1: y splits become [0,1,6], maxY=6-1=5. maxX is still 4. Area=4*5=20 (also matches).
This logic holds because any larger rectangle would require spanning across a split line, which isn't allowed—so the biggest valid rectangle must fit entirely within one of the x-axis segments and one of the y-axis segments.
2. How to optimize your solution?
Your initial approach of traversing the entire list each time to find maxX/maxY works, but it's inefficient for large q (e.g., 10^5 queries) since each query would take O(k) time (k is the number of split lines so far). Instead, we can use specialized data structures to reduce each query's time complexity to O(log k):
Key Idea
We can handle the x-axis and y-axis independently. For each axis, we need two things:
- A way to maintain split lines in sorted order, so we can quickly find the neighbors of a new split line.
- A way to track the maximum gap between consecutive split lines, without rechecking all gaps every time.
Recommended Data Structures & Steps
Let's use the x-axis as an example (y-axis works exactly the same):
a. Maintain Sorted Split Lines
Use an ordered list (in Python, we can use the bisect module to keep a list sorted). When inserting a new split x=r:
- Use
bisect.bisect_leftto find the index wherershould be inserted. - Get the left neighbor (
left = splits_x[index-1]) and right neighbor (right = splits_x[index]).
b. Track & Update Gaps Efficiently
To avoid rechecking all gaps, we can use a sorted multiset (like Python's SortedList from the sortedcontainers library) to store all current gaps. Here's the process:
- Initialize:
splits_x = SortedList([0, n])gaps_x = SortedList([n - 0])maxX = n
- When inserting
x=r:- Find
leftandrightas above. - Calculate the old gap:
old_gap = right - left - Remove one instance of
old_gapfromgaps_x(since this gap is now split into two) - Add the two new gaps:
r - leftandright - rtogaps_x - Update
maxXtogaps_x[-1](the last element of the sorted list is the largest gap)
- Find
Alternative: Max Heap with Gap Counting
If you don't have access to SortedList, you can use a max heap plus a hash map to track valid gaps:
- Initialize:
splits_x(sorted list viabisect) = [0, n]heap_x(max heap, stored as negative values since Python'sheapqis a min-heap) = [-n]gap_count(hash map) = {n: 1}maxX = n
- When inserting
x=r:- Find
leftandright, calculateold_gap = right - left - Decrement
gap_count[old_gap]by 1 (remove it from the map if count reaches 0) - Add the two new gaps to
gap_count(increment their counts) and push their negative values toheap_x - Now, clean up the heap: while the top of the heap (negative gap) corresponds to a gap not in
gap_countor with a count of 0, pop it from the heap. maxX = -heap_x[0]
- Find
Time Complexity
With either approach, each query takes O(log k) time (k is the number of split lines on the axis), which is efficient enough for large q.
内容的提问来源于stack exchange,提问作者User_Targaryen




