LeetCode Trie提交结果与本地Node.js运行输出不匹配问题
问题描述
- 本地Node v16.15.1环境下测试自行实现的LeetCode Trie(前缀树)题目时,输出结果与LeetCode平台返回结果不匹配。
- 初始测试用例可正常通过,提交时第8个测试用例执行失败:用例逻辑为对刚初始化的空Trie执行search操作,本地运行输出
false(符合题目预期的正确结果),但LeetCode平台返回结果为true。
LeetCode题目说明
Trie(发音同"try",即前缀树)是一种树形数据结构,用于高效存储和检索字符串数据集中的键,常见应用场景包括自动补全、拼写检查等。
需要实现的Trie类接口如下:
Trie():初始化Trie对象void insert(String word):向Trie中插入字符串wordboolean search(String word):如果字符串word之前已经插入到Trie中则返回true,否则返回falseboolean startsWith(String prefix):如果之前插入的任意字符串以prefix为前缀则返回true,否则返回false
示例1
输入:
["Trie", "insert", "search", "search", "startsWith", "insert", "search"] [[], ["apple"], ["apple"], ["app"], ["app"], ["app"], ["app"]]
输出:
[null, null, true, false, true, null, true]
解释:
const trie = new Trie(); trie.insert("apple"); trie.search("apple"); // 返回 True trie.search("app"); // 返回 False trie.startsWith("app"); // 返回 True trie.insert("app"); trie.search("app"); // 返回 True
失败测试用例
['Trie', 'search'] [[],'a']
- 本地运行输出:
[null, false],为符合预期的正确结果 - LeetCode平台输出:
[null, true],为不符合预期的错误结果
问题原因
问题出在代码中使用了ES2022标准的私有类方法语法(即方法名前加#的写法):
- 本地使用的Node v16.15.1原生支持该语法,因此代码运行逻辑正常,输出符合预期
- LeetCode当前的JavaScript运行环境对该语法的支持存在兼容问题,
#getLastNode这个私有方法无法被正确识别和调用,导致search、startsWith方法的执行逻辑完全异常,才会出现空Trie搜索字符返回true的诡异结果。
修复方案
将#开头的私有方法改为普通方法,按照JS社区惯例用下划线_前缀标记内部使用的方法即可,不需要修改核心逻辑。
修复后的完整代码:
class Node{ constructor(c){ this.char = c; this.isWord = false; this.children = {}; } } class Trie{ constructor(){ // 根节点不存储实际字符 this.root = new Node(''); } insert(word){ let curr = this.root; for(let i = 0; i < word.length; i++){ let c = word[i]; if(!curr.children[c]){ curr.children[c] = new Node(c); } curr = curr.children[c]; } curr.isWord = true; } search(word){ let node = this._getLastNode(word); return !!(node && node.isWord); } startsWith(prefix){ return this._getLastNode(prefix) != null; } // 内部辅助方法,获取对应字符串路径的最后一个节点 _getLastNode(word){ let curr = this.root; for (let i = 0; i < word.length; i++) { const c = word[i]; if(!curr.children[c]){ return null; } curr = curr.children[c]; } return curr; } }
注:类顶部单独声明的
char; isWord; children; root;这类字段声明语句在旧版JS环境下也可能存在兼容问题,直接在constructor中赋值即可,不需要单独提前声明。
内容的提问来源于stack exchange,提问作者BJ Rutledge
相关产品推荐
相关产品推荐

