我正在练习面试问题,您希望通过一次更改一个字母来返回beginWord
到endWord
的最短路径,并且每个新单词必须位于wordList
。
Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:
Only one letter can be changed at a time
Each intermediate word must exist in the word list
For example,
Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.
我通过获取当前单词的可能转换(只有一个字母差异的单词)并递归每个邻居来使用dfs来解决这个问题
public int ladderLength(String beginWord, String endWord, Set<String> wordList) {
return this.dfs(beginWord, endWord, wordList, new ArrayList<String>()).size();
}
public ArrayList<String> dfs(String curr, String endWord, Set<String> wordList, ArrayList<String> path)
{
path.add(curr);
ArrayList<String> n = this.getNeighbors(curr, wordList);
for(String w: n)
{
if(this.differsByOne(w, endWord))
{
path.add(w);
path.add(endWord);
return path;
}
this.dfs(w, endWord, wordList, path);
}
path.remove(path.size() - 1);
return path;
}
public boolean differsByOne(String w1, String w2)
{
int diff = 0;
for(int i=0; i < w1.length(); i++)
{
if(!(w1.charAt(i) == w2.charAt(i)))
{
diff += 1;
}
if(diff > 1)
return false;
}
return true;
}
public ArrayList<String> getNeighbors(String beginWord, Set<String> wordList)
{
ArrayList<String> n = new ArrayList<String>();
//int bwindex = 0;
int windex = 0;
for(String w: wordList)
{
if(!(beginWord.equals(w)) && this.differsByOne(beginWord, w))
n.add(w);
}
return n;
}
我收到了StackOverflowException。如果没有命中基础案例,就会发生这种情况,但我不明白为什么我的基本案例this.differsByOne(w, endWord)
不会被命中。 (在上面的示例中失败了)wordList
中必须有一个单词,endWord
的变换与一个变为一,所以当找到它时它应该返回。
编辑:
停止StackOverflowException但得到错误答案......
public int ladderLength(String beginWord, String endWord, Set<String> wordList) {
ArrayList<ArrayList<String>> paths = this.dfs(beginWord, endWord, wordList, new ArrayList<String>(), new ArrayList<ArrayList<String>>(), new HashMap<String, String>());
int min = 1000000;
for(ArrayList<String> n: paths)
{
if(n.size() < min)
min = n.size();
}
return min;
}
public ArrayList<String> dfs(String curr, String endWord, Set<String> wordList, ArrayList<String> path, ArrayList<ArrayList<String>> paths, HashMap<String, String> visited)
{
path.add(curr);
visited.put(curr, curr);
ArrayList<String> n = this.getNeighbors(curr, wordList, visited);
for(String w: n)
{
if(this.differsByOne(w, endWord) || w.equals(endWord))
{
path.add(w);
path.add(endWord);
paths.add(path);
return paths;
}
this.dfs(w, endWord, wordList, path, visited);
}
path.remove(path.size() - 1);
visited.remove(curr);
return paths;
}
public boolean differsByOne(String w1, String w2)
{
int diff = 0;
for(int i=0; i < w1.length(); i++)
{
if(!(w1.charAt(i) == w2.charAt(i)))
{
diff += 1;
}
if(diff > 1)
return false;
}
return true;
}
public ArrayList<String> getNeighbors(String beginWord, Set<String> wordList, HashMap<String, String> visited)
{
ArrayList<String> n = new ArrayList<String>();
//int bwindex = 0;
int windex = 0;
for(String w: wordList)
{
if(!(beginWord.equals(w)) && this.differsByOne(beginWord, w) && !visited.containsKey(w)) {
n.add(w);
visited.put(w, w);
}
}
return n;
}