最长连续序列

128 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天,点击查看活动详情

128. 最长连续序列 - 力扣(LeetCode)

给定一个未排序的整数数组 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 <= 10^5
  • -10^9 <= nums[i] <= 10^9

思路

看到这道题,第一反应就是排序后遍历求解,方法简单,但是并不符合题目时间复杂度为O(n) 的要求,参照解法一。
本题的难点在于如何使用O(1)的时间判断nums[i]的下一个连续数组nums[i] + 1是否也在数组nums中,首先想到的使用map来存储nums中的数字,然后遍历map,参照解法二。解法三用set代替map是一种讨巧的解法,借助set构造函数省去了map中遍历存储nums的步骤,思路是一样的。

解题

解法一

/**
 * @param {number[]} nums
 * @return {number}
 */
var longestConsecutive = function (nums) {
  const n = nums.length;
  if (n <= 1) return n;
  nums.sort((a, b) => a - b);
  let res = 1;
  let count = 1
  for (let i = 1; i < nums.length; i++) {
    const diff = nums[i] - nums[i - 1];
    if (diff === 1) {
      count++;
    } else if (diff > 1) {
      res = Math.max(count, res);
      count = 1;
    }
  }
  return Math.max(count, res);
};

解法二

/**
 * @param {number[]} nums
 * @return {number}
 */
var longestConsecutive = function (nums) {
  const n = nums.length;
  if (n <= 1) return n;
  const map = new Map();
  let res = 1;
  for (let i = 0; i < n; i++) {
    map.set(nums[i], 1);
  }
  for (let num of map.keys()) {
    if (map.has(num - 1)) {
      continue;
    }
    let count = 1;
    while (map.has(num + count)) {
      count++;
    }
    res = Math.max(count, res);
  }
  return res;
};

解法三

/**
 * @param {number[]} nums
 * @return {number}
 */
var longestConsecutive = function (nums) {
  const n = nums.length;
  if (n <= 1) return n;
  const set = new Set(nums);
  let res = 1;
  for (let i of set) {
    if (set.has(i - 1)) {
      continue;
    }
    let count = 1;
    while (set.has(i + count)) {
      count++;
    }
    res = Math.max(count, res);
  }
  return res;
};