Find Final Destination
Given a list of directed edges representing one-way connections between nodes in a graph, and a starting node start. Each edge is given as a two-element array [u, v] where u is the source node and v is the target node.
Your task is to find the destination node (a node without outgoing edges) by traveling from the starting node along these directed edges until you reach the destination.
Note that the graph might have multiple disconnected components, but it is guaranteed that for the given input, there is a unique destination reachable from start and no cycles exist in the graph.
Example 1
Input
edges = [["B","C"], ["D","B"], ["C","A"], ["E","F"]], start = "D"Output
"A"Explanation
Beginning at node 'D', we look for an edge starting with 'D'. We find ['D', 'B'], so we move to 'B'. From 'B', we follow ['B', 'C'] to 'C'. From 'C', we follow ['C', 'A'] to 'A'. Since there are no edges starting with 'A', 'A' is the final destination.
Example 2
Input
edges = [["A","B"], ["B","C"], ["C","D"], ["D","E"], ["E","F"], ["F","G"]], start = "A"Output
"G"
Example 3
Input
edges = [["A","D"], ["B","D"], ["C","D"], ["D","E"], ["F","G"], ["G","E"]], start = "F"Output
"E"
Constraints
- All nodes are represented by unique strings.
- The graph is acyclic.
- There is exactly one unique destination reachable from the given starting node.
1 <= edges.length <= 10⁴
Find Final Destination
Overview
The problem asks us to traverse a directed graph starting from a specific node start until we reach a "sink" node—a node that has no outgoing edges. We are guaranteed that the graph is a Directed Acyclic Graph (DAG) and that a unique destination is reachable from our starting point.
The core intuition is to treat this as a path-following problem. Since every node in our path (except the destination) has exactly one transition we care about to reach the goal, we simply need an efficient way to look up "Where do I go next from here?"
Brute Force
A brute-force approach involves searching through the entire list of edges every time we want to move to the next node. We start at current = start, then iterate through the edges list to find an edge where the source matches current. If we find it, we update current to the target of that edge and repeat the process. If we scan the entire list and find no such edge, we have reached the destination.
def find_destination(edges: list[list[str]], start: str) -> str:
current = start
while True:
found_next = False
for u, v in edges:
if u == current:
current = v
found_next = True
break
if not found_next:
return current
Time complexity: O(N * L) — Where N is the number of nodes in the path and L is the length of the edges list; we potentially scan all edges for every step taken.
Space complexity: O(1) — We only store the current node string and a few loop variables.
Optimal / Best Approach
The bottleneck in the brute-force approach is the repeated O(L) scan of the edges list. We can optimize this by pre-processing the edges into a Hash Map (dictionary in Python).
Since we are guaranteed a unique path and no cycles, each node we encounter during the traversal will have at most one outgoing edge that leads toward the destination. By mapping source -> target, we can achieve O(1) lookups for the next node.
- Create a dictionary
graphwheregraph[u] = vfor every edge[u, v]. - Set
current = start. - While
currentexists as a key in ourgraphdictionary, updatecurrenttograph[current]. - Return
current.
def find_destination(edges: list[list[str]], start: str) -> str:
# Pre-process edges into a adjacency map for O(1) lookup
# Note: Because the destination is unique and reachable,
# we only need to store one target per source.
mapping = {u: v for u, v in edges}
current = start
# Traverse until we reach a node that isn't a source in our mapping
while current in mapping:
current = mapping[current]
return current
Time complexity: O(E) — Where E is the number of edges. We iterate through the edges once to build the map, and then traverse the path (which is at most E nodes). Space complexity: O(E) — We store the edges in a dictionary to allow for fast lookups.
Why this works
- Acyclic Guarantee: Because the graph is acyclic, we are guaranteed never to fall into an infinite loop. The
whileloop must eventually terminate. - Unique Destination: The problem guarantees one reachable sink from the start. Even if the graph has multiple components or other sinks, the path from
startis deterministic because we only care about the outgoing edge from our current location. - Dictionary Efficiency: In Python, dictionary lookups are average-case O(1), making this approach significantly faster than re-scanning the list for large inputs.
Fast
Comments on the solution
No comments on the solution yet. Start a thread about the editorial or your own approach.
No comments yet for Find Final Destination. Be the first to start the thread.
No submissions recorded for this problem yet. Use Submit in the editor — each judge run is stored here.
Output
Input
Expected
Your output
Run to see your output.