俗话说总结才有收获,每日一题栏目从每天一篇水博客到一周一篇水博客啦!下面回顾一下本周做了那些题吧!
设计实现双端队列。
实现 MyCircularDeque
类:
MyCircularDeque(int k)
:构造函数,双端队列最大为 k 。boolean insertFront()
:将一个元素添加到双端队列头部。 如果操作成功返回 true ,否则返回 false 。boolean insertLast()
:将一个元素添加到双端队列尾部。如果操作成功返回 true ,否则返回 false 。boolean deleteFront()
:从双端队列头部删除一个元素。 如果操作成功返回 true ,否则返回 false 。boolean deleteLast()
:从双端队列尾部删除一个元素。如果操作成功返回 true ,否则返回 false 。int getFront()
:从双端队列头部获得一个元素。如果双端队列为空,返回 -1 。int getRear()
:获得双端队列的最后一个元素。 如果双端队列为空,返回 -1 。boolean isEmpty()
:若双端队列为空,则返回 true ,否则返回 false 。boolean isFull()
:若双端队列满了,则返回 true ,否则返回 false 。来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/design-circular-deque
本题是很简单的模拟题,有两种实现方法:数组实现和链表实现,下面介绍链表实现:
size == 0
;size == capacity
;// cpp实现
struct DLinkListNode {
int val;
DLinkListNode *prev, *next;
DLinkListNode(int _val): val(_val), prev(nullptr), next(nullptr) {
}
};
class MyCircularDeque {
private:
DLinkListNode *head, *tail;
int capacity;
int size;
public:
MyCircularDeque(int k): capacity(k), size(0), head(nullptr), tail(nullptr) {
}
bool insertFront(int value) {
if (size == capacity) {
return false;
}
DLinkListNode *node = new DLinkListNode(value);
if (size == 0) {
head = tail = node;
} else {
node->next = head;
head->prev = node;
head = node;
}
size++;
return true;
}
bool insertLast(int value) {
if (size == capacity) {
return false;
}
DLinkListNode *node = new DLinkListNode(value);
if (size == 0) {
head = tail = node;
} else {
tail->next = node;
node->prev = tail;
tail = node;
}
size++;
return true;
}
bool deleteFront() {
if (size == 0) {
return false;
}
DLinkListNode *node = head;
head = head->next;
if (head) {
head->prev = nullptr;
}
delete node;
size--;
return true;
}
bool deleteLast() {
if (size == 0) {
return false;
}
DLinkListNode *node = tail;
tail = tail->prev;
if (tail) {
tail->next = nullptr;
}
delete node;
size--;
return true;
}
int getFront() {
if (size == 0) {
return -1;
}
return head->val;
}
int getRear() {
if (size == 0) {
return -1;
}
return tail->val;
}
bool isEmpty() {
return size == 0;
}
bool isFull() {
return size == capacity;
}
};
有 n 个 (id, value) 对,其中 id 是 1 到 n 之间的一个整数,value 是一个字符串。不存在 id 相同的两个 (id, value) 对。
设计一个流,以 任意 顺序获取 n 个 (id, value) 对,并在多次调用时 按 id 递增的顺序 返回一些值。
实现 OrderedStream 类:
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/design-an-ordered-stream
按照题目描述模拟即可
class OrderedStream {
public:
vector<string> strs;
int ptr;
OrderedStream(int n) {
strs.resize(n + 1);
ptr = 1;
}
vector<string> insert(int idKey, string value) {
strs[idKey] = value;
vector<string> res;
while(ptr < strs.size() && !strs[ptr].empty()){
res.emplace_back(strs[ptr]);
ptr++;
}
return res;
}
};
/**
* Your OrderedStream object will be instantiated and called as such:
* OrderedStream* obj = new OrderedStream(n);
* vector param_1 = obj->insert(idKey,value);
*/
给你一棵二叉树的根节点 root ,请你返回 层数最深的叶子节点的和 。
题目链接:https://leetcode.cn/problems/deepest-leaves-sum/
这道题没啥好说的,层序遍历完事儿,初学二叉树遍历的朋友可以拿这道题试试手。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int deepestLeavesSum(TreeNode* root) {
// 层次遍历
vector<int> treeList;
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
int size = q.size();
int sum = 0;
while(size--){
TreeNode *temp = q.front();
q.pop();
sum+=temp->val;
if(temp->left){
q.push(temp->left);
}
if(temp->right){
q.push(temp->right);
}
}
treeList.emplace_back(sum);
}
return treeList[treeList.size()-1];
}
};
给你一个正整数数组 nums
,请你帮忙从该数组中找出能满足下面要求的 最长 前缀,并返回该前缀的长度:
从前缀中 恰好删除一个 元素后,剩下每个数字的出现次数都相同。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/maximum-equal-frequency
更改最长前缀的情况有以下三种:
i
个元素时,所有已经遍历过的元素的出现次数均为 1
,此时可以将最长前缀 res + 1
;_max
乘以出现次数为_max
的元素个数 + 1 == 当前遍历长度length, 则更新最长前缀为 length。(_max - 1) * ( sum[_max - 1] + 1 ) + 1 = length
,则更新最长前缀。class Solution {
public:
int maxEqualFreq(vector<int>& nums) {
vector<int> freq(100010,0); // 记录某个数字的出现次数
vector<int> sum(100010,0);
int n = nums.size();
int _max = 1; // 记录最大的出现次数
int res = 1;
for(int i = 0; i < n; i++){
int t = nums[i];
int cur = ++freq[t];
int length = i + 1;
sum[cur]++; // 出现次数为cur的数的次数
sum[cur - 1]--;
_max = max(_max, cur);
if(_max == 1) res = length;
if(_max * sum[_max] + 1 == length) res = length;
if((_max - 1) * (sum[_max - 1] + 1) + 1 == length) res = length;
}
return res;
}
};
给你两个整数数组 startTime(开始时间)
和 endTime(结束时间)
,并指定一个整数 queryTime
作为查询时间。
已知,第 i
名学生在 startTime[i]
时开始写作业并于 endTime[i]
时完成作业。
请返回在查询时间 queryTime
时正在做作业的学生人数。形式上,返回能够使 queryTime
处于区间 [startTime[i], endTime[i]]
的学生人数。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/number-of-students-doing-homework-at-a-given-time
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
暴力法当然时能做的,毕竟是一道简单题嘛;
但是翻看题解我发现了一种新的方法:差分数组,本题是一道差分数组的经典模板题.
class Solution {
public:
int busyStudent(vector<int>& startTime, vector<int>& endTime, int queryTime) {
// 差分数组
vector<int> c(1010);
int n = startTime.size();
for(int i = 0; i < n; i++){
c[startTime[i]]++;
c[endTime[i]+1]--;
}
for(int i = 1; i <= queryTime; i++){
c[i] += c[i-1];
}
return c[queryTime];
}
};