-
-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy path332. Reconstruct Itinerary.java
More file actions
executable file
·101 lines (89 loc) · 3.92 KB
/
332. Reconstruct Itinerary.java
File metadata and controls
executable file
·101 lines (89 loc) · 3.92 KB
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
M
tags: Graph, DFS, Backtracking
time: O(n^n)
space: O(m)
#### DFS with backtcking
- Construct graph: `map<String, List<Destination>>`; sort the list of destinations.
- DFS:
- with any curr city, go over the destination list: `graph.get(curr)`
- add visit city to rst
- remove visited city from the desitnation list
- backtrack
- NOTE:
- 1) the graph allows cycle: revisiting same city. Do NOT assume no cycle
- 2) it asks to us to treat `smaller lexical order city` with priority; however:
- it does NOT mean visiting `smaller lexical order city` is THE correc anser
- it can be a leaf sink node of the graph and does not provide correct trip plan
- time: O(n^n). n = # of cities. worst case, each city has (n-1) edges and need to try all combinations
- space: O(n^2), there can at most be n * (n - 1) edges
```
/*
Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], reconstruct the itinerary in order. All of the tickets belong to a man who departs from JFK. Thus, the itinerary must begin with JFK.
Note:
If there are multiple valid itineraries, you should return the itinerary that has the smallest lexical order when read as a single string. For example, the itinerary ["JFK", "LGA"] has a smaller lexical order than ["JFK", "LGB"].
All airports are represented by three capital letters (IATA code).
You may assume all tickets form at least one valid itinerary.
Example 1:
Input: [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]]
Output: ["JFK", "MUC", "LHR", "SFO", "SJC"]
Example 2:
Input: [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]]
Output: ["JFK","ATL","JFK","SFO","ATL","SFO"]
Explanation: Another possible reconstruction is ["JFK","SFO","ATL","JFK","ATL","SFO"].
But it is larger in lexical order.
*/
/*
- Construct map<String, Queue<String>> based on input, and DFS
- Order the items by name;
- remove edge after use; dfs and backtrack
*/
/*
- Construct graph: `map<String, List<Destination>>`; sort the list of destinations.
- DFS:
- with any curr city, go over the destination list: `graph.get(curr)`
- add visit city to rst
- remove visited city from the desitnation list
- backtrack
- NOTE:
- 1) the graph allows cycle: revisiting same city. Do NOT assume no cycle
- 2) it asks to us to treat `smaller lexical order city` with priority; however:
- it does NOT mean visiting `smaller lexical order city` is THE correc anser
- it can be a leaf sink node of the graph and does not provide correct trip plan
*/
class Solution {
int n = 0;
public List<String> findItinerary(List<List<String>> tickets) {
List<String> rst = new LinkedList<>();
Set<String> citySet = new HashSet<>();
Map<String, List<String>> map = buildMap(tickets);
n = tickets.size();
rst.add("JFK");
dfs(rst, map, "JFK");
return rst;
}
private boolean dfs(List<String> list, Map<String, List<String>> map, String curr) {
if (list.size() == n + 1) return true;
if (!map.containsKey(curr)) return false;
List<String> destinations = map.get(curr);
for (int i = 0; i < destinations.size(); i++) {
String next = destinations.get(i);
destinations.remove(i);
list.add(next);
if (dfs(list, map, next)) return true;
// backtrack
destinations.add(i, next);
list.remove(list.size() - 1);
}
return false;
}
private Map<String, List<String>> buildMap(List<List<String>> tickets) {
Map<String, List<String>> map = new HashMap<>();
for (List<String> ticket : tickets) {
map.putIfAbsent(ticket.get(0), new LinkedList<>());
map.get(ticket.get(0)).add(ticket.get(1));
}
for (String key : map.keySet()) Collections.sort(map.get(key));
return map;
}
}
```