[C++] LeetCode/Hard/0745-prefix-and-suffix-search

2025. 3. 25. 21:06·C++/Coding Test

Prefix and Suffix Search (LeetCode 745)

문제 개요

  • 문제 설명:
    주어진 문자열 배열 words에서, 특정 접두사(pref)와 접미사(suff)를 모두 만족하는 단어 중 가장 큰 인덱스를 반환하는 문제이다.
  • 문제의 어려움:
    단순한 선형 검색이나 해시맵 기반 방법으로는 모든 단어에 대해 접두사와 접미사를 확인해야 하므로 비효율적이다.
    따라서, 빠른 검색을 위해 Trie(트라이) 자료구조를 활용하는 최적화된 방법이 필요하다.

접근 방식: Trie를 이용한 최적화

  • 핵심 아이디어:
    한 단어의 모든 가능한 접두사와 접미사 조합을 미리 Trie에 삽입해 놓는다.
    이를 통해 f(pref, suff) 함수 호출 시, suff + "{" + pref 문자열을 만들어 한 번의 탐색으로 원하는 단어의 인덱스를 찾아낼 수 있다.
  • 왜 "{"인가?
    '{' 문자는 알파벳 'z'보다 뒤에 오기 때문에, 접미사와 접두사를 구분하는 구분자(separator) 역할을 한다.
    예를 들어, 단어 "apple"의 경우, "apple{" 형태로 만들어 접미사와 접두사의 조합을 관리한다.

코드 동작 원리

  1. TrieNode 구조체
    • 각 노드는 unordered_map<char, TrieNode*> children를 가지고 있어 다음 문자를 가리키며,
    • index 멤버는 현재 노드를 거치는 단어들 중 마지막에 나온(즉, 가장 큰 인덱스) 단어의 인덱스를 저장한다.
  2. 생성자 WordFilter(vector<string>& words)
    • 각 단어에 대해 word + "{" 형태의 문자열을 만든다.
    • 이 문자열을 이용해 모든 가능한 접미사와 접두사의 조합을 Trie에 삽입한다.
    • 예를 들어, 단어 "apple"이라면,
      • "apple{", "pple{", "ple{", "le{", "e{", "{" 등을 고려하며,
      • 각 삽입 시마다 해당 노드의 index를 현재 단어의 인덱스로 갱신한다.
  3. 함수 f(string pref, string suff)
    • 입력받은 접두사와 접미사를 조합해 쿼리 문자열 query = suff + "{" + pref를 생성한다.
    • Trie를 순회하면서 해당 경로가 존재하면, 최종 노드의 index를 반환하고,
    • 경로가 없다면 -1을 반환한다.

코드 전체

class WordFilter {
    struct TrieNode {
        unordered_map<char, TrieNode*> children;
        int index = -1;
    };
    
    TrieNode* root;
    
public:
    WordFilter(vector<string>& words) {
        root = new TrieNode();
        int n = words.size();
        
        for (int i = 0; i < n; i++) {
            // '{'는 알파벳보다 큰 값으로, 접두사와 접미사 구분자 역할
            string word = words[i] + "{";  
            int len = word.size();
            
            // 모든 가능한 접미사 + 접두사 조합을 Trie에 삽입
            for (int j = 0; j < len; j++) {
                TrieNode* node = root;
                for (int k = j; k < 2 * len - 1; k++) {
                    char c = word[k % len]; 
                    if (!node->children.count(c)) {
                        node->children[c] = new TrieNode();
                    }
                    node = node->children[c];
                    node->index = i; // 현재 단어의 인덱스 (가장 마지막에 삽입된 단어가 우선)
                }
            }
        }
    }
    
    int f(string pref, string suff) {
        string query = suff + "{" + pref;
        TrieNode* node = root;
        
        for (char c : query) {
            if (!node->children.count(c)) return -1;
            node = node->children[c];
        }
        return node->index;
    }
};

'C++ > Coding Test' 카테고리의 다른 글

[C++] 백준/Gold/1011. Fly me to the Alpha Centauri  (0) 2025.04.02
[C++] 백준/Platinum/1786. 찾기  (0) 2025.03.28
[C++] 백준/Gold/2011. 암호코드  (0) 2025.03.19
[C++] 백준/Gold/1915. 가장 큰 정사각형  (0) 2025.03.14
[C++] 백준/Gold/1253. 좋다  (0) 2025.03.13
'C++/Coding Test' 카테고리의 다른 글
  • [C++] 백준/Gold/1011. Fly me to the Alpha Centauri
  • [C++] 백준/Platinum/1786. 찾기
  • [C++] 백준/Gold/2011. 암호코드
  • [C++] 백준/Gold/1915. 가장 큰 정사각형
돼지표
돼지표
https://github.com/wkdgns135
  • 돼지표
    돼지표 개발 스토리
    돼지표
  • 전체
    오늘
    어제
    • 분류 전체보기 (112)
      • C++ (60)
        • Coding Test (53)
        • Study (1)
      • Python (1)
      • Machine Learning (2)
      • Computer Graphics (4)
        • Curly Hair Simulation (2)
      • GPU Programming (11)
        • CUDA basic (7)
        • CUDA fluidsGL (4)
      • Unreal 5 (26)
        • Troubleshooting (4)
        • FPS Shooting (5)
        • Study (10)
        • EOS (1)
        • STILL LOADING (5)
      • Computer Science (7)
        • Algorithm (3)
      • Other (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    dp
    GPU Programming
    FPS
    STILL LOADING
    Rendering Pipeline
    구현
    BFS
    자료 구조
    OpenGL
    CUDA
    unreal 5
    C++
    CS
    Fluid Simulation
    수학
    아이작 맵 생성
    UE5
    정렬
    Algorithm
    그래프 탐색
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
돼지표
[C++] LeetCode/Hard/0745-prefix-and-suffix-search
상단으로

티스토리툴바