LC上最近有人出了一道新題球匕,十分有意思纹磺,叫做 Teemo Attacking(提莫攻擊)。
這道算法題描述的是:
在擼啊擼世界中亮曹,提莫的普通攻擊(吹箭)自帶箭毒傷害橄杨,每一次吹箭擊中敵人(以下假想敵為艾希),艾希都會(huì)受到持續(xù)特定時(shí)間的箭毒傷害照卦。
但箭毒傷害不會(huì)疊加式矫,只會(huì)把之前的持續(xù)時(shí)間結(jié)束并立即刷新開始計(jì)算持續(xù)時(shí)間。
問題是給定一個(gè)提莫攻擊的時(shí)間點(diǎn)組成的數(shù)組timeSeries役耕,以及固定的箭毒持續(xù)時(shí)間duration采转,寫出算法計(jì)算出艾希一共會(huì)受到多少時(shí)間的箭毒傷害。
題目還給出了幾個(gè)用例以提供解釋:
例子一:
輸入:[1, 4], 2
輸出:4
解釋:
提莫在時(shí)間點(diǎn)1攻擊艾希時(shí)瞬痘,箭毒立刻生效并持續(xù)2秒故慈;
箭毒持續(xù)完成后提莫又在時(shí)間點(diǎn)4攻擊一次艾希,兩次攻擊沒有箭毒疊加框全,因此艾希一共受到4秒箭毒傷害察绷。
例子二:
輸入:[1, 2], 2
輸出:3
解釋:
提莫在時(shí)間點(diǎn)1攻擊艾希,箭毒生效并持續(xù)了1秒到達(dá)攻擊時(shí)間點(diǎn)2時(shí)津辩,箭毒刷新并重計(jì)時(shí)2秒拆撼,因此一共會(huì)受到3秒傷害。
這題被標(biāo)記為中等難度丹泉,但實(shí)際上如果理清楚條理情萤,這一題其實(shí)可以算簡單難度。
我們可以用一次遍歷來完成計(jì)數(shù)摹恨。
- 使用一個(gè)變量保存艾希受到的總傷害時(shí)間筋岛;
- 遍歷攻擊時(shí)間點(diǎn)數(shù)組,在每一次攻擊時(shí)間點(diǎn)進(jìn)行判斷晒哄;
- 如果上一次攻擊的時(shí)間點(diǎn)與當(dāng)前循環(huán)的時(shí)間點(diǎn)之差大于一個(gè)箭毒持續(xù)時(shí)間睁宰,那么就可以直接累加一個(gè)持續(xù)時(shí)間;
- 如果這個(gè)差小于持續(xù)時(shí)間寝凌,那么累加這兩次攻擊點(diǎn)的差柒傻;
- 需要注意的是因?yàn)槊看窝h(huán)是與上一次進(jìn)行比較,在最后一次循環(huán)時(shí)较木,也就是最后一次攻擊會(huì)跳出循環(huán)红符,但這一次攻擊必然會(huì)造成一個(gè)持續(xù)時(shí)間的箭毒傷害,因此最后還需要加一次再返回。
以下是具體代碼:
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;
}
作為一個(gè)ex-LOLer预侯,看到這樣的算法題致开,很感慨,因?yàn)橥嬗螒蛞部梢酝娴煤苡凶非笪凇V灰阍敢馊ニ伎急举|(zhì)双戳。