2021-11-10每日刷题打卡
力扣——每日一题
495. 提莫攻击
在《英雄联盟》的世界中,有一个叫 “提莫” 的英雄。他的攻击可以让敌方英雄艾希(编者注:寒冰射手)进入中毒状态。
当提莫攻击艾希,艾希的中毒状态正好持续 duration 秒。
正式地讲,提莫在 t 发起发起攻击意味着艾希在时间区间 [t, t + duration - 1](含 t 和 t + duration - 1)处于中毒状态。如果提莫在中毒影响结束 前 再次攻击,中毒状态计时器将会 重置 ,在新的攻击之后,中毒影响将会在 duration 秒后结束。
给你一个 非递减 的整数数组 timeSeries ,其中 timeSeries[i] 表示提莫在 timeSeries[i] 秒时对艾希发起攻击,以及一个表示中毒持续时间的整数 duration 。
返回艾希处于中毒状态的 总 秒数。
示例 1:
输入:timeSeries = [1,4], duration = 2
输出:4
解释:提莫攻击对艾希的影响如下:
- 第 1 秒,提莫攻击艾希并使其立即中毒。中毒状态会维持 2 秒,即第 1 秒和第 2 秒。
- 第 4 秒,提莫再次攻击艾希,艾希中毒状态又持续 2 秒,即第 4 秒和第 5 秒。
艾希在第 1、2、4、5 秒处于中毒状态,所以总中毒秒数是 4 。
这题也太草了,看到这题时忍不住笑了。这题解释一下就是说如果艾希中毒状态结束后被攻击,那就是两次攻击中毒时间分开计算,即2*duration,如果是中毒结束前被再次攻击,那就要一起算了,即timeSeries[i]-timeSeries[i-1]+duration,此时我们也知道这道题的解法了,准备一个数ans来计算中毒总时长,计算timeSeries数组里相邻两个元素的差值,如果差值大于等于duration,那第一次攻击的有效中毒时间就是duration,加到ans上,如果是小于duration,那就说明第一次攻击的有效中毒时间就是timeSeries[i]-timeSeries[i-1],加到ans上。注意,到了末尾时我们的循环就结束了,但最后一次攻击也是有中毒时间的,而且因为没有下一次攻击,所以最后一次攻击的中毒时间必是duration,所以我们要把ans加上duration才是正确答案(也可以一开始初始化ans时不初始为0而初始为duration),然后再返回ans。
class Solution {
public:
int findPoisonedDuration(vector<int>& timeSeries, int duration) {
int n=timeSeries.size(),ans=duration;
for(int i=0;i<n-1;i++)
if(timeSeries[i+1]-timeSeries[i]>=duration)
ans+=duration;
else
ans+=timeSeries[i+1]-timeSeries[i];
return ans;
}
};
力扣——二叉搜索树
173. 二叉搜索树迭代器和剑指 Offer II 055. 二叉搜索树迭代器
实现一个二叉搜索树迭代器类BSTIterator ,表示一个按中序遍历二叉搜索树(BST)的迭代器:
BSTIterator(TreeNode root) 初始化 BSTIterator 类的一个对象。BST 的根节点 root 会作为构造函数的一部分给出。指针应初始化为一个不存在于 BST 中的数字,且该数字小于 BST 中的任何元素。
boolean hasNext() 如果向指针右侧遍历存在数字,则返回 true ;否则返回 false 。
int next()将指针向右移动,然后返回指针处的数字。
注意,指针初始化为一个不存在于 BST 中的数字,所以对 next() 的首次调用将返回 BST 中的最小元素。
你可以假设 next() 调用总是有效的,也就是说,当调用 next() 时,BST 的中序遍历中至少存在一个下一个数字。
示例:
输入
[“BSTIterator”, “next”, “next”, “hasNext”, “next”, “hasNext”, “next”, “hasNext”, “next”, “hasNext”]
[[[7, 3, 15, null, null, 9, 20]], [], [], [], [], [], [], [], [], []]
输出
[null, 3, 7, true, 9, true, 15, true, 20, false]
解释
BSTIterator bSTIterator = new BSTIterator([7, 3, 15, null, null, 9, 20]);
bSTIterator.next(); // 返回 3
bSTIterator.next(); // 返回 7
bSTIterator.hasNext(); // 返回 True
bSTIterator.next(); // 返回 9
bSTIterator.hasNext(); // 返回 True
bSTIterator.next(); // 返回 15
bSTIterator.hasNext(); // 返回 True
bSTIterator.next(); // 返回 20
bSTIterator.hasNext(); // 返回 False
这是一道实现题,要我们实现三个函数的功能,要实现这个功能,我们的迭代器要做成一条单一的链,而不是树的情况(不然next和hasNext的遍历比较麻烦),首先我们要先准备一个成员变量的树节点p作为最开始的头指针,这个节点的值因为题目要求说比所给树的所有节点都小,那我们就找这个树最小的节点-1即可,先中序遍历一遍root,用所得到的中序序列来初始化p,每次从中序序列里取一个值初始化p的right节点,以此往复。最后就得到了一条只有right的树,且这个树的节点值递增的,也就是之前所给树的中序序列。一开始p是头结点,它的下一个才是根节点,然后next就把p往right走并返回节点值即可。hasNext即判断p->right是否为空,如果为空就返回false,不为空就返回true。
/**
* 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 BSTIterator {
private:
TreeNode* p;
public:
BSTIterator(TreeNode* root) {
vector<int>v;
stack<TreeNode*>sta;
while(sta.size()||root)
{
while(root)
{
sta.push(root);
root=root->left;
}
root=sta.top();
sta.pop();
v.push_back(root->val);
root=root->right;
}
this->p=new TreeNode(v[0]-1);
dfs(p->right,v,0);
}
void dfs(TreeNode *&p,vector<int>v,int i)
{
if(i>=v.size())return;
p=new TreeNode(v[i++]);
dfs(p->right,v,i);
}
int next() {
this->p=this->p->right;
return this->p->val;
}
bool hasNext() {
return (p->right)==NULL?false:true;
}
};
/**
* Your BSTIterator object will be instantiated and called as such:
* BSTIterator* obj = new BSTIterator(root);
* int param_1 = obj->next();
* bool param_2 = obj->hasNext();
*/
剑指 Offer II 053. 二叉搜索树中的中序后继
给定一棵二叉搜索树和其中的一个节点 p ,找到该节点在树中的中序后继。如果节点没有中序后继,请返回 null 。
节点 p 的后继是值比 p.val 大的节点中键值最小的节点,即按中序遍历的顺序节点 p 的下一个节点。
示例 1:
输入:root = [2,1,3], p = 1
输出:2
解释:这里 1 的中序后继是 2。请注意 p 和返回值都应是 TreeNode 类型。
中序遍历一遍二叉树,把他的中序序列存在vector容器v中,然后遍历v,找到所给p节点的val值,然后返回它的下一个数据,如果v中没有下一个数据就返回NULL。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<TreeNode*>v;
TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
dfs(root);
int n=v.size();
for(int i=0;i<n;i++)
if(v[i]->val==p->val)
return (i+1)>=n?NULL:v[i+1];
return {};
}
void dfs(TreeNode*root)
{
if(!root)return;
dfs(root->left);
v.push_back(root);
dfs(root->right);
}
};
或者我们可以在中序遍历的时候就创建好节点,这样一来不用遍历两便中序遍历,二来不需要多余的vector容器来存中序序列。
首先准备一个节点q,一开始指向NULL,拿一个bool类型flag=false来判断什么时候该拿root的val值初始化q,我们用迭代的方法中序遍历,每次比较root的值之前先判断一下flag是否为true,如果为true就拿当前值来初始化q,然后返回q结束程序。如果不为true就比较root和所给节点p的值,然后当遍历到节点值和所给节点p的值相同时,我们把flag改为true,这样我们的下一个中序序列的值就可以那来初始化q了。如果root没有下一个值了,那q仍然是NULL,会被直接返回。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
TreeNode*q;
q=NULL;
bool flag=false;
stack<TreeNode*>sta;
while(root||sta.size())
{
while(root)
{
sta.push(root);
root=root->left;
}
root=sta.top();
sta.pop();
if(flag&&root->val!=num)
{
q=new TreeNode(root->val);
return q;
}
if(root->val==p->val)
flag=true;
root=root->right;
}
return q;
}
};
501. 二叉搜索树中的众数
给定一个有相同值的二叉搜索树(BST),找出 BST 中的所有众数(出现频率最高的元素)。
假定 BST 有如下定义:
结点左子树中所含结点的值小于等于当前结点的值
结点右子树中所含结点的值大于等于当前结点的值
左子树和右子树都是二叉搜索树
例如:
给定 BST [1,null,2,2],
1
2
/
2
先中序遍历一遍root,把中序序列结果存入v中,然后遍历一遍v,找到出现频率最高的数,然后再遍历一遍v,把出现频率最高的数全都存入另一个vector容器中,最后返回这个容器。
/**
* 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:
vector<int>mymap;
vector<int> findMode(TreeNode* root) {
vector<int>v;
dfs(root);
int max=0,num=mymap[0],score=0;;
for(auto i:mymap)
if(i==num)
score++;
else
{
max=max>score?max:score;
num=i;
score=1;
}
max = max > score ? max : score;
score=0;
num=mymap[0];
for(auto i:mymap)
{
if(i==num)
score++;
else
{
score=1;
num=i;
}
if(score==max)
v.push_back(num);
}
return v;
}
void dfs(TreeNode*root)
{
if(!root)return;
dfs(root->left);
mymap.push_back(root->val);
dfs(root->right);
}
};