栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

76.最小覆盖字字串(使用到collection.defaultdict)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

76.最小覆盖字字串(使用到collection.defaultdict)

最小覆盖字串 方式一:滑动窗口 思路:使用两个指针,不断使得窗口扩大,然后找出包含所有的子串的子串。

有几个很重要的变量:need,needCnt,i,j
新建字典need的作用(两个地方使用):
1.这里主要在排查是否完全出现了t中的元素的时候:通过int整数的增减来统计元素的个数,若遍历到含有t的元素,新建的len()减一,直到len()为零,则算是包含了全部,并且t所含的元素个数置零
2.判断是否是最小子串,排查前边的元素的时候
3.其中need[c]的减一加一是一个很重要的点。

from collections import defaultdict
def minWindow(s: str, t: str):
    # 创建need[c],通过字典统计t中的元素出现的次数。
    need = defaultdict(int)
    for c in t:
        need[c]+=1
    needCnt=len(t)
    i=0#首指针
    res=(0,float('inf'))

    #两个循环嵌套,第一个j用来移动尾指针j的位置,第二个while用来移动首指针i的位置
    for j,c in enumerate(s):
        if need[c]>0:#若是在s当中出现t中的元素
            needCnt-=1#zeneedCnt-1,用于统计是否覆盖最小子串的全部内容。
        need[c]-=1#无论是否是t中出现的元素,都减一,而一开始的时候t中元素已经是1,所以减一之后是0,不是t中的元素则是-1,新建字典need中元素个数减一
        if needCnt==0:       #步骤一:滑动窗口包含了所有T元素
            while True:      #步骤二:增加i,排除多余元素(排除的是前边的元素,后边元素的结点已经确定了)
                c=s[i]#第一遍循环是从s[0]开始的,从s[0]开始排查直到出现t中包含的元素为止。
                print(need[c])
                h = need[c]
                if need[c]==0:
                    break#当前结束之后,i指针指向的是s中出现的第一个字母,j指针指向的是t出现的最后一个字母。
                need[c]+=1#??这一步的作用是什么
                i+=1
            #这也是一个挺牛皮的点,因为要用小于号,所以这里创建的是从零到正无穷的变量
            if j-i0时候,needCnt减一,判断为已经包含全部字符,进入下一个循环。'''
            need[s[i]]+=1  #步骤三:i增加一个位置,寻找新的满足条件滑动窗口
            needCnt+=1
            i+=1
    return '' if res[1]>len(s) else s[res[0]:res[1]+1]    #如果res始终没被更新过,代表无满足条件的结果

a = minWindow('ADOBECODEBANC','ABC')
print(a)

方式二:暴力遍历
lass Solution:
    def minWindow(self, s, t):
        need_dict = collections.defaultdict(int) #用来装分别需要的字符数量,包括必要的和非必要的,需要的必要字符数量>0,非必要的字符数量<0
        for ch in t:   #初始化需要的必要字符数量
            need_dict[ch] += 1
        need_cnt = len(t) #用来判断总共需要多少字符才能达到要求
        i = j = 0
        res = [0,float('inf')]
        for j in range(len(s)):
            if need_dict[s[j]] > 0: #只有必要字符的数量才可能>0
                need_cnt -= 1
            need_dict[s[j]] -= 1  #任意值都可以装进need_dict,但是非必要字符只可能<0
            if need_cnt == 0:  # 需要的字符都足够了
                while need_cnt == 0: #开始准备右移左指针,缩短距离
                    if j-i < res[1] - res[0]: #字符串更短,替换答案
                        res = [i,j]
                    need_dict[s[i]] += 1    #在移动左指针之前先将左指针的值加回来,这里可以是非必要字符
                    if s[i] in t and need_dict[s[i]] > 0: #确认是必要字符且不多于所需要的数量(有多余的话只可能<=0,因为上一句我们已经将字符+1了)后,将need_cnt+1
                        need_cnt += 1
                    i += 1   #右移左指针,寻找下一个符合的子串
        return s[res[0]:res[1]+1] if res[1]-res[0] 
补充知识:collection.defaultdict 
作用:在collection.default()中,如果是list,则可以对键进行归类,通过sort进行排序,如果是int,可以进行键个数的加减。 
python中通过key访问字典,当Key不存在的时候,会引发KeyError异常,为了避免这种状况发生,可以使用collections类当中的defaultdict()方法来为字典提供默认值。 
  • 1.使用list作为第一个参数,可以很容易将键-值对序列转换为列表字典。
from collections import defaultdict

s = [('yellow',1),('blue',2),('yellow',3),('blue',4),('red',5)]
d = defaultdict(list)
for k, v in s:
    d[k].append(v)
a = sorted(d.items())
print(d)
print(a)

dict.setdefault()也有同样的效果,但是这个更为便捷

s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
d={}
for k, v in s:
  d.setdefault(k,[]).append(v)
print(d)
a=sorted(d.items())
print(a)
  • 2.defaultdict还可以用来计数,将default_factory设置为int
    #字符串中的字母第一次出现的时候,字典中没有非字母,default_factory函数调用int()为其提供一个默认值0
s = 'mississippi'
d = defaultdict(int)
for k in s:
    print(k)
    d[k] += 1#这种方式可以直接字典d中的值
print(d)
a=sorted(d.items())
print(a)
  • 3.函数int()是常值函数的一种特例,总是返回0,使用匿名函数lambda function可以更快、更灵活的创建常值函数,返回包括0在内的任意常数值
def constant_factory(value):
    return lambda:value
d = defaultdict(constant_factory(''))
print(d)
d.update(name = 'John', action = 'ran')
print(d)
print('%(name)s%(action)s to %(object)s%d')
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/857825.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号