Word_Ladder

题目描述:

   Given two words (start and end), and a dictionary,
   find the length of shortest transformation sequence from start to end, such that:
   Only one letter can be changed at a time
   Each intermediate(中间的) word must exist in the dictionary

   For example,

   Given:
   start = "hit"
   end = "cog"
   dict = ["hot","dot","dog","lot","log"]

   As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
   return its length 5.

   Note:

    Return 0 if there is no such transformation sequence.
    All words have the same length.
    All words contain only lowercase alphabetic characters.
    (所有单词只包含小写字母字符)

思路:典型BFS,将每位字母用其他25个字母替换(记得某位字母在替换了所有其余25个字母之后最后要将其换回来),如果换过的字母组成的字符串在单词列表中就将其存入节点列表,如此重复直到找到结果。

public class Word_Ladder {
	public static int ladderLength(String beginWord, String endWord, List<String> wordList) 
    {
    	List<Node> mid = new ArrayList<Node>();
    	return getLength(beginWord,endWord,wordList,mid);
    }
    public static int getLength(String beginWord, String endWord, List<String> wordList,List<Node> mid)
    {
    	if(beginWord.length()!=endWord.length()||wordList.size()==0||!wordList.contains(endWord))
    		return 0;
    	if(beginWord.equals(endWord))
    		return 2;
    	Node begin = new Node(beginWord,1);
    	mid.add(begin);
    	while(mid.size()!=0)
    	{
    		String str = mid.get(0).str;
    		int length = mid.get(0).length;
    		mid.remove(0);
    		for(int i=0;i<str.length();i++)
    		{
    			char array[] = str.toCharArray(); 
    			char ch = array[i];
    			for(char j='a';j<='z';j++)
    			{
    				if(ch==j)
    					continue;
    				array[i] = j;
    				String newStr = new String(array);
//    				System.out.println(newStr);
    				if(wordList.contains(newStr))
    				{
    					//为了不造成环路
    					wordList.remove(newStr);
    					if(newStr.equals(endWord))
    						return length+1;
    					Node node = new Node(newStr,length+1);
    					mid.add(node);
    				}
    			}
    		}
    	}
    	return 0;
    }
	public static void main(String[] args) {
		String start = "hit";
		String end = "cog";
	    ArrayList<String> dict = new ArrayList<String>();
	    dict.add("hot");
	    dict.add("dot");
	    dict.add("dog");
	    dict.add("lot");
	    dict.add("log");
	    dict.add("cog");
	    System.out.println(ladderLength(start,end,dict));
	}
}
class Node
{
	String str;
	int length;
	Node(String str,int length)
	{
		this.str = str;
		this.length = length;
	}
}

还有一种思路是双向BFS一个从beginword开始构建数,一个从endWord开始构建数,找到他们两个的交集即为找到了两字符串之间的通路。

public class WordLadder_DoubleBFS {
	public static int ladderLength(String beginWord, String endWord, List<String> wordList) 
    {
		if(beginWord.length()!=endWord.length()||wordList.size()==0||!wordList.contains(endWord))
    		return 0;
		if(beginWord.equals(endWord))
    		return 2;
		//字典
		List<String> SwordList = new ArrayList<String>(wordList);
		List<String> EwordList = new ArrayList<String>(wordList);
		//存放树的列表
		List<Node> totalStart = new ArrayList<Node>();
		Node Snode = new Node(beginWord,1);
		totalStart.add(Snode);
		List<Node> totalEnd = new ArrayList<Node>();
		Node Enode = new Node(endWord,1);
		totalEnd.add(Enode);
		//存放每层结果的列表
		List<Node> Sresult = new ArrayList<Node>();
		Sresult.add(Snode);
		List<Node> Eresult = new ArrayList<Node>();
		Eresult.add(Enode);
		while(Sresult.size()!=0&&Eresult.size()!=0)
		{
			List<Node> Smid = BFS(Sresult,SwordList);
			List<Node> Emid = BFS(Eresult,EwordList);
			Sresult = Smid;
			Eresult = Emid;
			for(int i=0;i<Smid.size();i++)
				totalStart.add(Smid.get(i));
			for(int i=0;i<Emid.size();i++)
				totalEnd.add(Emid.get(i));
			for(int i=0;i<totalStart.size();i++)
			{
				for(int j=0;j<totalEnd.size();j++)
				{
					if(totalStart.get(i).str.equals(totalEnd.get(j).str))
					{
						return totalStart.get(i).length+totalEnd.get(j).length-1;
					}
				}
			}
		}
    	return 0;
    }
	//求树的每层
	public static List<Node> BFS(List<Node> word,List<String> wordList)
	{
		List<Node> result = new ArrayList<Node>();
		while(word.size()!=0)
		{
			String midStr = word.get(0).str;
			int length = word.get(0).length;
			word.remove(0);
			for(int i=0;i<midStr.length();i++)
			{
				char array[] = midStr.toCharArray();
				char ch = array[i];
				for(char j='a';j<='z';j++)
				{
					if(ch==j)
    					continue;
					array[i] = j;
					String newStr = new String(array);
					if(wordList.contains(newStr))
					{
						wordList.remove(newStr);
						Node node = new Node(newStr,length+1);
						result.add(node);
					}
				}
			}
		}
		return result;
	}
	public static void main(String[] args) 
	{
		String start = "hot";
		String end = "dog";
	    ArrayList<String> dict = new ArrayList<String>();
	    dict.add("hot");
	    dict.add("dot");
	    dict.add("dog");
	    dict.add("lot");
	    dict.add("log");
	    dict.add("cog");
	    System.out.println(ladderLength(start,end,dict));
	}
}
class Node
{
	String str;
	int length;
	Node(String str,int length)
	{
		this.str = str;
		this.length = length;
	}
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值