Problem Statement
Given an unsorted array of integers nums, return the length of the longest consecutive elements sequence.
You must write an algorithm that runs in O(n) time.
Additional information
0 <= nums.length <= 10^5-10^9 <= nums[i] <= 10^9
Example 1:
Input: nums = [100, 4, 200, 1, 3, 2]
Output: 4
Example 2:
Input: nums = [0, 3, 7, 2, 5, 8, 4, 6, 0, 1]
Output: 9
Brute Force
Intuition
The simplest approach is to consider every number in the array as the potential start of a sequence. For each number x, we check if x + 1 exists in the array, then x + 2, and so on, counting the length of the sequence until we can't find the next number. We do this for every single number and keep track of the longest sequence found.
Algorithm
- Initialize
longest_streakto 0. - Iterate through each number
numin the arraynums. - For each
num, setcurrent_numtonumandcurrent_streakto 1. - While
current_num + 1exists in the array:
- Increment
current_numandcurrent_streak.
- Update
longest_streakwith the maximum oflongest_streakandcurrent_streak. - Return
longest_streak.
def longest_consecutive(nums: list[int]) -> int:
longest_streak = 0
for num in nums:
current_num = num
current_streak = 1
while current_num + 1 in nums:
current_num += 1
current_streak += 1
longest_streak = max(longest_streak, current_streak)
return longest_streak
Time & Space Complexity
Time complexity:
O(n^3)Reason: The outer loop runs
ntimes. Thewhileloop can run up tontimes in the worst case (e.g., if the sequence is1, 2, 3... n). Theinoperator in Python lists takesO(n)time. Total:O(n * n * n).Space complexity:
O(1)Reason: We only use a few variables for tracking streaks.
Sorting
Intuition
If the array were sorted, consecutive elements would be adjacent to each other. We could simply iterate through the sorted array and count the length of the current consecutive sequence, resetting the count whenever the sequence breaks. While this is intuitive and faster than brute force, sorting takes O(n log n), which does not meet the O(n) requirement.
Algorithm
- If the array is empty, return 0.
- Sort the array.
- Initialize
longestto 1 andcurrent_streakto 1. - Iterate through the sorted array from index 1.
- If the current number is the same as the previous one, skip it (duplicates don't break or extend a sequence).
- If the current number is exactly 1 greater than the previous one, increment
current_streak. - Otherwise, update
longestwith the max oflongestandcurrent_streak, and resetcurrent_streakto 1. - Return the maximum of
longestandcurrent_streak.
def longest_consecutive(nums: list[int]) -> int:
if not nums:
return 0
nums.sort()
longest = 1
current_streak = 1
for i in range(1, len(nums)):
if nums[i] == nums[i - 1]:
continue
if nums[i] == nums[i - 1] + 1:
current_streak += 1
else:
longest = max(longest, current_streak)
current_streak = 1
return max(longest, current_streak)
Time & Space Complexity
Time complexity:
O(n log n)Reason: The sorting operation dominates the complexity.
Space complexity:
O(1)orO(n)Reason: Depends on the sorting implementation (e.g., Python's Timsort uses
O(n)).
Hash Set (Optimal)
Intuition
To achieve O(n) time, we can use a Hash Set to allow O(1) lookups. The key insight is to identify the start of a sequence. A number x is the start of a sequence if x - 1 does not exist in the set. Once we find a start, we can simply count upwards (x + 1, x + 2, ...) to find the length of that specific sequence. This ensures we only visit each sequence once.
Algorithm
- Create a set
num_setfromnumsto remove duplicates and allowO(1)lookups. - Initialize
longestto 0. - Iterate through each number
nin the set. - Check if
n - 1exists in the set.
- If it does, then
nis not the start of a sequence, so we skip it. - If it does not, then
nis the start of a sequence.
- If
nis a start, check forn + 1,n + 2, etc., increasing thelengthcount until the sequence breaks. - Update
longestwith the maximum length found. - Return
longest.
def longest_consecutive(nums: list[int]) -> int:
num_set = set(nums)
longest = 0
for n in num_set:
# Check if 'n' is the start of a sequence
if (n - 1) not in num_set:
length = 0
while (n + length) in num_set:
length += 1
longest = max(length, longest)
return longest
Time & Space Complexity
Time complexity:
O(n)Reason: Although there is a
whileloop inside theforloop, each number is visited at most twice: once by theforloop and once by thewhileloop (only if it's part of a valid sequence lookup).Space complexity:
O(n)Reason: We use a set to store all unique elements of the array.
Track
| Question | Difficulty | Company | Access |
|---|
Meta