最长连续序列

给定一个未排序的整数数组,找出最长连续序列的长度。

说明

要求你的算法复杂度为O(n)

样例

给出数组[100, 4, 200, 1, 3, 2],这个最长的连续序列是 [1, 2, 3, 4],返回所求长度 4

解题

排序后比较简单,快排O(nlogn)

后面只需要O(n)的时间复杂度求解了

发现原数组里面有重复数字的时候,下面方法行不通了。

 

public class Solution {
    /**
     * @param nums: A list of integers
     * @return an integer
     */
    public int longestConsecutive(int[] num) {
        // write you code here
        quickSort(num,0,num.length - 1);
        int maxLen = 1;
        int subLen = 1;
        if(num.length ==4){
            for(int i = 0;i< num.length;i++){
                System.out.print(num[i] + "\t");
            }
        }
        for(int i = 0;i<= num.length-2 ;i++){
            if(num[i] + 1 ==num[i+1]){
                subLen++;
            }else{
                subLen = 1;
                
            }
            maxLen = Math.max(maxLen,subLen);
        }
        return maxLen;
    }
    
    public void quickSort(int[] A,int low ,int high){
        if(low>= high)
            return;
        int i = low;
        int j = high;
        int tmp  = A[low];
        while(i<j){
            while(i<j && A[j] > tmp)
                j--;
            if(i<j){
                A[i] = A[j];
                i++;
            }
            
            while(i<j && A[i]<= tmp)
                i++;
            if(i<j){
                A[j] = A[i];
                j--;
            }
            
        }
        A[i] = tmp;
        quickSort(A,low,i-1);
        quickSort(A,i+1,high);
    }
}
View Code

稍作修改,对连续相等的说长度不变

public class Solution {
    /**
     * @param nums: A list of integers
     * @return an integer
     */
    public int longestConsecutive(int[] num) {
        // write you code here
        quickSort(num,0,num.length - 1);
        int maxLen = 1;
        int subLen = 1;
        // if(num.length ==4){
        //     for(int i = 0;i< num.length;i++){
        //         System.out.print(num[i] + "\t");
        //     }
        // }
        for(int i = 0;i<= num.length-2 ;i++){
            if(num[i] + 1 ==num[i+1]){
                subLen++;
            }else if(num[i]==num[i+1]){
                // 相等的时候不做处理
            }else{
                subLen = 1;
                
            }
            maxLen = Math.max(maxLen,subLen);
        }
        return maxLen;
    }
    
    public void quickSort(int[] A,int low ,int high){
        if(low <0 || high>A.length || low>= high)
            return;
        int i = low;
        int j = high;
        int tmp  = A[low];
        while(i<j){
            while(i<j && A[j] > tmp)
                j--;
            if(i<j){
                A[i] = A[j];
                i++;
            }
            
            while(i<j && A[i]<= tmp)
                i++;
            if(i<j){
                A[j] = A[i];
                j--;
            }
            
        }
        A[i] = tmp;
        quickSort(A,low,i-1);
        quickSort(A,i+1,high);
    }
}
View Code

但是96% 数据通过测试时,出现了快排的栈溢出

这个数据量是一万,同时还是完全逆序,网上的解释就是快排数据量太多了。

programcreek 上的方法

定义一个集合,去除了重复数,在每个数两边找,判断是否连续

public class Solution {
    /**
     * @param nums: A list of integers
     * @return an integer
     */
    public int longestConsecutive(int[] num) {
        // write you code here
        if(num.length <= 1)
            return num.length;
        Set<Integer> set = new HashSet<Integer>();
        for(int e:num)
            set.add(e);
        int max = 1;
        for(int e:num){
            int  count = 1;
            int left = e - 1;
            int right = e + 1;
            while(set.contains(left)){
                count++;
                set.remove(left);
                left--;
            }
            while(set.contains(right)){
                count++;
                set.remove(right);
                right++;
            }
            max = Math.max(max,count);
        }
        return max;
    }
}

Python 集合更方便

class Solution:
    """
    @param num, a list of integer
    @return an integer
    """
    def longestConsecutive(self, num):
        # write your code here
        s = set(num)
        Max = 1
        for e in num:
            count = 1
            left = e - 1
            right = e + 1
            while left in s:
                count+=1
                s.remove(left)
                left -=1
            while right in s:
                count+=1
                s.remove(right)
                right+=1
            Max = max(Max,count)
        return Max