题目描述:
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;
}
}