最小操作数递归实现

题目:

给了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. 1.采用的是递归实现
  2. 2.最短路径必须是不能有重复的词出现,否则极易容易产生无限循环,况且也不是最佳路径
  3. 3.因为每次只能换一个单词,分析词法是否能转换,必须至少有(单词长度-1)个相同,结尾词也是如此判断
  4. 4.一次执行结束和已经保存的记录比较,如果相同则加入结果集中,如果比存在的记录短,则清空结果集并存入该记录
  5. 问题:
  6. 没有经过严格测试,可能存在一些问题
  7. 执行效率不高,存在改进的地方
  8. 主要代码:
  9. 	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);
    				}
    			}
    		}
    	}
  10. 结果:

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值