算法-字典树

前言

Trie:单词查找树(字典树、前缀树),一种特定的树结构,一般用于查询热频单词等。

构成:单词查找树根节点不存储数据,每个子节点下最多存在26个子节点,每个子节点存储一个英文字符;一条分支路径上可能存在多个英文单词,英文单词结尾处的节点需要进行标记。

使用

如下通过字典树解决最长公共前缀的问题,题目来源leetcode

package com.example.test;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * 字典树
 *
 * @author hulei
 * @date 2021/4/6
 */
public class Solution {
    public static void main(String[] args) {
        String[] strs = {"flower", "flow", "flight"};
        System.out.println(new Solution().longestCommonPrefix(strs));
    }

    public String longestCommonPrefix(String[] strs) {
        // 单词录入到字典树中
        for (String str : strs) {
            Trie.insert(str);
        }

        Trie.TrieNode node = Trie.root;
        StringBuilder builder = new StringBuilder();
        // 找到子节点数量不为1,即字典树产生多个分叉的位置
        while (node.getChildMap().size() == 1) {
            Set<Map.Entry<Character, Trie.TrieNode>> entries = node.getChildMap().entrySet();
            Map.Entry<Character, Trie.TrieNode> entry = entries.stream().findFirst().get();

            builder.append(Objects.isNull(entry.getKey()) ? "" : entry.getKey());
            node = entry.getValue();
        }

        return builder.toString();
    }

    /**
     * 字典树
     *
     * @author hulei
     * @date 2021/4/6
     */
    public static class Trie {
        // 根节点
        public static TrieNode root = new TrieNode();

        // 将单词录入到字典树中
        public static void insert(String word) {
            // 节点指针初始指向根节点
            TrieNode cur = root;
            for (int i = 0; i < word.length(); i++) {
                char c = word.charAt(i);
                Map<Character, TrieNode> childMap = cur.getChildMap();
                if (!childMap.containsKey(c)) {
                    childMap.put(c, new TrieNode(c));
                }

                // 节点指针指向下一个节点
                cur = childMap.get(c);
            }
        }
        
        /**
         * 字典树节点
         *
         * @author hulei
         * @date 2021/4/6
         */
        public static class TrieNode {
            // 子节点集合,子节点表示的英文字符:子节点
            private Map<Character, TrieNode> childMap;
            // 当前节点表示的英文字符
            private Character value;

            public Map<Character, TrieNode> getChildMap() {
                return childMap;
            }

            public void setChildMap(Map<Character, TrieNode> childMap) {
                this.childMap = childMap;
            }

            public Character getValue() {
                return value;
            }

            public void setValue(Character value) {
                this.value = value;
            }

            public TrieNode() {
                childMap = new HashMap<>();
                value = null;
            }

            public TrieNode(Character value) {
                childMap = new HashMap<>();
                this.value = value;
            }
        }
    }

}
posted @ 2021-04-07 17:04  规划中~~~  阅读(79)  评论(0)    收藏  举报