题目
基因序列可以表示为一条由 8 个字符组成的字符串,其中每个字符都是
'A'
、'C'
、'G'
和 'T'
之一。
假设我们需要调查从基因序列 start
变为 end
所发生的基因变化。一次基因变化就意味着这个基因序列中的一个字符发生了变化。
- 例如,
"AACCGGTT" --> "AACCGGTA"
就是一次基因变化。
另有一个基因库 bank
记录了所有有效的基因变化,只有基因库中的基因才是有效的基因序列。(变化后的基因必须位于基因库
bank
中)
给你两个基因序列 start
和 end
,以及一个基因库 bank
,请你找出并返回能够使
start
变化为 end
所需的最少变化次数。如果无法完成此基因变化,返回 -1
。
注意:起始基因序列 start
默认是有效的,但是它并不一定会出现在基因库中。
示例 1:
1 2
| 输入:start = "AACCGGTT", end = "AACCGGTA", bank = ["AACCGGTA"] 输出:1
|
示例 2:
1 2
| 输入:start = "AACCGGTT", end = "AAACGGTA", bank = ["AACCGGTA","AACCGCTA","AAACGGTA"] 输出:2
|
示例 3:
1 2
| 输入:start = "AAAAACCC", end = "AACCCCCC", bank = ["AAAACCCC","AAACCCCC","AACCCCCC"] 输出:3
|
提示:
start.length == 8
end.length == 8
0 <= bank.length <= 10
bank[i].length == 8
start
、end
和 bank[i]
仅由字符 ['A', 'C', 'G', 'T']
组成
题解
参考:
433.
最小基因变化 - 力扣(LeetCode)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| class Solution { static char[] items = new char[]{'A', 'C', 'G', 'T'}; public int minMutation(String S, String T, String[] bank) { Set<String> set = new HashSet<>(); for (String s : bank) set.add(s); Deque<String> d = new ArrayDeque<>(); Map<String, Integer> map = new HashMap<>(); d.addLast(S); map.put(S, 0); while (!d.isEmpty()) { int size = d.size(); while (size-- > 0) { String s = d.pollFirst(); char[] cs = s.toCharArray(); int step = map.get(s); for (int i = 0; i < 8; i++) { for (char c : items) { if (cs[i] == c) continue; char[] clone = cs.clone(); clone[i] = c; String sub = String.valueOf(clone); if (!set.contains(sub)) continue; if (map.containsKey(sub)) continue; if (sub.equals(T)) return step + 1; map.put(sub, step + 1); d.addLast(sub); } } } } return -1; } }
|