LeetCode刷题(19)

本文探讨如何在给定字符串中找到包含所有指定单词的子字符串,介绍两种方法:一种是逐个检查每个可能的子串,另一种是使用滑动窗口技术优化搜索过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Substring with Concatenation of All Words
寻找包含所有单词的子字符串,按照人工寻找的方式有如下代码,对于每一个index依次进行比对,该方案通过了167/169,最后两个字符串超时了

class Solution(object):
    def findSubstring(self, s, words):
        """
        :type s: str
        :type words: List[str]
        :rtype: List[int]
        """
        ls = len(s)
        lw = len(words)
        if not ls or not lw:
            return -1
        wl = len(words[0])
        res = []

        dic = {}
        for word in words:
            if not dic.has_key(word):
                dic[word] = 1
            else :
                dic[word] += 1

        i = 0 
        while i + wl <= ls:
            if s[i: i+wl] not in words:
                i += 1
            else :
                tdic = {}
                tdic[s[i: i+wl]] = 1
                j = 1
                while i + j * wl + wl <= ls:
                    if s[i + j * wl: i + j * wl + wl] not in words:
                        #i = i + 1
                        break
                    else :
                        if not tdic.has_key(s[i + j * wl: i + j * wl + wl]):
                            tdic [s[i + j * wl: i + j * wl + wl]] = 1
                            j += 1
                        else :
                            if tdic[s[i + j * wl: i + j * wl + wl]] < dic[s[i + j * wl: i + j * wl + wl]]:
                                tdic [s[i + j * wl: i + j * wl + wl]] += 1
                                j += 1
                            else :
                                break
                flag = 0
                for key in dic:
                    if not tdic.has_key(key):
                        flag = 1
                        break
                    elif tdic[key] != dic[key]:
                        flag = 1
                        break
                if not flag :
                    res += [i]
                i += 1

        return res

研究一下讨论区的其他算法:

class Solution(object):
    def findSubstring(self, s, words):
        """
        :type s: str
        :type words: List[str]
        :rtype: List[int]
        """
        if not s or not words or not words[0]:
            return []
        n = len(s)
        k = len(words[0])
        t = len(words) * k
        req = {}
        for w in words:
            req[w] = req[w] + 1 if w in req else 1
        ans = []
        for i in range(min(k, n - t + 1)):
            self._findSubstring(i, i, n, k, t, s, req, ans)
        return ans
    def _findSubstring(self, l, r, n, k, t, s, req, ans):
        curr = {}
        while r + k <= n:
            w = s[r:r + k]
            r += k
            if w not in req:
                l = r
                curr.clear()
            else:
                curr[w] = curr[w] + 1 if w in curr else 1
                while curr[w] > req[w]:
                    curr[s[l:l + k]] -= 1
                    l += k
                if r - l == t:
                    ans.append(l)

这个算法实现的主要是一个滑动窗口,当word[0],word[1],word[0]出现时,向后滑一个从word[1],word[0]以及往后开始重新记,其中假设word[0]在words中是唯一的,不唯一时就在超出数量时滑动。为了防止每次滑动一个单词长度遗漏答案,特意将开始的word长度字符分别做头。

AC算法看起来正是用来解决此类问题的,AC算法详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值