列表

详情


729. 我的日程安排表 I

实现一个 MyCalendar 类来存放你的日程安排。如果要添加的日程安排不会造成 重复预订 ,则可以存储这个新的日程安排。

当两个日程安排有一些时间上的交叉时(例如两个日程安排都在同一时间内),就会产生 重复预订

日程可以用一对整数 startend 表示,这里的时间是半开区间,即 [start, end), 实数 x 的范围为,  start <= x < end

实现 MyCalendar 类:

 

示例:

输入:
["MyCalendar", "book", "book", "book"]
[[], [10, 20], [15, 25], [20, 30]]
输出:
[null, true, false, true]

解释:
MyCalendar myCalendar = new MyCalendar();
myCalendar.book(10, 20); // return True
myCalendar.book(15, 25); // return False ,这个日程安排不能添加到日历中,因为时间 15 已经被另一个日程安排预订了。
myCalendar.book(20, 30); // return True ,这个日程安排可以添加到日历中,因为第一个日程安排预订的每个时间都小于 20 ,且不包含时间 20 。

 

提示:

相似题目

我的日程安排表 II

我的日程安排表 III

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class MyCalendar { public: MyCalendar() { } bool book(int start, int end) { } }; /** * Your MyCalendar object will be instantiated and called as such: * MyCalendar* obj = new MyCalendar(); * bool param_1 = obj->book(start,end); */

golang 解法, 执行用时: 144 ms, 内存消耗: 7.6 MB, 提交时间: 2022-11-21 10:04:57

type MyCalendar struct {
    tree, lazy map[int]bool
}

func Constructor() MyCalendar {
    return MyCalendar{map[int]bool{}, map[int]bool{}}
}

func (c MyCalendar) query(start, end, l, r, idx int) bool {
    if r < start || end < l {
        return false
    }
    if c.lazy[idx] { // 如果该区间已被预订,则直接返回
        return true
    }
    if start <= l && r <= end {
        return c.tree[idx]
    }
    mid := (l + r) >> 1
    return c.query(start, end, l, mid, 2*idx) ||
        c.query(start, end, mid+1, r, 2*idx+1)
}

func (c MyCalendar) update(start, end, l, r, idx int) {
    if r < start || end < l {
        return
    }
    if start <= l && r <= end {
        c.tree[idx] = true
        c.lazy[idx] = true
    } else {
        mid := (l + r) >> 1
        c.update(start, end, l, mid, 2*idx)
        c.update(start, end, mid+1, r, 2*idx+1)
        c.tree[idx] = true
        if c.lazy[2*idx] && c.lazy[2*idx+1] {
            c.lazy[idx] = true
        }
    }
}

func (c MyCalendar) Book(start, end int) bool {
    if c.query(start, end-1, 0, 1e9, 1) {
        return false
    }
    c.update(start, end-1, 0, 1e9, 1)
    return true
}

/**
 * Your MyCalendar object will be instantiated and called as such:
 * obj := Constructor();
 * param_1 := obj.Book(start,end);
 */

python3 解法, 执行用时: 940 ms, 内存消耗: 19.7 MB, 提交时间: 2022-11-21 10:04:04

class MyCalendar:
    def __init__(self):
        self.tree = set()
        self.lazy = set()

    def query(self, start: int, end: int, l: int, r: int, idx: int) -> bool:
        if r < start or end < l:
            return False
        if idx in self.lazy:  # 如果该区间已被预订,则直接返回
            return True
        if start <= l and r <= end:
            return idx in self.tree
        mid = (l + r) // 2
        return self.query(start, end, l, mid, 2 * idx) or \
               self.query(start, end, mid + 1, r, 2 * idx + 1)

    def update(self, start: int, end: int, l: int, r: int, idx: int) -> None:
        if r < start or end < l:
            return
        if start <= l and r <= end:
            self.tree.add(idx)
            self.lazy.add(idx)
        else:
            mid = (l + r) // 2
            self.update(start, end, l, mid, 2 * idx)
            self.update(start, end, mid + 1, r, 2 * idx + 1)
            self.tree.add(idx)
            if 2 * idx in self.lazy and 2 * idx + 1 in self.lazy:
                self.lazy.add(idx)

    def book(self, start: int, end: int) -> bool:
        if self.query(start, end - 1, 0, 10 ** 9, 1):
            return False
        self.update(start, end - 1, 0, 10 ** 9, 1)
        return True


# Your MyCalendar object will be instantiated and called as such:
# obj = MyCalendar()
# param_1 = obj.book(start,end)

python3 解法, 执行用时: 224 ms, 内存消耗: 16.3 MB, 提交时间: 2022-11-21 10:02:51

from sortedcontainers import SortedDict

class MyCalendar:
    def __init__(self):
        self.booked = SortedDict()

    def book(self, start: int, end: int) -> bool:
        i = self.booked.bisect_left(end)
        if i == 0 or self.booked.items()[i - 1][1] <= start:
            self.booked[start] = end
            return True
        return False


# Your MyCalendar object will be instantiated and called as such:
# obj = MyCalendar()
# param_1 = obj.book(start,end)

golang 解法, 执行用时: 60 ms, 内存消耗: 7.1 MB, 提交时间: 2022-11-21 10:01:55

type MyCalendar struct {
    *redblacktree.Tree
}

func Constructor() MyCalendar {
    t := redblacktree.NewWithIntComparator()
    t.Put(math.MaxInt32, nil) // 哨兵,简化代码
    return MyCalendar{t}
}

func (c MyCalendar) Book(start, end int) bool {
    node, _ := c.Ceiling(end)
    it := c.IteratorAt(node)
    if !it.Prev() || it.Value().(int) <= start {
        c.Put(start, end)
        return true
    }
    return false
}

/**
 * Your MyCalendar object will be instantiated and called as such:
 * obj := Constructor();
 * param_1 := obj.Book(start,end);
 */

golang 解法, 执行用时: 68 ms, 内存消耗: 7 MB, 提交时间: 2022-11-21 10:00:23

type pair struct{ start, end int }
type MyCalendar []pair

func Constructor() MyCalendar {
    return MyCalendar{}
}

func (c *MyCalendar) Book(start, end int) bool {
    for _, p := range *c {
        if p.start < end && start < p.end {
            return false
        }
    }
    *c = append(*c, pair{start, end})
    return true
}

/**
 * Your MyCalendar object will be instantiated and called as such:
 * obj := Constructor();
 * param_1 := obj.Book(start,end);
 */

python3 解法, 执行用时: 680 ms, 内存消耗: 15.8 MB, 提交时间: 2022-11-21 10:00:06

class MyCalendar:
    def __init__(self):
        self.booked = []

    def book(self, start: int, end: int) -> bool:
        if any(l < end and start < r for l, r in self.booked):
            return False
        self.booked.append((start, end))
        return True



# Your MyCalendar object will be instantiated and called as such:
# obj = MyCalendar()
# param_1 = obj.book(start,end)

上一题