leetcode-HOT100-HashSet-最长连续序列(重思路)

题目描述:

给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

请你设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例:

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

解题思路:

(1)结合题目的要求我们可以提取到是快速查找+去重!立马联想到是用HashSet

为什么去重?因为如果给出的nums是1,2,2,3,4;我们最终也是要1,2,3,4,所以需要去重哦~~~~

(2)然后思考怎么实现?观察需求,需要类似1,2,3,4这样的连续的序列,也就是说要越来越大的连续序列,提取关键字:越来越大,且是一个比一个大1!

那可以得出,当我们找到1之后,我们需要判断2在里面吗?3在里面吗?4在里面吗?

即:num+1在里面吗?num+2在里面吗?num+3在里面吗?.........直到断掉!

(3)好,第二个要思考我们怎么找到这个1?也就是说我们怎么找到这个起始的数字?

可以发现,1 是连续序列里面开头的,即最小的!只要我们确定1最小即可!

推出=>有没有比1还小的在里面?即1-1是否存在?存在的话那么1就不是最小的了,不存在那我1就是最小的,我们就可以继续上面的num+1、num+2的判断了~~~

总结步骤:

  1. 把所有数字扔进哈希集合(去重+快速查找)。

  2. 遍历数组,找序列开头:对于每个数 num,检查 num-1 是否在集合中:

    • 如果 num-1 不存在,说明 num 可能是某个序列的开头。

    • 如果 num-1 存在,跳过(因为它不是开头)直接不检查了。

  3. 扩展序列:如果是开头,就不断检查 num+1num+2... 是否在集合中,直到断掉。

  4. 更新最长长度

JAVA代码实现:

import java.util.HashSet;
import java.util.Set;

public class LongestConsecutiveSequence {
    public int longestConsecutive(int[] nums) {
        Set<Integer> numSet = new HashSet<>();
        for (int num : nums) {
            numSet.add(num); // 所有数字存入HashSet
        }

        int maxLength = 0;

        for (int num : nums) {
            // 检查是否是序列开头(没有比它更小的数)
            if (!numSet.contains(num - 1)) {
                int currentNum = num;
                int currentLength = 1;

                // 向后扩展序列
                while (numSet.contains(currentNum + 1)) {
                    currentNum++;
                    currentLength++;
                }
                // 每次找到一个新序列时,需判断它是否比之前记录的更长
                maxLength = Math.max(maxLength, currentLength);
            }
        }

        return maxLength;
    }
}

解析查找过程:

第一个检查100:  100-1=99在不在里面?99不在!那么100可能就是开头的,继续100+1在不在?,不在!断了....

第二个检查4: 4-1=3在不在? 3在哦!!那直接不检查了

第三个检查200:  200-1=199在不在? 不在!继续200+1=201在不在?不在!断了....

第三个检查1:   1-1=0在不在?不在,继续1+1=2在不在?2存在!,1+2=3在不在?,3也存在,1+3=4在不在?4也存在!1=4=5在不在?5不在!!断了,最长就是1234了

第四个检查3: (不想写了T-T)

第五个检查2:(不想写了T-T)

为什么是 O(n) 时间复杂度?

虽然代码中有嵌套循环(for + while),但实际每个数字最多被访问 两次

  1. 第一次:在 for 循环中遍历到。

  2. 第二次:在 while 循环中作为某个序列的后续数字被检查。


既然这里用到了HashSet,那就补充一下这个知识点吧~~

HashSet

HashSet 是 Java 集合框架中的一个类,它实现了 Set 接口,基于哈希表(Hash Table)的数据结构。

HashSet特点:

  1. 基于哈希表实现
    • HashSet 内部使用哈希表来存储元素,哈希表是一种高效的数据结构,支持快速的插入、删除和查询操作
  2. 不允许重复元素/对象
    • HashSet 中的元素是唯一的,如果尝试添加重复元素,添加操作会被忽略。
    • 元素的唯一性是通过 equals() 和 hashCode() 方法来判断的
  3. 无序性
    • HashSet 不保证元素的顺序,元素的存储顺序可能与插入顺序不同。取决于 hash 后,再确定索引的结果
  4. 允许 null 元素
    • HashSet 允许存储 null 值,但只能存储一个 null
  5. 非线程安全
    • HashSet 不是线程安全的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值