Skip to content

Latest commit

 

History

History
270 lines (222 loc) · 6.08 KB

File metadata and controls

270 lines (222 loc) · 6.08 KB

题目描述

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

 

示例 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 <= 104
  • -109 <= nums[i] <= 109

 

进阶:可以设计并实现时间复杂度为 O(n) 的解决方案吗?

 

注意:本题与主站 128 题相同: https://leetcode.cn/problems/longest-consecutive-sequence/

解法

方法一:排序

设 res 表示连续序列的最大长度,t 表示当前合法连续序列的长度,初始时 res = t = 1

先排序数组,然后从下标 1 开始遍历数组,判断 nums[i] 与前一个数 nums[i - 1] 的大小关系:

  • nums[i] == nums[i - 1],直接跳过;
  • nums[i] - nums[i - 1] == 1,说明是连续序列,t 自增,利用 res = max(res, t) 更新最大长度;
  • 否则 t 重置为 1,继续往下遍历。

时间复杂度 $O(nlogn)$,空间复杂度 $O(1)$

方法二:哈希表

设 res 表示连续序列的最大长度,初始为 0。哈希表 s 存放数组出现的每个元素。

遍历数组,以当前遍历到的元素 nums[i] 做为起点,循环判断 nums[i] + 1nums[i] + 2 ... 是否存在 s 中,并不断更新连续序列的最大长度。

在这个过程中,如果 nums[i], nums[i] + 1, nums[i + 2], ... 是一个连续序列,遍历下个元素 nums[i] + 1 时,其实无需再重复循环。因此,只需要判断 nums[i] - 1 是否在 s 中,是则直接跳过。

时间复杂度 $O(n)$,空间复杂度 $O(n)$

Python3

class Solution:
    def longestConsecutive(self, nums: List[int]) -> int:
        n = len(nums)
        if n < 2:
            return n
        nums.sort()
        res = t = 1
        for i in range(1, n):
            if nums[i] == nums[i - 1]:
                continue
            if nums[i] - nums[i - 1] == 1:
                t += 1
                res = max(res, t)
            else:
                t = 1
        return res
class Solution:
    def longestConsecutive(self, nums: List[int]) -> int:
        s, res = set(nums), 0
        for num in nums:
            if num - 1 not in s:
                t = 1
                next = num + 1
                while next in s:
                    t += 1
                    next += 1
                res = max(res, t)
        return res

Java

class Solution {
    public int longestConsecutive(int[] nums) {
        int n = nums.length;
        if (n < 1) {
            return n;
        }
        Arrays.sort(nums);
        int res = 1, t = 1;
        for (int i = 1; i < n; ++i) {
            if (nums[i] == nums[i - 1]) {
                continue;
            }
            if (nums[i] - nums[i - 1] == 1) {
                t += 1;
                res = Math.max(res, t);
            } else {
                t = 1;
            }
        }
        return res;
    }
}
class Solution {
    public int longestConsecutive(int[] nums) {
        Set<Integer> s = new HashSet<>();
        for (int num : nums) {
            s.add(num);
        }
        int res = 0;
        for (int num : nums) {
            if (!s.contains(num - 1)) {
                int t = 1, next = num + 1;
                while (s.contains(next++)) {
                    ++t;
                }
                res = Math.max(res, t);
            }
        }
        return res;
    }
}

C++

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        int n = nums.size();
        if (n < 2)
            return n;
        sort(nums.begin(), nums.end());
        int res = 1, t = 1;
        for (int i = 1; i < n; ++i) {
            if (nums[i] == nums[i - 1])
                continue;
            if (nums[i] - nums[i - 1] == 1) {
                ++t;
                res = max(res, t);
            } else {
                t = 1;
            }
        }
        return res;
    }
};
class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        unordered_set<int> s;
        for (int num : nums)
            s.insert(num);
        int res = 0;
        for (int num : nums) {
            if (!s.count(num - 1)) {
                int t = 1, next = num + 1;
                while (s.count(next++))
                    ++t;
                res = max(res, t);
            }
        }
        return res;
    }
};

Go

func longestConsecutive(nums []int) int {
	n := len(nums)
	if n < 2 {
		return n
	}
	sort.Ints(nums)
	res, t := 1, 1
	for i := 1; i < n; i++ {
		if nums[i] == nums[i-1] {
			continue
		}
		if nums[i]-nums[i-1] == 1 {
			t++
			res = max(res, t)
		}
	}
	return res
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}
func longestConsecutive(nums []int) int {
	s := make(map[int]bool)
	for _, num := range nums {
		s[num] = true
	}
	res := 0
	for _, num := range nums {
		if !s[num-1] {
			t, next := 1, num+1
			for s[next] {
				next++
				t++
			}
			res = max(res, t)
		}
	}
	return res
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

...