1. DFS with Backtracking
Intuition
Explore all valid one-character mutations recursively using Depth-First Search. Track visited gene strings to prevent infinite cycles. Keep track of the minimum path length to reach endGene.
Algorithm
- If
endGeneis not inbank, return -1. - Initialize
visitedset. - Define
dfs(curr, depth): - If
curr == endGene, updateminDepth = min(minDepth, depth). - For each gene in
banknot invisiteddiffering by exactly 1 character: -
visited.add(gene) -
dfs(gene, depth + 1) -
visited.remove(gene)(backtrack) - Run
dfs(startGene, 0). - Return
minDepth == infinity ? -1 : minDepth.
#include <iostream>#include <vector>#include <string>#include <unordered_set>#include <algorithm>#include <climits> bool differsByOneChar(const std::string& a, const std::string& b) { int diff = 0; for (int i = 0; i < 8; ++i) { if (a[i] != b[i]) { if (++diff > 1) return false; } } return diff == 1;} void dfsGene(const std::string& curr, const std::string& target, int depth, const std::vector<std::string>& bank, std::vector<bool>& visited, int& minDepth) { if (depth >= minDepth) return; if (curr == target) { minDepth = depth; return; } for (size_t i = 0; i < bank.size(); ++i) { if (!visited[i] && differsByOneChar(curr, bank[i])) { visited[i] = true; dfsGene(bank[i], target, depth + 1, bank, visited, minDepth); visited[i] = false; } }} int minMutationDFS(std::string startGene, std::string endGene, std::vector<std::string>& bank) { int minDepth = INT_MAX; std::vector<bool> visited(bank.size(), false); dfsGene(startGene, endGene, 0, bank, visited, minDepth); return minDepth == INT_MAX ? -1 : minDepth;} int main() { std::vector<std::string> bank = {"AACCGGTA"}; std::cout << "Min Mutation (DFS): " << minMutationDFS("AACCGGTT", "AACCGGTA", bank) << std::endl; return 0;}Time & Space Complexity
- Time complexity:
O(B!) where B is bank.length (B <= 10). - Space complexity:
O(B) for recursion stack and visited set.