1.最开始的想法,wa了。想的是把所有列表中单词全都替换#串,这样的话,再扫描替换后的字符串,这个字符串中只要有连着的符合#号个数的#串,就是题目中要找的子串。然后发现题目中给的第二个样例都过不了,因为这个方法会将第二个样例整个替换成#。
class Solution:
def findSubstring(self, s: str, words: List[str]) -> List[int]:
if len(words) == 0:
return [];
tmp_s = s;
subs = "";
replace_s = "";#替换word的#串
wordl = len(words[0]);
for i in range(wordl):
replace_s += "#";
for word in words:
tmp_s = tmp_s.replace(word, replace_s);
subs = subs + replace_s;
#print (tmp_s);
result = [];
for it in re.finditer(subs, tmp_s):
result.append(it.start());
#print (tmp.start());
return result;
2.后来的想法,参考了第3题中的思路
第三题解答链接:https://blog.youkuaiyun.com/Ema1997/article/details/92798234
然而这种解法没有考虑到words中有重复单词的情况,又WA了,好吧我还是去看题解吧,我尽力了。
class Solution:
def findSubstring(self, s: str, words: List[str]) -> List[int]:
if len(words) == 0:
return []
result = []
l = len(s)
wordl = len(words[0])
word_num = len(words)
dic = {} #单词上一次出现位置
i = 0
left = 0 #记录当前串开始索引
while i + wordl <= l:
#print (l)
if i - left == word_num * wordl: #已经找到了匹配
result.append(left)
left += wordl
#print('2 {}'.format(i))
if s[i:i+wordl] in words: #当前单词是words中的
if s[i:i+wordl] not in dic or dic[s[i:i+wordl]] < left: #从未出现过或者出现位置在left之前
dic[s[i:i+wordl]] = i
#print('1 {}'.format(i))
else:
left = dic[s[i:i+wordl]] + wordl
#print('left {}'.format(left))
dic[s[i:i+wordl]] = i
i += wordl
else:
i += 1
left = i
#print('3 {} {}'.format(i, left))
return result
3.看了题解之后,学习到了python中一个特别有用的函数Counter,可以用来统计list中每个元素出现过多少次,并返回一个Counter类型的值,这个Counter类型的值还能与字典类型的值做比较,判断是否相同,比如以下这段代码:
a = [1,4,2,3,2,3,4,2]
from collections import Counter
print (Counter(a))
b = Counter(a)
dic = {2: 3, 3: 2, 4: 2, 1: 1}
print(b == dic)
输出如下:
Counter({2: 3, 3: 2, 4: 2, 1: 1})
True
在了解了这个函数之后,这道题就好做许多了。我这里参考的是题解中的解法二,具体讲解大家看这个链接就行了,此处不做赘述。
from collections import Counter
class Solution:
def findSubstring(self, s: str, words: List[str]) -> List[int]:
if len(words) == 0:
return []
result = []
l = len(s)
wordl = len(words[0])
word_num = len(words)
count = Counter(words) #每个单词出现多少次
count_now = {} #当前字符串单词出现次数
i = 0
left = 0 #记录当前串开始索引
for i in range(wordl):
left = i
count_now = {}
while (i + wordl <= l):
word = s[i:i+wordl]
if (word not in words): #情况1,当前单词不再单词列表中
i += wordl #跳到下一单词
left = i
count_now = {}
continue
if (word not in count_now):
count_now[word] = 1
else:
count_now[word] += 1
while (count_now[word] > count[word]): #情况2,单词出现次数超过单词列表中次数
count_now[s[left:left+wordl]] -= 1
left += wordl
if (count_now == count):#情况3,匹配成功
result.append(left)
count_now[s[left:left+wordl]] -= 1
left += wordl
i += wordl
return result
终于把这道题做完了~\(≧▽≦)/~,感动。