Trie(前缀树)

Trie,又称前缀树或字典树,是一棵有根树.

实现 Trie (前缀树)(力扣 208)

插入字符串

插入字符串,对于当前字符对应的子节点,有两种情况:

子节点存在:沿着指针移动到子节点,继续处理下一个字符。
子节点不存在:创建一个新的子节点,记录在 children 数组的对应位置上,然后继续搜索下一个字符。

查找前缀

查找前缀,有两种情况:
子节点存在:沿着指针移动到子节点,继续搜索下一个字符。
子节点不存在:说明字典树中不包含该前缀,返回空指针。

class Trie {
    private Trie[] children;
    private boolean isEnd;

    public Trie() {
        children = new Trie[26];
        isEnd = false;
    }
    
    public void insert(String word) {
        Trie node = this;
        for (int i = 0; i < word.length(); i++) {
            char ch = word.charAt(i);
            int index = ch - '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 = searchPrefix(word);
        return node != null && node.isEnd;
    }
    
    public boolean startsWith(String prefix) {
        return searchPrefix(prefix) != null;
    }

    private Trie searchPrefix(String prefix) {
        Trie node = this;
        for (int i = 0; i < prefix.length(); i++) {
            char ch = prefix.charAt(i);
            int index = ch - 'a';
            if (node.children[index] == null) {
                return null;
            }
            node = node.children[index];
        }
        return node;
    }
}

词典中最长的单词(力扣 720)

class Solution {
    public String longestWord(String[] words) {
        Trie trie = new Trie();
        int index = 0;
        for (String word: words) {
            trie.insert(word, ++index); //indexed by 1
        }
        trie.words = words;
        return trie.dfs();
    }
}
class Node {
    char c;
    HashMap<Character, Node> children = new HashMap();
    int end;
    public Node(char c){
        this.c = c;
    }
}

class Trie {
    Node root;
    String[] words;
    public Trie() {
        root = new Node('0');
    }

    public void insert(String word, int index) {
        Node cur = root;
        for (char c: word.toCharArray()) {
            cur.children.putIfAbsent(c, new Node(c));
            cur = cur.children.get(c);
        }
        cur.end = index;
    }

    public String dfs() {
        String ans = "";
        Stack<Node> stack = new Stack();
        stack.push(root);
        while (!stack.empty()) {
            Node node = stack.pop();
            if (node.end > 0 || node == root) {
                if (node != root) {
                    String word = words[node.end - 1];
                    if (word.length() > ans.length() ||
                            word.length() == ans.length() && word.compareTo(ans) < 0) {
                        ans = word;
                    }
                }
                for (Node nei: node.children.values()) {
                    stack.push(nei);
                }
            }
        }
        return ans;
    }
}

前K个高频单词(力扣 692)

class Solution {
    
    class TrieNode {	

        private TrieNode[] children;


        private boolean isEnd;
        private final int R = 26; 
        private int appearTimes;
        private boolean hasChildren;
        private String word;

      
        public TrieNode() {
            isEnd = false;
            children = new TrieNode[R];
            appearTimes = 0;
            hasChildren = false;
        }

        public boolean containsChar(char ch) {
            return children[ch-'a'] != null;
        }

     
        public boolean isEnd() {
            return isEnd;
        }
        public void setEnd(boolean _isEnd) {
            isEnd = _isEnd;
            appearTimes++;
        }


        public TrieNode get(char ch) {
            return children[ch-'a'];
        }

        
        public void put(char ch, TrieNode node) {
            children[ch-'a'] = node;
            hasChildren = true;
        }

        
        public TrieNode[] getChildren() {
            return children;
        }

     
        public int getAppearTimes() {
            return appearTimes;
        }
        

        public boolean hasChildren() {
            return hasChildren;
        }
        
    
        public String getCurrentWord() {
            return word;
        }
 
        public void setCurrentWord(String _word) {
            word = _word;
        }
    }
    
    class Trie {
	
        private TrieNode root;


        public Trie() {
            root = new TrieNode();
        }


        public TrieNode getRoot() {
            return root;
        }


        public void insert(String word) {
            TrieNode node = root;
            for( int i = 0; i < word.length(); i++ ) {
                char currentChar = word.charAt(i);
                if( !node.containsChar(currentChar) ) {
                    node.put(currentChar, new TrieNode());
                }
                node = node.get(currentChar);
            }
            node.setEnd(true);
            node.setCurrentWord(word);
        }

     
        public boolean search(String word) {
            TrieNode node = root;
            for( int i = 0; i < word.length(); i++ ) {
                char currentChar = word.charAt(i);
                if( node.containsChar(currentChar) ) {
                    node = node.get(currentChar);
                }
                else {
                    return false;
                }
            }
            return node.isEnd();       
        }


        public boolean searchPrefix(String prefix) {
            TrieNode node = root;
            for( int i = 0; i < prefix.length(); i++ ) {
                char currentChar = prefix.charAt(i);
                if( node.containsChar(currentChar) ) {
                    node = node.get(currentChar);
                }
                else {
                    return false;
                }
            }  	
            return true;        
        }

    }
    
    public List<String> topKFrequent(String[] words, int k) {
        
        
     
        Trie trie = new Trie();
        for( String str : words ) {
            trie.insert(str);
        }
        HashMap<String, Integer> count = new HashMap<String, Integer>();

 
        dfs(trie.getRoot(), count);
        
        
        class WordComparator implements Comparator<String> {
            public int compare(String s1, String s2) {
                int times1 = count.get(s1);
                int times2 = count.get(s2);
                if( times1 < times2 ) {
                    return -1;
                }
                else if( times1 > times2 ) {
                    return 1;
                }
                else {

                    return s2.compareTo(s1);   
                   
                }
            }
        }
        PriorityQueue<String> heap = new PriorityQueue<String>(new WordComparator());

        for (String word: count.keySet()) {
            heap.offer(word);
            if (heap.size() > k) {
                heap.poll();
            }
        }

        List<String> ans = new ArrayList();
        while (!heap.isEmpty()) {
            ans.add(heap.poll());
        }
        Collections.reverse(ans);
        return ans;
        
    }
    
   
    private void dfs(TrieNode node, HashMap<String, Integer> count) {
        if( node.isEnd() ) {
            count.put(node.getCurrentWord(), node.getAppearTimes());
        }
       
        if( !node.hasChildren() ) {
            return ; 
        }        
       
        TrieNode[] children = node.getChildren();
        for( int i = 0; i < children.length; i++ ) {
            if( children[i] != null ) {
                dfs(node.children[i], count);
            }
        }        
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值