🛠️ Settings
Problem Statement
Given an array nums
of n
integers, return the length of the longest sequence of consecutive integers. The integers in this sequence can appear in any order.
Examples
Example 1:
Input: nums = [100, 4, 200, 1, 3, 2]
Output: 4
Explanation: The longest sequence of consecutive elements in the array is [1, 2, 3, 4], which has a length of 4.
Example 2:
Input: nums = [0, 3, 7, 2, 5, 8, 4, 6, 0, 1]
Output: 9
Explanation: The longest sequence of consecutive elements in the array is [0, 1, 2, 3, 4, 5, 6, 7, 8], which has a length of 9.
Different Approaches
1️⃣ Brute Force Approach
Intuition:
Make use of linear search, for each number x
in the array, we will check if the next numbers like x + 1
, x + 2
, x + 3
, and so on, are also in the array and maintain a counter.
Approach:
- As you iterate through each number in the array, begin by checking if consecutive numbers like ( x+1, x+2, x+3 ), and so on, exist in the array. The occurrence of the next consecutive number can be checked by using linear search.
- When you find consecutive numbers, start counting them using a counter. Increment this counter each time you find the next consecutive number in the sequence.
- This counter effectively keeps track of how long the current consecutive sequence is as you move through the array and find more consecutive numbers.
Code:
#include <bits/stdc++.h>
using namespace std;
class Solution {
private:
// Helper function to perform linear search
bool linearSearch(vector<int>& a, int num) {
int n = a.size();
// Traverse through the array
for (int i = 0; i < n; i++) {
if (a[i] == num)
return true;
}
return false;
}
public:
// Function to find the longest consecutive sequence
int longestConsecutive(vector<int>& nums) {
// If the array is empty
if (nums.size() == 0) {
return 0;
}
int n = nums.size();
// Initialize the longest sequence length
int longest = 1;
// Iterate through each element in the array
for (int i = 0; i < n; i++) {
// Current element
int x = nums[i];
// Count of the current sequence
int cnt = 1;
// Search for consecutive numbers
while (linearSearch(nums, x + 1) == true) {
// Move to the next number in the sequence
x += 1;
// Increment the count of the sequence
cnt += 1;
}
// Update the longest sequence length found so far
longest = max(longest, cnt);
}
return longest;
}
};
int main() {
vector<int> a = {100, 4, 200, 1, 3, 2};
// Create an instance of the Solution class
Solution solution;
// Function call for longest consecutive sequence
int ans = solution.longestConsecutive(a);
cout << "The longest consecutive sequence is " << ans << "\n";
return 0;
}
Complexity Analysis:
- Time Complexity:
O(n^2)
, wheren
is the size of given array.- Since we are using nested loops each running for approximately
n
times. The outer loop traverses for finding the consecutive sequence of every element and the inner loop works for checking if the next value exists in the array or not.
- Since we are using nested loops each running for approximately
- Space Complexity:
O(1)
2️⃣ Better Approach (Sorting)
Approach:
- Sort the Array: By sorting the array, consecutive numbers will be placed next to each other. This will help in easily detecting the longest sequence of consecutive numbers.
- Iterate Through the Array: After sorting, iterate through the array and compare each element with the next one. If two consecutive elements are the same or differ by more than 1, reset the current streak of consecutive numbers. If they differ by 1, continue counting the streak.
- Track the Maximum Length: During the iteration, maintain the current length of the consecutive sequence and the maximum length found.
Code:
#include <vector>
#include <algorithm>
using namespace std;
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
if (nums.empty()) return 0;
// Sort the array
sort(nums.begin(), nums.end());
// Variables to track the longest streak
int maxLength = 1, currentLength = 1;
// Iterate through the sorted array to find the longest consecutive sequence
for (int i = 1; i < nums.size(); i++) {
// If current number is the same as the previous number, skip it
if (nums[i] == nums[i - 1]) {
continue;
}
// If the current number is consecutive to the previous number
if (nums[i] == nums[i - 1] + 1) {
currentLength++;
} else {
// Reset the streak
maxLength = max(maxLength, currentLength);
currentLength = 1; // Reset for new sequence
}
}
// After the loop, check the last streak
maxLength = max(maxLength, currentLength);
return maxLength;
}
};
Explanation:
- Sorting: We first sort the array in ascending order. This allows consecutive numbers to be adjacent in the sorted array.
- Iterating Through the Sorted Array:
- We iterate through the sorted array from the second element to the last.
- For each element, check if it is the same as the previous element (to avoid duplicates) or if it is one more than the previous element. If it's one more, it means we are still in a consecutive sequence, so we increment the current sequence length.
- If the current element is not consecutive to the previous one, we compare the current sequence length with the maximum length found so far, update
maxLength
if necessary, and reset the current sequence length.
- Final Update: After the loop, we need to check if the last sequence we were counting was the longest one. Therefore, we do a final comparison to update
maxLength
.
Complexity Analysis:
- Time Complexity:
O(n log n) + O(n)
- Sorting the array takes
O(n log n)
time - Iterating through the array takes
O(n)
time.
- Sorting the array takes
- Space Complexity:
O(1)
3️⃣ HashSet
Intuition:
- Insert all elements into a HashSet: This allows us to check for the presence of any element in constant time,
O(1)
. - Iterate through each number in the array:
- For each number, check if it is the start of a sequence. This is true if the number-1 is not in the set.
- If it’s the start of a sequence, count the length of the consecutive sequence starting from this number by checking if
num + 1
,num + 2
, etc., exist in the set.
- Update the maximum sequence length as you go.
Algorithm:
- Insert all elements in the array into a
HashSet
. - For each element, check if it's the start of a sequence.
- Count the length of the consecutive sequence starting from that element.
- Track the maximum length encountered.
Dry Run:
+-----+-----+-----+-----+-----+-----+
nums = | 100 | 4 | 200 | 1 | 3 | 2 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
Step 1: Insert elements into the unordered_set:
+-----+-----+-----+-----+-----+-----+
nums = | 100 | 4 | 200 | 1 | 3 | 2 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
longestCount = 0
unordered_set
+-----+
| 100 |
+-----+
| 4 |
+-----+
| 200 |
+-----+
| 1 |
+-----+
| 3 |
+-----+
| 2 |
+-----+
Iterate through the nums:
+-----+-----+-----+-----+-----+-----+
nums = | 100 | 4 | 200 | 1 | 3 | 2 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^
|
i
unordered_set
+-----+
| 100 |
+-----+
| 4 |
+-----+
| 200 |
+-----+
| 1 |
+-----+
| 3 |
+-----+
| 2 |
+-----+
longestCount = 0
Iteration 1: i = 0
Check if it is the starting point by finding
the nums[i] - 1 exist in the set or not.
nums[0] - 1
100 - 1
99, does not exist in the set.
Set currentStreak = 1
Look for the next item in the set
Does nums[i] + 1, exist
nums[0] + 1
100 + 1
101, does not exist,
means streak is broken
Update longestCount with the max of
longestCount and currentStreak.
longestCount = max(longestCount, currentStreak)
= max(0, 1)
= 1
Iteration 2: i = 1
+-----+-----+-----+-----+-----+-----+
nums = | 100 | 4 | 200 | 1 | 3 | 2 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^
|
i
longestCount = 1
unordered_set
+-----+
| 100 |
+-----+
| 4 |
+-----+
| 200 |
+-----+
| 1 |
+-----+
| 3 |
+-----+
| 2 |
+-----+
Check nums[i] if it is the starting point by
finding the nums[i] - 1 exist in the set or not.
nums[1] - 1
4 - 1
3, does exist in the set.
Iteration 3: i = 2
+-----+-----+-----+-----+-----+-----+
nums = | 100 | 4 | 200 | 1 | 3 | 2 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^
|
i
longestCount = 1
unordered_set
+-----+
| 100 |
+-----+
| 4 |
+-----+
| 200 |
+-----+
| 1 |
+-----+
| 3 |
+-----+
| 2 |
+-----+
Check nums[i] if it is the starting point by
finding the nums[i] - 1 exist in the set or not.
nums[2] - 1
200 - 1
199, does not exist in the set.
means it is the starting of new streak.
Set currentStreak = 1
Look for the next item in the set
Does nums[i] + 1, exist
nums[2] + 1
200 + 1
201, does not exist,
means streak is broken
Update longestCount with the max of
longestCount and currentStreak.
longestCount = max(longestCount, currentStreak)
= max(1, 1)
= 1
Iteration 4: i = 3
+-----+-----+-----+-----+-----+-----+
nums = | 100 | 4 | 200 | 1 | 3 | 2 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^
|
i
longestCount = 1
unordered_set
+-----+
| 100 |
+-----+
| 4 |
+-----+
| 200 |
+-----+
| 1 |
+-----+
| 3 |
+-----+
| 2 |
+-----+
Check nums[i] if it is the starting point by
finding the nums[i] - 1 exist in the set or not.
nums[3] - 1
1 - 1
0, does not exist in the set.
means it is the starting of new streak.
Set currentStreak = 1
Look for the next item in the set
Does nums[i] + 1, exist
nums[3] + 1
1 + 1
2, does exist,
increment currentStreak and look
for next number in set.
currentStreak = 2
nextNumber = 3
3, does exist,
increment currentStreak and look
for next number in set.
currentStreak = 3
nextNumber = 4
4, does exist,
increment currentStreak and look
for next number in set
currentStreak = 4
nextNumber = 5
5, does not exist
means the streak is broken.
Update longestCount with the max of
longestCount and currentStreak.
longestCount = max(longestCount, currentStreak)
= max(1, 4)
= 4
Iteration 5: i = 4
+-----+-----+-----+-----+-----+-----+
nums = | 100 | 4 | 200 | 1 | 3 | 2 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^
|
i
longestCount = 4
unordered_set
+-----+
| 100 |
+-----+
| 4 |
+-----+
| 200 |
+-----+
| 1 |
+-----+
| 3 |
+-----+
| 2 |
+-----+
Check nums[i] if it is the starting point by
finding the nums[i] - 1 exist in the set or not.
nums[4] - 1
3 - 1
2, does exist in the set.
Iteration 6: i = 5
+-----+-----+-----+-----+-----+-----+
nums = | 100 | 4 | 200 | 1 | 3 | 2 |
+-----+-----+-----+-----+-----+-----+
0 1 2 3 4 5
^
|
i
longestCount = 4
unordered_set
+-----+
| 100 |
+-----+
| 4 |
+-----+
| 200 |
+-----+
| 1 |
+-----+
| 3 |
+-----+
| 2 |
+-----+
Check nums[i] if it is the starting point by
finding the nums[i] - 1 exist in the set or not.
nums[5] - 1
2 - 1
1, does exist in the set.
Return the longestCount
, which would contain the longest sequence.
Code:
#include <iostream>
#include <vector>
#include <unordered_set>
#include <algorithm>
using namespace std;
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
if (nums.empty()) return 0;
unordered_set<int> numSet(nums.begin(), nums.end());
int longestSeq = 0;
for (int num : nums) {
// If it's the start of a sequence
if (numSet.find(num - 1) == numSet.end()) {
int currentNum = num;
int currentStreak = 1;
// Count the consecutive sequence starting from `num`
while (numSet.find(currentNum + 1) != numSet.end()) {
currentNum++;
currentStreak++;
}
// Update longest sequence length
longestSeq = max(longestSeq, currentStreak);
}
}
return longestSeq;
}
};
// Example usage
int main() {
Solution solution;
vector<int> nums = {100, 4, 200, 1, 3, 2};
cout << "Longest Consecutive Sequence Length: " << solution.longestConsecutive(nums) << endl;
return 0;
}
Complexity Analysis:
- Time Complexity:
O(n)+(2*n)
=O(3*n)
, wheren
is the size of the array.- The function takes
O(N)
to insert all elements into the set data structure. After that, for every starting element, we find the consecutive elements. Although nested loops are used, the set will be traversed at most twice in the worst case. Therefore, the time complexity isO(2xn)
instead ofO(n^2)
.
- The function takes
- Space Complexity:
O(n)
- As we store array elements in the set data structure.