leetcode热门100题之哈希解法

139 阅读3分钟

hot100之哈希

热门100中, 以下三题适用于哈希解决

  1. 两数之和(第1题easy)
  2. 字母异位词分组(第49题medium)
  3. 最长连续序列(第128题medium)

哈希在js中可以简单理解为就是键值对, 可以是Object/Array/Map/Set.

哈希为什么能解决这类问题, 就是利用键找到对应值的时间复杂度为O (1).

两数之和(第1题easy)

题目描述

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回答案。

解题

原理: 遍历数组, 判断哈希中是否有差值, 如果有则找到答案, 如果没有则将当前值存入哈希

// 也可以存入差值, 判断当前值是否存在
var twoSum = function (nums, target) {
  // 初始化哈希表
  const map = new Map()
  for (let i = 0; i < nums.length; i++) {
    const now = nums[i]
    // 和目标值的差值
    const diff = target - now
    if (map.has(diff)) {
      // 如果差值存在, 则证明找到
      return [map.get(diff), i]
    } else {
      // 存入当前值
      map.set(now, i)
    }
  }
  // 没有答案, 返回失败值
  return [-1, -1]
}

字母异位词分组(第49题medium)

题目描述

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

解题

原理: 将字符串排序后存入哈希, 排序后的字母异位词将相等

var groupAnagrams = function (strs) {
  // 初始化哈希
  const map = new Map()
  for (let str of strs) {
    // 将字符串排序, 使得字母异位词存在同一个键下
    const sortStr = str.split('').sort().join('')
    if (map.has(sortStr)) {
      map.get(sortStr).push(str)
    } else {
      map.set(sortStr, [str])
    }
  }
  // 返回结果
  return [...map.values()]
}

最长连续序列(第128题medium)

题目描述

给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

请你设计并实现时间复杂度为 O(n) 的算法解决此问题。

解题

原理: 将数组存入哈希, 对每个元素判断, 如果-1不存在则是连续序列的开始.

var longestConsecutive = function (nums) {
  // 初始化哈希, 之所以使用Set, 是因为初始化数组到哈希, Set比较方便
  const set = new Set(nums)
  let maxLen = 0
  for (let num of nums) {
    // 关键判断, 如果它之前的数字不存在, 证明当前这个数字是一个潜在的最长连续序列的开始
    if (!set.has(num - 1)) {
      // 以当前数字开始的长度
      let len = 1
      // 相当于当前数字+1, +2, +3...存在, 可以求出当前数字开始的连续序列的长度
      while (set.has(num + len)) {
        len++
      }
      // 更新最长长度
      maxLen = Math.max(maxLen, len)
    }
  }
  // 返回结果
  return maxLen
}