[백준] 14426번 접두사 찾기 _ JAVA

2024. 2. 21. 10:31·Algorithms/Data Structure

[초기 접근 방법]

검사 문자열 inspect에 대해 집합 S 문자의 접두사가 맞는지 체크

→ 시간복잡도가 O(MN * len(inspect[i])) = O(1억 *  a) 으로 시간초과가 된다.

 

 

 

[생각]

문제 유형을 보니 "Trie"라는 처음 보는 자료구조여서 블로그를 참조해 먼저 공부했다.

 

 

Trie

: 문자열을 저장하고 효율적으로 탐색하기 위한 '트리' 형태의 자료구조

→ 자동완성, 사전 검색 등 문자열 탐색 기능

 

 

- insert()

// 생성 시간 복잡도 : O(N*L)

void insert(String word) {
    TrieNode node = this.rootNode;

    // 문자열의 각 단어의 자식노드를 찾아 return 하거나, 자식노드 새로 생성
    // Map에서 현재 문자를 key로 Value를 가지고 오거나, 없으면 새로운 노드를 생성한다.
    for (int i = 0; i < word.length(); ++i) {
        node = node.childNodes.computeIfAbsent(word.charAt(i), c -> new TrieNode());
    }

    // 문자열의 마지막 문자 노드에서, 리프노드 임을 명시
    node.isLeaf = true;
}

 

 

- search()

// 탐색 시간 복잡도 : O(L)

boolean search(String word) {
    TrieNode node = this.rootNode;

    for (int i = 0; i < word.length(); ++i) {
        // 문자열의 각 단어에 매핑된 노드가 존재하면 가져온다. 없으면 null을 반환한다.
        node = node.childNodes.getOrDefault(word.charAt(i), null);

        // 현재 Trie에 해당 문자열이 없다.
        if (node == null) {
            return false;
        }
    }

    // 접두사를 찾는 문제이므로, 해당 문자열이 있다면 true를 반환한다.
    // 정확한 문자열 찾기 문제였다면 리프노드인지 확인을 하고
        // "return node.isLeaf"로 수정해주어야 한다.
    return true;
}

 

 

- 참고

https://velog.io/@kimdukbae/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%ED%8A%B8%EB%9D%BC%EC%9D%B4-Trie

 

https://codingnojam.tistory.com/40

 

 

 

[코드]

1. 검사 문자열에 대해 문자 1개씩 접두사가 맞는지 일일이 검사 (시간초과)

# 풀이 시간 : 15분
# 시간복잡도 : O(MN*len())
# 공간복잡도 : O(M or N)
# 참고 : -

N, M = map(int, input().split())

# 집합 S에 포함되어 있는 문자열
setS = [input() for _ in range(N)]
# 검사해야 하는 문자열
inspect = [input() for _ in range(M)]

# 모든 검사 문자열에 대해, setS에 포함되는지 탐색
result = 0
for i in range(M):
    for j in range(N):
        if len(inspect[i]) > len(setS[j]): # 검사하는 문자열이 더 긴 경우
            break

        else:
            judge = True
            for k in range(len(inspect[i])):
                if inspect[i][k] != setS[j][k]:
                    judge = False
                    break

            if judge:
                result += 1
                break

print(result)

 

 

 

2. 정렬 후 최적화 (시간초과)

# 풀이 시간 : 15분 + 10분(생각) + 10분
# 시간복잡도 : O(MN)
# 공간복잡도 : O(M or N)
# 참고 : https://melody-coding.tistory.com/154

import sys
input = sys.stdin.readline

N, M = map(int, input().split())

# 집합 S에 포함되어 있는 문자열
setS = [input().rstrip() for _ in range(N)]
# 검사해야 하는 문자열
inspect = [input().rstrip() for _ in range(M)]

setS.sort()
inspect.sort()

# 모든 검사 문자열에 대해, setS에 포함되는지 탐색
result = 0
s = 0
for i in inspect:
    for j in range(s, N):
        if i == setS[j][:len(i)]:
            result += 1
            s = j
            break

print(result)

 

 

3. Trie 자료구조 이용

// 풀이 시간 : 15분 + 10분(생각) + 1시간
// 시간복잡도
    // N : 모든 문자열 갯수, L : 문자열 최대 길이
    // 생성 : O(N * L)
    // 탐색 : O(L)
