栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

字典树 前缀树

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

字典树 前缀树

字典树是一种数据结构,也叫前缀树、Trie树。比较常用的应用有前缀匹配和词频统计。其特点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较。Trie的核心思想是空间换时间,利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。

浏览器的搜索算法就是字典树的一种典型应用:

字典树的特性
  • 根节点不包含字符,除了根节点其他每个节点都只包含一个字符。根节点不包含字符的目的是为了能包括所有字符串。
  • 从根节点到每一个节点,经过的字符串起来就是该节点对应的字符串。
  • 每个节点的所有子节点包含的字符都不相同。
java实现字典树

LeetCode208题

定义根节点的结构体

root节点的结构体中包含一个长度为26的数组,代表’a’~‘z’。boolean类型变量isEnd表示是否为字符串末尾。

有的场景还会添加一个String类型的变量,用于存储从根节点到此节点串成的字符串。

    class TrieNode {
        TrieNode[] children = new TrieNode[26];
        boolean isEnd = false;
    }
Trie初始化
public class Trie {
    TrieNode root;

    public Trie() {
        root = new TrieNode();
    }
}
insert方法

insert方法用于向字典树中插入字符串word。

    public void insert(String word) {
        TrieNode tmp = root;
        for (char c : word.toCharArray()) {
            int index = c - 'a';
            if (tmp.children[index] == null) {
                tmp.children[index] = new TrieNode();
            }
            tmp = tmp.children[index];
        }
        tmp.isEnd = true;
    }
search方法

search方法用于查询字典树中是否存在字符串word。除了要判断字典树中word开头的字符串是否存在,还需要判断isEnd。

    public boolean search(String word) {
        TrieNode tmp = root;
        for (char c : word.toCharArray()) {
            int index = c - 'a';
            if (tmp.children[index] == null) {
                return false;
            }
            tmp = tmp.children[index];
        }
        return tmp.isEnd;
    }
startsWith方法

startsWith方法用于判断字典树中是否存在prefix开头的字符串,存在返回true,不存在则返回false。

    public boolean startsWith(String prefix) {
        TrieNode tmp = root;
        for (char c : prefix.toCharArray()) {
            int index = c - 'a';
            if (tmp.children[index] == null) {
                return false;
            }
            tmp = tmp.children[index];
        }
        return true;
    }
LeetCode练习题 720. 词典中最长的单词
    public String longestWord(String[] words) {
        Trie trie = new Trie();
        for (String word : words) {
            trie.insert(word);
        }
        String longest = "";
        for (String word : words) {
            if (!trie.search(word)) {
                continue;
            }
            if (longest.length() < word.length()) {
                longest = word;
            } else if (longest.length() == word.length() && longest.compareTo(word) > 0) {
                longest = word;
            }
        }
        return longest;
    }

    class Trie {
        class TrieNode {
            TrieNode[] children = new TrieNode[26];
            boolean isEnd = false;
        }

        TrieNode root = new TrieNode();

        public void insert(String word) {
            TrieNode tmp = root;
            for (char c : word.toCharArray()) {
                int index = c - 'a';
                if (tmp.children[index] == null) {
                    tmp.children[index] = new TrieNode();
                }
                tmp = tmp.children[index];
            }
            tmp.isEnd = true;
        }

        public boolean search(String word) {
            TrieNode tmp = root;
            for (char c : word.toCharArray()) {
                int index = c - 'a';
                if (tmp.children[index] == null) {
                    return false;
                }
                // 区别于208题的地方。
                // 因为判断的word必须是由其他字符串在末尾加上一位组成,
                // 因此树中必须存在1~len-1位的字符串,且这些字符串也都满足这个要求
                if (!tmp.children[index].isEnd) {
                    return false;
                }
                tmp = tmp.children[index];
            }
            return tmp.isEnd;
        }
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/952694.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号