Trie字典树的实现(力扣第208题)

Trie树的基本概念

  Trie树又称为前缀树或者字典树,用于判断字符串是否存在或者是否具有某种字符串的前缀。Trie 的每个 Node 保存一个字符。用链表来描述的话,就是一个字符串就是一个链表。每个Node都保存了它的所有子节点。

Trie树的实现

  本文通过链表来实现Trie树,基本的操作主要包括插入、查询、前缀查询等。由于主要是采用链表实现字典树,所以链表的数据结构需要针对字典树的特点进行设计,链表中的每个节点主要包括两个部分:

    1、一个标识符,即标识从之前的节点到当前的节点为止,是否是一个单词(boolean isWord);

    2、一个数组或者哈希表,用于存储当前节点的所有子节点,可以通过map保存或者数组保存;

  力扣第208题要求实现的正是Trie树的实现和基本操作:

  (1)链表的结构

    /**
     * 使用链表来实现Trie树,链表的每个node的结构主要包括两个部分:
     * 1、标识是否是单词(boolean isWord)
     * 2、通过一个map或者一个数组记录当前节点的所有子节点
     */
    private class Node{

        boolean isWord;
        Map childNode = new HashMap<String,String>();
    }

 

  (2)插入

   /**
     * 节点的所有子节点,通过一个Map来存储,key是当前子节点对应的字符,value是子节点
     * 如果往Trie中插入一个单词,需要把该单词的最后一个字符的节点的isWord设置为true
     */
    /** Inserts a word into the trie. */
    public void insert(String word) {
        Node curr = root;
        if ( word == null ){
            return;
        }

        if ( word.length() == 0 ){
            curr.isWord = true;
            return;
        }

        char[] chars = word.toCharArray();

        for (char aChar : chars) {

            Node next = (Node) curr.childNode.get(aChar);

            if ( next == null ){
                curr.childNode.put(aChar,new Node());
            }
            curr = (Node) curr.childNode.get(aChar);
        }

        if ( !curr.isWord ){
            curr.isWord = true;
        }

    }

  (3)查询

 /**
     * 遍历带查找的字符串的字符,如果每个节点都存在,
     * 并且待查找字符串的最后一个字符对应的Node的 isWord 属性为 true ,则表示该单词存在
     */
    /** Returns if the word is in the trie. */
    public boolean search(String word) {

        Node curr = root;

        char[] chars = word.toCharArray();

        for (char aChar : chars) {

            Node next = (Node) curr.childNode.get(aChar);

            if ( next == null ){
                return false;
            }

            curr = next;
        }

        return curr.isWord;
    }

  (4)前缀查询

  前缀查询与查询操作基本原理相同,只是不再需要判断给定的字符串是否是单词字典树中的单词这一操作。

    public boolean startsWith(String prefix) {

        Node curr = root;

        char[] chars = prefix.toCharArray();

        for (char aChar : chars) {

            Node next = (Node) curr.childNode.get(aChar);
            if ( next == null ){
                return false;
            }
            curr = next;
        }
        return true;
    }

 

posted @ 2020-09-27 08:07  有心有梦  阅读(629)  评论(0编辑  收藏  举报