프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
📄 문제
두 개의 단어 begin, target과 단어의 집합 words가 있습니다. 아래와 같은 규칙을 이용하여 begin에서 target으로 변환하는 가장 짧은 변환 과정을 찾으려고 합니다.
- 1. 한 번에 한 개의 알파벳만 바꿀 수 있습니다.
- 2. words에 있는 단어로만 변환할 수 있습니다.
예를 들어 begin이 "hit", target가 "cog", words가 ["hot","dot","dog","lot","log","cog"]라면 "hit" -> "hot" -> "dot" -> "dog" -> "cog"와 같이 4단계를 거쳐 변환할 수 있습니다.
두 개의 단어 begin, target과 단어의 집합 words가 매개변수로 주어질 때, 최소 몇 단계의 과정을 거쳐 begin을 target으로 변환할 수 있는지 return 하도록 solution 함수를 작성해주세요.
❗️ 제한사항
- 각 단어는 알파벳 소문자로만 이루어져 있습니다.
- 각 단어의 길이는 3 이상 10 이하이며 모든 단어의 길이는 같습니다.
- words에는 3개 이상 50개 이하의 단어가 있으며 중복되는 단어는 없습니다.
- begin과 target은 같지 않습니다.
- 변환할 수 없는 경우에는 0를 return 합니다.
📝 풀이
문제를 이해하는데 시간이 걸렸습니다.
- words 배열에 target이 없으면 변환 자체가 불가능합니다.
- words 배열에서 하나씩 선택하여 target을 만들면 됩니다.
- begin을 변경하되, 한 글자만 변경이 가능하며 이는 words 배열의 원소이어야 합니다.
- words 배열에서 순서는 의미가 없습니다.
다음과 같은 방법으로 접근하여 해결하였습니다.
- dfs를 이용하여 begin부터 시작하여 words 배열을 모두 검사하여 한글자씩 변경이 가능한 단어인경우, 해당 단어로 변경하여 target까지 변환을 시도하여 answer의 최소값을 구합니다.
- bool sel[51]을 통해 중복선택을 피하여 최적의 값을 구할 수 있도록 합니다.
#include <string>
#include <vector>
#include <climits>
#include <set>
#include <algorithm>
using namespace std;
bool sel[51]; // words 속 해당 단어를 사용하였는가?
int answer = INT_MAX; // 정답 최소값을 갱신
bool check(string begin, string word)
{
int cnt = 0;
for(int i = 0; i < begin.size(); ++i)
if(begin[i] != word[i])
++cnt;
return cnt == 1;
}
void dfs(string word, string target, vector<string> words, int cnt)
{
// 현재 생성된 단어가 target과 동일하다면 더 이상 진행하지 않고 최소값 갱신
if(word == target)
{
answer = min(answer, cnt);
return;
}
// 모든 words를 검사하여 변환 가능하다면 뻗어나가기
for(int i = 0; i < words.size(); ++i)
{
// 선택하지 않은 단어이면서, 글자가 한개만 차이가 난다면?
if(!sel[i] && check(word, words[i]))
{
// 선택 완료 후 해당 문자열로 뻗어나가기
sel[i] = true;
dfs(words[i], target, words, cnt + 1);
// 함수가 종료되면 다시 복구
sel[i] = false;
}
}
}
int solution(string begin, string target, vector<string> words) {
// words에 target이 없다면 변환 자체가 불가능!
if(find(words.begin(), words.end(), target) == words.end())
return 0;
// dfs 탐색
dfs(begin, target, words, 0);
// 탐색 후 answer가 한번도 갱신되지 않았다면 0 리턴
return answer == INT_MAX ? 0 : answer;
}
'algorithms (C++)' 카테고리의 다른 글
[C++][프로그래머스] 최고의 집합 (1) | 2024.02.27 |
---|---|
[C++][프로그래머스] 네트워크(Union-Find) (1) | 2024.02.26 |
[C++][프로그래머스] 정수 삼각형 (0) | 2024.02.26 |
[C++][백준 2579번] 계단오르기 (0) | 2023.12.11 |
[C++][백준 9095번] 1, 2, 3 더하기 (0) | 2023.12.11 |