[LeetCode] 128. Longest Consecutive Sequence 求最長連續序列

Given an unsorted array of integers, find the length of the longest consecutive elements sequence.html

For example,
Given [100, 4, 200, 1, 3, 2],
The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4.java

Your algorithm should run in O(n) complexity.python

給一個非排序的整數數組,找出最長連續序列的長度。要求時間複雜度:O(n)。數組

解法1:要O(n)複雜度,排序顯然不行,要用hash table。將序列中的全部數存到一個unordered_set中。對於序列裏任意一個數A[i],能夠經過set立刻能知道A[i]+1和A[i]-1是否也在序列中。若是在,繼續找A[i]+2和A[i]-2,以此類推,直到將整個連續序列找到。爲了不在掃描到A[i]-1時再次重複搜索該序列,在從每次搜索的同時將搜索到的數從set中刪除。直到set中爲空時,全部連續序列搜索結束。this

解法2: 參考自:StefanPochmannspa

First turn the input into a set of numbers. That takes O(n) and then we can ask in O(1) whether we have a certain number.Then go through the numbers. If the number x is the start of a streak (i.e., x-1 is not in the set), then test y = x+1, x+2, x+3, ... and stop at the first number y not in the set. The length of the streak is then simply y-x and we update our global best with that. Since we check each streak only once, this is overall O(n). This ran in 44 ms on the OJ, one of the fastest Python submissions.code

 

其它參考:GeeksforGeekshtm

1) Create an empty hash.
2) Insert all array elements to hash.
3) Do following for every element arr[i]
  a) Check if this element is the starting point of a subsequence. To check this, we simply look forarr[i] - 1 in hash, if not found, then this is the first element a subsequence.
If this element is a first element, then count number of elements in the consecutive starting with this element.blog

If count is more than current res, then update res.排序

 

Java:

class Solution {
    public static int longestConsecutive(int[] num) {
      // if array is empty, return 0
      if (num.length == 0) {
        return 0;
      }

      Set<Integer> set = new HashSet<Integer>();
      int max = 1;

      for (int e : num)
        set.add(e);

      for (int e : num) {
        int left = e - 1;
        int right = e + 1;
        int count = 1;

        while (set.contains(left)) {
          count++;
          set.remove(left);
          left--;
        }

        while (set.contains(right)) {
          count++;
          set.remove(right);
          right++;
        }

        max = Math.max(count, max);
      }

      return max;
    }
}  

Java:

public int longestConsecutive(int[] num) {
    int res = 0;
    HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
    for (int n : num) {
        if (!map.containsKey(n)) {
            int left = (map.containsKey(n - 1)) ? map.get(n - 1) : 0;
            int right = (map.containsKey(n + 1)) ? map.get(n + 1) : 0;
            // sum: length of the sequence n is in
            int sum = left + right + 1;
            map.put(n, sum);
            
            // keep track of the max length 
            res = Math.max(res, sum);
            
            // extend the length to the boundary(s)
            // of the sequence
            // will do nothing if n has no neighbors
            map.put(n - left, sum);
            map.put(n + right, sum);
        }
        else {
            // duplicates
            continue;
        }
    }
    return res;
}  

Java:

public int longestConsecutive(int[] nums) {
        Map<Integer,Integer> ranges = new HashMap<>();
        int max = 0;
        for (int num : nums) {
            if (ranges.containsKey(num)) continue;
            
            // 1.Find left and right num
            int left = ranges.getOrDefault(num - 1, 0);
            int right = ranges.getOrDefault(num + 1, 0);
            int sum = left + right + 1;
            max = Math.max(max, sum);
            
            // 2.Union by only updating boundary
            // Leave middle k-v dirty to avoid cascading update
            if (left > 0) ranges.put(num - left, sum);
            if (right > 0) ranges.put(num + right, sum);
            ranges.put(num, sum); // Keep each number in Map to de-duplicate
        }
        return max;
    } 

Java: 2

public int longestConsecutive(int[] nums) {
            Set<Integer> set = new HashSet<>();
            for(int n : nums) {
                set.add(n);
            }
            int best = 0;
            for(int n : set) {
                if(!set.contains(n - 1)) {  // only check for one direction
                    int m = n + 1;
                    while(set.contains(m)) {
                        m++;
                    }
                    best = Math.max(best, m - n);
                }
            }
            return best;
        }  

Python:

class Solution:
    # @param num, a list of integer
    # @return an integer
    def longestConsecutive(self, num):
        result, lengths = 1, {key: 0 for key in num}
        for i in num:
            if lengths[i] == 0:
                lengths[i] = 1
                left, right = lengths.get(i - 1, 0), lengths.get(i + 1, 0)
                length = 1 + left + right
                result, lengths[i - left], lengths[i + right] = max(result, length), length, length
        return result

Python: 2

def longestConsecutive(self, nums):
    nums = set(nums)
    best = 0
    for x in nums:
        if x - 1 not in nums:
            y = x + 1
            while y in nums:
                y += 1
            best = max(best, y - x)
    return best  

C++:

class Solution {
public:
    int longestConsecutive(vector<int> &num) {
        if(num.empty()) return 0;
        unordered_set<int> ht;
        for(int i=0; i<num.size(); i++)
            ht.insert(num[i]);
            
        int maxLen = 1;
        for(int i=0; i<num.size(); i++) {
            if(ht.empty()) break;
            int curLen = 0;
            int curNum = num[i];
            
            while(ht.count(curNum)) {
                ht.erase(curNum);
                curLen++;
                curNum++;
            }
            
            curNum = num[i]-1;
            while(ht.count(curNum)) {
                ht.erase(curNum);
                curLen++;
                curNum--;
            }
            
            maxLen = max(maxLen, curLen);
        }
        
        return maxLen;
    }
};

 

相似題目:

[LeetCode] 298. Binary Tree Longest Consecutive Sequence 二叉樹最長連續序列

 

All LeetCode Questions List 題目彙總

相關文章
相關標籤/搜索