|
| 1 | +# golang_reconstruct_itinerary |
| 2 | + |
| 3 | +You are given a list of airline `tickets` where `tickets[i] = [fromi, toi]` represent the departure and the arrival airports of one flight. Reconstruct the itinerary in order and return it. |
| 4 | + |
| 5 | +All of the tickets belong to a man who departs from `"JFK"`, thus, the itinerary must begin with `"JFK"`. If there are multiple valid itineraries, you should return the itinerary that has the smallest lexical order when read as a single string. |
| 6 | + |
| 7 | +- For example, the itinerary `["JFK", "LGA"]` has a smaller lexical order than `["JFK", "LGB"]`. |
| 8 | + |
| 9 | +You may assume all tickets form at least one valid itinerary. You must use all the tickets once and only once. |
| 10 | + |
| 11 | +## Examples |
| 12 | + |
| 13 | +**Example 1:** |
| 14 | + |
| 15 | + |
| 16 | + |
| 17 | +``` |
| 18 | +Input: tickets = [["MUC","LHR"],["JFK","MUC"],["SFO","SJC"],["LHR","SFO"]] |
| 19 | +Output: ["JFK","MUC","LHR","SFO","SJC"] |
| 20 | +
|
| 21 | +``` |
| 22 | + |
| 23 | +**Example 2:** |
| 24 | + |
| 25 | + |
| 26 | + |
| 27 | +``` |
| 28 | +Input: tickets = [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]] |
| 29 | +Output: ["JFK","ATL","JFK","SFO","ATL","SFO"] |
| 30 | +Explanation: Another possible reconstruction is ["JFK","SFO","ATL","JFK","ATL","SFO"] but it is larger in lexical order. |
| 31 | +
|
| 32 | +``` |
| 33 | + |
| 34 | +**Constraints:** |
| 35 | + |
| 36 | +- `1 <= tickets.length <= 300` |
| 37 | +- `tickets[i].length == 2` |
| 38 | +- `fromi.length == 3` |
| 39 | +- `toi.length == 3` |
| 40 | +- $`from_i`$ and $`to_i`$ consist of uppercase English letters. |
| 41 | +- $`from_i$ != $to_i$` |
| 42 | + |
| 43 | +## 解析 |
| 44 | + |
| 45 | +題目給定一個整數矩陣 tickets , 其中每個 entry ticket[i] = [$location_1$, $location_2$] 代表 |
| 46 | + |
| 47 | +$location_1$ 到 $location_2$ 有一個 path 可以經過 |
| 48 | + |
| 49 | +要求寫一個演算法 |
| 50 | + |
| 51 | +找出從 “JFK” 出發按照給定的 tickets 以及地點字母排序 走訪完所有 path 的一個可行順序 |
| 52 | + |
| 53 | +首先是這次的 path 是有順序的 |
| 54 | + |
| 55 | +所以關鍵是要透過 tickets 做出 adjacency list |
| 56 | + |
| 57 | +然後這些 adjacency list 需要按照字母順序排列 |
| 58 | + |
| 59 | +一個可行的作法是先把 tickets 先做字母排序 |
| 60 | + |
| 61 | +然後在照順序做 adjacency list |
| 62 | + |
| 63 | +然後依序從 “JFK” 做 DFS |
| 64 | + |
| 65 | +然後每次經過一個地點 就把原本的 adjacency list 的 path消去一個 |
| 66 | + |
| 67 | + |
| 68 | + |
| 69 | +## 程式碼 |
| 70 | +```go |
| 71 | +package sol |
| 72 | + |
| 73 | +import ( |
| 74 | +"sort" |
| 75 | +"strings" |
| 76 | +) |
| 77 | + |
| 78 | +type Locations []string |
| 79 | + |
| 80 | +func findItinerary(tickets [][]string) []string { |
| 81 | +sortedTickets := SortInput(tickets) |
| 82 | +adjacencyMap := make(map[string]Locations) |
| 83 | +for _, ticket := range sortedTickets { |
| 84 | +adjacencyMap[ticket[0]] = append(adjacencyMap[ticket[0]], ticket[1]) |
| 85 | +} |
| 86 | +result := []string{"JFK"} |
| 87 | +var dfs func(location string) bool |
| 88 | +dfs = func(location string) bool { |
| 89 | +if len(result) == len(tickets)+1 { |
| 90 | +return true |
| 91 | +} |
| 92 | +adjacencyList, ok := adjacencyMap[location] |
| 93 | +if !ok { |
| 94 | +return false |
| 95 | +} |
| 96 | +temp := make([]string, len(adjacencyList)) |
| 97 | +copy(temp, adjacencyList) |
| 98 | +for _, loc := range adjacencyList { |
| 99 | +result = append(result, loc) |
| 100 | +adjacencyList = adjacencyList[1:] |
| 101 | +adjacencyMap[location] = adjacencyList |
| 102 | +if dfs(loc) { |
| 103 | +return true |
| 104 | +} |
| 105 | +result = result[:len(result)-1] |
| 106 | +adjacencyList = append(adjacencyList, loc) |
| 107 | +adjacencyMap[location] = adjacencyList |
| 108 | +} |
| 109 | +return false |
| 110 | +} |
| 111 | +dfs("JFK") |
| 112 | +return result |
| 113 | +} |
| 114 | + |
| 115 | +func SortInput(tickets [][]string) [][]string { |
| 116 | +temp := make([]string, len(tickets)) |
| 117 | +result := make([][]string, len(tickets)) |
| 118 | +for idx, ticket := range tickets { |
| 119 | +temp[idx] = ticket[0] + "," + ticket[1] |
| 120 | +} |
| 121 | +sort.Strings(temp) |
| 122 | +for idx, item := range temp { |
| 123 | +result[idx] = strings.Split(item, ",") |
| 124 | +} |
| 125 | +return result |
| 126 | +} |
| 127 | + |
| 128 | +``` |
| 129 | +## 困難點 |
| 130 | + |
| 131 | +1. 理解如何達成有序的找到 Location |
| 132 | +2. 對 DFS 需要去理解 |
| 133 | + |
| 134 | +## Solve Point |
| 135 | + |
| 136 | +- [x] 需要知道如何找到鄰近的 Location |
| 137 | +- [x] 建立 adjacency list 時需要透過 sort 去處理 |
0 commit comments