LeetCode495-提莫攻击 | 算法练习系列

124 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情

前言

提莫队长正在待命!团战可以输,提莫必须死!迅捷。听到这些话相信经常游走在召唤师峡谷的兄弟们都知道这是谁,没错,她就是人见人爱,但有时又让人恨之入骨的提莫。下面来道题目来看看提莫的E技能到底是怎么计算中毒时长的。

题目描述

在《英雄联盟》的世界中,有一个叫 “提莫” 的英雄。他的攻击可以让敌方英雄艾希(编者注:寒冰射手)进入中毒状态。

当提莫攻击艾希,艾希的中毒状态正好持续 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:

输入:timeSeries = [1,2], duration = 2 输出:3 解释:提莫攻击对艾希的影响如下:

  • 第 1 秒,提莫攻击艾希并使其立即中毒。中毒状态会维持 2 秒,即第 1 秒和第 2 秒。
  • 第 2 秒,提莫再次攻击艾希,并重置中毒计时器,艾希中毒状态需要持续 2 秒,即第 2 秒和第 3 秒。 艾希在第 1、2、3 秒处于中毒状态,所以总中毒秒数是 3 。

解题思路

千万不要被这么长的题目吓到了,其实它就是简单的数组处理问题,通过读题可以提出关键点有以下几点

  • 数组的每项是开始中毒的起始时间
  • duration是每次中毒的时长
  • 中毒的情况分为两种,一种是开始中毒,经历了duration秒后才受到下次攻击,这时中毒的总时长使用totalTime+duration即可
  • 第二种情况是,当在中毒的duration秒内再次中毒了,这时总时长的计算就不能使用totalTime+duration了,而是要改成totalTime+(下次攻击的开始时间-本次攻击的开始时间)
  • 由于上述第二种状态的存在,我们要对程序进行一些改变,那就是循环的时候不能循环到最后一个项,而是在倒数第二项就结束,在循环结束时当前总时长+duration就是真正的中毒总秒数

代码如下:

/**
 * @param {number[]} timeSeries
 * @param {number} duration
 * @return {number}
 */
var findPoisonedDuration = function(timeSeries, duration) {
    let totalTime = 0 //记录中毒总时长
    for(let i=0;i<timeSeries.length-1;i++){
        //第一种情况
        if(timeSeries[i+1]-timeSeries[i]>=duration){
            for(let k=0;k<duration;k++){
                totalTime++
            }
           //第二种情况
        }else{
            for(let j=0;j<timeSeries[i+1]-timeSeries[i];j++){
            totalTime++
        }
        }
        
    }
    //千万不要忘记了加上最后一次攻击的中毒时长,也就是duration
    return totalTime+duration
};

运行结果如下图:

image.png

优化一下

 */
var findPoisonedDuration = function(timeSeries, duration) {
    let totalTime = 0
     for(let i=0;i<timeSeries.length-1;i++){
     if(timeSeries[i+1]-timeSeries[i]>=duration){
         totalTime+=duration
     }else{
            
            totalTime+=timeSeries[i+1]-timeSeries[i]
        }
        
    }
    return totalTime+duration
};

优化后的代码去掉了第二层for循环,刚才不知道怎么想的,完全没有用第二层for循环的必要,这样时间复杂度就是O(n)了

总结

这题属于简单题目,但讲道理题目描述的长度挺唬人的,代码这东西就得先写出来再慢慢优化,gogogo