[LeetCode]30.串联所有单词的子串(python)

1.代码

from typing import List
from collections import Counter

class Solution:
    def findSubstring(self, s: str, words: List[str]) -> List[int]:
        nums = []
        
        word_len = len(words[0])  
        num_words = len(words) 
        total_len = word_len * num_words  
        if total_len > len(s):
            return nums
        word_count = Counter(words)
        
        for i in range(word_len): 
            left = i  
            right = i  
            current_count = Counter()  
            
            while right + word_len <= len(s):  
                word = s[right:right + word_len]
                right += word_len  
                
                if word in word_count:  
                    current_count[word] += 1
                    while current_count[word] > word_count[word]:
                        current_count[s[left:left + word_len]] -= 1
                        left += word_len
                    if right - left == total_len:
                        nums.append(left)  
                else:
                    current_count.clear()
                    left = right
        
        return nums

2.思路

首先用哈希表统计列表中各个词的出现次数,并用空的哈希表记录滑动窗口中各个词的出现次数。运用了多起点的滑动窗口以避免漏检,共word_len个起点。对于每个起点,其右端每次向右滑动word_len,如果新增词在列表中存在,则将该词的出现次数加1,并且检查是否超出列表中的出现次数,如超出,则逐次将滑动窗口左端右移word_len至与列表中出现次数相等。更新窗口后,检查滑动窗口长度,若等于total_len,则对应的left是一个子串的起点。如果新增词不在列表中,则清空哈希表和滑动窗口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值