#699
Falling Squares
HardArraySegment TreeOrdered SetSegment TreeDynamic Programming
Approaches
Brute ForceOptimal
Complexity Comparison
| Brute Force | Optimal Solution★ | |
|---|---|---|
| Time | O(n²) | O(n log n) |
| Space | O(1) | O(n) |
💡
Intuition
Time O(n log n)Space O(n)
Using a data structure like a Segment Tree allows us to efficiently track the heights of the squares and quickly find the maximum height in the overlapping regions. This significantly reduces the time complexity compared to the brute force method.
⚙️
Algorithm
3 steps- 1Step 1: Use a Segment Tree to maintain the heights of the squares.
- 2Step 2: For each square, calculate its landing height by querying the Segment Tree for the maximum height in the range it occupies.
- 3Step 3: Update the Segment Tree with the new height of the square after it lands.
solution.py41 lines
1class SegmentTree:
2 def __init__(self, size):
3 self.size = size
4 self.tree = [0] * (4 * size)
5
6 def update(self, index, value, node=1, start=0, end=None):
7 if end is None:
8 end = self.size - 1
9 if start == end:
10 self.tree[node] = max(self.tree[node], value)
11 else:
12 mid = (start + end) // 2
13 if index <= mid:
14 self.update(index, value, node * 2, start, mid)
15 else:
16 self.update(index, value, node * 2 + 1, mid + 1, end)
17 self.tree[node] = max(self.tree[node * 2], self.tree[node * 2 + 1])
18
19 def query(self, left, right, node=1, start=0, end=None):
20 if end is None:
21 end = self.size - 1
22 if left > end or right < start:
23 return 0
24 if left <= start and end <= right:
25 return self.tree[node]
26 mid = (start + end) // 2
27 return max(self.query(left, right, node * 2, start, mid), self.query(left, right, node * 2 + 1, mid + 1, end))
28
29
30def fallingSquares(positions):
31 max_position = 0
32 for left, side in positions:
33 max_position = max(max_position, left + side)
34 seg_tree = SegmentTree(max_position)
35 result = []
36 for left, side in positions:
37 right = left + side - 1
38 height = seg_tree.query(left, right)
39 seg_tree.update(left, height + side)
40 result.append(max(seg_tree.tree))
41 return resultℹ
Complexity note: The time complexity is O(n log n) because each update and query operation in the Segment Tree takes O(log n) time, and we perform these operations for each square. The space complexity is O(n) due to the storage used for the Segment Tree.
- 1Using a Segment Tree allows efficient height tracking.
- 2Understanding the overlap of squares is crucial.
Solutions and explanations are original Tejav content. Problem titles © LeetCode — use the LeetCode button above for the full problem statement.