We have n cities and m bi-directional roads where roads[i] = [ai, bi] connects city ai with city bi. Each city has a name consisting of exactly three upper-case English letters given in the string array names.
Starting at any city x, you can reach any city y where y != x (i.e., the cities and the roads are forming an undirected connected graph).
You will be given a string array targetPath. You should find a path in the graph of the same length and with the minimum edit distance to targetPath.
You need to return the order of the nodes in the path with the minimum edit distance. The path should be of the same length of targetPath and should be valid (i.e., there should be a direct road between ans[i] and ans[i + 1]).
If there are multiple answers return any one of them.
The edit distance is defined as follows:
Edit distance is the number of positions where the path differs from the target path
Lower edit distance means the path is more similar to the target
💡 Note:Path [1,2] gives ["BBB","CCC"] vs target ["AAA","CCC"] with edit distance 1. Path [0,2] is invalid since there's no direct edge 0-2. The optimal valid path [1,2] has edit distance 1.
The key insight is to use dynamic programming to track the minimum edit distance at each position and city. Build a DP table where dp[i][j] represents the minimum edit distance to reach city j at position i, then reconstruct the optimal path. Best approach is DP with backtracking. Time: O(k × n × m), Space: O(k × n)
Common Approaches
✓
Brute Force - Try All Paths
⏱️ Time: O(n^k)
Space: O(k)
Use DFS to generate every possible path of the same length as targetPath, calculate edit distance for each path, and return the one with minimum edit distance.
Dynamic Programming Solution
⏱️ Time: O(k × n × m)
Space: O(k × n)
Build a 2D DP table where dp[i][j] represents the minimum edit distance to reach city j at position i of the target path. Reconstruct the optimal path by backtracking.
Brute Force - Try All Paths — Algorithm Steps
Build adjacency list from roads
Use DFS to generate all paths of target length
Calculate edit distance for each path
Return path with minimum edit distance
Visualization
Tap to expand
Step-by-Step Walkthrough
1
Build Graph
Create adjacency list from roads
2
DFS All Paths
Generate all paths of target length
3
Calculate Distance
Find edit distance for each path
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#define MAX_CITIES 100
#define MAX_NAME_LEN 20
#define MAX_LINE 10000
static int graph[MAX_CITIES][MAX_CITIES];
static int graphSize[MAX_CITIES];
static char cityNames[MAX_CITIES][MAX_NAME_LEN];
static char target[MAX_CITIES][MAX_NAME_LEN];
static int targetLen;
static int minDist = INT_MAX;
static int bestPath[MAX_CITIES];
static int bestPathLen;
void dfs(int currentCity, int* path, int pathLen, int pos, int n) {
if (pos == targetLen) {
// Calculate edit distance
int distance = 0;
for (int i = 0; i < targetLen; i++) {
if (strcmp(cityNames[path[i]], target[i]) != 0) {
distance++;
}
}
if (distance < minDist) {
minDist = distance;
for (int i = 0; i < pathLen; i++) {
bestPath[i] = path[i];
}
bestPathLen = pathLen;
}
return;
}
// Try all neighboring cities for next position
for (int i = 0; i < graphSize[currentCity]; i++) {
int nextCity = graph[currentCity][i];
path[pathLen] = nextCity;
dfs(nextCity, path, pathLen + 1, pos + 1, n);
}
}
void parseRoads(const char* str, int roads[][2], int* roadsSize) {
*roadsSize = 0;
const char* p = str;
// Find outer '['
while (*p && *p != '[') p++;
if (*p == '[') p++;
while (*p && *p != ']') {
// Skip whitespace and commas
while (*p == ' ' || *p == ',' || *p == '\n' || *p == '\r') p++;
if (*p == ']' || *p == '\0') break;
if (*p == '[') {
p++; // Skip '['
// Parse first number
while (*p == ' ') p++;
roads[*roadsSize][0] = (int)strtol(p, (char**)&p, 10);
// Skip comma
while (*p == ' ' || *p == ',') p++;
// Parse second number
roads[*roadsSize][1] = (int)strtol(p, (char**)&p, 10);
(*roadsSize)++;
// Find closing ']'
while (*p && *p != ']') p++;
if (*p == ']') p++;
} else {
p++;
}
}
}
void parseNames(const char* str, char names[][MAX_NAME_LEN], int* namesSize) {
*namesSize = 0;
const char* p = str;
// Find outer '['
while (*p && *p != '[') p++;
if (*p == '[') p++;
while (*p && *p != ']') {
// Skip whitespace and commas
while (*p == ' ' || *p == ',' || *p == '\n' || *p == '\r') p++;
if (*p == ']' || *p == '\0') break;
// Found opening quote
if (*p == '"') {
p++; // Skip opening quote
int i = 0;
// Read characters until closing quote
while (*p && *p != '"' && i < MAX_NAME_LEN - 1) {
names[*namesSize][i++] = *p++;
}
names[*namesSize][i] = '\0';
(*namesSize)++;
// Skip closing quote
if (*p == '"') p++;
} else {
p++;
}
}
}
int* solution(int n, int roads[][2], int roadsSize, char names[][MAX_NAME_LEN], int namesSize,
char targetPath[][MAX_NAME_LEN], int targetPathSize, int* returnSize) {
// Initialize graph
for (int i = 0; i < n; i++) {
graphSize[i] = 0;
}
// Build adjacency list
for (int i = 0; i < roadsSize; i++) {
int a = roads[i][0], b = roads[i][1];
graph[a][graphSize[a]++] = b;
graph[b][graphSize[b]++] = a;
}
minDist = INT_MAX;
targetLen = targetPathSize;
bestPathLen = 0;
// Copy names and target
for (int i = 0; i < namesSize; i++) {
strcpy(cityNames[i], names[i]);
}
for (int i = 0; i < targetPathSize; i++) {
strcpy(target[i], targetPath[i]);
}
// Start DFS from each city
for (int start = 0; start < n; start++) {
int path[MAX_CITIES];
path[0] = start;
dfs(start, path, 1, 1, n);
}
// Return best path
int* result = (int*)malloc(bestPathLen * sizeof(int));
for (int i = 0; i < bestPathLen; i++) {
result[i] = bestPath[i];
}
*returnSize = bestPathLen;
return result;
}
int main() {
char line[MAX_LINE];
int n;
// Read n
if (scanf("%d", &n) != 1) {
printf("[]\n");
return 0;
}
getchar(); // Consume newline
// Read roads
if (fgets(line, MAX_LINE, stdin) == NULL) {
printf("[]\n");
return 0;
}
int roads[MAX_CITIES][2];
int roadsSize;
parseRoads(line, roads, &roadsSize);
// Read city names
if (fgets(line, MAX_LINE, stdin) == NULL) {
printf("[]\n");
return 0;
}
char names[MAX_CITIES][MAX_NAME_LEN];
int namesSize;
parseNames(line, names, &namesSize);
// Read target path
if (fgets(line, MAX_LINE, stdin) == NULL) {
printf("[]\n");
return 0;
}
char targetPath[MAX_CITIES][MAX_NAME_LEN];
int targetPathSize;
parseNames(line, targetPath, &targetPathSize);
// Solve
int returnSize;
int* result = solution(n, roads, roadsSize, names, namesSize, targetPath, targetPathSize, &returnSize);
// Output result
printf("[");
for (int i = 0; i < returnSize; i++) {
printf("%d", result[i]);
if (i < returnSize - 1) printf(",");
}
printf("]\n");
free(result);
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
O(n^k)
Where k is target path length, we explore n^k possible paths in worst case
n
2n
✓ Linear Growth
Space Complexity
O(k)
Recursion depth is k (target path length) plus adjacency list storage
n
2n
⚡ Linearithmic Space
23.4K Views
MediumFrequency
~35 minAvg. Time
542 Likes
Ln 1, Col 1
Smart Actions
💡Explanation
AI Ready
💡 SuggestionTabto acceptEscto dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen
Algorithm Visualization
Pinch to zoom • Tap outside to close
Test Cases
0 passed
0 failed
3 pending
Select Compiler
Choose a programming language
Compiler list would appear here...
AI Editor Features
Header Buttons
💡
Explain
Get a detailed explanation of your code. Select specific code or analyze the entire file. Understand algorithms, logic flow, and complexity.
🔧
Fix
Automatically detect and fix issues in your code. Finds bugs, syntax errors, and common mistakes. Shows you what was fixed.
💡
Suggest
Get improvement suggestions for your code. Best practices, performance tips, and code quality recommendations.
💬
Ask AI
Open an AI chat assistant to ask any coding questions. Have a conversation about your code, get help with debugging, or learn new concepts.
Smart Actions (Slash Commands)
🔧
/fix Enter
Find and fix issues in your code. Detects common problems and applies automatic fixes.
💡
/explain Enter
Get a detailed explanation of what your code does, including time/space complexity analysis.
🧪
/tests Enter
Automatically generate unit tests for your code. Creates comprehensive test cases.
📝
/docs Enter
Generate documentation for your code. Creates docstrings, JSDoc comments, and type hints.
⚡
/optimize Enter
Get performance optimization suggestions. Improve speed and reduce memory usage.
AI Code Completion (Copilot-style)
👻
Ghost Text Suggestions
As you type, AI suggests code completions shown in gray text. Works with keywords like def, for, if, etc.
Tabto acceptEscto dismiss
💬
Comment-to-Code
Write a comment describing what you want, and AI generates the code. Try: # two sum, # binary search, # fibonacci
💡
Pro Tip: Select specific code before using Explain, Fix, or Smart Actions to analyze only that portion. Otherwise, the entire file will be analyzed.