💬 문제
https://school.programmers.co.kr/learn/courses/30/lessons/43163
💬 Idea
[첫번째 아이디어]
- words를 돌면서
한 번에 한 개의 알파벳만 바꿀 수 있습니다. 라는 조건에 부합하는 words 트리를 만든다. - ex: [”hit”: [”hot”], “hot”: [”dot”, “lot”], “dot”: [”dog”], “lot”: [”log”], “dog”: [”log”, “cog”], “log”: “[”dog”, “cog”]]
- 이후 시작 단어인 begin부터 dfs 작업을 수행하며 방문한 노드가 적은 경우라면 minChangeCnt를 갱신해주었다.
- 재귀함수 종료 조건:
word == target
💬 풀이1
import Foundation
varminChangeCnt=0func solution(_ begin:String, _ target:String, _ words:[String])->Int{if !words.contains(target){return0}letwords=[begin]+ words
varchangableDict:[String:[String]]=[:]foriin words {leti=String(i)ifchangableDict[i]==nil{changableDict[i]=[]}forjin words {if j == i {continue}ifisChangableWord(i, j){changableDict[i]?.append(j)}}}dfsToFindTargetWord(begin, target,[], changableDict)return minChangeCnt
}func isChangableWord(_ word1:String, _ word2:String)->Bool{letword1=Array(word1)letword2=Array(word2)vardiff=0foriin0..<word1.count {ifword1[i]!=word2[i]{
diff +=1}}return diff ==1?true:false}func dfsToFindTargetWord(_ word:String, _ target:String, _ visited:[String], _ dict:[String:[String]]){varvisited= visited
if word == target {
minChangeCnt = minChangeCnt ==0? visited.count :min(visited.count, minChangeCnt)return}guardlet _ =dict[word]else{return}ifdict[word]!.isEmpty {return}else{
visited.append(word)foriindict[word]! {if !visited.contains(i){dfsToFindTargetWord(i, target, visited, dict)}}}}💬 Idea
[두번째 아이디어]
- 트리를 만들지 않고 방문처리를 통해서만 dfs를 수행해준다.
- 재귀함수 종료 조건:
word == target - words를 돌면서
- 해당 노드를 방문하지 않았고, 해당 노드가 시작 word와 한 개의 알파벳만이 다른 경우라면
- 방문처리를 해준 후
- word를 해당 노드로 변경하고 depth + 1을 하여 dfs를 수행한다.
- dfs 수행 이후에 다른 경로로는 해당 노드를 다시 방문할 수 있도록 하기 위해 해당 노드의 visited 상태를 false로 변경해준다.
💬 풀이2
import Foundation
varminChangeCnt=0func solution(_ begin:String, _ target:String, _ words:[String])->Int{if !words.contains(target){return0}varvisited=Array(repeating:false, count: words.count)dfsToFindTargetWord(words, begin, target,0,&visited)return minChangeCnt
}func isChangableWord(_ word1:String, _ word2:String)->Bool{letword1=Array(word1)letword2=Array(word2)vardiff=0foriin0..<word1.count {ifword1[i]!=word2[i]{
diff +=1}}return diff ==1?true:false}func dfsToFindTargetWord(_ words:[String], _ word:String, _ target:String, _ depth:Int, _ visited:inout[Bool]){if word == target {
minChangeCnt = minChangeCnt ==0? depth :min(depth, minChangeCnt)return}for(idx, i)in words.enumerated(){ifvisited[idx]==false && isChangableWord(word, i){visited[idx]=truedfsToFindTargetWord(words, i, target, depth +1,&visited)visited[idx]=false}}}
2번째 풀이가 훨씬 좋은 효율성을 가지는 것을 확인할 수 있다 😊
💬 문제https://school.programmers.co.kr/learn/courses/30/lessons/43163
💬 Idea[첫번째 아이디어]
한 번에 한 개의 알파벳만 바꿀 수 있습니다.라는 조건에 부합하는 words 트리를 만든다.word == target💬 풀이1💬 Idea[두번째 아이디어]
word == target💬 풀이22번째 풀이가 훨씬 좋은 효율성을 가지는 것을 확인할 수 있다 😊