LC上最近有人出了一道新题,十分有意思,叫做 Teemo Attacking(提莫攻击)。
这道算法题描述的是:
在撸啊撸世界中,提莫的普通攻击(吹箭)自带箭毒伤害,每一次吹箭击中敌人(以下假想敌为艾希),艾希都会受到持续特定时间的箭毒伤害。
但箭毒伤害不会叠加,只会把之前的持续时间结束并立即刷新开始计算持续时间。
问题是给定一个提莫攻击的时间点组成的数组timeSeries,以及固定的箭毒持续时间duration,写出算法计算出艾希一共会受到多少时间的箭毒伤害。
题目还给出了几个用例以提供解释:
例子一:
输入:[1, 4], 2
输出:4
解释:
提莫在时间点1攻击艾希时,箭毒立刻生效并持续2秒;
箭毒持续完成后提莫又在时间点4攻击一次艾希,两次攻击没有箭毒叠加,因此艾希一共受到4秒箭毒伤害。
例子二:
输入:[1, 2], 2
输出:3
解释:
提莫在时间点1攻击艾希,箭毒生效并持续了1秒到达攻击时间点2时,箭毒刷新并重计时2秒,因此一共会受到3秒伤害。
这题被标记为中等难度,但实际上如果理清楚条理,这一题其实可以算简单难度。
我们可以用一次遍历来完成计数。
- 使用一个变量保存艾希受到的总伤害时间;
- 遍历攻击时间点数组,在每一次攻击时间点进行判断;
- 如果上一次攻击的时间点与当前循环的时间点之差大于一个箭毒持续时间,那么就可以直接累加一个持续时间;
- 如果这个差小于持续时间,那么累加这两次攻击点的差;
- 需要注意的是因为每次循环是与上一次进行比较,在最后一次循环时,也就是最后一次攻击会跳出循环,但这一次攻击必然会造成一个持续时间的箭毒伤害,因此最后还需要加一次再返回。
以下是具体代码:
public int findPoisonedDuration(int[] timeSeries, int duration) {
if (timeSeries == null || timeSeries.length == 0 || duration <= 0) return 0;
int count = 0;
int start = timeSeries[0];
for (int i = 0; i < timeSeries.length; i ++) {
if (timeSeries[i] >= start + duration) {
count += duration;
} else {
count += timeSeries[i] - start;
}
start = timeSeries[i];
}
count += duration;
return count;
}
作为一个ex-LOLer,看到这样的算法题,很感慨,因为玩游戏也可以玩得很有追求。只要你愿意去思考本质。