[路飞]_最长连续序列

214 阅读1分钟

128. 最长连续序列

题目

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

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

示例1

输入: nums = [100,4,200,1,3,2]
输出: 4
解释: 最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。

题解

哈希表

个人思路

  • 时间复杂度要求o(n);空间换时间;枚举数组,将数组数据保存到map中
  • 第二次枚举数组,找到map中左侧和右侧相邻数据长度;因为得到长度后将map数据删除,防止多次查询
  • 得到map相邻长度最大值
  • 得到答案

代码

var longestConsecutive = function (nums) {
  // 时间复杂度要求o(n);空间换时间
  const map = {}
  for (let i = 0; i < nums.length; i++) {
    map[nums[i]] = nums[i]
  }
 // console.log('map', map[1])
  let result = 0
  for (let i = 0; i < nums.length; i++) {
    if (map[nums[i]] !== undefined) {
      const n = find(nums[i])
      result = Math.max(result, n)
    }
  }
  return result
  function find(n) {
    let num = 1
    let left = n - 1
    let right = n + 1
    map[n] = undefined
    while (map[left] !== undefined) {
      map[left] = undefined
      left--
      num++
    }

    while (map[right] !== undefined) {
      map[right] = undefined
      right++
      num++
    }

    return num
  }
}

优化

个人思路需要两次遍历数组,并且代码比较长,所以优化一下

优化后代码

var longestConsecutive = function (nums) {
  let len = nums.length
  if (len === 0) return 0
  let map = {}
  let max = 0
  for (let i = 0; i < len; i++) {
    const n = nums[i]
    if (map[n] === undefined) {
      let left = map[n - 1] || 0
      let right = map[n + 1] || 0
      let l = left + right + 1
      map[n] = l
      max = Math.max(max, l)
      map[n - left] = l
      map[n + right] = l
    }
    //console.log(map);
  }

  return max
}