leetcode-30-串联所有单词的子串
题目描述:
方法一:暴力O(MN)
class Solution: def findSubstring(self, s: str, words: List[str]) -> List[int]: res = [] if not s or not words: return res for j in range(len(s)-len(words[0])*len(words)+1): i = j tmp = words.copy() while i - j <= (len(words)-1)*len(words[0]): if s[i:i+len(words[0])] in tmp: tmp.remove(s[i:i+len(words[0])]) if not tmp: res.append(j) i += len(words[0]) else: break return res
优化:
class Solution: def findSubstring(self, s: str, words: List[str]) -> List[int]: from collections import Counter if not s or not words:return [] one_word = len(words[0]) all_len = len(words) * one_word n = len(s) words = Counter(words) res = [] for i in range(0, n - all_len + 1): tmp = s[i:i+all_len] c_tmp = [] for j in range(0, all_len, one_word): c_tmp.append(tmp[j:j+one_word]) if Counter(c_tmp) == words: res.append(i) return res
方法二:滑动窗口: O(N)
class Solution: def findSubstring(self, s: str, words: List[str]) -> List[int]: from collections import Counter if not s or not words:return [] one_word = len(words[0]) word_num = len(words) n = len(s) if n < one_word:return [] words = Counter(words) res = [] for i in range(0, one_word): cur_cnt = 0 left = i right = i cur_Counter = Counter() while right + one_word <= n: w = s[right:right + one_word] right += one_word if w not in words: left = right cur_Counter.clear() cur_cnt = 0 else: cur_Counter[w] += 1 cur_cnt += 1 while cur_Counter[w] > words[w]: left_w = s[left:left+one_word] left += one_word cur_Counter[left_w] -= 1 cur_cnt -= 1 if cur_cnt == word_num : res.append(left) return res