思路比较简单

  • 就是以基因序列为点,以找一个字母变一下为变。求点层数。
  • 属于思路很定点的BFS题目,直接看完整注释就行

    1. class Solution {
    2. public int minMutation(String start, String end, String[] bank) {
    3. //把基因库数组存入哈希表,以方便查找
    4. Set<String> bankSet = new HashSet<String>(Arrays.asList(bank));
    5. //用来记录一个基因,是从start 开始,变了多少步骤
    6. Map<String,Integer> depthMap = new HashMap<>();
    7. //记录一下子标准基因
    8. char[] jiyins = {'A', 'C', 'G', 'T'};
    9. //如果end不合法不在基因库直接返回
    10. if(!bankSet.contains(end)){
    11. return -1;
    12. }
    13. //广搜BFS需要使用队列
    14. Queue<String> queue = new LinkedList<>();
    15. //先把start放入队列中去
    16. queue.add(start);
    17. //执行BFS标准广搜
    18. while (!queue.isEmpty()){
    19. //队头出队,拿到一个当前基因
    20. String oneJiyin = queue.poll();
    21. //因为基因是8个字母,所以从每一个字母开始,向额外的三个字母开始扩展,变变化
    22. //八个字母,所以循环8次,把每一个字母都尝试变一次
    23. for(int i = 0; i < 8; i++){
    24. //遍历合法基因字母,一共四个,去向着除了自己的那个,剩下的三个方向扩展
    25. for(char jy : jiyins){
    26. //在这里才转换数组,是因为每一次要使用新的值,这一次改变不能把原值替换掉,换过方向的要是新对象
    27. char[] jiyinChars = oneJiyin.toCharArray();
    28. if(jiyinChars[i] != jy){
    29. //找到一个新的可替换的值,就进行替换
    30. jiyinChars[i] = jy;
    31. //然后入队列,并且保存深度。深度等于原深度+1
    32. String newJiyin = new String(jiyinChars);
    33. //如果新的基因,不在基因库里,则继续搜索,忽略这个新基因
    34. if(!bankSet.contains(newJiyin)){
    35. continue;
    36. }
    37. //如果基因深度记录器,已经有过这个新基因了,说明这个新基因出现过了,那就忽略这个新基因
    38. if(depthMap.containsKey(newJiyin)){
    39. continue;
    40. }
    41. queue.add(newJiyin);
    42. depthMap.put(newJiyin,depthMap.getOrDefault(oneJiyin,0) + 1);
    43. //如果这个新的基因就是end结果,那么返回其深度。也就是最终变化了多少次
    44. if(newJiyin.equals(end)){
    45. return depthMap.get(newJiyin);
    46. }
    47. }
    48. }
    49. }
    50. }
    51. //如果start无法转换成end 返回-1
    52. return -1;
    53. }
    54. }