Algorithms first
最小基因变化 · 交互式算法学习
每次改变一个字符且中间串必须在 bank 中,求最少变化次数。
#433 · 图的广度优先搜索
最小基因变化
Minimum Genetic Mutation
start = AACCGGTT, end = AAACGGTA树 / 图3 个关键状态
步骤 1前沿从起点与终点同时开始。
step=0推荐
双向 BFS
时间
O(B·L·4)空间 O(B)从 start、end 同时扩展较小集合,前沿相交即得到最短路。
1function minMutation(start, end, bank) {2 const set = new Set(bank);3 if (!set.has(end)) return -1;4 let a = new Set([start]),5 b = new Set([end]),6 step = 0;7 while (a.size && b.size) {8 if (a.size > b.size)[a, b] = [b, a];9 const next = new Set();10 for (const s of a)11 for (let i = 0; i < s.length; i++)12 for (const c of 'ACGT') {13 const n = s.slice(0, i) + c + s.slice(i + 1);14 if (b.has(n)) return step + 1;15 if (set.delete(n)) next.add(n)16 }17 a = next;18 step++;19 }20 return -1;21}多语言参考
来源 · CC BY-SA 4.0 ↗Java · C++ · Go
这是一组同题正确实现,独立于上方当前动画方法;不同语言可能采用另一种正确策略。
1class Solution {2 public int minMutation(String startGene, String endGene, String[] bank) {3 Deque<String> q = new ArrayDeque<>();4 q.offer(startGene);5 Set<String> vis = new HashSet<>();6 vis.add(startGene);7 int depth = 0;8 while (!q.isEmpty()) {9 for (int m = q.size(); m > 0; --m) {10 String gene = q.poll();11 if (gene.equals(endGene)) {12 return depth;13 }14 for (String next : bank) {15 int c = 2;16 for (int k = 0; k < 8 && c > 0; ++k) {17 if (gene.charAt(k) != next.charAt(k)) {18 --c;19 }20 }21 if (c > 0 && !vis.contains(next)) {22 q.offer(next);23 vis.add(next);24 }25 }26 }27 ++depth;28 }29 return -1;30 }31}交互式算法学习
从执行步骤真正理解 LeetCode 经典 150
本站整理 150 道高频算法面试题和 302 种解法。动画方法同步展示 JavaScript 与 Python;每题另提供 Java、C++ 与 Go 同题参考实现。
AlgoViz Lab
最小基因变化 · 解法对比
每次改变一个字符且中间串必须在 bank 中,求最少变化次数。
- 测试用例
start = AACCGGTT, end = AAACGGTA- 题目分类
- 图的广度优先搜索
- 解法对比
- 2
单向 BFS
每次枚举每个位置的 A/C/G/T 替换,合法未访问基因入队。
- 时间
O(B·L·4)- 空间
O(B)
双向 BFS
从 start、end 同时扩展较小集合,前沿相交即得到最短路。
- 时间
O(B·L·4)- 空间
O(B)