题目:
给你一个长度为 n 的数组 words ,该数组由 非空 字符串组成。
定义字符串 word 的 分数 等于以 word 作为 前缀 的 words[i] 的数目。
- 例如,如果
words = ["a", "ab", "abc", "cab"],那么"ab"的分数是2,因为"ab"是"ab"和"abc"的一个前缀。
返回一个长度为 **n 的数组 **answer **,其中 **answer[i] **是 **words[i] 的每个非空前缀的分数 总和 。
注意: 字符串视作它自身的一个前缀。
算法:
方法一:暴力模拟
TLE!
func sumPrefixScores(words []string) []int {
ans := make([]int, len(words))
for i := range words {
ans[i] = len(words[i])
for j := range words {
if i == j {
continue
}
for k := len(words[i]); k > 0; k -- {
if strings.HasPrefix(words[j], words[i][:k]) {
ans[i] = ans[i] + k
break
}
}
}
}
return ans
}
方法二:优化
剪枝
func sumPrefixScores(words []string) []int {
ans := make([]int, len(words))
for i := range words {
ans[i] = len(words[i])
for j := range words {
// 看下测试用例,剪枝
if i == j || words[i][0] != words[j][0]{
continue
}
for k := len(words[i]); k > 0; k -- {
if strings.HasPrefix(words[j], words[i][:k]) {
ans[i] = ans[i] + k
break
}
}
}
}
return ans
}
方法三:字典树
随机应变,没必要有字符串终止的标志。
func sumPrefixScores(words []string) []int {
ans := make([]int, len(words))
tier := &node{}
for i := range words {
t := tier
for j := range words[i] {
pos := words[i][j] - 'a'
if t.nodes[pos] == nil {
t.nodes[pos] = &node{}
}
t = t.nodes[pos]
t.score ++
}
}
for i := range words {
t := tier
for j := range words[i] {
pos := words[i][j] - 'a'
t = t.nodes[pos]
ans[i] = ans[i] + t.score
}
}
return ans
}
type node struct {
score int
nodes [26]*node
}