Leetcode: Add and Search Word - Data structure design (Java)

最近尝试完全脱离C++,转而只用java刷题。这是我用java做出的第一道树。题目在这里。说几点做题思路。
1. 暴力用Hashtable存单词,显然浪费空间,每个字母每个位次应该只存一次。暴力用Regex匹配,只适用于Hash字典。每个字母每个位次只存一次,在脑子里想一下,就能想到这就是要建一棵26叉树。
2. TreeNode除了字母值和大小为26的TreeNode数组外,还应包含一个整数min,用于表示当前字母到该分支最短单词最后一个字母的长度,例如存abc,那么字母b的min应为1,表示查找的时候,还需要再向下查一层才行,否则,查找ab的时候就会返回真,而事实上我们并未存储过ab这个单词。
3. Tree结构的查找用的是典型的递归查找。匹配’.’与匹配其他26个字母的不同,在于我需要查找当前TreeNode的所有非空的子树,且只要一棵子树查找成功即可。
4. 最重要的是TreeNode类的设计:

public class TreeNode {
        char val;
        int min;
        TreeNode[] next;
        TreeNode(char c) {
            val = c; 
            next = new TreeNode[26];
        }
    }

其中最重要的是TreeNode的构造函数,当我们执行

next = new TreeNode[26];

时,我们仅仅声明了next数组的大小,而并未分配内存,而这正是我们想要的。(如果你创建了一个非基本类型的数组,那么你就创建了一个引用数组。-《Java编程思想》5.8 数组初始化)

贴代码:

public class WordDictionary {
    public class TreeNode {
        char val;
        int min;
        TreeNode[] next;
        TreeNode(char c) {
            val = c; 
            next = new TreeNode[26];
        }
    }

    public TreeNode root;

    public WordDictionary() {
        root = new TreeNode(' ');
    }

    // Adds a word into the data structure.
    public void addWord(String word) {
        int len = word.length();
        int i;
        int index;
        char c;
        TreeNode current = root;
        int min_len = len;
        for (i=0;i<len;i++) {
            min_len--;
            c = word.charAt(i);
            index = (int)(c - 97);
            if (current.next[index]==null) {
                current.next[index] = new TreeNode(c);
                current.next[index].min = min_len;
            }
            else if (current.next[index].min>min_len) current.next[index].min = min_len;
            current = current.next[index];
        }
    }

    // Returns if the word is in the data structure. A word could
    // contain the dot character '.' to represent any one letter.
    public boolean search(String word) {
        return searchTree(word, root);
    }

    public boolean searchTree(String word, TreeNode current) {
        int len = word.length();
        if(len==0) {
            if (current.min>0) return false;
            else return true;
        }
        char c = word.charAt(0);
        if (c!='.') {
            int index = (int)(c-97);
            if (current.next[index]==null) return false;
            else if (current.next[index].val!=c) return false;
            else {
                return searchTree(word.substring(1), current.next[index]);
            }
        }
        else {
            int i;
            for (i=0;i<26;i++) {
                if (current.next[i]!=null) {
                    if (searchTree(word.substring(1), current.next[i])==true) return true;
                }
            }
            return false;
        }
    }
}

// Your WordDictionary object will be instantiated and called as such:
// WordDictionary wordDictionary = new WordDictionary();
// wordDictionary.addWord("word");
// wordDictionary.search("pattern");

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值