当前位置: 首页 > article >正文

LeetCode 0732.我的日程安排表 III:线段树

【LetMeFly】732.我的日程安排表 III:线段树

力扣题目链接:https://leetcode.cn/problems/my-calendar-iii/

k 个日程存在一些非空交集时(即, k 个日程包含了一些相同时间),就会产生 k 次预订。

给你一些日程安排 [startTime, endTime) ,请你在每个日程安排添加后,返回一个整数 k ,表示所有先前日程安排会产生的最大 k 次预订。

实现一个 MyCalendarThree 类来存放你的日程安排,你可以一直添加新的日程安排。

  • MyCalendarThree() 初始化对象。
  • int book(int startTime, int endTime) 返回一个整数 k ,表示日历中存在的 k 次预订的最大值。

 

示例:

输入:
["MyCalendarThree", "book", "book", "book", "book", "book", "book"]
[[], [10, 20], [50, 60], [10, 40], [5, 15], [5, 10], [25, 55]]
输出:
[null, 1, 1, 2, 3, 3, 3]

解释:
MyCalendarThree myCalendarThree = new MyCalendarThree();
myCalendarThree.book(10, 20); // 返回 1 ,第一个日程安排可以预订并且不存在相交,所以最大 k 次预订是 1 次预订。
myCalendarThree.book(50, 60); // 返回 1 ,第二个日程安排可以预订并且不存在相交,所以最大 k 次预订是 1 次预订。
myCalendarThree.book(10, 40); // 返回 2 ,第三个日程安排 [10, 40) 与第一个日程安排相交,所以最大 k 次预订是 2 次预订。
myCalendarThree.book(5, 15); // 返回 3 ,剩下的日程安排的最大 k 次预订是 3 次预订。
myCalendarThree.book(5, 10); // 返回 3
myCalendarThree.book(25, 55); // 返回 3

 

提示:

  • 0 <= startTime < endTime <= 109
  • 每个测试用例,调用 book 函数最多不超过 400

解题方法:线段树

离散化线段树,tree记录区间最大值,lazy懒标记区间的累加次数。

  • 时间复杂度 O ( n log ⁡ C ) O(n\log C) O(nlogC),线段树最大深度为 log ⁡ C \log C logC,其中 C = 1 0 9 C=10^9 C=109
  • 空间复杂度 O ( n log ⁡ C ) O(n\log C) O(nlogC),每次预定最多新增 log ⁡ C \log C logC个节点

AC代码

C++
/*
 * @Author: LetMeFly
 * @Date: 2025-01-05 21:26:02
 * @LastEditors: LetMeFly.xyz
 * @LastEditTime: 2025-01-05 21:33:46
 */
class MyCalendarThree {
private:
    unordered_map<int, int> tree, lazy;

    void update(int start, int end, int index, int l, int r) {
        if (start > r || l > end) {
            return;
        }
        if (l >= start && r <= end) {
            tree[index]++;
            lazy[index]++;
        } else {
            int mid = (l + r) >> 1;
            update(start, end, index * 2 + 1, l, mid);
            update(start, end, index * 2 + 2, mid + 1, r);
            tree[index] = lazy[index] + max(tree[index * 2 + 1], tree[index * 2 + 2]);
        }
    }
public:
    MyCalendarThree() {}
    
    int book(int startTime, int endTime) {
        update(startTime, endTime - 1, 0, 0, 1000000000);
        return tree[0];
    }
};

/**
 * Your MyCalendarThree object will be instantiated and called as such:
 * MyCalendarThree* obj = new MyCalendarThree();
 * int param_1 = obj->book(startTime,endTime);
 */
Python
'''
Author: LetMeFly
Date: 2025-01-05 21:34:19
LastEditors: LetMeFly.xyz
LastEditTime: 2025-01-05 21:38:20
'''
from collections import defaultdict

class MyCalendarThree:

    def __init__(self):
        self.tree = defaultdict(int)
        self.lazy = defaultdict(int)

    def update(self, start: int, end: int, index: int, l: int, r: int) -> None:
        if l > end or start > r:
            return
        if start <= l and r <= end:
            self.tree[index] += 1
            self.lazy[index] += 1
        else:
            mid = (l + r) >> 1
            self.update(start, end, index * 2 + 1, l, mid)
            self.update(start, end, index * 2 + 2, mid + 1, r)
            self.tree[index] = self.lazy[index] + max(self.tree[index * 2 + 1], self.tree[index * 2 + 2])

    def book(self, startTime: int, endTime: int) -> int:
        self.update(startTime, endTime - 1, 0, 0, 1000000000)
        return self.tree[0]


