题目
按下述要求实现 StreamChecker 类:
StreamChecker(words):构造函数,用给定的字词初始化数据结构。
query(letter):如果存在某些 k >= 1,可以用查询的最后 k个字符(按从旧到新顺序,包括刚刚查询的字母)拼写出给定字词表中的某一字词时,返回 true。否则,返回 false。
示例:
StreamChecker streamChecker = new StreamChecker([“cd”,“f”,“kl”]); // 初始化字典
streamChecker.query(‘a’); // 返回 false
streamChecker.query(‘b’); // 返回 false
streamChecker.query(‘c’); // 返回 false
streamChecker.query(‘d’); // 返回 true,因为 ‘cd’ 在字词表中
streamChecker.query(‘e’); // 返回 false
streamChecker.query(‘f’); // 返回 true,因为 ‘f’ 在字词表中
streamChecker.query(‘g’); // 返回 false
streamChecker.query(‘h’); // 返回 false
streamChecker.query(‘i’); // 返回 false
streamChecker.query(‘j’); // 返回 false
streamChecker.query(‘k’); // 返回 false
streamChecker.query(‘l’); // 返回 true,因为 ‘kl’ 在字词表中。
提示:
1 <= words.length <= 2000
1 <= words[i].length <= 2000
字词只包含小写英文字母。
待查项只包含小写英文字母。
待查项最多 40000 个。
民间解法
- 思路
1.使用字典树的方式存储单词列表,并标记在什么位置可以形成单词
2.记录最大长度,只记录最大长度的查询字符
3.查询字符时,只需要从后向前遍历即可
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class Solution1032 {
}
/**
* 按下述要求实现 StreamChecker 类:
*
* StreamChecker(words):构造函数,用给定的字词初始化数据结构。
* query(letter):如果存在某些 k >= 1,可以用查询的最后 k个字符(按从旧到新顺序,包括刚刚查询的字母)拼写出给定字词表中的某一字词时,返回 true。否则,返回 false。
*
*/
class StreamChecker {
Letter root;
int maxLength;
List<Character> history;
public StreamChecker(String[] words) {
root = new Letter();
maxLength = 0;
if (null == words || words.length == 0) {
return;
}
for (String word : words) {
if (0 == word.length()) {
continue;
}
if (word.length() > maxLength) {
maxLength = word.length();
}
Letter node = root;
for (int i=word.length()-1; i>=0; i--) {
char c = word.charAt(i);
if (null == node.next) {
node.next = new HashMap<>();
Letter letter = new Letter();
letter.isKeyWord = false;
node.next.put(c, letter);
} else if (null == node.next.get(c)) {
Letter letter = new Letter();
letter.isKeyWord = false;
node.next.put(c, letter);
}
node = node.next.get(c);
}
node.isKeyWord = true;
}
history = new LinkedList<Character>();
}
public boolean query(char letter) {
history.add(letter);
if (maxLength < history.size()) {
history.remove(0);
}
Letter node = root;
for (int i=history.size()-1; i>=0; i--) {
Letter next = node.next.get(history.get(i));
if (null == next) {
break;
} else {
if (next.isKeyWord) {
return true;
}
node = next;
}
}
return false;
}
}
/**
* 字母链表
* 用来存储单词
*/
class Letter{
/* 单词标识 */
boolean isKeyWord;
/* 下一个字母 */
Map<Character, Letter> next;
}
- 这道题主要的问题是存储和查询
- 没有用字符串的方式匹配,是感觉如果匹配每个字符串会重复遍历字符