LeetCode 128. Longest Consecutive Sequence(java)

本文介绍了解决寻找整数数组中最长连续元素序列的问题的三种方法。包括使用伪哈希表、HashMap以及HashSet的方法,并详细解释了每种方法的实现思路与代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.

解法一:用伪哈希表来记录每个数字,然后遍历一遍伪哈希表,找出最长的连续的不为0的长度,即可返回。但是这种方法的缺点:max - min可能会导致溢出,但是数组的长度最多只能放int的范围(0 ~ 2^31),因此,这个方法会导致溢出的可能。
public int longestConsecutive(int[] nums) {
        if (nums.length == 0) return 0;
        if (nums.length == 1) return 1;
        int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] < min) {
                min = nums[i];
            }
            if (nums[i] > max) {
                max = nums[i];
            }
        }
        long number = (long)max - (long)min + 1;
        int[] helper = new int[number];
        for (int i = 0; i < nums.length; i++) {
            helper[nums[i] - min]++;
        }
        int i = 0,result = 0;
        while (i < helper.length) {
            if (helper[i] != 0) {
                int length = 0;
                while (i < helper.length && helper[i++] != 0) {
                    length++;
                }
                if (length > result) {
                    result = length;
                }
            } else {
                i++;
            }
        }
        return result;
    }
解法二:HashMap,key存num值,value存这个num值可以组成的最长的连续子数组的长度,因此,每次update num的value值为(left + right + 1),left表示num = left时候的最长子数组长度,right表示num = right的时候最长子数组的长度,遍历数组同时maintain max的值,最后返回max即可。注意重复元素的处理!
public int longestConsecutive(int[] nums) {
        if (nums.length == 0) return 0;
        HashMap<Integer,Integer> map = new HashMap<Integer, Integer>();
        int max = 0;
        for (int i = 0; i < nums.length; i++) {
            if (!map.containsKey(nums[i])) {
                int num = nums[i];
                int left = map.containsKey(num - 1) ? map.get(num - 1) : 0;
                int right = map.containsKey(num + 1) ? map.get(num + 1) : 0;
                int sum = left + right + 1;
                if (sum > max) max = sum;
                //记住这里一定要把正在遍历的元素也po进去,为了保证下一次遍历此元素的时候可以跳过。
                map.put(num, sum);
                map.put(num - left, sum);
                map.put(num + right, sum);
            }
        }
        return max;
    }
解法三:(最优解法)用hashset,首先可以完成元素去重的功能,其次,遍历数组,每次po出这个数字,如果可以po出,那么就顺带po出所有可能的连续的周边数组直到找不到为止,同时更新最大的max值,最后返回max值。
public int longestConsecutive(int[] nums) {
        if (nums.length == 0) return 0;
        HashSet<Integer> set = new HashSet<Integer>();
        int max = 0;
        for (int i : nums) set.add(i);
        for (int i : nums) {
            if (set.remove(i)) {
                int pre = i - 1, next = i + 1;
                while (set.remove(pre)) pre--;
                while (set.remove(next)) next++;
                if (next - pre - 1 > max) max = next - pre - 1;
            }
        }
        return max;
    }
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值