python练习:求一串珠子中包含所有颜色最短的一串长度

题目

某年 百度的面试题。

一串首尾相连的珠子有 m 个,共有 N 种颜色(N <= 10)。设计一个算法,取出其中一段,要求包含所有 N 种颜色,并且长度最短。

 

思路

使用一个额外的数组 flags 存储颜色计数。若遍历的当前序列中包含了第 i 种颜色,则将数组中第 i 号元素值加 1。

使用双指针遍历原珠子数组 beads ,分别表示最短包含 N 种颜色珠子的最短子串的首尾。

  1. 两个指针,一开始都指向头结点。
  2. 指针一往后移动,在范围内,当包含了所有颜色的时候,停下来
  3. 指针二往后移动,在范围内,移动的过程中判断是否包含了所有颜色,不包含的时候停下来
  4. 计算此时两指针之间的距离,如果小于上一个最小记录,则更新为该距离
  5. 重复以上动作直到指针一越界停止。
  6. 对于颜色数组,开始时数组所有元素置为0。当指针一移动时,将指针一指向的元素下标对应 flags 中元素值加一;指针二移动时,将指针二指向的元素下标对应 flags 中元素值减一。(这一段有点绕口,对照着下面的代码理解就知道了)

时间复杂度为 O(m),空间复杂度为 O(N)。

 

python代码

def isFull(flags):  # 如果序列中包含了所有颜色,则每个颜色索引对应的值都会大于1,那么乘积一定不会为0
    result = 1
    for i in flags:
        result *= i
    return False if result == 0 else True


def getShortestBeads(beads, flags):
    ap = bp = 0
    least = len(beads)
    while bp < len(beads):
        # bp 一直往后移动,直到 flags 中所有颜色都至少有一个
        while not isFull(flags) and bp < len(beads):  
            flags[beads[bp]] += 1  # beads[bp]颜色号加一
            bp += 1
        # ap 一直往后移动,同时判断是否包含了所有颜色
        while isFull(flags) and ap < len(beads):
            flags[beads[ap]] -= 1  # beads[ap]颜色号减一
            ap += 1
        # 更新最短序列长度
        if bp <= len(beads):
            count = bp - ap + 1
            if count < least:
                least = count
        else:
            return least
    return least


if __name__ == '__main__':
    beads = [1, 2, 2, 1, 1, 3, 0, 0, 2, 2, 3, 2, 3]
    flags = [0] * 4  # 分别对应结果序列中各颜色的数量
    print(getShortestBeads(beads, flags))  # 输出结果为 5
    print(getShortestBeads([2, 1, 0, 1, 1, 2, 1, 0, 1, 1], [0, 0, 0]))  # 输出结果为 3

结合代码理解分析过程,说白了就是用两个指针 ap 和 bp 来代表结果序列。bp 往后一直遍历珠子数组,使得 flags 颜色数组中每个颜色都至少有一个。然后 ap 往后一直遍历珠子数组,尝试着去尽可能减少当前结果序列中的总珠子个数,同时还得满足当前结果序列包含了所有颜色。

借用 isFull 函数来判断是否包含了所有颜色,可太妙了!敬佩大佬们!

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值