LeetCode-128. Longest Consecutive Sequence

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zxm1306192988/article/details/80354945

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

要求算法的时间复杂度为 O(n)。

示例:

输入: [100, 4, 200, 1, 3, 2]
输出: 4
解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。

分析:
要求时间复杂度为 O(n)
如果先 Arrays.sort(nums) 排序, 时间复杂度取决于 排序的时间复杂度 ,一般为O(nlgn),大于要求的O(n)

采用 HashSet 存储数列,查找每个元素的时间复杂度为O(1),遍历所有HashSet 中所有元素,并且依次查找大于 该元素的元素,时间复杂度依然会到达 O(n2)

        for (int num : num_set) {
                int currentNum = num;
                int currentStreak = 1;
                while (num_set.contains(currentNum+1)) {
                    currentNum += 1;
                    currentStreak += 1;
                }

                longestStreak = Math.max(longestStreak, currentStreak);
        }

继续优化,我们每次只从可能是最长序列的最小的数开始计算,如果有比他小的就跳出,只查找了尽可能少的元素,这样时间复杂度可以达到 O(n)

class Solution {
    public int longestConsecutive(int[] nums) {
        Set<Integer> num_set = new HashSet<Integer>();
        for (int num : nums) {
            num_set.add(num);
        }

        int longestStreak = 0;

        for (int num : num_set) {
            if (num_set.contains(num - 1)) {//优化
                continue;
            }
            int currentNum = num;
            int currentStreak = 1;

            while (num_set.contains(currentNum + 1)) {
                currentNum += 1;
                currentStreak += 1;
            }

            longestStreak = Math.max(longestStreak, currentStreak);
        }
        return longestStreak;
    }
}

解法二:
比较容易想
依然用 HashSet 保存每个元素,查找时间复杂度为O(1)。
遍历 nums 数组,依次查找此元素是否在 num_set 中,依次找小于他的元素是否在 num_set 中,依次找大于他的元素是否在 num_set 中,如果在 就将其从 num_set 中移除,防止以后重复计算。

class Solution {
    public int longestConsecutive(int[] nums) {
        Set<Integer> num_set = new HashSet<Integer>();
        for (int num : nums) {
            num_set.add(num);
        }

        int longestStreak = 0;

        for (int num : nums) {
            if(!num_set.contains(num)){//如果num_set已不存在此元素,说明计算过,直接跳出
                continue;
            }
            int currentStreak=1;//记录本次找到序列的长度
            int downNum=num-1;
            while(num_set.contains(downNum)){//依次查找小于他的数
                currentStreak++;
                num_set.remove(downNum);
                downNum--;
            }

            int upNum=num+1;
            while(num_set.contains(upNum)){//依次查找大于他的数
                currentStreak++;
                num_set.remove(upNum);
                upNum++;
            }

            longestStreak = Math.max(longestStreak, currentStreak);
        }
        return longestStreak;
    }
}
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页