Skip to content

Commit 7340a73

Browse files
committed
feat: add solutions to lc problem: No.0850
No.0850.Rectangle Area II
1 parent c0bb94f commit 7340a73

File tree

6 files changed

+473
-175
lines changed

6 files changed

+473
-175
lines changed

solution/0800-0899/0850.Rectangle Area II/README.md

+164-63
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,17 @@
5151

5252
**方法一:离散化 + 线段树 + 扫描线**
5353

54-
线段树将整个区间分割为多个不连续的子区间,子区间的数量不超过 `log(width)`。更新某个元素的值,只需要更新 `log(width)` 个区间,并且这些区间都包含在一个包含该元素的大区间内。区间修改时,需要使用**懒标记**保证效率。
54+
线段树将整个区间分割为多个不连续的子区间,子区间的数量不超过 $log(width)$。更新某个元素的值,只需要更新 $log(width)$ 个区间,并且这些区间都包含在一个包含该元素的大区间内。区间修改时,需要使用**懒标记**保证效率。
5555

5656
- 线段树的每个节点代表一个区间;
57-
- 线段树具有唯一的根节点,代表的区间是整个统计范围,如 `[1, N]`
58-
- 线段树的每个叶子节点代表一个长度为 1 的元区间 `[x, x]`
59-
- 对于每个内部节点 `[l, r]`,它的左儿子是 `[l, mid]`,右儿子是 `[mid + 1, r]`, 其中 `mid = ⌊(l + r) / 2⌋` (即向下取整)。
57+
- 线段树具有唯一的根节点,代表的区间是整个统计范围,如 $[1, N]$
58+
- 线段树的每个叶子节点代表一个长度为 1 的元区间 $[x, x]$
59+
- 对于每个内部节点 $[l, r]$,它的左儿子是 $[l, mid]$,右儿子是 $[mid + 1, r]$, 其中 $mid = ⌊(l + r) / 2⌋$ (即向下取整)。
6060

6161
对于本题,线段树节点维护的信息有:
6262

63-
1. 区间被覆盖的次数 cnt;
64-
1. 区间被覆盖的长度 len。
63+
1. 区间被覆盖的次数 `cnt`
64+
1. 区间被覆盖的长度 `len`
6565

6666
另外,由于本题利用了扫描线本身的特性,因此,区间修改时,不需要懒标记,也无须进行 pushdown 操作。
6767

@@ -74,10 +74,8 @@
7474
```python
7575
class Node:
7676
def __init__(self):
77-
self.l = 0
78-
self.r = 0
79-
self.cnt = 0
80-
self.length = 0
77+
self.l = self.r = 0
78+
self.cnt = self.length = 0
8179

8280

8381
class SegmentTree:
@@ -107,11 +105,13 @@ class SegmentTree:
107105

108106
def pushup(self, u):
109107
if self.tr[u].cnt:
110-
self.tr[u].length = self.nums[self.tr[u].r + 1] - self.nums[self.tr[u].l]
108+
self.tr[u].length = self.nums[self.tr[u].r + 1] - \
109+
self.nums[self.tr[u].l]
111110
elif self.tr[u].l == self.tr[u].r:
112111
self.tr[u].length = 0
113112
else:
114-
self.tr[u].length = self.tr[u << 1].length + self.tr[u << 1 | 1].length
113+
self.tr[u].length = self.tr[u << 1].length + \
114+
self.tr[u << 1 | 1].length
115115

116116
@property
117117
def length(self):
@@ -125,15 +125,15 @@ class Solution:
125125
for x1, y1, x2, y2 in rectangles:
126126
segs.append((x1, y1, y2, 1))
127127
segs.append((x2, y1, y2, -1))
128-
alls.add(y1)
129-
alls.add(y2)
128+
alls.update([y1, y2])
129+
130+
segs.sort()
130131
alls = sorted(alls)
131-
m = {v: i for i, v in enumerate(alls)}
132132
tree = SegmentTree(alls)
133-
segs.sort()
133+
m = {v: i for i, v in enumerate(alls)}
134134
ans = 0
135135
for i, (x, y1, y2, k) in enumerate(segs):
136-
if i > 0:
136+
if i:
137137
ans += tree.length * (x - segs[i - 1][0])
138138
tree.modify(1, m[y1], m[y2] - 1, k)
139139
ans %= int(1e9 + 7)
@@ -146,27 +146,24 @@ class Solution:
146146

147147
```java
148148
class Node {
149-
int l;
150-
int r;
151-
int cnt;
152-
int len;
149+
int l, r, cnt, length;
153150
}
154151

