# 연관 링크
- [문제 풀이 스케줄](https://github.com/orgs/DaleStudy/projects/6/views/5)
- [답안 코드 제출법](https://github.com/DaleStudy/leetcode-study/wiki/%EB%8B%B5%EC%95%88-%EC%A0%9C%EC%B6%9C-%EA%B0%80%EC%9D%B4%EB%93%9C)

# Problem
- 문제 링크 : https://leetcode.com/problems/design-add-and-search-words-data-structure/description/
- 문제 이름 : design add and search words data structure
- 문제 번호 : 211
- 난이도 : medium
- 카테고리 :

# 문제 설명
- 데이터베이스에 input word를 더하고 찾는 자료구조 디자인하기

# 아이디어
- 이전 주차 word search와 동일한 접근 방법으로 풀이 가능
### Trie
```cpp
class TrieNode{
public:
    bool isCompleteWord;
    TrieNode* children[26];

    TrieNode() {
        isCompleteWord = false;
        memset(children, 0, sizeof(children));
    }
};
```

- 가지 중간인지, 아니면 완결된 단어인지를 확인할 수 있음.
- 해당 로직을 통해, Prefix 확인하는 메서드 또한 쉽게 만들 수 있음.

# ✅ 코드 (Solution)

## Trie - wrong answer
```cpp
class TrieNode{
public:
    bool isCompleteWord;
    TrieNode* children[26];

    TrieNode() {
        isCompleteWord = false;
        memset(children, 0, sizeof(children));
    }
};

class WordDictionary {
    TrieNode* root;
public:
    WordDictionary() {
        root = new TrieNode();
    }
    
    void addWord(string word) {
        auto cur = root;
        for(auto c: word){
            if(!cur->children[c-'a']){
                cur->children[c-'a'] = new TrieNode();
            }
            cur = cur->children[c-'a'];
        }
        cur->isCompleteWord = true;
    }
    
    bool search(string word) {
        auto cur = root;
        for(auto c: word){
            if(!cur->children[c-'a']){
                return false;
            }
            cur = cur->children[c-'a'];
        }
        return cur->isCompleteWord;
    }
};

/**
 * Your WordDictionary object will be instantiated and called as such:
 * WordDictionary* obj = new WordDictionary();
 * obj->addWord(word);
 * bool param_2 = obj->search(word);
 */
```

- 잘못 작성한 코드
- 자료구조 적용 중, edge case(`.` - dot)을 고려하지 않음
  - 아는 문제라고 쉽게 생각한 것이 잘못.

```cpp
class TrieNode {
public:
    bool isCompleteWord;
    TrieNode* children[26];

    TrieNode() {
        isCompleteWord = false;
        memset(children, 0, sizeof(children));
    }
};

class WordDictionary {
    TrieNode* root;

    bool dfs(TrieNode* node, const string& word, int index) {
        if (!node) return false;
        if (index == word.size()) return node->isCompleteWord;

        char c = word[index];
        if (c == '.') {
            // '.'이므로 모든 자식을 시도해본다
            for (int i = 0; i < 26; ++i) {
                if (dfs(node->children[i], word, index + 1)) {
                    return true;
                }
            }
            return false;
        } else {
            return dfs(node->children[c - 'a'], word, index + 1);
        }
    }

public:
    WordDictionary() {
        root = new TrieNode();
    }

    void addWord(string word) {
        TrieNode* cur = root;
        for (char c : word) {
            int idx = c - 'a';
            if (!cur->children[idx]) {
                cur->children[idx] = new TrieNode();
            }
            cur = cur->children[idx];
        }
        cur->isCompleteWord = true;
    }

    bool search(string word) {
        return dfs(root, word, 0);
    }
};

```

- dfs로 구현

# 🔍 코드 설명


# 최적화 포인트 (Optimality Discussion)
•	최적화한 이유와 원리
•	더 줄일 수 있는 여지는 있는가?
•	기존 방법 대비 얼마나 효율적이었는지

# 🧪 테스트 & 엣지 케이스

# 📚 관련 지식 복습

# 🔁 회고


