1 <= word.length, prefix.length <= 2000
word
prefix
는 영문 소문자로만 구성된다. insert
, search
, startsWith
의 최대 호출 횟수는 3*10^4
.트리의 노드를 나타낼 클래스가 필요하다.
Node
children
을 가지고 있다.isEndOfWord
를 가지고 있어 해당 문자가 끝나는 지점인지 알 수 있다.root
Trie는 생성 시 root Node를 가지고 있다.public class Node{
public Map<Character, Node> children;
public boolean isEndOfWord;
public Node() {
this.children = new HashMap<>();
this.isEndOfWord = false;
}
}
insert
는 다음과 같은 작업들이 필요하다.word
만 인수로 받지만 재귀 함수로 나타내기 위해 Node
도 받는 함수가 되도록 한다. public void insert(String word) {
insert(this.root, word);
}
private void insert(Node node, String word) {
if (word.length() == 0) {
node.isEndOfWord = true;
return;
}
char c = word.charAt(0);
Node child = node.children.get(c);
if (child == null) {
child = new Node(); // 자식 노드가 없으면 생성
node.children.put(c, child);
}
insert(child, word.substring(1));
}
search
와 startsWith
은 비슷한 로직으로 해결할 수 있다.search
는 받은 단어의 모든 character가 깊이에 맞춰 모두 있어야 한다.(모두 일치)startsWiths
는 받은 단어만큼만 순서대로 트리에 있으면 된다.(일부 일치)false
를 반환한다.startsWith
은 기존 search
로직에서 마지막 확인 부분인 노드 끝부분 까지 찾았다는 것을 확인하지 않도록 하면 된다. public boolean search(String word) {
Node child = root;
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (!child.children.containsKey(c)) {
return false;
}
child = child.children.get(c);
}
return child.isEndOfWord;
}
class Trie {
public class Node{
public Map<Character, Node> children;
public boolean isEndOfWord;
public Node() {
this.children = new HashMap<>();
this.isEndOfWord = false;
}
}
private Node root;
public Trie() {
this.root = new Node();
}
public void insert(String word) {
insert(this.root, word);
}
private void insert(Node node, String word) {
if (word.length() == 0) {
node.isEndOfWord = true;
return;
}
char c = word.charAt(0);
Node child = node.children.get(c);
if (child == null) {
child = new Node(); // 자식 노드가 없으면 생성
node.children.put(c, child);
}
insert(child, word.substring(1));
}
public boolean search(String word) {
Node child = root;
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (!child.children.containsKey(c)) {
return false;
}
child = child.children.get(c);
}
return child.isEndOfWord;
}
public boolean startsWith(String prefix) {
Node child = root;
for (int i = 0; i < prefix.length(); i++) {
char c = prefix.charAt(i);
if (!child.children.containsKey(c)) {
return false;
}
child = child.children.get(c);
}
return true;
}
}
시간 복잡도
공간 복잡도
다음과 같은 점수를 기록했다.
다른 사람들의 예시를 보면 자식 노드를 배열로 다루기 위해 아스키코드 값을 사용하는 방법으로 성능을 개선하고 있다.