zoukankan      html  css  js  c++  java
  • Leetcode_30【串联所有单词的子串】

    文章目录:

    • 题目
    • 脚本一
    • 脚本一逻辑
    • 脚本二
    • 脚本二逻辑

    题目:

    给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。

    注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。

    示例 1:

    输入:
    s = "barfoothefoobarman",
    words = ["foo","bar"]
    输出:[0,9]
    解释:
    从索引 0 和 9 开始的子串分别是 "barfoo" 和 "foobar" 。
    输出的顺序不重要, [9,0] 也是有效答案。
    示例 2:

    输入:
    s = "wordgoodgoodgoodbestword",
    words = ["word","good","best","word"]
    输出:[]


    脚本一:【用时:2300ms】

    class Solution:
        def findSubstring(self, s: str, words: List[str]) -> List[int]:
            try:
                leng1 = len(words[0])
            except IndexError:
                return([])
            leng1 = len(words[0])
            leng2 = len(s)
            leng3 = len(words)
            leng4 = words.count(words[0])
            num1 = leng1 * leng3
            try:
                str_1 = s[0] * leng2
            except IndexError:
                return([])
            list1 = words[:]
            list2 = []
            flag1,flag2,flag3 = 1,1,1
            if str_1 == s:
                flag1 = 0
            if leng3 == leng4:
                flag2 = 0
            if words[0] in s:
                flag3 = 0
            if flag1 == 0 and flag2 == 0 and flag3 == 0:
                result = leng2 - num1 + 1
                list2 = list(range(result))
                return(list2)
            i = 0
            k = 0
            while True:
                j = i + leng1
                str1 = s[i:j]
                if str1 in list1:
                    list1.remove(str1)
                    i += leng1
                    if not list1:
                        list2.append(k)
                        k += 1
                        i = k
                        list1 = words[:]
                else:
                    k += 1
                    i = k
                    list1 = words[:]
                if i > leng2:
                    return(list2)

    脚本一逻辑:

    • 此题是笔者想到的解法,可以规类为暴力破解,原脚本是超时的;但笔者根据leetcode的超时反馈,做了一些调优
    • 脚本的基本逻辑如下:
      • 比如长字符串str为abbcc,words组合为[aa,bb]
      • 第一步:先在长字符串str获取长度为2的短字符串str1为"ab"(aa的长度为2),由于"ab"不在words中,所以长字符串获取点由0加1变为1
      • 第二步:再获取长度为2的短字符串bb,由于bb在words中,则剔除words中的该元素,则words变为[aa]
      • 第三步:再获取长度为2的短字符串aa,由于aa在words中,则剔除words中的此元素,则words变为[]
      • 第四步:如果words变为空,则返回最新开始的取点位,如本例中的1,并将1添加到空列表中
      • 重复

    脚本二:【用时:870ms 转载】

    class Solution:
        def findSubstring(self, s: str, words: List[str]) -> List[int]:
            res = []
            write = []
            if len(words) == 0:
                return []
            if len(s) < len(words)*len(words[0]):
                return []
            dic = {}
            flag = 0
            for i in words:
                try:
                    dic[i]+=1
                except KeyError:
                    dic[i]=1
                    flag+=1
                    write.append(i)
            #是否存在用字典查看
            left, right = 0, len(words)*len(words[0])
            #滑动窗口
            while right<=len(s):
                n,start = 0,left
                per = len(words[0])
                tag = dict(zip(write,[0]*flag))
                while n < len(words):
                    #若存在于字典中
                    if dic.get(s[start:start+per]):
                        if tag[s[start:start+per]] < dic[s[start:start+per]]:
                            tag[s[start:start+per]] += 1
                            n+=1
                            start+=per
                        else:
                            break
                    else:
                        break
                if n == len(words):
                    res.append(left)
                left+=1
                right+=1
            return res
    
            

    脚本二逻辑:

    • 第一:对明显不符合的情况进行排除,比如子串列表为空,或者子串总长度比字符串s还要长
    • 第二:创建两个字典dic、tag和一个列表res,其中dic记录子串列表words中的信息,words中每个元素作为字典的键,元素个数作为字典的值;每次进行最外层循环时,tag循环都会恢复原样,原样为已words列表作为字典的键,以0作为值 
    • 第三:每次进行主循环时,以长字符串的某个字符为起点,进入次循环;若次循环中满足条件则记录结果的空列表增加起点字符的索引值后,起点索引值自增1,进入主循环;若次循环条件不满足,则起点索引值自增1并再次进入主循环;直到未遍历的长字符串字符数小于words所有元素总长度
  • 相关阅读:
    ByteBuffer的mark、position、limit、flip、reset,get方法介绍ok
    java.nio.ByteBuffer的flip、rewind和compact几个方法的区分使用
    maven之一:maven安装和eclipse集成
    Java 8 函数式接口
    Lambda 表达式
    jdk8十大新的特性
    阿里巴巴73款开源产品列表,值得收藏
    【Java】java.util.Objects 工具类方法研究
    ARIMA 模型简单介绍
    python 二维数组取值
  • 原文地址:https://www.cnblogs.com/mailong/p/12046508.html
Copyright © 2011-2022 走看看