From 1293f69df3ab590d6acc0ed395789e79eb42bf18 Mon Sep 17 00:00:00 2001 From: gameloader Date: Sat, 28 Sep 2024 16:35:37 +0800 Subject: [PATCH] leetcode update --- content/posts/leetcode.md | 225 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) diff --git a/content/posts/leetcode.md b/content/posts/leetcode.md index de0765e..493fb8c 100644 --- a/content/posts/leetcode.md +++ b/content/posts/leetcode.md @@ -14220,3 +14220,228 @@ public: } }; ``` + +## day213 2024-09-27 + +### 731. My Calendar II + +You are implementing a program to use as your calendar. We can add a new event if adding the event will not cause a triple booking. + +A triple booking happens when three events have some non-empty intersection (i.e., some moment is common to all the three events.). + +The event can be represented as a pair of integers start and end that represents a booking on the half-open interval [start, end), the range of real numbers x such that start <= x < end. + +Implement the MyCalendarTwo class: + +MyCalendarTwo() Initializes the calendar object. +boolean book(int start, int end) Returns true if the event can be added to the calendar successfully without causing a triple booking. Otherwise, return false and do not add the event to the calendar. + +![0927rcG0qD6TNhbk](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0927rcG0qD6TNhbk.png) + +### 题解 + +本题仍然可以使用线段树求解,我们思考线段树的作用是什么,线段树使用了额外的空间保存了不断二分的区间的状态,从而对于有些区间问题,我们只需要知道这个区间拥有的某些性质即足以解决问题,没必要了解区间内的全部细节。这种区间对应了整体思想,将某些部分当作一个整体,用整体性质去求解。经典的线段树保存的是区间内全部数字的和,对于本题,我们只需修改区间保存的状态就可复用线段树解题。 + +本题中我们需要知道的是某个时间被访问过几次,则可以记录每个时间被访问的次数,对于区间我们可以记录该区间内这个访问次数的最大值。因为某个时间区间被预订后,该区间的所有时间的访问次数都要加1,因此仍然可以先将这个加1的状态保留在顶层的节点,在需要时再向下探索并将状态传递下去。 + +则我们需要构造线段树,其query查询的是某个区间的最大值,update将区间所有节点均加1。遍历book数组,对于每个预订,判断对应区间的最大值是否等于2,等于2则不能预定,小于2则可以预定并更新区间值。 + +### 代码 + +```cpp +class MyCalendarTwo { +private: + struct Node { + Node* left; + Node* right; + int val; + int lazy; + Node() : left(nullptr), right(nullptr), val(0), lazy(0) {} + }; + + Node* root; + const int MAX_RANGE = 1e9; + + void pushDown(Node* node, int start, int end) { + if (!node->left) node->left = new Node(); + if (!node->right) node->right = new Node(); + if (node->lazy) { + int mid = start + (end - start) / 2; + node->left->val += node->lazy; + node->left->lazy += node->lazy; + node->right->val += node->lazy; + node->right->lazy += node->lazy; + node->lazy = 0; + } + } + + int query(Node* node, int start, int end, int l, int r) { + if (l <= start && end <= r) return node->val; + pushDown(node, start, end); + int mid = start + (end - start) / 2; + int res = 0; + if (l <= mid) res = max(res,query(node->left, start, mid, l, r)); + if (r > mid) res = max(res,query(node->right, mid + 1, end, l, r)); + return res; + } + + void update(Node* node, int start, int end, int l, int r, int val) { + if (l <= start && end <= r) { + node->val += val; + node->lazy += val; + return; + } + pushDown(node, start, end); + int mid = start + (end - start) / 2; + if (l <= mid) update(node->left, start, mid, l, r, val); + if (r > mid) update(node->right, mid + 1, end, l, r, val); + node->val = max(node->left->val, node->right->val); + } + +public: + MyCalendarTwo() { + root = new Node(); + } + + bool book(int start, int end) { + if (query(root, 0, MAX_RANGE, start, end - 1) >=2 ) { + return false; + } + update(root, 0, MAX_RANGE, start, end - 1, 1); + return true; + + } +}; + +/** + * Your MyCalendarTwo object will be instantiated and called as such: + * MyCalendarTwo* obj = new MyCalendarTwo(); + * bool param_1 = obj->book(start,end); + */ +``` + +### 总结 + +当然本题仍然可以通过暴力或者二分求解,下面给出暴力的示例代码 + +```cpp +class MyCalendarTwo { + vector> b; + vector>db; +public: + MyCalendarTwo() { + + } + + bool book(int start, int end) { + + for(pair x: db){ + if(startx.first) return false; + } + for(pair x : b){ + if(startx.first){ + db.push_back({max(start,x.first),min(end,x.second)}); + } + } + b.push_back({start,end}); + return true; + + } +}; +``` + +## day214 2024-09-28 + +### 641. Design Circular Deque + +Design your implementation of the circular double-ended queue (deque). + +Implement the MyCircularDeque class: + +MyCircularDeque(int k) Initializes the deque with a maximum size of k. +boolean insertFront() Adds an item at the front of Deque. Returns true if the operation is successful, or false otherwise. +boolean insertLast() Adds an item at the rear of Deque. Returns true if the operation is successful, or false otherwise. +boolean deleteFront() Deletes an item from the front of Deque. Returns true if the operation is successful, or false otherwise. +boolean deleteLast() Deletes an item from the rear of Deque. Returns true if the operation is successful, or false otherwise. +int getFront() Returns the front item from the Deque. Returns -1 if the deque is empty. +int getRear() Returns the last item from Deque. Returns -1 if the deque is empty. +boolean isEmpty() Returns true if the deque is empty, or false otherwise. +boolean isFull() Returns true if the deque is full, or false otherwise. + +![0928P8VO6toCeM2T](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0928P8VO6toCeM2T.png) + +### 题解 + +本题是中等难度题,但题目本身逻辑比较简单,要实现双端循环链表,只需记录下链表的首部和尾部位置信息,链表的当前大小和最大容量按要求实现即可。可以用数组也可以用链表,本题中我使用数组实现。 + +### 代码 + +```cpp + +class MyCircularDeque { +private: + vector data; + int front; + int rear; + int size; + int capacity; + +public: + MyCircularDeque(int k) : data(k), front(0), rear(0), size(0), capacity(k) {} + + bool insertFront(int value) { + if (isFull()) return false; + data[front] = value; + if(size == 0){ + rear = (front+1)%capacity; + } + front = (front - 1 + capacity) % capacity; + size++; + return true; + } + + bool insertLast(int value) { + if (isFull()) return false; + data[rear] = value; + if (size == 0){ + front = (rear - 1 + capacity) % capacity; + } + rear = (rear + 1) % capacity; + size++; + return true; + } + + bool deleteFront() { + if (isEmpty()) return false; + front = (front + 1) % capacity; + size--; + return true; + } + + bool deleteLast() { + if (isEmpty()) return false; + rear = (rear - 1 + capacity) % capacity; + size--; + return true; + } + + int getFront() { + if (isEmpty()) return -1; + return data[(front+1)%capacity]; + } + + int getRear() { + if (isEmpty()) return -1; + return data[(rear - 1 + capacity) % capacity]; + } + + bool isEmpty() { + return size == 0; + } + + bool isFull() { + return size == capacity; + } +}; + +```