Skip to content

Commit 7c9cbad

Browse files
committedJun 6, 2022
feat: add golang solution to lc problem: No.0732
No.0732.My Calendar III
1 parent 1df4fcb commit 7c9cbad

File tree

3 files changed

+344
-4
lines changed

3 files changed

+344
-4
lines changed
 

‎solution/0700-0799/0732.My Calendar III/README.md

+125-4
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,21 @@ myCalendarThree.book(25, 55); // 返回 3
5353

5454
**方法一:线段树**
5555

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

5858
- 线段树的每个节点代表一个区间;
59-
- 线段树具有唯一的根节点,代表的区间是整个统计范围,如 `[1, N]`
60-
- 线段树的每个叶子节点代表一个长度为 1 的元区间 `[x, x]`
61-
- 对于每个内部节点 `[l, r]`,它的左儿子是 `[l, mid]`,右儿子是 `[mid + 1, r]`, 其中 `mid = ⌊(l + r) / 2⌋` (即向下取整)。
59+
- 线段树具有唯一的根节点,代表的区间是整个统计范围,如 $[1, N]$;
60+
- 线段树的每个叶子节点代表一个长度为 $1$ 的元区间 $[x, x]$;
61+
- 对于每个内部节点 $[l, r]$,它的左儿子是 $[l, mid]$,右儿子是 $[mid + 1, r]$, 其中 $mid = ⌊(l + r) / 2⌋$ (即向下取整)。
62+
63+
对于本题,线段树节点维护的信息有:
64+
65+
1. 区间范围内被预定的次数的最大值 $v$
66+
1. 懒标记 $add$
67+
68+
由于 $0<=start<end<=109$,时间范围非常大,因此我们采用动态开点。
69+
70+
时间复杂度 $O(nlogn)$,其中 n 表示日程安排的数量。
6271

6372
<!-- tabs:start -->
6473

@@ -362,6 +371,118 @@ public:
362371
*/
363372
```
364373
374+
### **Go**
375+
376+
```go
377+
type node struct {
378+
left *node
379+
right *node
380+
l, mid, r int
381+
v, add int
382+
}
383+
384+
func newNode(l, r int) *node {
385+
return &node{
386+
l: l,
387+
r: r,
388+
mid: int(uint(l+r) >> 1),
389+
}
390+
}
391+
392+
func max(x, y int) int {
393+
if x > y {
394+
return x
395+
}
396+
return y
397+
}
398+
399+
type segmentTree struct {
400+
root *node
401+
}
402+
403+
func newSegmentTree() *segmentTree {
404+
return &segmentTree{
405+
root: newNode(1, 1e9+1),
406+
}
407+
}
408+
409+
func (t *segmentTree) modify(l, r, v int, n *node) {
410+
if l > r {
411+
return
412+
}
413+
if n.l >= l && n.r <= r {
414+
n.v += v
415+
n.add += v
416+
return
417+
}
418+
t.pushdown(n)
419+
if l <= n.mid {
420+
t.modify(l, r, v, n.left)
421+
}
422+
if r > n.mid {
423+
t.modify(l, r, v, n.right)
424+
}
425+
t.pushup(n)
426+
}
427+
428+
func (t *segmentTree) query(l, r int, n *node) int {
429+
if l > r {
430+
return 0
431+
}
432+
if n.l >= l && n.r <= r {
433+
return n.v
434+
}
435+
t.pushdown(n)
436+
v := 0
437+
if l <= n.mid {
438+
v = max(v, t.query(l, r, n.left))
439+
}
440+
if r > n.mid {
441+
v = max(v, t.query(l, r, n.right))
442+
}
443+
return v
444+
}
445+
446+
func (t *segmentTree) pushup(n *node) {
447+
n.v = max(n.left.v, n.right.v)
448+
}
449+
450+
func (t *segmentTree) pushdown(n *node) {
451+
if n.left == nil {
452+
n.left = newNode(n.l, n.mid)
453+
}
454+
if n.right == nil {
455+
n.right = newNode(n.mid+1, n.r)
456+
}
457+
if n.add != 0 {
458+
n.left.add += n.add
459+
n.right.add += n.add
460+
n.left.v += n.add
461+
n.right.v += n.add
462+
n.add = 0
463+
}
464+
}
465+
466+
type MyCalendarThree struct {
467+
tree *segmentTree
468+
}
469+
470+
func Constructor() MyCalendarThree {
471+
return MyCalendarThree{newSegmentTree()}
472+
}
473+
474+
func (this *MyCalendarThree) Book(start int, end int) int {
475+
this.tree.modify(start+1, end, 1, this.tree.root)
476+
return this.tree.query(1, int(1e9)+1, this.tree.root)
477+
}
478+
479+
/**
480+
* Your MyCalendarThree object will be instantiated and called as such:
481+
* obj := Constructor();
482+
* param_1 := obj.Book(start,end);
483+
*/
484+
```
485+
365486
### **...**
366487

367488
```

‎solution/0700-0799/0732.My Calendar III/README_EN.md

