433. 最小基因变化
题目:


思路:
【1】可以参考 剑指 Offer II 108. 单词演变(127. 单词接龙)这篇,本质上题目是类似的,或者说差不多
代码展示:
//时间1 ms 击败 66.44% //内存39.8 MB 击败 11.69% class Solution { private Map<String, Integer> wordId = new HashMap<String, Integer>(); private List<List<Integer>> edge = new ArrayList<List<Integer>>(); private int nodeNum = 0; public int minMutation(String startGene, String endGene, String[] bank) { // 将给出的可以变化的序列构建成图 for (String word : bank) { addEdge(word); } // 起始点也要加入 addEdge(startGene); if (!wordId.containsKey(endGene)) return -1; int[] disBegin = new int[nodeNum]; Arrays.fill(disBegin, Integer.MAX_VALUE); int beginId = wordId.get(startGene); disBegin[beginId] = 0; Queue<Integer> queBegin = new LinkedList<Integer>(); queBegin.offer(beginId); int[] disEnd = new int[nodeNum]; Arrays.fill(disEnd, Integer.MAX_VALUE); int endId = wordId.get(endGene); disEnd[endId] = 0; Queue<Integer> queEnd = new LinkedList<Integer>(); queEnd.offer(endId); while (!queBegin.isEmpty() && !queEnd.isEmpty()) { int queBeginSize = queBegin.size(); for (int i = 0; i < queBeginSize; ++i) { int nodeBegin = queBegin.poll(); if (disEnd[nodeBegin] != Integer.MAX_VALUE) { return (disBegin[nodeBegin] + disEnd[nodeBegin]) / 2; } for (int it : edge.get(nodeBegin)) { if (disBegin[it] == Integer.MAX_VALUE) { disBegin[it] = disBegin[nodeBegin] + 1; queBegin.offer(it); } } } int queEndSize = queEnd.size(); for (int i = 0; i < queEndSize; ++i) { int nodeEnd = queEnd.poll(); if (disBegin[nodeEnd] != Integer.MAX_VALUE) { return (disBegin[nodeEnd] + disEnd[nodeEnd]) / 2; } for (int it : edge.get(nodeEnd)) { if (disEnd[it] == Integer.MAX_VALUE) { disEnd[it] = disEnd[nodeEnd] + 1; queEnd.offer(it); } } } } return -1; } /** * 假设加入的单词是AAAACCCC * 会将单词变更为 AAA*CCCC, *AAACCC, AAAACC*C, AA*ACCCC, AAAAC*CC, AAAACCC*, A*AACCCC, AAAA*CCCd多种情况 * 即在list中 AAAACCCC-> {AAA*CCCC, *AAACCC, AAAACC*C, AA*ACCCC, AAAAC*CC, AAAACCC*, A*AACCCC, AAAA*CCC} * 而其余的类似 AAA*CCCC 也会指向 {AAAACCCC} * * 如果填入 ["AAAAACCC","AAAACCCC","AAACCCCC","AACCCCCC"] 这四个字符串 * 那么最终结果 * MAP = {AAC*CCCC=20, AACC*CCC=21, AACCCCCC=17, AAAAAC*C=31, AAAACC*C=7, AA*AACCC=28, A*ACCCCC=11, AAAA*CCC=5, AAA*ACCC=29, AAA*CCCC=4, AAAAA*CC=30, AAAAACC*=32, AAAAC*CC=6, AAAACCC*=8, *AACCCCC=10, AAACCCCC=9, AACCC*CC=22, AACCCCC*=24, A*AAACCC=27, AA*CCCCC=12, AAACCC*C=15, AAAC*CCC=13, AAACC*CC=14, *AAACCCC=1, AAACCCC*=16, AA*ACCCC=3, A*AACCCC=2, *AAAACCC=26, AACCCC*C=23, AAAAACCC=25, *ACCCCCC=18, AAAACCCC=0, A*CCCCCC=19} * 其中MAP中的value则是list的下标,下标指向的集合即是可达集合 * LIST = [[1, 2, 3, 4, 5, 6, 7, 8], [0], [0], [0], [0, 9], [0, 25], [0], [0], [0], [10, 11, 12, 4, 13, 14, 15, 16], [9], [9], [9, 17], [9], [9], [9], [9], [18, 19, 12, 20, 21, 22, 23, 24], [17], [17], [17], [17], [17], [17], [17], [26, 27, 28, 29, 5, 30, 31, 32], [25], [25], [25], [25], [25], [25], [25]] * @param word 构建成图的单词 */ public void addEdge(String word) { // 将这个单词加入 addWord(word); int id1 = wordId.get(word); char[] array = word.toCharArray(); for (int i = 0; i < array.length; ++i) { char tmp = array[i]; array[i] = '*'; String newWord = new String(array); addWord(newWord); int id2 = wordId.get(newWord); edge.get(id1).add(id2); edge.get(id2).add(id1); array[i] = tmp; } } /** * 塞入到MAP中,记录在list里面的下标 * 先通过MAP判断在不在,再找出可以指向的集合 * @param word 加入的单词 */ public void addWord(String word) { if (!wordId.containsKey(word)) { wordId.put(word, nodeNum++); edge.add(new ArrayList<Integer>()); } } } // 更加快速的版本 //时间0 ms 击败 100% //内存39.3 MB 击败 86.79% class Solution { public int minMutation(String startGene, String endGene, String[] bank) { Queue<String> q=new LinkedList<>(); HashSet<String> set=new HashSet<>(); q.offer(startGene); int m=1; while(!q.isEmpty()){ int size=q.size(); for(int i=0;i<size;i++){ String qq=q.poll(); List<String> list=replace(qq,bank); if(list.size()!=0){ for(String s:list){ if(!set.contains(s)){ if(s.equals(endGene)) return m; q.offer(s); set.add(s); } } } } m++; } return -1; } public List<String> replace(String x,String[] bank){ List<String> res=new ArrayList<String>(); for(String b:bank){ int r=0; for(int i=0;i<x.length();i++){ if(x.charAt(i)!=b.charAt(i)) r++; } if(r==1) res.add(b); } return res; } }

浙公网安备 33010602011771号