// 공간복잡도 : O(ML)
// 참고
    // 구현 : https://melody-coding.tistory.com/154
    // 트라이 : https://velog.io/@kimdukbae/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%ED%8A%B8%EB%9D%BC%EC%9D%B4-Trie
    //         https://codingnojam.tistory.com/40

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

class TrieNode{
    Map<Character, TrieNode> childNodes = new HashMap<>();
    boolean isLeaf = false; // 초기에는 리프노드 X
}

class Trie{
    TrieNode rootNode;

    public Trie() {
        this.rootNode = new TrieNode();
    }

    void insert(String word) {
        TrieNode node = this.rootNode;

        // 문자열의 각 단어의 자식노드를 찾아 return 하거나, 자식노드 새로 생성
        // Map에서 현재 문자를 key로 Value를 가지고 오거나, 없으면 새로운 노드를 생성한다.
        for (int i = 0; i < word.length(); ++i) {
            node = node.childNodes.computeIfAbsent(word.charAt(i), c -> new TrieNode());
        }

        // 문자열의 마지막 문자 노드에서, 리프노드 임을 명시
        node.isLeaf = true;
    }

    boolean search(String word) {
        TrieNode node = this.rootNode;

        for (int i = 0; i < word.length(); ++i) {
            // 문자열의 각 단어에 매핑된 노드가 존재하면 가져온다. 없으면 null을 반환한다.
            node = node.childNodes.getOrDefault(word.charAt(i), null);

            // 현재 Trie에 해당 문자열이 없다.
            if (node == null) {
                return false;
            }
        }

        // 접두사를 찾는 문제이므로, 해당 문자열이 있다면 true를 반환한다.
        // 정확한 문자열 찾기 문제였다면 리프노드인지 확인을 하고
            // "return node.isLeaf"로 수정해주어야 한다.
        return true;
    }
}

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        Trie trie = new Trie();
        int count = 0;

        int N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());

        for (int i = 0; i < N; ++i) {
            trie.insert(br.readLine());
        }

        for (int i = 0; i < M; ++i) {
            boolean bool = trie.search(br.readLine());

            if (bool) {
                count += 1;
            }
        }

        System.out.println(count);
    }
}

 

 

 

https://www.acmicpc.net/problem/14426

 

저작자표시 (새창열림)

'Algorithm > Data Structure' 카테고리의 다른 글

[백준] 5052번 전화번호 목록 _ Java, Python  (0) 2024.03.02
[백준] 1043번 거짓말 _ Python  (0) 2024.02.20
[백준] 14725번 개미굴 _ Python  (0) 2024.02.09
'Algorithms/Data Structure' 카테고리의 다른 글
  • [백준] 5052번 전화번호 목록 _ Java, Python
  • [백준] 1043번 거짓말 _ Python
  • [백준] 14725번 개미굴 _ Python
wch_t
wch_t
  • wch_t
    끄적끄적(TIL)
    wch_t
  • 글쓰기 관리
  • 전체
    오늘
    어제
    • 분류 전체보기 (170) N
      • Architecture (0)
      • Algorithm (67)
        • Math (5)
        • Simulation (1)
        • Data Structure (4)
        • DP (7)
        • Brute Fource (10)
        • Binary Search (6)
        • Greedy (2)
        • Graph (11)
        • Mst (1)
        • Shortest path (10)
        • Two Pointer (1)
        • Tsp (3)
        • Union Find (2)
        • Mitm (1)
      • CS (2)
        • 데이터베이스 (5)
        • 네트워크 (5)
      • DB (6)
      • DevOps (17)
        • AWS (9)
        • Docker (1)
        • CI-CD (5)
      • Error (1)
      • Project (0)
        • kotrip (0)
      • Spring (59)
        • 끄적끄적 (5)
        • 기본 (9)
        • MVC 1 (7)
        • MVC 2 (11)
        • ORM (8)
        • JPA 1 (7)
        • JPA 2 (5)
        • Spring Data Jpa (7)
      • Test (2)
      • TIL (5) N
  • 블로그 메뉴

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

  • 공지사항

  • 인기 글

  • 태그

    docker: not found
    백준 17289 파이썬
    spring-cloud-starter-bootstrap
    Sxssf
    애플
    response_mode
    docker
    백준 17299 파이썬
    spring-cloud-starter-aws-secrets-manager-config
    백준 3015 파이썬
    aws secrets manager
    form_post
    Merge
    view algorithm
    apache poi
    TempTable
    scope
    Jenkins
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
wch_t
[백준] 14426번 접두사 찾기 _ JAVA
상단으로

티스토리툴바