155152
class SegmentTree {
156153
private Node[] tr;
157154
private int[] nums;
158155

159156
public SegmentTree(int[] nums) {
160-
int n = nums.length - 1;
161157
this.nums = nums;
158+
int n = nums.length - 1;
162159
tr = new Node[n << 2];
163160
for (int i = 0; i < tr.length; ++i) {
164161
tr[i] = new Node();
165162
}
166163
build(1, 0, n - 1);
167164
}
168165

169-
public void build(int u, int l, int r) {
166+
private void build(int u, int l, int r) {
170167
tr[u].l = l;
171168
tr[u].r = r;
172169
if (l != r) {
@@ -191,19 +188,19 @@ class SegmentTree {
191188
pushup(u);
192189
}
193190

194-
public int query() {
195-
return tr[1].len;
196-
}
197-
198-
public void pushup(int u) {
191+
private void pushup(int u) {
199192
if (tr[u].cnt > 0) {
200-
tr[u].len = nums[tr[u].r + 1] - nums[tr[u].l];
193+
tr[u].length = nums[tr[u].r + 1] - nums[tr[u].l];
201194
} else if (tr[u].l == tr[u].r) {
202-
tr[u].len = 0;
195+
tr[u].length = 0;
203196
} else {
204-
tr[u].len = tr[u << 1].len + tr[u << 1 | 1].len;
197+
tr[u].length = tr[u << 1].length + tr[u << 1 | 1].length;
205198
}
206199
}
200+
201+
public int query() {
202+
return tr[1].length;
203+
}
207204
}
208205

209206
class Solution {
@@ -212,27 +209,29 @@ class Solution {
212209
public int rectangleArea(int[][] rectangles) {
213210
int n = rectangles.length;
214211
int[][] segs = new int[n << 1][4];
215-
int idx = 0;
212+
int i = 0;
216213
TreeSet<Integer> ts = new TreeSet<>();
217-
for (int[] rect : rectangles) {
218-
int x1 = rect[0], y1 = rect[1], x2 = rect[2], y2 = rect[3];
219-
segs[idx++] = new int[] {x1, y1, y2, 1};
220-
segs[idx++] = new int[] {x2, y1, y2, -1};
214+
for (var e : rectangles) {
215+
int x1 = e[0], y1 = e[1], x2 = e[2], y2 = e[3];
216+
segs[i++] = new int[] {x1, y1, y2, 1};
217+
segs[i++] = new int[] {x2, y1, y2, -1};
221218
ts.add(y1);
222219
ts.add(y2);
223220
}
224-
Map<Integer, Integer> m = new HashMap<>();
221+
Arrays.sort(segs, (a, b) -> a[0] - b[0]);
222+
Map<Integer, Integer> m = new HashMap<>(ts.size());
223+
i = 0;
225224
int[] nums = new int[ts.size()];
226-
idx = 0;
227225
for (int v : ts) {
228-
nums[idx] = v;
229-
m.put(v, idx++);
226+
m.put(v, i);
227+
nums[i++] = v;
230228
}
231-
Arrays.sort(segs, Comparator.comparingInt(a -> a[0]));
229+
232230
SegmentTree tree = new SegmentTree(nums);
233231
long ans = 0;
234-
for (int i = 0; i < segs.length; ++i) {
235-
int x = segs[i][0], y1 = segs[i][1], y2 = segs[i][2], k = segs[i][3];
232+
for (i = 0; i < segs.length; ++i) {
233+
var e = segs[i];
234+
int x = e[0], y1 = e[1], y2 = e[2], k = e[3];
236235
if (i > 0) {
237236
ans += (long) tree.query() * (x - segs[i - 1][0]);
238237
}
@@ -249,18 +248,17 @@ class Solution {
249248
```cpp
250249
class Node {
251250
public:
252-
int l, r, cnt, len;
251+
int l, r, cnt, length;
253252
};
254253

255254
class SegmentTree {
256-
private:
255+
public:
257256
vector<Node*> tr;
258257
vector<int> nums;
259258

260-
public:
261259
SegmentTree(vector<int>& nums) {
262-
int n = nums.size() - 1;
263260
this->nums = nums;
261+
int n = nums.size() - 1;
264262
tr.resize(n << 2);
265263
for (int i = 0; i < tr.size(); ++i) tr[i] = new Node();
266264
build(1, 0, n - 1);
@@ -288,51 +286,154 @@ public:
288286
}
289287

290288
int query() {
291-
return tr[1]->len;
289+
return tr[1]->length;
292290
}
293291

294292
void pushup(int u) {
295293
if (tr[u]->cnt)
296-
tr[u]->len = nums[tr[u]->r + 1] - nums[tr[u]->l];
294+
tr[u]->length = nums[tr[u]->r + 1] - nums[tr[u]->l];
297295
else if (tr[u]->l == tr[u]->r)
298-
tr[u]->len = 0;
296+
tr[u]->length = 0;
299297
else
300-
tr[u]->len = tr[u << 1]->len + tr[u << 1 | 1]->len;
298+
tr[u]->length = tr[u << 1]->length + tr[u << 1 | 1]->length;
301299
}
302300
};
303301

304302
class Solution {
305303
public:
304+
const int mod = 1e9 + 7;
305+
306306
int rectangleArea(vector<vector<int>>& rectangles) {
307307
int n = rectangles.size();
308-
vector<vector<int>> segs;
308+
vector<vector<int>> segs(n << 1);
309309
set<int> ts;
310-
int mod = 1e9 + 7;
311-
for (auto& rect : rectangles) {
312-
int x1 = rect[0], y1 = rect[1], x2 = rect[2], y2 = rect[3];
313-
segs.push_back({x1, y1, y2, 1});
314-
segs.push_back({x2, y1, y2, -1});
310+
int i = 0;
311+
for (auto& e : rectangles) {
312+
int x1 = e[0], y1 = e[1], x2 = e[2], y2 = e[3];
313+
segs[i++] = {x1, y1, y2, 1};
314+
segs[i++] = {x2, y1, y2, -1};
315315
ts.insert(y1);
316316
ts.insert(y2);
317317
}
318-
unordered_map<int, int> m;
319-
int idx = 0;
320-
for (int v : ts) m[v] = idx++;
321318
sort(segs.begin(), segs.end());
319+
unordered_map<int, int> m;
320+
i = 0;
321+
for (int v : ts) m[v] = i++;
322322
vector<int> nums(ts.begin(), ts.end());
323323
SegmentTree* tree = new SegmentTree(nums);
324324
long long ans = 0;
325325
for (int i = 0; i < segs.size(); ++i) {
326-
int x = segs[i][0], y1 = segs[i][1], y2 = segs[i][2], k = segs[i][3];
327-
if (i > 0) ans += (long long)tree->query() * (x - segs[i - 1][0]);
326+
auto e = segs[i];
327+
int x = e[0], y1 = e[1], y2 = e[2], k = e[3];
328+
if (i > 0) ans += (long long) tree->query() * (x - segs[i - 1][0]);
328329
tree->modify(1, m[y1], m[y2] - 1, k);
329330
}
330331
ans %= mod;
331-
return (int)ans;
332+
return (int) ans;
332333
}
333334
};
334335
```
335336
337+
### **Go**
338+
339+
```go
340+
func rectangleArea(rectangles [][]int) int {
341+
var mod int = 1e9 + 7
342+
segs := [][]int{}
343+
alls := map[int]bool{}
344+
for _, e := range rectangles {
345+
x1, y1, x2, y2 := e[0], e[1], e[2], e[3]
346+
segs = append(segs, []int{x1, y1, y2, 1})
347+
segs = append(segs, []int{x2, y1, y2, -1})
348+
alls[y1] = true
349+
alls[y2] = true
350+
}
351+
nums := []int{}
352+
for v := range alls {
353+
nums = append(nums, v)
354+
}
355+
sort.Ints(nums)
356+
sort.Slice(segs, func(i, j int) bool { return segs[i][0] < segs[j][0] })
357+
m := map[int]int{}
358+
for i, v := range nums {
359+
m[v] = i
360+
}
361+
tree := newSegmentTree(nums)
362+
ans := 0
363+
for i, e := range segs {
364+
x, y1, y2, k := e[0], e[1], e[2], e[3]
365+
if i > 0 {
366+
ans += tree.query() * (x - segs[i-1][0])
367+
ans %= mod
368+
}
369+
tree.modify(1, m[y1], m[y2]-1, k)
370+
}
371+
return ans
372+
}
373+
374+
type node struct {
375+
l int
376+
r int
377+
cnt int
378+
length int
379+
}
380+
381+
type segmentTree struct {
382+
tr []*node
383+
nums []int
384+
}
385+
386+
func newSegmentTree(nums []int) *segmentTree {
387+
n := len(nums) - 1
388+
tr := make([]*node, n<<2)
389+
for i := range tr {
390+
tr[i] = &node{}
391+
}
392+
t := &segmentTree{tr, nums}
393+
t.build(1, 0, n-1)
394+
return t
395+
}
396+
397+
func (t *segmentTree) build(u, l, r int) {
398+
t.tr[u].l, t.tr[u].r = l, r
399+
if l == r {
400+
return
401+
}
402+
mid := (l + r) >> 1
403+
t.build(u<<1, l, mid)
404+
t.build(u<<1|1, mid+1, r)
405+
}
406+
407+
func (t *segmentTree) modify(u, l, r, k int) {
408+
if t.tr[u].l >= l && t.tr[u].r <= r {
409+
t.tr[u].cnt += k
410+
} else {
411+
mid := (t.tr[u].l + t.tr[u].r) >> 1
412+
if l <= mid {
413+
t.modify(u<<1, l, r, k)
414+
}
415+
if r > mid {
416+
t.modify(u<<1|1, l, r, k)
417+
}
418+
}
419+
t.pushup(u)
420+
}
421+
422+
func (t *segmentTree) query() int {
423+
return t.tr[1].length
424+
}
425+
426+
func (t *segmentTree) pushup(u int) {
427+
if t.tr[u].cnt > 0 {
428+
t.tr[u].length = t.nums[t.tr[u].r+1] - t.nums[t.tr[u].l]
429+
} else if t.tr[u].l == t.tr[u].r {
430+
t.tr[u].length = 0
431+
} else {
432+
t.tr[u].length = t.tr[u<<1].length + t.tr[u<<1|1].length
433+
}
434+
}
435+
```
436+
336437
### **...**
337438

338439
```

0 commit comments

Comments
 (0)