【前端刷题】128.最长连续序列(MEDIUM)

120 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情

题目(Longest Consecutive Sequence)

链接:https://leetcode-cn.com/problems/longest-consecutive-sequence
解决数:1535
通过率:54.8%
标签:并查集 数组 哈希表 
相关公司:google amazon bytedance 

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

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

 

示例 1:

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

示例 2:

输入: nums = [0,3,7,2,5,8,4,6,0,1]
输出: 9

 

提示:

  • 0 <= nums.length <= 105
  • -109 <= nums[i] <= 109

思路

  1. 先使用快速排序,得到有序数组。
  2. 声明一个对象obj,来存放队列。key是当前元素arr[0],value是个数组,初始化只存放一个当前元素arr[0]
  3. 使用临时变量记录该队列
  4. 遍历数组: a. 如果差值等于1,则给队列push当前元素; b. 如果差值为0,继续; c. 如果差值不为0,当前队列结束,启动下一个队列。key是当前元素arr[i],value是个数组,初始化只存放一个当前元素arr[i]
  5. 最后得到obj为 { '1': [ 1, 2, 3, 4 ], '100': [ 100 ], '200': [ 200 ] }
  6. Object.values(obj)得到[ [ 1, 2, 3, 4 ], [ 100 ], [ 200 ] ]
  7. .map(arr => arr.length)得到 [4, 1, 1]
  8. 最后Math.max(...[4, 1, 1])得到最大值

事件复杂度 O(nlogn)

快速排序:O(nlogn) for循环: O(n)

代码

/**
 * @param {number[]} nums
 * @return {number}
 */
var longestConsecutive = function(nums) {
  if (nums.length === 0) return 0
  const arr = nums.sort((a, b) => a - b)
  const obj = {}
  obj[arr[0]] = [arr[0]]
  let temp = obj[arr[0]]
  for (let i = 1; i < arr.length; i++) {
    const diff = arr[i] - temp[temp.length - 1]
    if (diff === 1) {
      temp.push(arr[i])
    } else if (diff === 0) {
      continue
    } else {
      obj[arr[i]] = [arr[i]]
      temp = obj[arr[i]]
    }
  }
  return Math.max(...Object.values(obj).map(arr => arr.length))
};

思路2

  • 要求算法的时间复杂度为 O(n),即限制了只能循环一次;
  • 先对数组排序
  • 循环数组记录后一个元素等于前一个元素+1或者等于前一个元素的数量
    • 满足条件++,不然重置
    • 与之前记录的值取最大值
  • 个人觉得和题目的限制,虽然排序是用数组原生的方法做的,但是应该是多了一次排序的循环
/**
 * @param {number[]} nums
 * @return {number}
 */
  var longestConsecutive = function (nums) {
      if (nums.length < 2) return nums.length;
      var _result = 1, middleValue = 1;
      nums.sort((a, b) => a - b)
      for (let index = 0; index < nums.length; index++) {
          if (nums[index] === nums[index + 1]) {
              continue // 跳出本次循环
          } else if (nums[index] + 1 === nums[index + 1]) {
              middleValue++
          } else {
              middleValue = 1
          }
          _result = Math.max(_result, middleValue);
      }
      return _result;
  };