• [LeetCode] 128. Longest Consecutive Sequence 求最长连续序列


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

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

    Your algorithm should run in O(n) complexity.

    给一个非排序的整数数组,找出最长连续序列的长度。要求时间复杂度: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中为空时,所有连续序列搜索结束。

    解法2: 参考自:StefanPochmann

    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.

    其它参考:GeeksforGeeks

    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.

    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 题目汇总

  • 相关阅读:
    C#类继承情况下构造函数的执行过程
    vs快捷键大全(分类导航)
    vs常用快捷键
    Entity Framework实体无限循环问题
    entity framework实现left join功能
    理解requireJS-实现一个简单的模块加载器
    petshop4.0(王福朋)
    代码覆盖率工具 Istanbul 入门教程
    .net微信开发
    numpy的用法(一)
  • 原文地址:https://www.cnblogs.com/lightwindy/p/8692363.html
Copyright © 2020-2023  润新知