leetCode128 最长连续序列

17 阅读2分钟

真题描述

hashMap+动态规划

哈希表的value存什么

  • key存数字,value存什么? value存储当前数字所处的连续序列的长度
  • 新存入的数字,如果它找到相邻的数,它希望从邻居数那里获取什么信息?
  • 很显然它希望,左邻居告诉它左边能提供的连续长度,右邻居告诉它右边能提供的连续长度
  • 加上它自己的长度,就有了自己处在的连续序列的长度
  • 即 maxLen(n) = maxLen(n-1)+maxLen(n+1) +1

2894864f20ba11062c1383215cabee48f423d8813ce291ff0ae7a3c58bbc780e-image.png

更新新序列的两端数字的value

  • 同处一个连续序列的数字的value理应都相同,这是它们共同特征
  • 但没有必要每个的value都是序列长度,只需要两端的数存序列的长度就好
  • 因为靠的是两端和新数对接,序列是连续的,中间没有空位
  • 序列的一端找到邻居后,将另一端对应的value更新为最新的序列长度

2222.png

/**
 * @param {number[]} nums
 * @return {number}
 */
var longestConsecutive = function(nums) {
    /**
        1. 哈希表
         1.1key存数字、value存什么? value存储当前数字所处的连续序列的长度
         1.2新存入的数字,如果它找到相邻的数,它希望从邻居数那里获取什么信息?
         1.3很显然它希望,左邻居告诉它左边能提供的连续长度,右邻居告诉它右边能提供的连续长度,再加上它自己的长度,就有了自己处在的连续序列的长度,即 maxLen(n) = maxLen(n-1)+maxLen(n+1) +1
        2. 更新新序列的两端数字value
         2.1同处于 一个连续序列的数字的value理应都相同
         2.2 但没有必要每个的value都是序列长度,只需要两端的数存序列的长度即可
         2.3 因为靠的是两端和新数对接,序列是连续的,中间是没有空位的
         2.4 序列的一段找到邻居后,将另一端对应的value更新为最新的序列长度  
     */
     // 初始化一个map,key为数字,value为 该数字所处的连续序列长度
     let map = new Map()
     let max = 0
    for(let i = 0;i<nums.length;i++){
        // 判断元素是否已经存入map
        if(!map.has(nums[i])) {
            // 获取左邻居所处的连续序列长度
            const pre = map.get(nums[i]-1) || 0
             // 获取右邻居所处的连续序列长度
            const next = map.get(nums[i]+1) || 0
            // 当前元素所处连续序列的长度 maxLen(n) = maxLen(n-1)+maxLen(n+1) +1
            let cur = pre+next+1
            // 设置map
            map.set(nums[i],cur)
            // 更新最大值
            max = Math.max(max,cur)
            // 更新连续序列两端的value值
            map.set(nums[i]-pre,cur)
            map.set(nums[i]+next,cur)
        }
    }
    map = null
    return max
};