LeetCode Hot 100 (哈希)

36 阅读2分钟

哈希

两数之和

思路

利用 map:

  1. map 中的存储结构为 {key:数组元素值,value:数组元素值对应的下标}
  2. map 中存放我们访问过的元素

具体过程:

  • 在遍历数组时,只需要查询 map 中是否有和目前遍历元素比配的数值
  • 如果有,则返回该匹配对
  • 如果没有,则把目前遍历的元素放进 map 中

代码

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function (nums, target) {
    let map = {}
    for (let i = 0; i < nums.length; i++) {
        if (map[target - nums[i]] != undefined)
            return [map[target - nums[i]], i]
        map[nums[i]] = i
    }
    return []
};

字母异位词分组

思路

  1. 排序 + map
    • map 中的存储结构为 {key:排序后的字符串,value:对应 key 在字符串数组中的异位词组成的数组}
    • 将数组中的各字符串中的元素按照一定顺序排序,以排序后得到的字符串来区分各字符串的异位词分组
  2. 计数 + map
    • map 中的存储结构为 {key:字符串各字符频率对应的数组,value:对应 key 对应的字符串在字符串数组中的异位词组成的数组}
    • 对数组中的各字符串中的各元素进行计数并存入数组 count 中,以 count 数组来区分各字符串的异位词分组 ( count 数组的下标对应元素在字母表中的位置,从0开始 )

注意

代码

  1. 排序

    /**
     * @param {string[]} strs
     * @return {string[][]}
     */
    var groupAnagrams = function (strs) {
        let map = new Map()
        for (const str of strs) {
            let arr = Array.from(str)
            arr.sort()
            let str2 = arr.toString()
            let list = map.get(str2) ? map.get(str2) : []
            list.push(str)
            map.set(str2, list)
        }
        return Array.from(map.values())
    };
    
  2. 计数

    /**
     * @param {string[]} strs
     * @return {string[][]}
     */
    var groupAnagrams = function (strs) {
        let map = {}
        for (const str of strs) {
            const count = new Array(26).fill(0)
            for (const s of str) {
                count[s.charCodeAt() - 'a'.charCodeAt()]++
            }
            map[count] = map[count] ? map[count] : []
            map[count].push(str)
        }
        return Object.values(map)
    };
    

最长连续序列

思路:动态规划 + map

  1. map 中的存储结构为 {key:数组中的数字,value:对应 key 所在的已知连续序列的长度}
  2. 遍历数组:
    1. 若数字已在 map 中:跳过不做处理
    2. 若数字不在 map 中:
      • 取出其左右相邻数字所在的已知连续序列的长度 l 和 r
      • 计算当前数字所在的已知连续序列的长度:len = l + r + 1
      • 根据 len 更新最大长度 max 的值
      • 更新已知连续序列两端点数字对应的长度值

代码

/**
 * @param {number[]} nums
 * @return {number}
 */
var longestConsecutive = function (nums) {
    let map = {}, max = 0
    for (const n of nums) {
        if (!map[n]) {
            let l = map[n - 1]
            let r = map[n + 1]
            let len = (l || 0) + (r || 0) + 1

            max = len > max ? len : max

            map[n] = len
            if (l)
                map[n - l] = len
            if (r)
                map[n + r] = len
        }
    }
    return max
};