128.最长连续序列

image-20200606204647942

哈希表+双指针

思路

  • 先排序,后遍历
  • 题目要求找出最长连续序列的长度,注意是找出,所以数组中的元素有可能是重复的。
  • 如何排除重复值,很容易就想到Set集合,所以转成Set集合
  • 后续的遍历用到双指针,为了便于操作又把Set集合转数组,再排序。
  • 因为用到Arrays.sort(),其时间复杂度 为O(nlogn),其实是不符合所要求的O(n),但偷懒更快乐。

代码

/**
     * 5~7ms
     *
     * 若Set的实现类改成LinkedHashSet(保证插入顺序 和遍历取出顺序一致)  7ms
     */
    public static int longestConsecutive(int[] nums) {
        int ans = 0;
        if (nums == null || nums.length == 0) return ans;
        if (nums.length == 1) return 1;
        Set<Integer> set=new HashSet<>();
        for(int num:nums){
            set.add(num);
        }
        int[] nums2=new int[set.size()];
        int count=0;
        for(int num:set){
            nums2[count++]=num;
        }
        if(nums2.length==1) return 1;
        Arrays.sort(nums2);
        int len = nums2.length, start = 0, end = 1;
        while (end < len) {
            if (start == end) {
                ans = Math.max(ans, 1);
            } else {
                if(nums2[end]-nums2[end-1]!=1){
                    ans = Math.max(ans, end - start);
                    start = end;
                    ans = Math.max(ans, 1);
                }else{
                    ans=Math.max(ans, end-start+1);
                }
            }
            end++;
        }
        return ans;
    }

优化

  • 由上面臃肿的代码可以发现空间开销还是有点大的
  • 对于重复值,可以不用Set加工,只需在对排序后的数组遍历时,用continue跳过即可。

代码

//2ms 
public static int longestConsecutive2(int[] nums){
        int max=0;
        if(nums==null||nums.length==0) return max;
        Arrays.sort(nums);  						//O(nlogn)
        int curLen=1;max=1;
        for(int i=1,len=nums.length;i<len;i++){     //O(n)
            if(nums[i]-nums[i-1]==1){
                curLen++;
            }else if(nums[i]==nums[i-1]){		    //重复值跳过
                continue;
            }else{
                max=Math.max(max,curLen);
                curLen=1;
            }
        }
        return Math.max(max, curLen);
    }

posted @ 2020-06-06 21:10  YH_Simon  阅读(90)  评论(0编辑  收藏  举报