剑指 Offer II 064. 神奇的字典(676. 实现一个魔法字典)
题目:
思路:
【1】暴力枚举的方式:
【2】使用字典树优化的方式:
代码展示:
使用字典树优化的方式:
//时间29 ms击败58.92% //内存43.5 MB击败52.31% //时间复杂度:O(nl+ql∣Σ∣),其中 n 是数组 dictionary 的长度,l 是数组 dictionary 中字符串的平均长度,q 是函数 search(searchWord) 的调用次数,Σ 是字符集。 //初始化需要的时间为 O(nl),每一次查询最多会把与 searchWord 相差一个字符的单词全部遍历一遍,因此时间复杂度为 O(l∣Σ∣)。 //空间复杂度:O(nl),即为字典树需要使用的空间。 class MagicDictionary { Trie root; public MagicDictionary() { root = new Trie(); } public void buildDict(String[] dictionary) { for (String word : dictionary) { Trie cur = root; for (int i = 0; i < word.length(); ++i) { char ch = word.charAt(i); int idx = ch - 'a'; if (cur.child[idx] == null) { cur.child[idx] = new Trie(); } cur = cur.child[idx]; } cur.isFinished = true; } } public boolean search(String searchWord) { return dfs(searchWord, root, 0, false); } private boolean dfs(String searchWord, Trie node, int pos, boolean modified) { if (pos == searchWord.length()) { return modified && node.isFinished; } int idx = searchWord.charAt(pos) - 'a'; if (node.child[idx] != null) { if (dfs(searchWord, node.child[idx], pos + 1, modified)) { return true; } } if (!modified) { for (int i = 0; i < 26; ++i) { if (i != idx && node.child[i] != null) { if (dfs(searchWord, node.child[i], pos + 1, true)) { return true; } } } } return false; } } class Trie { boolean isFinished; Trie[] child; public Trie() { isFinished = false; child = new Trie[26]; } }
暴力枚举的方式:
//时间20 ms击败100% //内存42.1 MB击败73.18% //时间复杂度:O(qnl),其中 n 是数组 dictionary 的长度,l 是数组 dictionary 中字符串的平均长度,q 是函数 search(searchWord) 的调用次数。 //空间复杂度:O(nl),即为数组需要使用的空间。 class MagicDictionary { private String[] words; /** Initialize your data structure here. */ public MagicDictionary() { } public void buildDict(String[] dictionary) { words = dictionary; } //每次查找都是要遍历整个已存储的数组 //先是比对长度是否一致,再是比对相同位置不同字符的个数,如果相差不是1的,就返回false,包括相差为0的代表两字符相等 public boolean search(String searchWord) { for (String word : words) { if (word.length() != searchWord.length()) { continue; } int diff = 0; for (int i = 0; i < word.length(); ++i) { if (word.charAt(i) != searchWord.charAt(i)) { ++diff; if (diff > 1) { break; } } } if (diff == 1) { return true; } } return false; } } /** * Your MagicDictionary object will be instantiated and called as such: * MagicDictionary obj = new MagicDictionary(); * obj.buildDict(dictionary); * boolean param_2 = obj.search(searchWord); */