zoukankan      html  css  js  c++  java
  • LeetCode——实现Trie

    引用:https://blog.csdn.net/qq_29996285/article/details/86674779?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
    字典树是一种有序的,用于统计、排序和存储字符串的数据结构,他与二叉查找树不同,关键字不是直接保存在节点中,而是由节点在树中的位置决定,每个节点代表了一个字符,从第一层孩子节点到中间的某个标记的节点代表了存储的字符串。
    一个节点的所有子孙都有相同的前缀,而根节点对应空字符串。
    一般情况下,不是所有的节点都有对应的字符串,只有叶子节点和部分内部节点进行标记,才存储了字符串。
    字典树的最大优点就是利用字符串的公共前缀来减少存储空间与查询时间,从而最大限度的减少无味的字符串比较。查找和插入字符串都可达到O(1)算法复杂度。

    class TrieNode {
        char val;
        boolean isWord;//只有到叶子节点了才算一个word
        TrieNode[] children = new TrieNode[26];//当前层最多有a-z 26个字符
    
        TrieNode() {
        }
    
        TrieNode(char c) {
            val = c;
            isWord = false;
        }
    }
    
    class Trie {
        private TrieNode root;
    
        Trie() {
            root = new TrieNode();
        }
    
        public void insert(String word) {
            TrieNode node = root;
            for (int i = 0; i < word.length(); i++) {
                int index = word.charAt(i) - 'a';
                if (node.children[index] == null) {
                    node.children[index] = new TrieNode(word.charAt(i));
                }
                node = node.children[index];
            }
            node.isWord = true;
        }
    
        public boolean search(String word) {
            TrieNode node = root;
            for (int i = 0; i < word.length(); i++) {
                int index = word.charAt(i) - 'a';
                if (node.children[index] == null) {
                    return false;
                }
                node = node.children[index];
            }
            return node.isWord;
        }
    
        public boolean startwith(String prefix) {
            TrieNode node = root;
            for (int i = 0; i < prefix.length(); i++) {
                int index = prefix.charAt(i) - 'a';
                if (node.children[index] == null) {
                    return false;
                }
                node = node.children[index];
            }
            return true;
        }
    }
    

    验证一下:

        public static void main(String[] args) {
            Trie r = new Trie();
            r.insert("apple");
            boolean a = r.search("add");//false
            a = r.search("apple");//true
            a = r.startwith("app");//true
            a = r.startwith("b");//false
        }
    

    实现先序遍历:

        public static ArrayList<ArrayList<Character>> pre_order(TrieNode root) {
            ArrayList<ArrayList<Character>> arrayLists = new ArrayList<>();
            ArrayList<Character> arrayList = new ArrayList<>();
            dfs(arrayLists, arrayList, root);
            return arrayLists;
        }
    
        private static void dfs(ArrayList<ArrayList<Character>> arrayLists, ArrayList<Character> arrayList, TrieNode root) {
            for (int i = 0; i < root.children.length; i++) {
                if (root.children[i] != null) {
                    arrayList.add((char) (i + 'a'));
                    if (root.children[i].isWord) {
                        arrayLists.add(new ArrayList<>(arrayList));
                    }
                    dfs(arrayLists, arrayList, root.children[i]);
                    //回溯法恢复现场
                    arrayList.remove(arrayList.size() - 1);
                }
            }
        }
    
  • 相关阅读:
    Linux学习笔记之Linux Centos关闭防火墙
    ELK学习笔记之Logstash详解
    ELK学习笔记之ElasticSearch的索引详解
    C语言拼接字符串 -- 使用strcat()函数
    linux 中的 open() read() write() close() 函数
    stderr 和stdout
    ubuntu14.04 放开串口权限
    ubuntu14.04 安装 openssh-server
    串口接线
    ubuntu + usb转RS232驱动
  • 原文地址:https://www.cnblogs.com/xym4869/p/12561102.html
Copyright © 2011-2022 走看看