코딩 테스트/프로그래머스
[Python] 프로그래머스 lv.3 단어 변환
위시리
2024. 10. 29. 19:07
https://school.programmers.co.kr/learn/courses/30/lessons/43163
문제 분석
- 단어 begin, target
- 단어의 집합 words
- 다음 규칙을 이용하여 begin에서 target으로 변환하는 가장 짧은 변환 과정을 찾으려 한다.
- 1. 한 번에 한 개의 알파벳만 바꿀 수 있다.
- 2. words에 있는 단어로만 변환할 수 있다.
- 최소 몇 단계의 과정을 거쳐 begin을 target으로 변환할 수 있는지 return
코드 설계
- begin을 덱에 넣고 시작
- 현재 단어를 덱에 넣고 덱에 넣을 때 해당 단어의 인덱스에 대한 v[index] = True
- words를 순회하면서 만약 한 단어만 다르고
- 이전에 바꿨던 단어가 아니면 (visited)
- 그 단어로 바꾸기
- 단어를 바꿀 때마다 변환 횟수 계산
- 만약 begin == target이면 return 횟수
- 변환할 수 없는 경우 0 return
- 한 단어만 다른지 어떻게 체크할 것인가 ?
정답 코드
실패..
from collections import deque
def solution(begin, target, words):
answer = 0
d = deque()
v = [False] * len(words)
d.append(begin, 0)
def check_diff(word1, word2) :
list(word1)
list(word2)
for w in word1 :
if
while d :
word, cnt = d.popleft()
if word == target :
return cnt
for s in words :
if v : # 바뀌었던 단어
continue
if :# 두 글자 이상 다르면
continue
return answer
다른 사람 풀이 1 - bfs
from collections import deque
def solution(begin, target, words):
answer = 0
q = deque()
q.append([begin, 0])
V = [0 for _ in range(len(words))]
while q:
word, cnt = q.popleft()
if word == target:
return cnt
for i in range(len(words)):
temp_cnt = 0
if not V[i]: # 바뀌지 않은 단어라면
for j in range(len(word)):
if word[j] != words[i][j]: # 몇개의 단어와 다른지 체크
temp_cnt += 1
if temp_cnt == 1: # 한 단어가 다르다면
q.append([words[i], cnt + 1])
V[i] = 1
return answer
- 처음 큐에 시작 단어와 깊이를 넣는다.
- popleft 하면서 단어가 1글자만 다를 때 큐에 넣어 넓이 우선 탐색을 한다.
다른 사람 풀이 2 - bfs
from collections import deque
def solution(begin, target, words):
if target not in words :
return 0
return bfs(begin, target, words)
#최소 단계를 찾아야 하므로 bfs
def bfs(begin, target, words):
queue = deque()
queue.append([begin, 0]) #시작 단어와 단계 0으로 초기화
while queue:
now, step = queue.popleft()
if now == target:
return step
#단어를 모두 체크하면서, 해당 단어가 변경될 수 있는지 체크
for word in words:
count = 0
for i in range(len(now)): #단어의 길이만큼 반복하여
if now[i] != word[i]: #단어에 알파벳 한개씩 체크하기
count += 1
if count == 1:
queue.append([word, step+1])
- 단어가 변환되기 위해선 1개의 알파벳만 바뀔 수 있고, word안에 있는 단어로 변환이 가능하다.
- 최소 단계를 찾아야하므로 BFS를 사용하면 될 것 같다.
- words 에 target이 없으면 바로 0을 반환한다.
- 시작 단어부터 시작해서 Queue에 담는다. 단계는 0으로 초기화한다.
- 해당 단어가 words 에 존재하는 단어들 중 1개의 알파벳값만 다르다면 큐에 넣어주고 반복한다.
- 만약 target값을 찾으면 지금까지 세어준 단계를 반환한다.
2회차 - 25.05.01
- DFS : 최단거리탐색
- DFS는 한 경로를 끝까지 깊게 들어갔다가, 더 이상 갈 수 없으면 뒤로 돌아가는 방식
- 한 글자만 다른 문자와 비교하다가 target과 같으면 while 문을 빠져나온다.
- 만약 한 글자만 다르고, 아직 확인하지 않은 단어라면 횟수를 갱신하고 deque에 추가한다.
from collections import deque
# 한 글자만 다른지 비교하는 메서드
def isDiffOne(word1, word2) :
cnt = 0
for idx in range(len(word1)) :
if word1[idx] != word2[idx] :
cnt += 1
if cnt > 1 :
return False
return True
def solution(begin, target, words):
answer = 0
d = deque()
v = [False for _ in range(len(words))]
d. append((0, begin)) # 변환 수(Count), 현재 단어
while d :
cnt, now = d.popleft()
if now == target :
answer = cnt
break
# words list를 확인하면서
for i in range(len(words)) :
new_word = words[i]
new_cnt = cnt
# words 안의 단어와 현재 단어가 한 글자만 다르고,
# 아직 방문하지 않았다면
# 덱에 추가
if isDiffOne(now, new_word) and not v[i] :
new_cnt += 1
d.append((new_cnt, new_word))
v[i] = True
return answer