💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨
前言
本栏目将记录博主暑假从0开始刷力扣的算法题,每一条题目我都会把知识点抽丝剥茧地进行分析,以便大家更好的理解和学习,话不多说,肝!
序号 | 标题 | 力扣序号 |
6 | 找到数组中消失的数字 | 448 |
7 | 最大连续1的个数 | 485 |
8 | 提莫攻击 | 495 |
1.找到数组中消失的数字
题目:
给你一个含 n
个整数的数组 nums
,其中 nums[i]
在区间 [1, n]
内。请你找出所有在 [1, n]
范围内但没有出现在 nums
中的数字,并以数组的形式返回结果。
示例 1:
输入:nums = [4,3,2,7,8,2,3,1] 输出:[5,6]
示例 2:
输入:nums = [1,1] 输出:[2]
解题思路:
对 1−n 的所有数字进行遍历,判断每个数字是否在数组中存在。
第一次遍历,把存在的数都赋值为true,第二次遍历,即选出不存在(false)的数存进数组。
代码(Java)
class Solution {
// 定义一个公开的方法,用于找到缺失的数字并返回它们的列表
public List<Integer> findDisappearedNumbers(int[] nums) {
// 创建一个空的ArrayList来存储结果
List<Integer> result = new ArrayList<>();
// 获取数组的长度
int n = nums.length;
// 创建一个布尔数组,用于记录1到n(包含n)中的每个数字是否出现过
// 数组长度为n+1是因为数组索引从0开始,但我们要检查的数字从1开始
boolean[] isPresnet = new boolean[n+1];
// 遍历输入数组中的每个数字
for (int num : nums) {
// 如果数字在有效范围内(即1到n之间),则标记对应的布尔数组元素为true
if (num >= 1 && num <= n) {
isPresnet[num] = true;
}
// 注意:如果num不在这个范围内,我们就不管它,因为题目只关心1到n之间的数字
}
// 再次遍历从1到n的每个数字
for (int i = 1; i <= n; i++) {
// 如果某个数字在输入数组中未出现过(即对应的布尔数组元素为false)
// 则将这个数字添加到结果列表中
if(!isPresnet[i]){
result.add(i);
}
}
// 返回包含所有缺失数字的列表
return result;
}
}
2.最大连续1的个数
题目:
给定一个二进制数组 nums
, 计算其中最大连续 1
的个数。
示例 :
输入:nums = [1,1,0,1,1,1] 输出:3 解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3
解题思路:
遍历数组,设置变量count来记录出现1的次数,设置变量maxCount来记录出现1的最大次数
注意:
遍历数组结束之后,需要再次使用当前的连续 1 的个数更新最大的连续 1 的个数,因为数组的最后一个元素可能是 1,且最长连续 1 的子数组可能出现在数组的末尾,如果遍历数组结束之后不更新最大的连续 1 的个数,则会导致结果错误。
代码(java):
class Solution {
public int findMaxConsecutiveOnes(int[] nums) {
int maxCount = 0, count = 0;
int n = nums.length;
for (int i = 0; i < n; i++) {
if (nums[i] == 1) {
count++;
} else {
maxCount = Math.max(maxCount,count);
count = 0;
}
}
maxCount = Math.max(maxCount,count);
return maxCount;
}
}
3.提莫攻击
题目:
在《英雄联盟》的世界中,有一个叫 “提莫” 的英雄。他的攻击可以让敌方英雄艾希(编者注:寒冰射手)进入中毒状态。
当提莫攻击艾希,艾希的中毒状态正好持续
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 。
解题思路:
- 初始化变量:
ans
:用于记录艾希处于中毒状态的总时间(秒)。expired
:表示上一次中毒状态应该结束的时间点(秒)。初始化为0,因为没有前一次攻击。
- 遍历攻击时间序列:
- 遍历提莫发起攻击的时间序列
timeSeries
。对于每个时间点timeSeries[i]
,我们都需要判断这次攻击对艾希中毒状态的影响。
- 遍历提莫发起攻击的时间序列
- 判断攻击与中毒状态的关系:
- 如果
timeSeries[i]
(当前攻击时间)大于等于expired
(上一次中毒结束时间),说明这次攻击是在上一次中毒状态结束后发起的,因此艾希会再次中毒duration
秒。我们直接将duration
加到ans
上。 - 如果
timeSeries[i]
小于expired
,说明这次攻击是在上一次中毒状态结束前发起的,中毒状态会重新计时。但艾希不会额外增加duration
秒的中毒时间,而是从当前攻击时间开始算起,再持续duration
秒。因此,我们需要计算从当前攻击时间点到上一次中毒结束时间点之间的时间差(expired - timeSeries[i]
),但这部分时间其实会被新的中毒状态所覆盖,所以我们只需要加上从当前攻击时间点到新中毒结束时间的时间(即timeSeries[i] + duration - expired
),并加到ans
上。
- 如果
- 更新中毒结束时间:
- 无论哪种情况,我们都需要更新
expired
为当前攻击后duration
秒的时间点,即expired = timeSeries[i] + duration
。
- 无论哪种情况,我们都需要更新
关键点
- 理解中毒状态的计时和重置机制。
- 利用
expired
变量来跟踪上一次中毒状态应该结束的时间点。 - 通过比较
timeSeries[i]
和expired
来判断攻击对中毒状态的影响。 - 适当地更新
ans
和expired
以反映中毒状态的变化。
class Solution {
public int findPoisonedDuration(int[] timeSeries, int duration) {
int ans = 0;
int expired = 0;
for (int i = 0; i < timeSeries.length; ++i) {
if (timeSeries[i] >= expired) {
ans += duration;
} else {
ans += timeSeries[i] + duration - expired;
}
expired = timeSeries[i] + duration;
}
return ans;
}
}
❤️❤️❤️小郑是普通学生水平,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄
💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