#暴力解法
#子序列:可以不连续
#子串:必须连续
class Solution:
def findSubstring(self, s: str, words: List[str]) -> List[int]:
from collections import Counter #Python count () 方法用于统计字符串里某个字符或子字符串出现的次数
result = [] #空列表用于返回结果
if not words or not s: #如果为空,返回空列表
return result
oneword_len = len(words[0]) #计算每个单词的长度(题目上每个单词长度一致)
allwords_len = oneword_len * len(words) #计算一共的长度(每个单词长度乘以words的长度)
s_len = len(s) #字符串的长度
words_counter = Counter(words)#words中每个单词出现的次数
for i in range(0, s_len - allwords_len + 1):
temp = s[i:allwords_len + i]#储存i到之后字符的情况
temp2 = []#空列表做储存
for j in range(0, allwords_len, oneword_len):#以oneword_len为一跳
temp2.append(temp[j:oneword_len + j])#反手就是暴力储存每个的情况
if words_counter == Counter(temp2):#相等就添加下标i的值
result.append(i)
return result
#哈希表,就不用暴力存储,直接返回
class Solution:
def findSubstring(self, s: str, words: List[str]) -> List[int]:
if not words:#特例判断
return []
word_dict = {} # words的哈希表
for word in words:
word_dict[word] = word_dict.get(word, 0) + 1 #.get获取其下单词的下标+1,没有为0+1
s_len, w_len = len(s), len(words[0]) # w_len表示一个单词的长度,s_len表示s的长度
t_len = w_len * len(words) # 符合要求的子串的长度
ans = []
for offset in range(w_len): # 起点偏移
tmp_dict = {} # 临时的哈希表
for i in range(offset, offset + t_len - w_len, w_len):
tmp_dict[s[i: i+w_len]] = tmp_dict.get(s[i: i+w_len], 0) + 1 # 放入除最后一个以外的单词
for begin in range(offset, s_len - t_len + 1, w_len):
# 补齐最后一个单词
tmp_dict[s[begin+t_len-w_len: begin+t_len]] = tmp_dict.get(s[begin+t_len-w_len: begin+t_len], 0) + 1
if tmp_dict == word_dict:
ans.append(begin)
tmp_dict[s[begin:begin + w_len]] -= 1 # 删除第一个单词
if tmp_dict[s[begin:begin + w_len]] == 0:
del tmp_dict[s[begin:begin + w_len]]
return ans