일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- javascript
- Level2
- 백준
- Doitvue.js입문
- OS
- python
- typescript
- react
- CS
- Medium
- 프로그래머스
- 리트코드
- 프로그래밍
- 배열
- 카카오
- dp
- 동적계획법
- sql
- 자바스크립트
- 파이썬
- 웹프로그래밍
- Level1
- Level3
- 고득점Kit
- 리액트
- C++
- web
- VUE
- LeetCode
- 코테연습
- Today
- Total
[프로그래머스] 단어퍼즐 - python 본문
단어 퍼즐
문제 설명
단어 퍼즐은 주어진 단어 조각들을 이용해서 주어진 문장을 완성하는 퍼즐입니다. 이때, 주어진 각 단어 조각들은 각각 무한개씩 있다고 가정합니다. 예를 들어 주어진 단어 조각이 [“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 이하입니다.
- 모든 문자열은 알파벳 소문자로만 이루어져 있습니다.
풀이
조합 또는 백트래킹을 이용해 풀 수 있을 것 같지만 t의 길이가 상당히 길기 때문에 동적 계획법을 생각해볼 수 있다.
작은 문제 정의하기
문제의 목표는 문장을 완성하기 위해 사용해야 하는 단어 조각 개수의 최솟값을 찾는 것이므로 작은 문제도 단어 조각 개수가 되어야 한다.
길이가 1인 문장을 완성하기 위한 단어 조각의 최소 개수는 ?
길이가 2인 문장을 완성하기 위한 단어 조각의 최소 개수는 ?
길이가 3인 문장을 완성하기 위한 단어 조각의 최소 개수는 ?
길이가 4인 문장을 완성하기 위한 단어 조각의 최소 개수는 ?
.
.
.
작은 문제로 큰 문제 풀 수 있는지 확인하기
주어진 조각이 [“ba”, “na”, “n”, “a”]이고 만들어야하는 문장이 banana라고 생각해보자
b를 만들 수 있는 단어 조각은?
없음
dp[1] = INF
방법이 없을 때는 무한으로 표시해준다. (최소값을 찾아야하므로)
ba를 만들 수 있는 단어 조각은?
ba = ba
= b + a
이전 값인 b를 만들 수 있는 방법이 없기 때문에 ba를 쓸 수 밖에 없다
ba가 단어조각 안에 들어있으므로 쓸 수 있다.
즉 ba를 만들 수 있는 최소 단어조각의 수는 1개이다. dp[2] = 1
ban를 만들 수 있는 단어 조각은?
ban = ban
= ba + n
= b + a + n
마찬가지로 이전 값인 b를 만들 수 있는 방법이 없기 때문에 b + a + n은 불가능하다.
이전에 ba를 만들 수 있는 방법이 1이었고 n을 만들기 위한 방법은 1이므로 2개를 사용해 만들 수 있다.
ban은 단어 조각 안에 없으므로 불가능하다
즉 ban을 만들 수 있는 최소 단어조각의 수는 2개이다. dp[3] = 2
bana를 만들 수 있는 단어 조각은?
bana = bana
= ban + a
= ba + n + a
= ba + na
= b + a + n
bana => 없음
ban + a => a를 만들 수 있는 방법은 1개이다. ban을 만들 수 있는 방법은 없으므로 불가능 하다
ba + n + a => a를 만드는 방법 1 + 이전에 ba + n을 만든 방법 2
ba + na => na를 만드는 최소 개수 1 + ba를 만드는 최소 개수 1
즉 ban을 만들 수 있는 최소 단어조각의 수는 2개이다. dp[4] = 2
문자열을 0부터 기준점으로 잡고 기준 왼쪽으로부터 한 단어씩 늘려가며 만들 수 있는 방법이 있는지 확인한다고 생각하면 된다.
이전에 만든 방법이 있을 경우 거기에 더해서 새로 만드는 게 최소인지 새로 하나를 만드는 게 최소인지 확인한다.
def solution(strs, t):
answer = 0
strs = set(strs)
n = len(t)
dp = [0] * (n + 1)
for i in range(1, n + 1):
dp[i] = float('inf')
for j in range(1, 6):
if i - j < 0:
s = 0
else:
s = i - j
if t[s:i] in strs:
dp[i] = min(dp[i], dp[i- j] + 1)
if dp[-1] == float('inf'):
return -1
return dp[-1]
KIJUL,,
'코테 문제 풀이' 카테고리의 다른 글
[이코테 실전문제] 개미전사 - python (0) | 2022.03.25 |
---|---|
[이코테 실전 문제] 1로 만들기 - python (0) | 2022.03.25 |
[프로그래머스] 자동완성 - python (0) | 2022.03.24 |
[프로그래머스] 가장 긴 팰린드롬 - python (0) | 2022.03.24 |
[프로그래머스] 등굣길 - python (0) | 2022.03.24 |