넘치게 채우기

[프로그래머스] 단어 변환 본문

PS/Programmers

[프로그래머스] 단어 변환

riveroverflow 2024. 3. 28. 17:29
728x90
반응형

https://school.programmers.co.kr/learn/courses/30/lessons/43163

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

프로그래머스 - 단어 변환

문제 유형 : DFS/BFS

문제 난이도 : Level 3

 

문제

두 개의 단어 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 배열의 0번째 인덱스에 시작 단어를 삽입합니다.

시작 단어의 인덱스는 0입니다.

 

target은 words 안에 있어야 하므로, 순차적으로 words의 요소들을 확인하면서 target의 인덱스를 알아냅니다.

만약 target을 발견하지 못하면, 불가능하므로 0을 반환합니다.

 

2차원 배열로 그래프를 표현하고, words배열을 n번 순회하면서, 유효한 단어들 간의 인접 리스트를 만듭니다.

 

인덱스 0부터 bfs를 통해서 단어들을 변환하고, 목표 인덱스에 도달하면 반환합니다.

 

코드

C++

#include <bits/stdc++.h>

using namespace std;
int n;

bool available(string &a, string &b) {
    int err = 0;
    
    for(int i = 0; i < n; i++) {
        if(a[i] != b[i]) err++;
    }
    
    return err == 1;
    
}

int solution(string begin, string target, vector<string> words) {
    n = begin.size();
    const int m = words.size() + 1;
    
    words.insert(words.begin(), begin);
    
    int from = 0;
    int to = 0;
    
    for(int i = 1; i < m; i++) {
        if(target == words[i]) {
            to = i;
            break;
        }
    }
    
    if(!to) return 0;
    
    vector<vector<int>> graph(m, vector<int>());
    for(int i = 0; i < m-1; i++) {
        for(int j = i+1; j < m; j++) {
            if(available(words[i], words[j])) {
                graph[i].push_back(j);
                graph[j].push_back(i);
            }
        }
    }
    
    vector<bool> visited(m, false);
    queue<pair<int, int>> q; // idx, times
    q.push({0, 0});
    visited[0] = true;
    
    while(!q.empty()) {
        auto curr = q.front();
        q.pop();
        if(curr.first == to) return curr.second;
        
        for(const auto &next : graph[curr.first]) {
            if(!visited[next]) {
                visited[next] = true;
                q.push({next, curr.second+1});
            }
        }
    }
    
    return 0;
}
728x90
반응형