leetcode 732. 我的日程安排表 III

题目:732. 我的日程安排表 III - 力扣(LeetCode)

这个数据规模,暴力就够了

struct Book {
    int begin;
    int end;
    
    Book(int b, int e) {
        begin = b;
        end = e;
    }
};
class MyCalendarThree {
public:
    MyCalendarThree() {
    }
    
    int book(int startTime, int endTime) {
        Book* b = new Book(startTime, endTime);
        books.push_back(b);
        for (size_t i = books.size() - 1; i > 0; i--) {
            if (books[i]->begin >= books[i - 1]->begin) {
                break;
            }
            Book* t = books[i];
            books[i] = books[i - 1];
            books[i - 1] = t;
        }
        int ret = 0;
        int current = 0;
        ends.clear();
        for (size_t i = 0; i < books.size(); i++) {
            current++;
            while (ends.size() && ends[ends.size() - 1] <= books[i]->begin) {
                current--;
                ends.pop_back();
            }
            if (current > ret) {
                ret = current;
            }
            ends.push_back(books[i]->end);
            for (size_t k = ends.size() - 1; k > 0; k--) {
                if (ends[k] <= ends[k - 1]) {
                    break;
                }
                int t = ends[k];
                ends[k] = ends[k - 1];
                ends[k - 1] = t;
            }
        }
        return ret;
    }
    
private:
    vector<Book*> books;
    vector<int> ends;
};

### 日程安排 III 的算法解与实现方案 #### 背景介绍 日程安排 IIILeetCode 上的一道经典问,目标是在多次调用 `book` 方法时动态维护一个时间区间内的最大重叠次数。此问可以通过 **差分数组** 和 **线段树** 来解决。 --- #### 解决方法一:差分数组 ##### 原理说明 差分数组是一种高效处理区间加减操作的数据结构。通过记录区间的起点和终点的变化量,在最后遍历时累加这些变化量即可得到任意时刻的重叠次数[^3]。 ##### 实现代码 (C++) 以下是基于 C++ 的差分数组实现: ```cpp class MyCalendarThree { public: map<int, int> diff; MyCalendarThree() {} int book(int start, int end) { diff[start]++; diff[end]--; int maxK = 0; int currentOverlap = 0; for (auto &[key, value] : diff) { currentOverlap += value; maxK = std::max(maxK, currentOverlap); } return maxK; } }; ``` 上述代码中,每次调用 `book(start, end)` 会更新差分数组中的两个位置,并在最后计算当前的最大重叠次数。 --- #### 解决方法二:线段树 ##### 原理说明 线段树适用于频繁查询和修改区间的情况。对于本问,我们可以构建一棵覆盖整个时间范围的线段树,节点存储该区间内的最大重叠次数。在线段树上执行区间增加操作并实时更新最大值[^5]。 ##### 实现代码 (Python) 以下是基于 Python 的线段树实现: ```python from collections import defaultdict class Node: def __init__(self): self.max_overlap = 0 self.lazy_add = 0 class SegmentTree: def __init__(self): self.tree = defaultdict(Node) def update(self, node_id, left, right, start, end, val): if end < left or start > right: return if start <= left and right <= end: self.tree[node_id].max_overlap += val self.tree[node_id].lazy_add += val return mid = (left + right) // 2 self.update(node_id * 2, left, mid, start, end, val) self.update(node_id * 2 + 1, mid + 1, right, start, end, val) self.tree[node_id].max_overlap = max( self.tree[node_id * 2].max_overlap, self.tree[node_id * 2 + 1].max_overlap ) + self.tree[node_id].lazy_add class MyCalendarThree: def __init__(self): self.st = SegmentTree() def book(self, start: int, end: int) -> int: self.st.update(1, 0, 10**9, start, end - 1, 1) return self.st.tree[1].max_overlap ``` 在此实现中,我们假设时间范围为 `[0, 1e9]` 并初始化了一棵线段树。每次调用 `book` 更新对应的时间区间,并返回全局最大值。 --- #### 时间复杂度分析 - **差分数组**: 单次 `book` 操作的时间复杂度为 \(O(n)\),其中 \(n\) 示已有的不同时间节点数量。 - **线段树**: 单次 `book` 操作的时间复杂度为 \(O(\log R)\),其中 \(R\) 示时间范围大小。 因此,当数据规模较大时,线段树通常现更优[^4]。 --- #### 结果验证 以下是一组测试样例及其预期结果: | 输入 | 输出 | |------|------| | `myCalendarThree.book(10, 20)` | 1 | | `myCalendarThree.book(50, 60)` | 1 | | `myCalendarThree.book(10, 40)` | 2 | | `myCalendarThree.book(5, 15)` | 3 | 以上结果均符合预期[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值