문제 설명:
주어진 항공권을 모두 이용하여 여행경로를 짜려고 합니다. 항상 "ICN" 공항에서 출발합니다.
항공권 정보가 담긴 2차원 배열 tickets가 매개변수로 주어질 때, 방문하는 공항 경로를 배열에 담아 return 하도록 solution 함수를 작성해주세요.
문제 풀이:
이 문제도 역시 경로를 탐색을 하는 문제이므로 깊이/너비 우선 탐색을 하는 문제이다. 또한 제한 사항 중에 주어진 항공권은 모두 사용해야 하고, 모든 도시를 방문을 할 수 없는 경우는 주어지지 않습니다. 라고 하였으니 항상 답이 있다고 가정을 하고 풀면 된다.
먼저 표의 현황을 깔끔하게 정리를 하기 위해서 tickets을 반복문으로 돌아가면서 이를 딕셔너리 타입(해시) 방식으로 정렬을 하였다. 매번 추가하면서 정렬을 한 이유는 만약 가능한 경로가 여러개라면 알파벳 순서가 앞서는 경로를 우선으로 해야하기 때문이다.
티켓을 정리한 뒤에 재귀적으로 탐색을 하는 함수인 travel에 ticket의 정보를 담고 있는 answer_set, 실제 경로인 answer, 출발하는 공항의 이름인 start, 그리고 모든 항공권을 사용했는지 탐색해야하므로 티켓의 갯수인 K 와 몇 개를 사용했는지 알려주는 count를 사용하였다.
처음에는 무조건 ICN에서 시작을 한다는 조건이 있었으므로 초기값은 ICN으로 시작한다. travel 함수에는 세 가지 조건이 존재한다.
1. count == K 일 때
종료 조건으로 모든 티켓을 다 사용한 경우에 해당한다. 따라서 True를 반환한다.
2. 잘못 경로를 탐색해서 들어갔을 경우
해시 구조를 통해서 티켓을 정리했다보니 B 공항으로 도착을 하긴 했지만 B 공항에서 출발을 하는 티켓이 없을 수도 있다. 따라서 이 경우에 이 값을 찾으려 하면 error가 발생하기 때문에 예외처리구문을 사용해서 이 case를 탐지했다. 이 경우가 발생한거면 잘못된 경로를 온 것이기 때문에 answer의 마지막 값을 빼주고 잘못된 경로이므로 False를 반환한다.
3. 위 두 경우가 아닐 때
해시로 정리한 티켓을 기준으로 하나씩 경로를 늘려가면서 탐색해본다.
위 과정을 거치다보면 answer를 구할 수 있게 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | import copy def travel(answer_set,answer,start,K,count): answer.append(start) if count==K: return True try: answer_set[start] except: answer.pop() return False for i in range(len(answer_set[start])): end=answer_set[start][i] count+=1 temp_set=copy.deepcopy(answer_set) temp_set[start]=temp_set[start][:i]+temp_set[start][i+1:] boolean=travel(temp_set,answer,end,K,count) if boolean: return True else: count-=1 answer.pop() return False def solution(tickets): answer_set={} for ticket in tickets: if ticket[0] in answer_set: answer_set[ticket[0]].append(ticket[1]) answer_set[ticket[0]].sort() else: answer_set[ticket[0]]=[ticket[1]] answer=[] count=0 start="ICN" travel(answer_set,answer,start,len(tickets),count) return answer | cs |