+112
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,118 @@ public:
343343
*/
344344
```
345345
346+
### **Go**
347+
348+
```go
349+
type node struct {
350+
left *node
351+
right *node
352+
l, mid, r int
353+
v, add int
354+
}
355+
356+
func newNode(l, r int) *node {
357+
return &node{
358+
l: l,
359+
r: r,
360+
mid: int(uint(l+r) >> 1),
361+
}
362+
}
363+
364+
func max(x, y int) int {
365+
if x > y {
366+
return x
367+
}
368+
return y
369+
}
370+
371+
type segmentTree struct {
372+
root *node
373+
}
374+
375+
func newSegmentTree() *segmentTree {
376+
return &segmentTree{
377+
root: newNode(1, 1e9+1),
378+
}
379+
}
380+
381+
func (t *segmentTree) modify(l, r, v int, n *node) {
382+
if l > r {
383+
return
384+
}
385+
if n.l >= l && n.r <= r {
386+
n.v += v
387+
n.add += v
388+
return
389+
}
390+
t.pushdown(n)
391+
if l <= n.mid {
392+
t.modify(l, r, v, n.left)
393+
}
394+
if r > n.mid {
395+
t.modify(l, r, v, n.right)
396+
}
397+
t.pushup(n)
398+
}
399+
400+
func (t *segmentTree) query(l, r int, n *node) int {
401+
if l > r {
402+
return 0
403+
}
404+
if n.l >= l && n.r <= r {
405+
return n.v
406+
}
407+
t.pushdown(n)
408+
v := 0
409+
if l <= n.mid {
410+
v = max(v, t.query(l, r, n.left))
411+
}
412+
if r > n.mid {
413+
v = max(v, t.query(l, r, n.right))
414+
}
415+
return v
416+
}
417+
418+
func (t *segmentTree) pushup(n *node) {
419+
n.v = max(n.left.v, n.right.v)
420+
}
421+
422+
func (t *segmentTree) pushdown(n *node) {
423+
if n.left == nil {
424+
n.left = newNode(n.l, n.mid)
425+
}
426+
if n.right == nil {
427+
n.right = newNode(n.mid+1, n.r)
428+
}
429+
if n.add != 0 {
430+
n.left.add += n.add
431+
n.right.add += n.add
432+
n.left.v += n.add
433+
n.right.v += n.add
434+
n.add = 0
435+
}
436+
}
437+
438+
type MyCalendarThree struct {
439+
tree *segmentTree
440+
}
441+
442+
func Constructor() MyCalendarThree {
443+
return MyCalendarThree{newSegmentTree()}
444+
}
445+
446+
func (this *MyCalendarThree) Book(start int, end int) int {
447+
this.tree.modify(start+1, end, 1, this.tree.root)
448+
return this.tree.query(1, int(1e9)+1, this.tree.root)
449+
}
450+
451+
/**
452+
* Your MyCalendarThree object will be instantiated and called as such:
453+
* obj := Constructor();
454+
* param_1 := obj.Book(start,end);
455+
*/
456+
```
457+
346458
### **...**
347459

348460
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
type node struct {
2+
left *node
3+
right *node
4+
l, mid, r int
5+
v, add int
6+
}
7+
8+
func newNode(l, r int) *node {
9+
return &node{
10+
l: l,
11+
r: r,
12+
mid: int(uint(l+r) >> 1),
13+
}
14+
}
15+
16+
func max(x, y int) int {
17+
if x > y {
18+
return x
19+
}
20+
return y
21+
}
22+
23+
type segmentTree struct {
24+
root *node
25+
}
26+
27+
func newSegmentTree() *segmentTree {
28+
return &segmentTree{
29+
root: newNode(1, 1e9+1),
30+
}
31+
}
32+
33+
func (t *segmentTree) modify(l, r, v int, n *node) {
34+
if l > r {
35+
return
36+
}
37+
if n.l >= l && n.r <= r {
38+
n.v += v
39+
n.add += v
40+
return
41+
}
42+
t.pushdown(n)
43+
if l <= n.mid {
44+
t.modify(l, r, v, n.left)
45+
}
46+
if r > n.mid {
47+
t.modify(l, r, v, n.right)
48+
}
49+
t.pushup(n)
50+
}
51+
52+
func (t *segmentTree) query(l, r int, n *node) int {
53+
if l > r {
54+
return 0
55+
}
56+
if n.l >= l && n.r <= r {
57+
return n.v
58+
}
59+
t.pushdown(n)
60+
v := 0
61+
if l <= n.mid {
62+
v = max(v, t.query(l, r, n.left))
63+
}
64+
if r > n.mid {
65+
v = max(v, t.query(l, r, n.right))
66+
}
67+
return v
68+
}
69+
70+
func (t *segmentTree) pushup(n *node) {
71+
n.v = max(n.left.v, n.right.v)
72+
}
73+
74+
func (t *segmentTree) pushdown(n *node) {
75+
if n.left == nil {
76+
n.left = newNode(n.l, n.mid)
77+
}
78+
if n.right == nil {
79+
n.right = newNode(n.mid+1, n.r)
80+
}
81+
if n.add != 0 {
82+
n.left.add += n.add
83+
n.right.add += n.add
84+
n.left.v += n.add
85+
n.right.v += n.add
86+
n.add = 0
87+
}
88+
}
89+
90+
type MyCalendarThree struct {
91+
tree *segmentTree
92+
}
93+
94+
func Constructor() MyCalendarThree {
95+
return MyCalendarThree{newSegmentTree()}
96+
}
97+
98+
func (this *MyCalendarThree) Book(start int, end int) int {
99+
this.tree.modify(start+1, end, 1, this.tree.root)
100+
return this.tree.query(1, int(1e9)+1, this.tree.root)
101+
}
102+
103+
/**
104+
* Your MyCalendarThree object will be instantiated and called as such:
105+
* obj := Constructor();
106+
* param_1 := obj.Book(start,end);
107+
*/

0 commit comments

Comments
 (0)
Please sign in to comment.