# Your MyCalendarThree object will be instantiated and called as such:
# obj = MyCalendarThree()
# param_1 = obj.book(startTime,endTime)
Java
/*
 * @Author: LetMeFly
 * @Date: 2025-01-05 21:39:30
 * @LastEditors: LetMeFly.xyz
 * @LastEditTime: 2025-01-05 21:44:12
 */
import java.util.HashMap;

class MyCalendarThree {
    private HashMap<Integer, Integer> tree, lazy;

    private void update(int start, int end, int index, int l, int r) {
        if (l > end || start > r) {
            return;
        }
        if (l >= start && r <= end) {
            tree.put(index, tree.getOrDefault(index, 0) + 1);
            lazy.put(index, lazy.getOrDefault(index, 0) + 1);
        } else {
            int mid = (l + r) >> 1;
            update(start, end, index * 2 + 1, l, mid);
            update(start, end, index * 2 + 2, mid + 1, r);
            tree.put(index, lazy.getOrDefault(index, 0) + Math.max(tree.getOrDefault(index * 2 + 1, 0), tree.getOrDefault(index * 2 + 2, 0)));
        }
    }

    public MyCalendarThree() {
        tree = new HashMap<Integer, Integer>();
        lazy = new HashMap<Integer, Integer>();
    }
    
    public int book(int startTime, int endTime) {
        update(startTime, endTime - 1, 0, 0, 1000000000);
        return tree.get(0);
    }
}

/**
 * Your MyCalendarThree object will be instantiated and called as such:
 * MyCalendarThree obj = new MyCalendarThree();
 * int param_1 = obj.book(startTime,endTime);
 */
Go
/*
 * @Author: LetMeFly
 * @Date: 2025-01-05 21:45:30
 * @LastEditors: LetMeFly.xyz
 * @LastEditTime: 2025-01-05 21:57:58
 */
package main

type pair_myCalendarIII struct {num, lazy int}
type MyCalendarThree map[int]pair_myCalendarIII

func max_MC3(a, b int) int {
    if a > b {
        return a
    }
    return b
}

func Constructor() MyCalendarThree {
    return MyCalendarThree{}
}

func (this MyCalendarThree) update(start, end, index, l, r int) {
    if l > end || start > r {
        return
    }
    if l >= start && r <= end {
        p := this[index]
        p.num++  // 不可直接this[index].num++
        p.lazy++
        this[index] = p
    } else {
        mid := (l + r) >> 1
        this.update(start, end, index * 2 + 1, l, mid)
        this.update(start, end, index * 2 + 2, mid + 1, r)
        p := this[index]
        p.num = this[index].lazy + max_MC3(this[index * 2 + 1].num, this[index * 2 + 2].num)
        this[index] = p
    }
}

func (this MyCalendarThree) Book(startTime int, endTime int) int {
    this.update(startTime, endTime - 1, 0, 0, 1000000000)
    return this[0].num
}

/**
 * Your MyCalendarThree object will be instantiated and called as such:
 * obj := Constructor();
 * param_1 := obj.Book(startTime,endTime);
 */

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

Tisfy:https://letmefly.blog.csdn.net/article/details/144951803


http://www.kler.cn/a/468697.html

相关文章:

  • 深入刨析数据结构之排序(上)
  • Backend - C# 操作数据库 DB(ADO.NET、LINQ to SQL、EF)
  • 51c自动驾驶~合集45
  • 周记-Repeater中的children和item区别
  • 工控安全需求分析与安全保护工程
  • SQL编程语言
  • [GCC]代码演示-Wl,-rpath-link链接时库搜索路径
  • 力扣hot100——动态规划 多维动态规划
  • 手动安装 Maven 依赖到本地仓库
  • Nginx:限流限速
  • 美食烹饪互动平台
  • 深入理解静态库与动态库
  • Go语言的 的并发编程(Concurrency)核心知识
  • PTA6-18 数字校验
  • MySQL和Hive中的行转列、列转行
  • Nginx——负载均衡与缓存(四/五)
  • 【开源免费】基于SpringBoot+Vue.JS海滨学院班级回忆录系统(JAVA毕业设计)
  • WIN10系统查看连接的无线网密码
  • 【微信小程序获取用户手机号
  • C++23 格式化输出新特性详解: std::print 和 std::println
  • 小E君自助餐厅流量分析
  • UOS 系统 Qt 版本切换
  • Linux 信号(结合系统理解)
  • 小结:DNS,HTTP,SMTP,IMAP,FTP,Telnet,TCP,ARP,ICMP
  • C#设计模式(行为型模式):状态模式
  • web实操9——session