添加 problem 729

This commit is contained in:
YDZ
2019-09-02 21:25:47 +08:00
parent c915217e86
commit 4e8d390f69
3 changed files with 211 additions and 0 deletions

View File

@ -0,0 +1,113 @@
package leetcode
// 解法一 二叉排序树
// Event define
type Event struct {
start, end int
left, right *Event
}
// Insert define
func (e *Event) Insert(curr *Event) bool {
if e.end > curr.start && curr.end > e.start {
return false
}
if curr.start < e.start {
if e.left == nil {
e.left = curr
} else {
return e.left.Insert(curr)
}
} else {
if e.right == nil {
e.right = curr
} else {
return e.right.Insert(curr)
}
}
return true
}
// MyCalendar define
type MyCalendar struct {
root *Event
}
// Constructor729 define
func Constructor729() MyCalendar {
return MyCalendar{
root: nil,
}
}
// Book define
func (this *MyCalendar) Book(start int, end int) bool {
curr := &Event{start: start, end: end, left: nil, right: nil}
if this.root == nil {
this.root = curr
return true
}
return this.root.Insert(curr)
}
// 解法二 快排 + 二分
// MyCalendar define
// type MyCalendar struct {
// calendar []Interval
// }
// // Constructor729 define
// func Constructor729() MyCalendar {
// calendar := []Interval{}
// return MyCalendar{calendar: calendar}
// }
// // Book define
// func (this *MyCalendar) Book(start int, end int) bool {
// if len(this.calendar) == 0 {
// this.calendar = append(this.calendar, Interval{Start: start, End: end})
// return true
// }
// // 快排
// quickSort(this.calendar, 0, len(this.calendar)-1)
// // 二分
// pos := searchLastLessInterval(this.calendar, start, end)
// // 如果找到最后一个元素,需要判断 end
// if pos == len(this.calendar)-1 && this.calendar[pos].End <= start {
// this.calendar = append(this.calendar, Interval{Start: start, End: end})
// return true
// }
// // 如果不是开头和结尾的元素,还需要判断这个区间是否能插入到原数组中(要看起点和终点是否都能插入)
// if pos != len(this.calendar)-1 && pos != -1 && this.calendar[pos].End <= start && this.calendar[pos+1].Start >= end {
// this.calendar = append(this.calendar, Interval{Start: start, End: end})
// return true
// }
// // 如果元素比开头的元素还要小,要插入到开头
// if this.calendar[0].Start >= end {
// this.calendar = append(this.calendar, Interval{Start: start, End: end})
// return true
// }
// return false
// }
// func searchLastLessInterval(intervals []Interval, start, end int) int {
// low, high := 0, len(intervals)-1
// for low <= high {
// mid := low + ((high - low) >> 1)
// if intervals[mid].Start <= start {
// if (mid == len(intervals)-1) || (intervals[mid+1].Start > start) { // 找到最后一个小于等于 target 的元素
// return mid
// }
// low = mid + 1
// } else {
// high = mid - 1
// }
// }
// return -1
// }
/**
* Your MyCalendar object will be instantiated and called as such:
* obj := Constructor();
* param_1 := obj.Book(start,end);
*/

View File

@ -0,0 +1,38 @@
package leetcode
import (
"fmt"
"testing"
)
func Test_Problem729(t *testing.T) {
obj := Constructor729()
param1 := obj.Book(10, 20)
fmt.Printf("param = %v obj = %v\n", param1, obj)
param1 = obj.Book(15, 25)
fmt.Printf("param = %v obj = %v\n", param1, obj)
param1 = obj.Book(20, 30)
fmt.Printf("param = %v obj = %v\n", param1, obj)
obj1 := Constructor729()
param2 := obj1.Book(47, 50)
fmt.Printf("param = %v obj = %v\n", param2, obj1)
param2 = obj1.Book(33, 41)
fmt.Printf("param = %v obj = %v\n", param2, obj1)
param2 = obj1.Book(39, 45)
fmt.Printf("param = %v obj = %v\n", param2, obj1)
param2 = obj1.Book(33, 42)
fmt.Printf("param = %v obj = %v\n", param2, obj1)
param2 = obj1.Book(25, 32)
fmt.Printf("param = %v obj = %v\n", param2, obj1)
param2 = obj1.Book(26, 35)
fmt.Printf("param = %v obj = %v\n", param2, obj1)
param2 = obj1.Book(19, 25)
fmt.Printf("param = %v obj = %v\n", param2, obj1)
param2 = obj1.Book(3, 8)
fmt.Printf("param = %v obj = %v\n", param2, obj1)
param2 = obj1.Book(8, 13)
fmt.Printf("param = %v obj = %v\n", param2, obj1)
param2 = obj1.Book(18, 27)
fmt.Printf("param = %v obj = %v\n", param2, obj1)
}

View File

@ -0,0 +1,60 @@
# [729. My Calendar I](https://leetcode.com/problems/my-calendar-i/)
## 题目:
Implement a `MyCalendar` class to store your events. A new event can be added if adding the event will not cause a double booking.
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`.
A double booking happens when two events have some non-empty intersection (ie., there is some time that is common to both events.)
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.
Your class will be called like this:
`MyCalendar cal = new MyCalendar();`
`MyCalendar.book(start, end)`
**Example 1:**
MyCalendar();
MyCalendar.book(10, 20); // returns true
MyCalendar.book(15, 25); // returns false
MyCalendar.book(20, 30); // returns true
Explanation:
The first event can be booked. The second can't because time 15 is already booked by another event.
The third event can be booked, as the first event takes every time less than 20, but not including 20.
**Note:**
- The number of calls to `MyCalendar.book` per test case will be at most `1000`.
- In calls to `MyCalendar.book(start, end)`, `start` and `end` are integers in the range `[0, 10^9]`.
## 题目大意
实现一个 MyCalendar 类来存放你的日程安排。如果要添加的时间内没有其他安排,则可以存储这个新的日程安排。
MyCalendar 有一个 book(int start, int end) 方法。它意味着在 start 到 end 时间内增加一个日程安排,注意,这里的时间是半开区间,即 [start, end), 实数 x 的范围为,  start <= x < end
当两个日程安排有一些时间上的交叉时例如两个日程安排都在同一时间内就会产生重复预订
每次调用 MyCalendar.book 方法时如果可以将日程安排成功添加到日历中而不会导致重复预订返回 true否则返回 false 并且不要将该日程安排添加到日历中
请按照以下步骤调用 MyCalendar 类: MyCalendar cal = new MyCalendar(); MyCalendar.book(start, end)
说明:
- 每个测试用例调用 MyCalendar.book 函数最多不超过 100次
- 调用函数 MyCalendar.book(start, end)  start  end 的取值范围为 [0, 10^9]。
## 解题思路
- 要求实现一个日程安排的功能如果有日程安排冲突了就返回 false如果不冲突则返回 ture
- 这一题有多种解法第一种解法可以用类似第 34 题的解法先排序每个区间然后再这个集合中用二分搜索找到最后一个区间的左值比当前要比较的区间左值小的如果找到再判断能否插入进去(判断右区间是否比下一个区间的左区间小)此方法时间复杂度 O(n log n)
- 第二种解法是用生成一个 BST 在插入树中先排除不能插入的情况例如区间有重合然后以区间左值为依据递归插入每次插入依次会继续判断区间是否重合直到不能插入则返回 fasle整个查找的时间复杂度是 O(log n)。