Golang用Trie实现最长公共前缀:节点计数不递增问题求助
问题根源:结构体值拷贝导致计数器修改无效
Go里的结构体是值类型,你代码里的LinkNodes map[string]Node存储的是Node结构体的副本,每次从map里取节点、给currentNode赋值,都是复制了一份新的结构体。你在循环里修改currentNode.CommonPrefixCounter时,改的只是这个副本的计数器,原前缀树里的节点根本没被更新,所以下一次访问同一个节点时,计数器还是初始的1。
修复方案:改用指针类型操作节点
把Node的引用(指针)存入map,这样所有操作都会直接作用于原节点,不会产生拷贝。具体改法:
- 修改Node结构体的LinkNodes类型为
map[string]*Node,存储节点指针 - 把rootNode、currentNode都声明为
*Node类型,用指针操作 - 创建新节点时返回指针(用
&Node{...}) - 修正节点存在性的判断逻辑:原来用
LinkNodes == nil不准确,应该先检查map中是否存在对应的key
修改后的完整代码
import ( "fmt" "strings" ) func longestCommonPrefix(strs []string) string { rootNode := &Node{CommonPrefixCounter: 0, LinkNodes: make(map[string]*Node, 26)} var currentNode *Node longestPrefix := "" if len(strs) == 1 { return strs[0] } for _, word := range strs { currentNode = rootNode currentPrefix := "" characters := strings.Split(word, "") for _, character := range characters { fmt.Printf("Current Letter is %s \n", character) // 先检查当前节点的子节点中是否存在该字符对应的节点 node, exists := currentNode.LinkNodes[character] if !exists { fmt.Println("Making a new node") newNode := &Node{CommonPrefixCounter: 1, LinkNodes: make(map[string]*Node, 26)} currentNode.LinkNodes[character] = newNode currentNode = newNode } else { currentPrefix += character currentNode = node currentNode.CommonPrefixCounter++ fmt.Printf("CurrentNode common prefix counter is %d\n", currentNode.CommonPrefixCounter) // 当计数器等于单词总数时,说明这个前缀是所有单词共有的,且长度更长时更新结果 if currentNode.CommonPrefixCounter == len(strs) && len(currentPrefix) > len(longestPrefix) { longestPrefix = currentPrefix } } } } fmt.Printf("Longest Common Prefix length was %d, value is %s\n", len(longestPrefix), longestPrefix) return longestPrefix } type Node struct { CommonPrefixCounter int LinkNodes map[string]*Node }
关键改动说明
LinkNodes map[string]*Node:存储指针而非结构体值,确保所有操作都指向同一个节点实例rootNode := &Node{...}:创建根节点指针,避免后续操作拷贝整个结构体node, exists := currentNode.LinkNodes[character]:正确判断子节点是否存在,避免零值Node的干扰- 调整最长前缀的判断逻辑:用
len(currentPrefix)对比更直观,因为计数器等于单词数时,当前前缀长度就是公共前缀的有效长度
内容的提问来源于stack exchange,提问作者Jason E
相关产品推荐
相关产品推荐

