面试150——字典树

208. 实现 Trie (前缀树)


思路

字典树的每条边代表一个字符,从根节点到某一节点的路径表示一个字符串。如果某节点被标记为结束节点,则表示该路径对应的字符串存在于集合中。

代码

java 复制代码
class Trie {
    Trie[] children;
    boolean isEnd;
    public Trie() {
        children = new Trie[26];
        isEnd = false;
    }
    
    public void insert(String word) {
        Trie node = this; // 获取当前节点
        for (char c : word.toCharArray()) {
            int index = c - 'a';
            if (node.children[index] == null) node.children[index] = new Trie();
            node = node.children[index];
        }
        node.isEnd = true;
    }
    
    public boolean search(String word) {
        Trie node = this;
        for (char c : word.toCharArray()) {
            int index = c - 'a';
            if (node.children[index] == null) return false;
            node = node.children[index];
        }
        return node.isEnd;
    }
    
    public boolean startsWith(String prefix) {
        Trie node = this;
        for (char c : prefix.toCharArray()) {
            int index = c - 'a';
            if (node.children[index] == null) return false;
            node = node.children[index];
        }
        return true;
    }
}

211. 添加与搜索单词 - 数据结构设计


思路

addWord就是正常的insert方法,search由于存在'.'代表任何一个数字,因此需要特判,分多种情况往下搜索dfs。
代码

java 复制代码
class WordDictionary {
    WordDictionary[] children;
    boolean isEnd;
    public WordDictionary() {
        children = new WordDictionary[26];
        isEnd = false;
    }
    
    public void addWord(String word) {
        WordDictionary node = this;
        for (char c : word.toCharArray()) {
            int index = c - 'a';
            if (node.children[index] == null) node.children[index] = new WordDictionary();
            node = node.children[index];
        }
        node.isEnd = true;
    }
    
    public boolean search(String word) {
        return dfs(this, word, 0);
    }

    public boolean dfs(WordDictionary root, String word, int index) {
        if (index == word.length()) {
            return root.isEnd;
        }
        char c = word.charAt(index);
        boolean flag = false;
        if (c != '.') {
            int i = c - 'a';
            if (root.children[i] == null) flag |= false;
            else flag |= dfs(root.children[i], word, index + 1);
        } else {
            for (int i = 0; i < 26; i ++) {
                if (root.children[i] == null) flag |= false;
                else flag |= dfs(root.children[i], word, index + 1);
            }
        }
        return flag;
    }
}

212. 单词搜索 II


思路

创建字典树,将单词列表的单词都添加到字典树中。之后在网格中全局搜索,以某个位置为起点搜索全网格,之后判断当前字符串是否在字典树中。
代码

java 复制代码
class Solution {
    Set<String> res;
    StringBuilder path;
    Trie trie; 
    int[][] directions = new int[][] {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
    boolean[][] used;
    public List<String> findWords(char[][] board, String[] words) {
        int n = board.length, m = board[0].length;
        path = new StringBuilder();
        trie = new Trie();
        res = new HashSet<>();
        used = new boolean[n][m];
        for (String word : words) trie.insert(word);
        for (int i = 0; i < n; i ++) {
            for (int j = 0; j < m; j ++) {
                char c = board[i][j];
                int index = c - 'a';
                if (trie.children[index] != null) {
                    used[i][j] = true;
                    path.append(c);
                    backtrace(board, i, j, trie.children[index]);
                    path.deleteCharAt(path.length() - 1);
                    used[i][j] = false;
                }
            }
        }
        return new ArrayList<>(res);
    }

    void backtrace(char[][] board, int x, int y, Trie cur) {
        int n = board.length, m = board[0].length;
        if (cur.isEnd) {
            res.add(path.toString());
        }

        for (int[] direction : directions) {
            int i = x + direction[0], j = y + direction[1];
            if (i >= 0 && i < n && j >= 0 && j < m && ! used[i][j]) {
                char c = board[i][j];
                int index = c - 'a';
                if (cur.children[index] == null) continue;
                else {
                    used[i][j] = true;
                    path.append(c);
                    backtrace(board, i, j, cur.children[index]);
                    path.deleteCharAt(path.length() - 1);
                    used[i][j] = false;
                }
            }
        }
    }

}

class Trie {
    Trie[] children;
    boolean isEnd;
    Trie() {
        this.children = new Trie[26];
        this.isEnd = false;
    }
    void insert(String word) {
        Trie node = this;
        for (char c : word.toCharArray()) {
            int index = c - 'a';
            if (node.children[index] == null) node.children[index] = new Trie();
            node = node.children[index];
        }
        node.isEnd = true;
    }
}
相关推荐
黄敬峰3 小时前
一文搞懂 Text2SQL:用大模型让自然语言直接查数据库
面试
Nil2085 小时前
leetcode 17电话号码的字母组合
算法·leetcode·职场和发展
ocean21037 小时前
2025-2026年AI算法与模型研发面试高频知识点洞察
人工智能·算法·面试
ShineWinsu9 小时前
对于MySQL:数据库的操作的解析
linux·数据库·c++·mysql·面试·笔试·库的操作
黄敬峰10 小时前
一文搞懂 LLM 结构化输出:从"抠 JSON"到"吐 JSON"的进化之路
面试
artificiali10 小时前
拼好卷 05
职场和发展
L小航呀11 小时前
代码随想录刷题 Day16
leetcode·面试
苦瓜小生13 小时前
【前端】【力扣与手撕】十天带你刷完前端算法与手撕,全是最简单好记的最优解法!day4
前端·数据结构·算法·leetcode·面试
AIsoft_868814 小时前
最好用的会议纪要APP怎么选?功能横评
面试·职场和发展·iphone