Skip to content

Commit 7070b1f

Browse files
authored
feat: add solutions to lc problem: No.0732 (doocs#3921)
No.0732.My Calendar III
1 parent ef0677c commit 7070b1f

File tree

5 files changed

+413
-42
lines changed

5 files changed

+413
-42
lines changed

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

+136-16
Original file line numberDiff line numberDiff line change
@@ -69,21 +69,21 @@ myCalendarThree.book(25, 55); // 返回 3
6969

7070
### 方法一:线段树
7171

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

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

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

8181
1. 区间范围内被预定的次数的最大值 $v$
82-
1. 懒标记 $add$
82+
1. 懒标记 $\text{add}$
8383

8484
由于时间范围为 $10^9$,非常大,因此我们采用动态开点。
8585

86-
时间复杂度 $O(nlogn)$,其中 $n$ 表示日程安排的数量。
86+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$,其中 $n$ 表示日程安排的数量。
8787

8888
<!-- tabs:start -->
8989

@@ -105,7 +105,7 @@ class SegmentTree:
105105
def __init__(self):
106106
self.root = Node(1, int(1e9 + 1))
107107

108-
def modify(self, l, r, v, node=None):
108+
def modify(self, l: int, r: int, v: int, node: Node = None):
109109
if l > r:
110110
return
111111
if node is None:
@@ -121,7 +121,7 @@ class SegmentTree:
121121
self.modify(l, r, v, node.right)
122122
self.pushup(node)
123123

124-
def query(self, l, r, node=None):
124+
def query(self, l: int, r: int, node: Node = None) -> int:
125125
if l > r:
126126
return 0
127127
if node is None:
@@ -136,10 +136,10 @@ class SegmentTree:
136136
v = max(v, self.query(l, r, node.right))
137137
return v
138138

139-
def pushup(self, node):
139+
def pushup(self, node: Node):
140140
node.v = max(node.left.v, node.right.v)
141141

142-
def pushdown(self, node):
142+
def pushdown(self, node: Node):
143143
if node.left is None:
144144
node.left = Node(node.l, node.mid)
145145
if node.right is None:
@@ -312,15 +312,21 @@ public:
312312
}
313313

314314
void modify(int l, int r, int v, Node* node) {
315-
if (l > r) return;
315+
if (l > r) {
316+
return;
317+
}
316318
if (node->l >= l && node->r <= r) {
317319
node->v += v;
318320
node->add += v;
319321
return;
320322
}
321323
pushdown(node);
322-
if (l <= node->mid) modify(l, r, v, node->left);
323-
if (r > node->mid) modify(l, r, v, node->right);
324+
if (l <= node->mid) {
325+
modify(l, r, v, node->left);
326+
}
327+
if (r > node->mid) {
328+
modify(l, r, v, node->right);
329+
}
324330
pushup(node);
325331
}
326332

@@ -329,12 +335,18 @@ public:
329335
}
330336

331337
int query(int l, int r, Node* node) {
332-
if (l > r) return 0;
338+
if (l > r) {
339+
return 0;
340+
}
333341
if (node->l >= l && node->r <= r) return node->v;
334342
pushdown(node);
335343
int v = 0;
336-
if (l <= node->mid) v = max(v, query(l, r, node->left));
337-
if (r > node->mid) v = max(v, query(l, r, node->right));
344+
if (l <= node->mid) {
345+
v = max(v, query(l, r, node->left));
346+
}
347+
if (r > node->mid) {
348+
v = max(v, query(l, r, node->right));
349+
}
338350
return v;
339351
}
340352

@@ -343,8 +355,12 @@ public:
343355
}
344356

345357
void pushdown(Node* node) {
346-
if (!node->left) node->left = new Node(node->l, node->mid);
347-
if (!node->right) node->right = new Node(node->mid + 1, node->r);
358+
if (!node->left) {
359+
node->left = new Node(node->l, node->mid);
360+
}
361+
if (!node->right) {
362+
node->right = new Node(node->mid + 1, node->r);
363+
}
348364
if (node->add) {
349365
Node* left = node->left;
350366
Node* right = node->right;
@@ -483,6 +499,110 @@ func (this *MyCalendarThree) Book(start int, end int) int {
483499
*/
484500
```
485501

502+
#### TypeScript
503+
504+
```ts
505+
class Node {
506+
left: Node | null = null;
507+
right: Node | null = null;
508+
l: number;
509+
r: number;
510+
mid: number;
511+
v: number = 0;
512+
add: number = 0;
513+
514+
constructor(l: number, r: number) {
515+
this.l = l;
516+
this.r = r;
517+
this.mid = (l + r) >> 1;
518+
}
519+
}
520+
521+
class SegmentTree {
522+
private root: Node = new Node(1, 1e9 + 1);
523+
524+
constructor() {}
525+
526+
modify(l: number, r: number, v: number, node: Node = this.root): void {
527+
if (l > r) {
528+
return;
529+
}
530+
if (node.l >= l && node.r <= r) {
531+
node.v += v;
532+
node.add += v;
533+
return;
534+
}
535+
this.pushdown(node);
536+
if (l <= node.mid) {
537+
this.modify(l, r, v, node.left!);
538+
}
539+
if (r > node.mid) {
540+
this.modify(l, r, v, node.right!);
541+
}
542+
this.pushup(node);
543+
}
544+
545+
query(l: number, r: number, node: Node = this.root): number {
546+
if (l > r) {
547+
return 0;
548+
}
549+
if (node.l >= l && node.r <= r) {
550+
return node.v;
551+
}
552+
this.pushdown(node);
553+
let v = 0;
554+
if (l <= node.mid) {
555+
v = Math.max(v, this.query(l, r, node.left!));
556+
}
557+
if (r > node.mid) {
558+
v = Math.max(v, this.query(l, r, node.right!));
559+
}
560+
return v;
561+
}
562+
563+
private pushup(node: Node): void {
564+
node.v = Math.max(node.left!.v, node.right!.v);
565+
}
566+
567+
private pushdown(node: Node): void {
568+
if (node.left === null) {
569+
node.left = new Node(node.l, node.mid);
570+
}
571+
if (node.right === null) {
572+
node.right = new Node(node.mid + 1, node.r);
573+
}
574+
if (node.add !== 0) {
575+
const left = node.left!;
576+
const right = node.right!;
577+
left.add += node.add;
578+
right.add += node.add;
579+
left.v += node.add;
580+
right.v += node.add;
581+
node.add = 0;
582+
}
583+
}
584+
}
585+
586+
class MyCalendarThree {
587+
private tree: SegmentTree;
588+
589+
constructor() {
590+
this.tree = new SegmentTree();
591+
}
592+
593+
book(start: number, end: number): number {
594+
this.tree.modify(start + 1, end, 1);
595+
return this.tree.query(1, 1e9 + 1);
596+
}
597+
}
598+
599+
/**
600+
* Your MyCalendarThree object will be instantiated and called as such:
601+
* var obj = new MyCalendarThree()
602+
* var param_1 = obj.book(startTime, endTime)
603+
*/
604+
```
605+
486606
<!-- tabs:end -->
487607

488608
<!-- solution:end -->

0 commit comments

Comments
 (0)