LeetCode 495——Teemo Attacking

In LOL world, there is a hero called Teemo and his attacking can make his enemy Ashe be in poisoned condition. Now, given the Teemo's attacking ascending time series towards Ashe and the poisoning time duration per Teemo's attacking, you need to output the total time that Ashe is in poisoned condition.

You may assume that Teemo attacks at the very beginning of a specific time point, and makes Ashe be in poisoned condition immediately.

Example 1:

Input: [1,4], 2
Output: 4
Explanation: At time point 1, Teemo starts attacking Ashe and makes Ashe be poisoned immediately. 
This poisoned status will last 2 seconds until the end of time point 2. 
And at time point 4, Teemo attacks Ashe again, and causes Ashe to be in poisoned status for another 2 seconds. So you finally need to output 4.

 

Example 2:

Input: [1,2], 2
Output: 3
Explanation: At time point 1, Teemo starts attacking Ashe and makes Ashe be poisoned. 
This poisoned status will last 2 seconds until the end of time point 2. 
However, at the beginning of time point 2, Teemo attacks Ashe again who is already in poisoned status. 
Since the poisoned status won't add up together, though the second poisoning attack will still work at time point 2, it will stop at the end of time point 3. 
So you finally need to output 3.

 

Note:

  1. You may assume the length of given time series array won't exceed 10000.
  2. You may assume the numbers in the Teemo's attacking time series and his poisoning time duration per attacking are non-negative integers, which won't exceed 10,000,000.

 


 

一道带有英雄联盟场景的题目:提莫的攻击 

提莫的攻击会让艾希中毒,给出提莫的攻击时间(按升序排列)和每次攻击的中毒时间,求出艾希的总中毒时间。

若提莫的攻速很快(相对于每次攻击的中毒时间来说),则会出现中毒时间的重叠,也就是上次的中毒时间尚未结束,下一次的攻击已经来了。此题的关键点也就在于此:如何正确计算总的时间,并保证一个较低的时间和空间复杂度。

我的初步想法是在循环时记录一个最大的结束时间,若某次的开始时间大于当前最大的结束时间,则总时间直接加duration即可;若某次的开始时间不大于当前最大结束时间,则总时间加上当前的结束时间与最大结束时间的差值。并且在每次执行结束后更新最大结束时间。循环体如下:

int poinsonedEnd = timeSeries[i] + duration - 1;
if (timeSeries[i] > maxEndTime) {
    totalDuration += duration;
} else {
    totalDuration += poinsonedEnd - maxEndTime;
}
maxEndTime = poinsonedEnd;

按照如上思路提交后的时间复杂度为最优,空间复杂度超过了66.67%的提交。

其实这道题还有另外一种解决思路,就实在解决重叠问题时,如果发现重叠,就只在这次在总时长上增加重叠的部分。

也就是判断这次和上次的起始时间差距,如果差距比duration大,则总时间增加duration;如果差距比duration小,则总时间增加,这次开始时间与上次开始时间的差值。也就是循环体为:

totalDuration += Math.min(timeSeries[i] - timeSeries[i - 1], duration);

并且在最后的返回结果中别忘记加上duration,因为最后一次的没有计算。

这样的思路看起来代码更清晰,并且也更加简洁,也是值得借鉴和学习的。

 

提莫队长,向你报到!


 

我的AC代码:

class Solution {
    public int findPoisonedDuration(int[] timeSeries, int duration) {
        int arrLen = timeSeries.length;
        int maxEndTime = -1;
        int totalDuration = 0;
        for (int i = 0; i < arrLen; ++i) {
            int poinsonedEnd = timeSeries[i] + duration - 1;
            if (timeSeries[i] > maxEndTime) {
                totalDuration += duration;
            } else {
                totalDuration += poinsonedEnd - maxEndTime;
            }
            maxEndTime = poinsonedEnd;
        }

        return totalDuration;
    }
}

 


如有错误,欢迎指摘。也欢迎通过左上角的“向TA提问”按钮问我问题,我将竭力解答你的疑惑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值