LeetCode热题100前3题解析

206 阅读2分钟

难度标识:⭐:简单,⭐⭐:中等,⭐⭐⭐:困难

tips:这里的难度不是根据LeetCode难度定义的,而是根据我解题之后体验到题目的复杂度定义的。

哈希

1.两数之和

  • 经典LeetCode第一题。

代码:

var twoSum = function (nums, target) {
    // 直接遍历数组,做差值寻找另一个数的下标 
    for (let i = 0; i < nums.length; i++) {
        const index = nums.indexOf(target - nums[i])
        if (index !== -1 && index !== i) {
            return [i, index]
        }
    }
}

上面这种写法的时间复杂度是 O(n²),空间复杂度是 O(1)

var twoSum = function (nums, target) {
    // 定义一个对象判断差值是否存在
    const obj = {}
    for (let i = 0; i < nums.length; i++) {
        const num = target - nums[i]
        if (obj[num] !== undefined) {
            return [i, obj[num]]
        }
        obj[nums[i]] = i
    }
}

上面 if(obj[num] !== undefined) 为什么不写成 if(obj[num]) ,这是处理 obj[num] 为0的情况。

上面这种写法的时间复杂度是 O(n),空间复杂度是 O(n)

2.字母异位词分组

思路:将数组中的每个字符串进行排序,然后排序相同的push到同一个数组中。

代码:

var groupAnagrams = function (strs) {
    const obj = {}
    for (let s of strs) {
        const sOrder = s.split('').sort().join('')
        if (!obj[sOrder]) {
            obj[sOrder] = []
        }
        obj[sOrder].push(s)
    }
    return Object.values(obj)
}

3.最长连续序列 ⭐⭐

思路:

  • 1.将数组放到一个Set集合中,因为题目不要求序列元素在原数组中连续,所以可以去重。

  • 2.遍历集合,如果当前数num-1不在集合中,那么当前数就是起点,然后判断后续num+1在不在集合中,在的话一直+1判断,一直到num+1不在集合中时,然后计算序列长度。

解这题的关键就是找到每个序列段的起点。不明白的也可以看这个视频

代码:

var longestConsecutive = function (nums) {
    const set = new Set(nums)
    let count = 0
    for (let num of set) {
        if (!set.has(num - 1)) {
            let val = num + 1
            while (set.has(val)) val++;
            count = Math.max(count, val - num)
        }
    }
    return count
}

时间复杂度:

  1. const set = new Set(nums):创建一个 Set 需要遍历整个 nums 数组,因此时间复杂度为 O(n)。

  2. 循环:for (let num of set):最坏的情况是遍历整个 set,即 O(n)。

    • 检查 set.has(num - 1) 的时间复杂度为 O(1)。

    • while (set.has(val)) val++;:这个循环可能看起来是一个内部循环,让人觉得是二重循环。但实际上,由于一个数字只会进入这个循环一次(之后它的前一个数字会在Set中,所以不会再执行该循环),因此,所有数字总共进入这个 while 循环的次数最多是 n 次。因此,这个循环的累积时间复杂度是 O(n)。

    • count = Math.max(count, val - num):时间复杂度为 O(1)。

  • 因此,整个代码块的时间复杂度是:

O(n)+O(n)×O(1)+O(1)+O(n))=O(n)+O(2n)=O(3n)=O(n)

所以,整体时间复杂度为 O(n)。