DEV Community

Alkesh Ghorpade
Alkesh Ghorpade

Posted on • Originally published at alkeshghorpade.me

1

LeetCode - Longest Consecutive Subsequence

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.

Problem statement taken from: https://leetcode.com/problems/longest-consecutive-sequence

Example 1:

Input: nums = [100, 4, 200, 1, 3, 2]
Output: 4
Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4.
Enter fullscreen mode Exit fullscreen mode

Example 2:

Input: nums = [0, 3, 7, 2, 5, 8, 4, 6, 0, 1]
Output: 9
Enter fullscreen mode Exit fullscreen mode

Constraints:

- 0 <= nums.length <= 10^5
- -10^9 <= nums[i] <= 10^9
Enter fullscreen mode Exit fullscreen mode

Explanation

Sorting

The naive solution is to sort the array and find the longest consecutive elements.
After sorting the array, we remove the duplicate elements.
We run a loop that counts the current number and maximum length of the consecutive elements.
If the current number is not a consecutive element of the previous one,
we reset the counter to 1 and update the maximum length.

A C++ snippet of the above approach is as below:

int ans = 0, count = 0;

sort(array, array + n);

vector<int> v;
v.push_back(array[0]);

for (int i = 1; i < n; i++) {
    if (array[i] != array[i - 1])
        v.push_back(array[i]);
}

for (int i = 0; i < v.size(); i++) {
    if (i > 0 && v[i] == v[i - 1] + 1)
        count++;
    else
        count = 1;

    ans = max(ans, count);
}

return ans;
Enter fullscreen mode Exit fullscreen mode

The time complexity of the above approach is O(n(logn)) and space complexity is O(n).

HashMap

We can reduce the time complexity to O(n) by using a HashMap.
Let's check the algorithm directly.

- set n = nums.size()

- if n == 0
    return 0

- initialize map: map<int, int> m

- loop for i = 0; i < n; i++
  - m[nums[i]]++

- set prev = m.begin()
      maxLength = 1
      result = 0

- loop for i = m.begin(); i < m.end(); i++
  - if prev->first + 1 == i->first
    - maxLength++
  - else
    - result = max(result, maxLength)
    - maxLength = 1

  - prev = i

- return max(result, maxLength)
Enter fullscreen mode Exit fullscreen mode

The time complexity of the above approach is O(n), and the space complexity is O(n).

Let's check our algorithm in C++, Golang, and Javascript.

C++ solution

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        int n = nums.size();
        if(n == 0) return 0;

        map<int, int> m;

        for(int i = 0; i < n; i++) {
            m[nums[i]];
        }

        auto prev = m.begin();
        int maxLength = 1, result = 0;

        for(auto i = m.begin(); i != m.end(); i++) {
            if(prev->first + 1 == i->first) {
                maxLength++;
            } else {
                result = max(result, maxLength);
                maxLength = 1;
            }

            prev = i;
        }

        return max(result, maxLength);
    }
};
Enter fullscreen mode Exit fullscreen mode

Golang solution

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

func longestConsecutive(nums []int) int {
    n := len(nums)
    if n == 0 {
        return 0
    }

    m := make(map[int]int)

    for i := 0; i < n; i++ {
        m[nums[i]]++
    }

    maxLength, result := 1, 0

    for num := range m {
        if _, ok := m[num-1]; !ok {
            currNum := num
            maxLength = 1

            for {
                if _, ok := m[currNum+1]; ok {
                    currNum += 1
                    maxLength += 1
                } else {
                    break
                }
            }

            result = max(result, maxLength)
        }
    }

    return result
}
Enter fullscreen mode Exit fullscreen mode

Javascript solution

var longestConsecutive = function(nums) {
    const n = nums.length;
    if(n === 0) {
        return 0
    }

    let set = new Set(nums)

    let maxLength = 1, result = 0

    for(let num of set) {
        if(set.has(num - 1)) {
            continue;
        }

        let current = num
        maxLength = 1

        while(set.has(current + 1)){
            current++
            maxLength++
        }

        result = Math.max(result, maxLength)
    }

    return result
};
Enter fullscreen mode Exit fullscreen mode

Let's dry-run our algorithm for Example 1.

Input: nums = [100, 4, 200, 1, 3, 2]

Step 1: int n = nums.size()
            n = 6

Step 2: n == 0
        6 == 0
        false

Step 3: map<int, int> m
        for(int i = 0; i < n; i++) {
            m[nums[i]];
        }

        m = {
            100: 0,
            4: 0,
            200: 0,
            1: 0,
            3: 0,
            2: 0,
        }

Step 4: prev = m.begin()
             = 1
        maxLength = 1
        result = 0

Step 5: loop for i = m.begin(); i != m.end()
            i = 1
            1 != m.end()
            true

            if prev->first + 1 == i->first
               1 + 1 == 1
               2 == 1
               false

            else
                result = max(result, maxLength)
                       = max(0, 1)
                       = 1

                maxLength = 1

            prev = i
                 = 1

            i++
            i -> 2

Step 6: loop for i != m.end()
            i = 2
            2 != m.end()
            true

            if prev->first + 1 == i->first
               1 + 1 == 2
               2 == 2
               true

               maxLength++
               maxLength = 2

            prev = i
                 = 2

            i++
            i -> 3

Step 7: loop for i != m.end()
            i = 3
            3 != m.end()
            true

            if prev->first + 1 == i->first
               2 + 1 == 3
               3 == 3
               true

               maxLength++
               maxLength = 3

            prev = i
                 = 3

            i++
            i -> 4

Step 8: loop for i != m.end()
            i = 4
            4 != m.end()
            true

            if prev->first + 1 == i->first
               3 + 1 == 4
               4 == 4
               true

               maxLength++
               maxLength = 4

            prev = i
                 = 4

            i++
            i -> 100

Step 9: loop for i != m.end()
            i = 100
            100 != m.end()
            true

            if prev->first + 1 == i->first
               4 + 1 == 100
               5 == 100
               false

            else
                result = max(result, maxLength)
                       = max(1, 4)
                       = 4

                maxLength = 1

            prev = i
                 = 100

            i++
            i -> 200

Step 10: loop for i != m.end()
            i = 200
            200 != m.end()
            true

            if prev->first + 1 == i->first
               100 + 1 == 200
               101 == 200
               false

            else
                result = max(result, maxLength)
                       = max(4, 4)
                       = 4

                maxLength = 4

            prev = i
                 = 200

            i++
            i -> end

Step 11: loop for i != m.end()
            false

Step 12: return max(result, maxLength)

We return the answer as 4.
Enter fullscreen mode Exit fullscreen mode

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

The Most Contextual AI Development Assistant

Pieces.app image

Our centralized storage agent works on-device, unifying various developer tools to proactively capture and enrich useful materials, streamline collaboration, and solve complex problems through a contextual understanding of your unique workflow.

👥 Ideal for solo developers, teams, and cross-company projects

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay