从零开始刷力扣(一)

143 阅读1分钟

数组篇

数组的遍历(一)

485. 最大连续 1 的个数

示例 1:
输入:nums = [1,1,0,1,1,1]
输出:3

解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3.
示例 2:
输入:nums = [1,0,1,1,0,1]
输出:2

第一版思路:设置两个变量,一个用来保存连续为1的数量,一个用来保存最大连续为1的数量,当连续为1的数量发生变化的时候,与之前的最大数量进行对比,然后进行更新最大数量

    let n = 0,m = 0;
    nums.map((item, i) => {
        if (item === 1) {
            n++
            if (n > m) {
                m = n
            }
        } else {
            if (n > m) {
                m = n
            }
            n = 0
        }
    })
    return m
};

第二版思路:双指针的思路

首先想到要找到每个的连续的1的长度,然后对比得出最长的那个就行。用双指针来限定找到的连续为1的左右两个点,左指针为1的时候,右指针往后走,不断刷新最大长度的值,当右指针不为1了,说明到达了当前连续为1的最大长度,然后左指针到右指针下个位置(为什么要下个位置?因为最后右指针会加一,为了和右指针同步否则[0,1]这种,它一直不会都等于1),两个都为1的时候再次重复上面的过程,最终输出最大值。

    let l = 0,r = 0,max = 0;
    while (l <nums.length && r<nums.length) {
        if (nums[l] === 1 && nums[r] === 1) {
            max = Math.max(max, r-l+1)
        } else {
            l = r+1
        }
        r++
    }
    return max
};

495. 提莫攻击


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

第一版思路:

先定义一个保存最大秒数的变量,让去循环这个攻击时间的数组,用当前时间➕时间间隔去和下一个时间对比,大于下一个时间,说明下一个时间的时候还在中毒时间内,下个时间和当前时间的差值就是这个时间内中毒的时间,否则就是一个完整的中毒时间,最后在最后一次攻击后是一个完整中毒时间,全部累积下来就是最终的中毒时间。

    let max = 0;
    timeSeries.forEach((item, i) => {
        if (timeSeries[i + 1]) {
            if ((item + duration) < timeSeries[i + 1]) {
                max = max + duration
            } else {
                max = max + (timeSeries[i + 1] - item)
            }
        } else {
            max = max + duration
        }
    })
    return max
};

第二版思路:

算是第一版思路的进阶版吧,定义一个总的秒数和一个中间缓存的上一个节点➕完整时间到的下一个时间。如果下一个时间小于缓存的那个中间那个时间,说明时间有重合,只需要将现在的时间+完整时间间隔➖去之前缓存的时间就能得到这段间隔实际的中毒时间,最终返回累积的时间。

    let max = 0,temp = 0;
    timeSeries.forEach(item => {
        if (item > temp) {
            max = max + duration
        } else {
            max = max + (item + duration - temp)
        }
        temp = item + duration
    })
    return max
};