본문 바로가기
개발/프로그래머스

깊이/너비 우선 탐색(DFS/BFS) > 단어 변환 (Level3)

by 민돌이2 2021. 11. 6.

문제 링크

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

 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

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 합니다.

 

입출력 예

 

입출력 예 설명

예제 #1
문제에 나온 예와 같습니다.

예제 #2
target인 "cog"는 words 안에 없기 때문에 변환할 수 없습니다.

 

소스코드

#include <string>
#include <vector>
#include <limits.h>

using namespace std;

void DFS(const string begin, const string target, const vector<string> words, int index, int count, vector<int>& datas, vector<bool>& visited)
{
	//begin이 찾는 target이라면
	if (begin == target)
	{
		datas.push_back(count);
		
		return;
	}

	for (int i = 0; i < words.size(); i++)
	{
		//이미 탐색한 것이라면
		if (visited[i] == true)
			continue;

		int num = 0; //다른 글자수 counter
		//다른 글자수 세기
		for (int j = 0; j < words[i].size(); j++)
		{
			if (begin[j] != words[i][j])
				num++;
		}
		
		if (num == 1)
		{
			visited[i] = true;
			DFS(words[i], target, words, i, count + 1, datas, visited);
			visited[i] = false;
		}
	}
}

int solution(string begin, string target, vector<string> words) 
{
	int answer = 0;
	vector<int> datas;

	bool  b = false;
	//찾는 target이 words에 없는 경우 예외처리
	for (string temp : words)
	{
		if (temp == target)
			b = true;
	}
	
	if (b == false)
		return 0;

	for (int i = 0; i < words.size(); i++)
	{
		vector<bool> visited(words.size(), false);
		DFS(begin, target, words, i, 0, datas, visited);
	}

	int min = INT_MAX;
	//최소값 찾기
	for (int i = 0; i < datas.size(); i++)
	{
		if (min > datas[i])
			min = datas[i];
	}

	answer = min;

	return answer;
}

 

생각해 볼 다른사람 코드

#include <string>
#include <vector>
#include <queue>

using namespace std;

int visited[50];

int possible(string a, string b)
{
    int i;
    int cnt = 0;

    for(i=0;i<a.length();i++)
    {
        if(a[i] != b[i]) cnt++;
    }

    if(cnt==1) return 1;
    else return 0;
}

int solution(string begin, string target, vector<string> words) {
    int answer = 0;
    queue<pair<string,int>> Q;
    int i;
    string temp;
    int num;

    Q.push(make_pair(begin,0));
    while(!Q.empty())
    {
        temp = Q.front().first;
        num = Q.front().second;
        Q.pop();

        if(temp.compare(target) == 0)
        {
            answer = num;
            break;
        }

        for(i=0;i<words.size();i++)
        {
            if(visited[i]) continue;
            if(possible(temp, words[i]))
            {
                visited[i] = 1;
                Q.push(make_pair(words[i],num+1));
            }
        }
    }

    return answer;
}

 

생각해 볼 것

벡터는 검색은 빠르지만 삽입, 삭제가 느리다는 단점이 있다. sort해서 최소값 찾는 것 보단 반복문으로 최소값 찾는게 더 빠르다는 테스트결과가 나왔다.

728x90

댓글