Skip to content

Commit 4e8d390

Browse files
committed
添加 problem 729
1 parent c915217 commit 4e8d390

File tree

3 files changed

+211
-0
lines changed

3 files changed

+211
-0
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package leetcode
2+
3+
// 解法一 二叉排序树
4+
// Event define
5+
type Event struct {
6+
start, end int
7+
left, right *Event
8+
}
9+
10+
// Insert define
11+
func (e *Event) Insert(curr *Event) bool {
12+
if e.end > curr.start && curr.end > e.start {
13+
return false
14+
}
15+
if curr.start < e.start {
16+
if e.left == nil {
17+
e.left = curr
18+
} else {
19+
return e.left.Insert(curr)
20+
}
21+
} else {
22+
if e.right == nil {
23+
e.right = curr
24+
} else {
25+
return e.right.Insert(curr)
26+
}
27+
}
28+
return true
29+
}
30+
31+
// MyCalendar define
32+
type MyCalendar struct {
33+
root *Event
34+
}
35+
36+
// Constructor729 define
37+
func Constructor729() MyCalendar {
38+
return MyCalendar{
39+
root: nil,
40+
}
41+
}
42+
43+
// Book define
44+
func (this *MyCalendar) Book(start int, end int) bool {
45+
curr := &Event{start: start, end: end, left: nil, right: nil}
46+
if this.root == nil {
47+
this.root = curr
48+
return true
49+
}
50+
return this.root.Insert(curr)
51+
}
52+
53+
// 解法二 快排 + 二分
54+
// MyCalendar define
55+
// type MyCalendar struct {
56+
// calendar []Interval
57+
// }
58+
59+
// // Constructor729 define
60+
// func Constructor729() MyCalendar {
61+
// calendar := []Interval{}
62+
// return MyCalendar{calendar: calendar}
63+
// }
64+
65+
// // Book define
66+
// func (this *MyCalendar) Book(start int, end int) bool {
67+
// if len(this.calendar) == 0 {
68+
// this.calendar = append(this.calendar, Interval{Start: start, End: end})
69+
// return true
70+
// }
71+
// // 快排
72+
// quickSort(this.calendar, 0, len(this.calendar)-1)
73+
// // 二分
74+
// pos := searchLastLessInterval(this.calendar, start, end)
75+
// // 如果找到最后一个元素,需要判断 end
76+
// if pos == len(this.calendar)-1 && this.calendar[pos].End <= start {
77+
// this.calendar = append(this.calendar, Interval{Start: start, End: end})
78+
// return true
79+
// }
80+
// // 如果不是开头和结尾的元素,还需要判断这个区间是否能插入到原数组中(要看起点和终点是否都能插入)
81+
// if pos != len(this.calendar)-1 && pos != -1 && this.calendar[pos].End <= start && this.calendar[pos+1].Start >= end {
82+
// this.calendar = append(this.calendar, Interval{Start: start, End: end})
83+
// return true
84+
// }
85+
// // 如果元素比开头的元素还要小,要插入到开头
86+
// if this.calendar[0].Start >= end {
87+
// this.calendar = append(this.calendar, Interval{Start: start, End: end})
88+
// return true
89+
// }
90+
// return false
91+
// }
92+
93+
// func searchLastLessInterval(intervals []Interval, start, end int) int {
94+
// low, high := 0, len(intervals)-1
95+
// for low <= high {
96+
// mid := low + ((high - low) >> 1)
97+
// if intervals[mid].Start <= start {
98+
// if (mid == len(intervals)-1) || (intervals[mid+1].Start > start) { // 找到最后一个小于等于 target 的元素
99+
// return mid
100+
// }
101+
// low = mid + 1
102+
// } else {
103+
// high = mid - 1
104+
// }
105+
// }
106+
// return -1
107+
// }
108+
109+
/**
110+
* Your MyCalendar object will be instantiated and called as such:
111+
* obj := Constructor();
112+
* param_1 := obj.Book(start,end);
113+
*/
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package leetcode
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
func Test_Problem729(t *testing.T) {
9+
obj := Constructor729()
10+
param1 := obj.Book(10, 20)
11+
fmt.Printf("param = %v obj = %v\n", param1, obj)
12+
param1 = obj.Book(15, 25)
13+
fmt.Printf("param = %v obj = %v\n", param1, obj)
14+
param1 = obj.Book(20, 30)
15+
fmt.Printf("param = %v obj = %v\n", param1, obj)
16+
17+
obj1 := Constructor729()
18+
param2 := obj1.Book(47, 50)
19+
fmt.Printf("param = %v obj = %v\n", param2, obj1)
20+
param2 = obj1.Book(33, 41)
21+
fmt.Printf("param = %v obj = %v\n", param2, obj1)
22+
param2 = obj1.Book(39, 45)
23+
fmt.Printf("param = %v obj = %v\n", param2, obj1)
24+
param2 = obj1.Book(33, 42)
25+
fmt.Printf("param = %v obj = %v\n", param2, obj1)
26+
param2 = obj1.Book(25, 32)
27+
fmt.Printf("param = %v obj = %v\n", param2, obj1)
28+
param2 = obj1.Book(26, 35)
29+
fmt.Printf("param = %v obj = %v\n", param2, obj1)
30+
param2 = obj1.Book(19, 25)
31+
fmt.Printf("param = %v obj = %v\n", param2, obj1)
32+
param2 = obj1.Book(3, 8)
33+
fmt.Printf("param = %v obj = %v\n", param2, obj1)
34+
param2 = obj1.Book(8, 13)
35+
fmt.Printf("param = %v obj = %v\n", param2, obj1)
36+
param2 = obj1.Book(18, 27)
37+
fmt.Printf("param = %v obj = %v\n", param2, obj1)
38+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# [729. My Calendar I](https://leetcode.com/problems/my-calendar-i/)
2+
3+
4+
## 题目:
5+
6+
Implement a `MyCalendar` class to store your events. A new event can be added if adding the event will not cause a double booking.
7+
8+
Your class will have the method, `book(int start, int end)`. Formally, this represents a booking on the half open interval `[start, end)`, the range of real numbers `x` such that `start <= x < end`.
9+
10+
A double booking happens when two events have some non-empty intersection (ie., there is some time that is common to both events.)
11+
12+
For each call to the method `MyCalendar.book`, return `true` if the event can be added to the calendar successfully without causing a double booking. Otherwise, return `false` and do not add the event to the calendar.
13+
14+
Your class will be called like this:
15+
16+
`MyCalendar cal = new MyCalendar();`
17+
18+
`MyCalendar.book(start, end)`
19+
20+
**Example 1:**
21+
22+
MyCalendar();
23+
MyCalendar.book(10, 20); // returns true
24+
MyCalendar.book(15, 25); // returns false
25+
MyCalendar.book(20, 30); // returns true
26+
Explanation:
27+
The first event can be booked. The second can't because time 15 is already booked by another event.
28+
The third event can be booked, as the first event takes every time less than 20, but not including 20.
29+
30+
**Note:**
31+
32+
- The number of calls to `MyCalendar.book` per test case will be at most `1000`.
33+
- In calls to `MyCalendar.book(start, end)``start` and `end` are integers in the range `[0, 10^9]`.
34+
35+
36+
37+
## 题目大意
38+
39+
实现一个 MyCalendar 类来存放你的日程安排。如果要添加的时间内没有其他安排,则可以存储这个新的日程安排。
40+
41+
MyCalendar 有一个 book(int start, int end) 方法。它意味着在 start 到 end 时间内增加一个日程安排,注意,这里的时间是半开区间,即 [start, end), 实数 x 的范围为,  start <= x < end。
42+
43+
当两个日程安排有一些时间上的交叉时(例如两个日程安排都在同一时间内),就会产生重复预订。
44+
45+
每次调用 MyCalendar.book 方法时,如果可以将日程安排成功添加到日历中而不会导致重复预订,返回 true。否则,返回 false 并且不要将该日程安排添加到日历中。
46+
47+
请按照以下步骤调用 MyCalendar 类: MyCalendar cal = new MyCalendar(); MyCalendar.book(start, end)
48+
49+
说明:
50+
51+
- 每个测试用例,调用 MyCalendar.book 函数最多不超过 100次。
52+
- 调用函数 MyCalendar.book(start, end) 时, start 和 end 的取值范围为 [0, 10^9]
53+
54+
55+
## 解题思路
56+
57+
58+
- 要求实现一个日程安排的功能,如果有日程安排冲突了,就返回 false,如果不冲突则返回 ture
59+
- 这一题有多种解法,第一种解法可以用类似第 34 题的解法。先排序每个区间,然后再这个集合中用二分搜索找到最后一个区间的左值比当前要比较的区间左值小的,如果找到,再判断能否插入进去(判断右区间是否比下一个区间的左区间小),此方法时间复杂度 O(n log n)
60+
- 第二种解法是用生成一个 BST 树。在插入树中先排除不能插入的情况,例如区间有重合。然后以区间左值为依据,递归插入,每次插入依次会继续判断区间是否重合。直到不能插入,则返回 fasle。整个查找的时间复杂度是 O(log n)。

0 commit comments

Comments
 (0)