求最长连续数列长度

输入一个乱序数列,输出其中连续数列的长度,要求算法复杂度为 O(n)

例如:输入 1,3,2,5,9,190 。那么连续数列就是 1,2,3 。输出:3

起始最简单的方法就是:先把数组排好序,然后查找最长连续数列。但是这样一来算法复杂度是: O(nlogn) + O(n) ,是不符合要求的。

要以算法复杂度为O(n)解决问题可以使用 hash map 。

思路:

我们在人工查找的时候思路是这样的: 从第一个数字看起,看到数字 1 ,就去找 0 和 2,发现没有 0 但是有 2,此时最长序列是 2,然后往下找 3 ,然后往下找 4..... , 如果当前数组的最左边和对右边都没有连续的数字了,那么当前最长数列的值就是: 当前数字左边连续数列长度 + 当前数字右边连续数列长度 + 1。

已给出的数组为例:第一个数值 1 左侧连续数列长度为 0 ,右侧连续数列的值有 2 和 3,长度为 2 ,则连续数列的长度 = 0 + 2 + 1 = 3 .....以此类推可以求出最长连续数列的值 。

1、先把所有数据 (nums数组) 都放进map (numsMap)中,以数值为 key,True为value ,去查找有没有当前数值的下一位的时候不去遍历 nums ,而是去 numsMap 的 allKeys 中查找。

2、遍历 nums ,以 left 记录 i 左侧连续数列长度, right 记录 i 右侧连续数列长度 , leftKey = i - 1 , rightKey = i + 1,  以 leftKey 和 rightKey 为 分别 key 去 numsMap 中查找,如果找到 left += 1 , right += 1 , leftKey -= 1 , rightKey -= 1 将当前键值对从 numsMap 中 pop 出去, 然后继续向下查找,直到 leftKey 和 rightKey 都找不到了 在整个 遍历过程中 maxLength = left + right + 1 。

下面是完成的 python 代码实现:

import sys

for line in sys.stdin:
    line = line.strip()
    nums = line.split(",")
    max_length = 0
    # list 中所有的元素作为 map 的key值
    numsMap = {}
    for i in nums:
        i = int(i)
        numsMap[i] = True
    for i in nums:
        i = int(i)
        if i not in numsMap.keys():
            continue
        leftLength = 0
        rightLength = 0
        leftKey = i - 1
        rightKey = i + 1
        while leftKey in numsMap.keys():
            numsMap.pop(leftKey)
            leftKey -= 1
            leftLength += 1
        while rightKey in numsMap.keys():
            numsMap.pop(rightKey)
            rightKey += 1
            rightLength += 1
        max_length = max(max_length, rightLength+leftLength+1)
    print (max_length)

 

还有一种思路就是:numsMap 的key 为 数值, value 为 与当前数值相连的最长数列的长度 。这种思路不做过多讲解了,有兴趣的可以自己研究下。贴出代码:

    for i in nums:
        i = int(i)
        if i in numsMap.keys():
            continue
        left = 0
        right = 0
        # i - 1
        leftKey = i - 1
        # i + i
        rightKey = i + 1
        # 如果拿到 left 值
        if leftKey in numsMap.keys():
            left = numsMap[leftKey]

        if rightKey in numsMap.keys():
            right = numsMap[rightKey]
        length = left + right + 1
        # 存储到字典
        numsMap[i] = length
        # 更新与 i 相连的连续序列的最左边和最右边的值
        numsMap[i-left] = length
        numsMap[i+right] = length
        max_length = max(max_length, length)

 

转载于:https://my.oschina.net/zhxx/blog/3034281

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值