1. 485. 最大连续 1 的个数
1.1 分析题意
- 首先:我们求的是连续的1的个数,所以我们不能也没必要对数组进行排序;
- 其次:只要求求出最大连续1的个数,并不要求具体的区间数目,所以我们只需要用一个值来记录这个结果;
1.2 思路分析:
一个for循环遍历数组里面的每一个元素,当前元素有两种情况:
- 当前元素为
1
,那就将temp+1
; - 如果当前元素不是
1
,那就更新ans
并将temp
重置为0
;
1.3 复杂度分析
时间复杂度:O(n)
空间复杂度:O(1)
2. 495. 提莫攻击
2.1 题意理解
我觉得这道题的关键点在:
如果提莫在中毒影响结束前再次攻击,中毒状态计时器将会重置,在新的攻击之后,中毒影响将会在
duration
秒后结束。
翻译成人话就是:中毒期间再次中毒,会按照新的中毒终止时间计算。
2.2 思路分析
- 定义两个变量,
start
和end
分别表示当前中毒状态下的起始时间和终止时间,初始化为第一次中毒时的参数设置; - 然后遍历下一次中毒参数,此时会有两种情况:
- 下一次中毒的起始时间
next_start ≤ end
,这就导致中毒区间重置,所以我们将end
更新为新的next_end
; - 下一次中毒的起始时间
next_start > end
,这样不会导致中毒区间重置,所以我们将start
和end
记录的中毒区间放入ans
中,并将start
和end
更新为next_start
和next_end
; - 重复这个过程,遍历完数组;
- 下一次中毒的起始时间
- 将最后一个
start
和end
代表的中毒区间放入ans
中
2.3 复杂度分析
时间复杂度:O(n)
空间复杂度:O(1)
3. 414. 第三大的数
3.1 题意理解
找到一个无序数组中第三大的数字;如果这个是不存在第三大的数字,那就返回最大的数字。
3.2 思路分析
一个最简单的方法就是:将数字遍历,然后从后往前进行遍历,找到第三大的数字。
但是该方法的时间复杂度为:O(n*logn)
,空间复杂度为:O(logn)
另一种方法是:我们不需要排序,但是使用最传统的模拟方法:用三个值来记录所有数据中的最大的三个,具体来说:
- a > b > c
- 如果新数据 x > a,那么就 将 x, a, b 赋值给 a, b, c;
- 如果新数据 a > x > b, 那么就将 a, x, b 赋值给 a, b, c;
- 如果新数据 b > x > c, 那么就将 a, b, x 赋值给 a, b, c;
在实现的过程中,有一个细节就是:使用Integer
类型的变量,根据是否为null
来标识是否进行了赋值操作,这样就可以进行统一操作,而不需要记录已经记录的数目。
if(a == null || x > a){
c = b;
b = a;
a = x;
}else if(a > x && (b == null || x > b)){
c = b;
b = x;
}else if((b != null && b > x) && (c == null || x > c)){
c = x;
}
3.3 复杂度分析
时间复杂度:O(n)
空间复杂度:O(1)
4. 628. 三个数的最大乘积
4.1 题意理解
从数组中任意选出三个数,同一个数不可以重复取,求出可以达到的最大乘积。
4.2 思路分析
- 将数组中数据从小到大进行排序;
- 最大的值一定是以下情况中的一种:
- 如果都是负数:那就是最大的三个负数的乘积最大;
- 如果都是正数:那就是最大的三个正数的乘积最大;
- 如果有正有负:那就是下面两种情况的最大值
- 最大的三个正数
- 最小的两个负数 x 最大的正数
4.3 复杂度分析
时间复杂度:O(n*logn)
空间复杂度:O(logn)
本文来自博客园,作者:睡觉不打呼,转载请注明原文链接:https://www.cnblogs.com/404er/p/leetcode_array_traversal.html