最近开始同时使用python和go做题,go的效率高很多,用python brute force的方法提交以后TLE,同样的方法用go可以AC,用python可以榨取更快的算法。
题目
给定一个字符串S和一个单词列表words
,找到words里所有S的子串。
Example :
Input:
S = “abcde”
words = [“a”, “bb”, “acd”, “ace”]
Output: 3
Explanation: There are three words in words that are a subsequence of S: “a”, “acd”, “ace”.
思路
查看某个字符串a是不是另一个字符串b的子串,可以使用python的str.find(str, start, end)函数,逐个查找a的每个字符按顺序在b中的位置,时间复杂度O(n),就地查找空间复杂度O(1)。
but, go里面没有find函数,只有strings.Index(string, substr),于是做了三次尝试:
- 每次查找子串先复制一个S的副本s,然后查完每个字符就通过slice缩短s,实现python的find类似功能,但是这样的空间复杂度是O(n)
- 自己写了一个类似python的find的函数,耗时长了很多
- 再加一个整型变量q,通过累加q实现find函数的start,空间复杂度O(1)
代码
# python
class Solution:
def numMatchingSubseq(self, S, words):
"""
:type S: str
:type words: List[str]
:rtype: int
"""
exist = set()
res = 0
for w in words:
if w in exist:
res+=1
continue
x=-1
for c in w:
x = S.find(c, x+1)
if x == -1:
break
else:
exist.add(w)
res += 1
return res
// golang
func numMatchingSubseq(S string, words []string) int {
var res int
exists := map[string]bool{}
for _, w := range words {
if exists[w] {
res ++
continue
}
flag := true
p, q := -1, 1
for _, c := range w {
p := strings.Index(S[p+q:], string(c))
if p == -1 {
flag = false
break
}
//通过q的累加实现python里面find函数的start参数的效果
p, q = 0, q+p+1
}
if flag == true {
exists[w] = true
res++
}
}
return res
}