在《英雄联盟》的世界中,有一个叫“提莫”的英雄,他的攻击可以让敌方英雄艾希(编者注:寒冰射手)进入中毒状态。现在,给出提莫对艾希的攻击时间序列和提莫攻击的中毒持续时间,你需要输出艾希的中毒状态总时长。
你可以认为提莫在给定的时间点进行攻击,并立即使艾希处于中毒状态。
示例1:
输入: [1,4], 2 输出: 4 原因: 在第1秒开始时,提莫开始对艾希进行攻击并使其立即中毒。中毒状态会维持2秒钟,直到第2秒钟结束。 在第4秒开始时,提莫再次攻击艾希,使得艾希获得另外2秒的中毒时间。 所以最终输出4秒。
示例2:
输入: [1,2], 2 输出: 3 原因: 在第1秒开始时,提莫开始对艾希进行攻击并使其立即中毒。中毒状态会维持2秒钟,直到第2秒钟结束。 但是在第2秒开始时,提莫再次攻击了已经处于中毒状态的艾希。 由于中毒状态不可叠加,提莫在第2秒开始时的这次攻击会在第3秒钟结束。 所以最终输出3。
注意:
- 你可以假定时间序列数组的总长度不超过10000。
- 你可以假定提莫攻击时间序列中的数字和提莫攻击的中毒持续时间都是非负整数,并且不超过10,000,000。
思路一:我们维护一个上一次的时间戳lastFinishTime,初始化为timeSeris[0]-1,然后从下标0开始遍历,如果当前时间戳timeSeris[i]大于上一次时间戳lastFinishTime,证明上次时间戳到这次时间戳之间有间隔,那res就应该加duration,lastFinishTime更新为timeSeries[i] + duration-1。否则我们判断(timeSeries[i] + duration - 1)是否大于上一次时间戳,如果不大于意味着这次的时间段太短,结束时间还没到上次的时间戳,直接进入下一次循环,如果小于,那么我们的res加上时间差:timeSeries[i] + duration - 1 - lastFinishTime,并将上次时间戳更新为最新的时间:(timeSeries[i] + duration - 1)
参考代码:
class Solution {
public:
int findPoisonedDuration(vector<int>& timeSeries, int duration) {
if (timeSeries.size() == 0) return 0;
int res = 0,lastFinishTime=timeSeries[0]-1;
for (int i = 0; i < timeSeries.size(); i++) {
if (timeSeries[i] > lastFinishTime) {
res += duration;
lastFinishTime = (timeSeries[i] + duration-1);
}
else {
if ((timeSeries[i] + duration - 1) > lastFinishTime) {
res += timeSeries[i] + duration - 1 - lastFinishTime;
lastFinishTime = (timeSeries[i] + duration - 1);
}
}
}
return res;
}
};
思路二:这种方法更加便捷,每次用一个变量dif记录这次时间戳timeSeries[i]和前一个时间戳timeSeries[i-1]的差值,如果大于等于duration,那么意味着上一次时间戳可以完全度过duration的时间,所以结果res+=duration,否则res+=上差值dif。
参考代码:
class Solution {
public:
int findPoisonedDuration(vector<int>& timeSeries, int duration) {
if (timeSeries.size() == 0) return 0;
int res = 0;
for (int i = 1; i < timeSeries.size(); i++) {
int dif = timeSeries[i] - timeSeries[i - 1];
res += (dif < duration ? dif : duration);
}
return res+duration;
}
};