128. Longest Consecutive Sequence

题目链接

我第一时间读到这个题,我的最开始的思路是:

将整个数据序列,构建一个只有两层的跳表,在构建的过程当中,把序列最长的信息,放在队列的头部 value 中,如果当前的数据属于最头部,那就把后面的头部数据,移动到最前面的数据来。每一个数据序列,都有一个向上的指针,二级链表(跳表的第二层),如果两个序列相连,则将后面的序列头部的 value 移除,从二级链表移除,代表它已经被前面的队列所吸收。构建完成之后 只需要将二级链表遍历一次即可。

我的思路会比较偏数据库,把整个队列在构建过程中流式的计算出来最长序列,类似并查集。但是题目并没有要求流式计算,并且希望能简单的得到答案,而无需涉及复杂的指针。

那么我们就使用传统思路了。

先把所有数据放在 map 中,然后遍历map:

  • 对每个元素X 如果 X-1 存在,则忽略。
  • 如果 X-1 不存在,则往后数,数到 X+N 断了则长度为 N

实现非常简单

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
func longestConsecutive(nums []int) int {
    maxSeq := 0
    m := make(map[int]int, len(nums))
    for _, number := range nums{
        m[number] = -1
    }

    for _, number := range nums {
        val := m[number]
        if val != -1{
            continue
        }
        _, hasPre := m[number - 1]
        if hasPre {
            continue
        }
        
        seqNumber := 1
        for i := number + 1; i < math.MaxInt64; i++{
            _, ok := m[i]
            if !ok{
                break
            }
            seqNumber += 1
        }
        if seqNumber >  maxSeq{
            maxSeq = seqNumber
        }

        m[number] = seqNumber
    }
    return maxSeq
}

性能足够好了

Licensed under CC BY-NC-SA 4.0
Built with Hugo
Theme Stack designed by Jimmy