【LeetCode 495. 提莫攻击】Java 详细题解

m0_59305477 2026-04-18 20:02:50

题目描述

在《英雄联盟》的世界中,有一个叫 “提莫” 的英雄,他的攻击可以让敌方英雄艾希进入中毒状态。

现在,给出提莫对艾希的攻击时间序列和提莫攻击的中毒持续时间,你需要输出艾希的总中毒时间。

  • 你可以认为提莫在给定的时间点进行攻击,艾希会立刻中毒。

示例 1:

plaintext

输入: timeSeries = [1,4], duration = 2
输出: 4
解释:
第 1 秒,提莫攻击艾希并使其立即中毒,中毒状态会持续 2 秒,即第 1、2 秒。
第 4 秒,提莫再次攻击艾希,中毒状态又持续 2 秒,即第 4、5 秒。
总中毒时间为 2 + 2 = 4。

示例 2:

plaintext

输入: timeSeries = [1,2], duration = 2
输出: 3
解释:
第 1 秒,提莫攻击艾希并使其立即中毒,中毒状态会持续 2 秒,即第 1、2 秒。
第 2 秒,提莫再次攻击艾希,此时艾希还在中毒中,中毒时间会被重置为 2 秒,即第 2、3 秒。
总中毒时间为 3。

提示:

  • timeSeries 是一个非递减序列
  • timeSeries.length <= 10^4
  • timeSeries[i], duration 是非负整数,且不会超过 107

解题思路(核心:贪心 / 区间合并)

这道题本质是区间合并问题

  1. 每次攻击生成一个中毒区间:[timeSeries[i], timeSeries[i] + duration - 1]
  2. 如果新攻击落在上一次中毒区间内,说明中毒时间重叠,只需要累加两次攻击的间隔时间
  3. 如果新攻击在中毒结束后,说明不重叠,直接累加完整中毒时长
  4. 最后一次攻击一定是完整中毒时长,单独加上即可

一句话总结:重叠取间隔,不重叠取完整,最后补最后一次攻击!


Java 完整代码(可直接提交)

java

运行

class Solution {
    public int findPoisonedDuration(int[] timeSeries, int duration) {
        // 边界情况:没有攻击,中毒时间为 0
        if (timeSeries.length == 0) {
            return 0;
        }
        
        // 记录总中毒时间
        int total = 0;
        
        // 从第二次攻击开始遍历,和前一次攻击比较
        for (int i = 1; i < timeSeries.length; i++) {
            // 上一次攻击的中毒结束时间
            int prevEnd = timeSeries[i - 1] + duration - 1;
            // 当前攻击的开始时间
            int currStart = timeSeries[i];
            
            if (currStart <= prevEnd) {
                // 中毒时间重叠:只累加两次攻击的间隔
                total += currStart - timeSeries[i - 1];
            } else {
                // 中毒时间不重叠:累加完整的中毒时长
                total += duration;
            }
        }
        
        // 最后一次攻击一定是完整中毒时长,必须单独加上
        total += duration;
        return total;
    }
}

代码逐行解析

  1. 边界判断:如果攻击时间数组为空,直接返回 0
  2. 遍历逻辑:从第 2 次攻击开始,和前一次对比,避免越界
  3. 重叠判断
    • 重叠:currStart <= prevEnd → 只加时间差(因为中毒被重置了)
    • 不重叠:直接加完整 duration
  4. 最后一次攻击:循环里只处理了前 n-1 次,最后一次必须单独补全

复杂度分析

  • 时间复杂度:O(n),只遍历一次数组,效率极高
  • 空间复杂度:O(1),仅使用常数额外空间,最优解

测试代码(本地运行)

java

运行

public class Main {
    public static void main(String[] args) {
        Solution solution = new Solution();
        
        // 测试用例 1
        int[] timeSeries1 = {1, 4};
        System.out.println(solution.findPoisonedDuration(timeSeries1, 2)); // 输出 4
        
        // 测试用例 2
        int[] timeSeries2 = {1, 2};
        System.out.println(solution.findPoisonedDuration(timeSeries2, 2)); // 输出 3
    }
}

文末小总结

这道题是贪心算法的入门经典题,核心就是判断区间是否重叠,掌握这个思路,同类区间合并题目都能轻松拿下!

...全文
115 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
m0_59305477 04-18 23:03
  • 打赏
  • 举报
回复

这道题有很多解法

151

社区成员

发帖
与我相关
我的任务
社区描述
这里专为新疆政法学院的探索者而建,英雄不问出处。起跑线是起点,热忱与坚持为加速器,无论bug缠身的项目,还是攻克的算法顿悟,每滴汗水皆被珍藏。执炬前行,终将照亮彼此峰顶,我们携手同行。
课程设计笔记经验分享 高校 新疆·图木舒克市
社区管理员
  • 雲中203
  • SHAO060706
  • 三叶草.
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

英雄不问出处

试试用AI创作助手写篇文章吧