기록하는삶
[코딩 테스트 연습(파이썬/Python)] 프로그래머스 _ 단어 퍼즐 본문
https://programmers.co.kr/learn/courses/30/lessons/12983
[문제 설명]
단어 퍼즐은 주어진 단어 조각들을 이용해서 주어진 문장을 완성하는 퍼즐입니다. 이때, 주어진 각 단어 조각들은 각각 무한개씩 있다고 가정합니다. 예를 들어 주어진 단어 조각이 [“ba”, “na”, “n”, “a”]인 경우 "ba", "na", "n", "a" 단어 조각이 각각 무한개씩 있습니다. 이때, 만들어야 하는 문장이 “banana”라면 “ba”, “na”, “n”, “a”의 4개를 사용하여 문장을 완성할 수 있지만, “ba”, “na”, “na”의 3개만을 사용해도 “banana”를 완성할 수 있습니다. 사용 가능한 단어 조각들을 담고 있는 배열 strs와 완성해야 하는 문자열 t가 매개변수로 주어질 때, 주어진 문장을 완성하기 위해 사용해야 하는 단어조각 개수의 최솟값을 return 하도록 solution 함수를 완성해 주세요. 만약 주어진 문장을 완성하는 것이 불가능하면 -1을 return 하세요.
[제한 조건]
- strs는 사용 가능한 단어 조각들이 들어있는 배열로, 길이는 1 이상 100 이하입니다.
- strs의 각 원소는 사용 가능한 단어조각들이 중복 없이 들어있습니다.
- 사용 가능한 단어 조각들은 문자열 형태이며, 모든 단어 조각의 길이는 1 이상 5 이하입니다.
- t는 완성해야 하는 문자열이며 길이는 1 이상 20,000 이하입니다.
- 모든 문자열은 알파벳 소문자로만 이루어져 있습니다.
[아이디어]
1) 단어 조각의 길이가 1 ~ 5임을 활용해, 현재 위치에서 다음에 필요한 단어 조각이 있는지 탐색하는 것이 핵심이다.
2) 처음에 재귀로 접근했는데, 최소가 될 수 없는 경우에 대해서도 재귀 호출이 반복적으로 일어나기 때문인지 시간초과가 발생했다.
3) 2)의 문제를 해결하기 위해 dp를 활용한 단순 반복문으로 변경하여 해결했다.
# 시간 초과
import sys
sys.setrecursionlimit(10**6)
def next_(x,strs,t,num):
global cnt
if x==t:
cnt = min(cnt, num)
return
n = len(x)
for i in range(1,6):
if (s:=t[n:n+i]) in strs:
next_(x+s,strs,t,num+1)
return
cnt = int(1e9)
def solution(strs, t):
strs = set(strs)
next_('',strs,t,0)
return -1 if cnt == int(1e9) else cnt
단어 조각도 100개 뿐이고 단어 길이가 20000 이하라길래 될 줄 알았는데,,
# 통과
def solution(strs, t):
strs = set(strs)
INF = int(1e9)
n = len(t)
dp = [0]+[INF]*n
for i in range(n):
for j in range(1,6):
if i+j<=n and t[i:i+j] in strs:
dp[i+j] = min(dp[i+j], dp[i]+1)
return -1 if dp[-1] == INF else dp[-1]