Problem Description
Given a connected undirected graph with n cities and m roads, each city has a 3-letter name. You are provided a targetPath (an array of 3-letter city names). The task is to find a valid path in this graph with the same length as targetPath that minimizes the edit distance with respect to targetPath. The edit distance here counts the number of positions where the city name in your path differs from the targetPath. There is also a follow-up if each city can be visited at most once.
Key Insights
- This problem is essentially a path-finding problem on a graph combined with sequence alignment (minimizing edit distance).
- Dynamic Programming is an ideal approach by treating each position in the targetPath as a state and considering all possible cities for that step.
- The DP state can be defined as dp[i][j]: minimum edit distance to match targetPath[0...i] when current city is j.
- Use transitions over all neighbors of a given city when moving from the (i-1)th to the ith step.
- To reconstruct the final path, keep a parent pointer that tracks which predecessor city provided the optimal cost.
- The graph structure is stored using an adjacency list for efficient neighbor lookup.
- The follow-up requiring cities to be visited only once changes the state to include visited nodes (or use DFS/BFS with a visited set), turning the problem into a variant of the Hamiltonian path problem.
Space and Time Complexity
Time Complexity: O(L * n * d), where L is the length of targetPath, n is the number of cities, and d is the average degree (number of neighbors). In the worst-case d can be O(n), so it could be O(L * n^2).
Space Complexity: O(L * n) to store the DP table and rollout table for reconstruction.
Solution
We use dynamic programming to solve the problem. The state dp[i][j] captures the minimum edit distance for aligning the first (i+1) characters of targetPath ending at city j. For the base state (i=0), for each city j, the cost is 0 if the city’s name matches targetPath[0], otherwise 1. For each subsequent position i, we try to reach city j from any neighbor k of j from the previous step and take the minimal cost. A parent pointer is maintained to help reconstruct the path once dp is fully computed. Finally, by selecting the city with minimum dp[targetPath.length-1][j], we can backtrack the optimal path.