LeetCode Substring with Concatenation of All Words

LeetCode解题之Substring with Concatenation of All Words


原题

现有一组长度相等的字符串words,要在原字符串中找出正好包含words中所有字符串的子字符串的起始位置。

注意点:

  • 返回结果的顺序没有关系

例子:

输入: s = “barfoothefoobarman”, words = [“foo”, “bar”]

输出: [0, 9]

解题思路

因为words中的单词可能有重复,所以要有一个dict来记录一下每个字符串的数目。然后在遍历原字符串的时候,只需要遍历单词的长度次即可,如”barfoothefoobarman”,因为目标单词的长度为3,所以只需遍历:

  • ‘bar’ | ‘foo’ | ‘the’ | ‘foo’ | ‘bar’ | ‘man’
  • ‘arf’ | ‘oot’ | ‘hef’ | ‘oob’ | ‘arm’
  • ‘rfo’ | ‘oth’ | ‘efo’ | ‘oba’ | ‘rma’

在遍历时,需要两个指针,一个用来标记子字符串的开始,另一个用来标记子字符串的结束。再用一个dict来记录当前字符串中单词的数量,如果下一个单词不在words中,那么清空该dict,把前指针直接跳到后指针处;如果在words中,那么相应的键值要加一,此时如果那个单词的数量超过了目标中的数目,那么前指针要不断后移直到吐出一个那个单词。通过前后指针之差是否等于所有目标单词长度之和来判断是否有目标子字符串。

AC源码

class Solution(object):
    def findSubstring(self, s, words):
        """
        :type s: str
        :type words: List[str]
        :rtype: List[int]
        """
        s_length = len(s)
        word_num = len(words)
        word_length = len(words[0])
        words_length = word_num * word_length
        result = []
        words_dict = {}
        for word in words:
            words_dict[word] = words_dict[word] + 1 if word in words_dict else 1
        for i in range(word_length):
            left = i
            right = i
            curr_dict = {}
            while right + word_length <= s_length:
                word = s[right:right + word_length]
                right += word_length
                if word in words_dict:
                    curr_dict[word] = curr_dict[word] + 1 if word in curr_dict else 1
                    while curr_dict[word] > words_dict[word]:
                        curr_dict[s[left:left + word_length]] -= 1
                        left += word_length
                    if right - left == words_length:
                        result.append(left)
                else:
                    curr_dict.clear()
                    left = right
        return result


if __name__ == "__main__":
    assert Solution().findSubstring("barfoothefoobarman", ["foo", "bar"]) == [0, 9]

欢迎查看我的Github (https://github.com/gavinfish/LeetCode-Python) 来获得相关源码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值