2416. 字符串的前缀分数和

70 阅读1分钟

题目:
给你一个长度为 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
}