题目:
给了A、B两个单词和一个单词集合Dict,每个的长度都相同。我们希望通过若干次操作把单词A变成单词B,每次操作可以改变单词中的一个字母,同时,新产生的单词必须是在给定的单词集合Dict中。求所有行得通步数最少的修改方法。
举个例子如下:Given: A = "hit" B = "cog" Dict = ["hot","dot","dog","lot","log"]
Return [["hit","hot","dot","dog","cog"],["hit","hot","lot","log","cog"]]
分析:
- 1.采用的是递归实现
- 2.最短路径必须是不能有重复的词出现,否则极易容易产生无限循环,况且也不是最佳路径
- 3.因为每次只能换一个单词,分析词法是否能转换,必须至少有(单词长度-1)个相同,结尾词也是如此判断
- 4.一次执行结束和已经保存的记录比较,如果相同则加入结果集中,如果比存在的记录短,则清空结果集并存入该记录
- 问题:
- 没有经过严格测试,可能存在一些问题
- 执行效率不高,存在改进的地方
- 主要代码:
-
public Vector<Vector<String>> findLadders(String start, String end, Set<String> dict) { Vector<Vector<String>> results = new Vector<Vector<String>>(); Vector<String> paths = getNextString(new Vector<String>() , null, start, end, dict, 1, false); Iterator<String> it = paths.iterator(); while(it.hasNext()){ Vector<String> collection = new Vector<String>(); String[] collectionStr = it.next().split("\\|"); for(int i=0;i<collectionStr.length;i++){ collection.add(collectionStr[i]); } results.add(collection); } System.out.println("结果个数:" + results.size()); return results ; } /** * 方法1.这里使用String而不是其他集合对象是因为,String是值引用,集合对象是地址引用 * 方法2.获得当前所在的循环层次,在截取对应的数据 * @param path 当期路径 null表示是第一次查询,需要构件基础路径 * @param currInput 当前匹配词 * @param end 结束词 * @param dict 字典 * @param first 是否是第一次匹配 * @param layer 表示当前所在层 * @param isFindAll 是否查找出所有结果 */ public Vector<String> getNextString(Vector<String> paths, String path, String currInput, String endInput, Set<String> dict, int layer, boolean isFindAll){ Iterator<String> it = dict.iterator(); char[] endArray = endInput.toCharArray();//结束词 char[] currArray = currInput.toCharArray();//匹配词 if(null == path){ path = new String(currInput+"|");//第一层数据 } while(it.hasNext()) { String currDict = it.next(); //System.out.println("所属层:" + layer + " 路径:" + path + " 当前查找词:"+currDict + " 当前匹配词:"+currInput); char[] dictArray = currDict.toCharArray(); int count1 = 0; int count2 = 0; //不能重复,考虑到重复的话容易产生死循环,况且不会是最小路径 if(!isContains(path, currDict)){ for(int i=0;i<dictArray.length;i++){//字符匹配度 char c1 = dictArray[i]; char c2 = currArray[i]; char c3 = endArray[i]; if(c1 == c2){ count1++; } if(c1 == c3){ count2++; } } int length = dictArray.length-1; if(count1 >= length){ path += currDict+"|";//这里表示的是进入下次层的路径 getNextString(paths, path, currDict, endInput, dict, ++layer, isFindAll);//进入该层的循环 if(count2 >= length){ path += endInput; addPathbyLayer(path, paths, isFindAll); } --layer; path = path.substring(0, path.lastIndexOf(currDict));//该层查找完毕后需要去掉 } } } if(layer == 1){ return paths;//走到这一步,查询推出 } return null;//走到这一步,说明一次查找失败 } public void addPathbyLayer(String path, Vector<String> paths, boolean isFindAll){ if(isFindAll){ paths.add(path); }else{ if(paths.size() < 1){ paths.add(path); }else{ int path1 = paths.get(0).split("\\|").length; int path2 = path.split("\\|").length; if(path1 == path2) paths.add(path); if(path1 > path2){ paths.clear(); paths.add(path); } } } }
- 结果:
2013-11-06 13:00:29 363
结果个数:2
[[hit, hot, lot, log, cog], [hit, hot, dot, dog, cog]]
2013-11-06 13:00:29 369
2013-11-06 13:00:29 369
结果个数:3
[[a2b, a2n, b2n, bmn], [a2b, a2n, amn, bmn], [a2b, b2b, b2n, bmn]]
2013-11-06 13:00:29 372