332. Reconstruct Itinerary
https://leetcode.com/problems/reconstruct-itinerary/
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Solution { | |
public List<String> findItinerary(List<List<String>> tickets) { | |
List<String> ans = new ArrayList<String>(); | |
// Priority Queue to order lexicographically, and remove once used | |
Map<String, PriorityQueue<String>> graph = new HashMap<String, PriorityQueue<String>>(); | |
buildGraph(tickets, graph); | |
// Post Order DFS => topological sort | |
dfs(graph, "JFK", ans); | |
return ans; | |
} | |
private void dfs(Map<String, PriorityQueue<String>> graph, String u, List<String> ans) { | |
// Greedy DFS .. no backtracking | |
// Note - Repeat expression graph.get(u), | |
// Do not use variable for graph.get(u), because PQ.poll() empties the graph | |
while (graph.get(u) != null && !graph.get(u).isEmpty()) { | |
dfs(graph, graph.get(u).poll(), ans); | |
} | |
// Post Order DFS | |
// Add first element to avoid Collections reverse in the end | |
ans.add(0, u); | |
} | |
private void buildGraph(List<List<String>> tickets, Map<String, PriorityQueue<String>> graph) { | |
for (List<String> edge: tickets) { | |
String u = edge.get(0); | |
String v = edge.get(1); | |
graph.putIfAbsent(u, new PriorityQueue<String>()); | |
graph.get(u).offer(v); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Solution { | |
public List<String> findItinerary(List<List<String>> tickets) { | |
List<String> ans = new ArrayList<String>(); | |
if (tickets == null || tickets.size() == 0) { | |
return ans; | |
} | |
Map<String, PriorityQueue<String>> graph = new HashMap<String, PriorityQueue<String>>(); | |
for (List<String> trip: tickets) { | |
String from = trip.get(0); | |
String to = trip.get(1); | |
PriorityQueue<String> destination = graph.getOrDefault(from, new PriorityQueue<String>()); | |
destination.add(to); | |
graph.put(from, destination); | |
} | |
Stack<String> stack = new Stack<String>(); | |
// Starting node | |
stack.push("JFK"); | |
// Nodes still to be visited | |
while (!stack.isEmpty()) { | |
// Destination nodes exist | |
while (graph.get(stack.peek()) != null && !graph.get(stack.peek()).isEmpty()) { | |
// Priority Queue - try min lexicographical first, and discard after use | |
stack.push(graph.get(stack.peek()).poll()); | |
} | |
// Add to first position to avoid Collections reverse in the end | |
ans.add(0, stack.pop()); | |
} | |
return ans; | |
} | |
} |