Java StackOverflowException不考虑基本情况
我正在练习一个面试问题,你想通过一次更改一个字母来返回从Java StackOverflowException不考虑基本情况,java,algorithm,Java,Algorithm,我正在练习一个面试问题,你想通过一次更改一个字母来返回从开始词到结束词的最短路径,并且每个新词必须在单词列表中 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 a
开始词到结束词的最短路径,并且每个新词必须在单词列表中
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;
}
我在递归方法中没有看到停止条件。我遗漏了什么吗?如果不同的字节(w,尾字)
。因此,如果邻居列表中的当前单词可以通过一次转换转化为结束单词,则将其添加到路径并返回。这里完全是在黑暗中拍摄的,因为我没有彻底检查代码,但是一种可能的方法是,如果它在已检查的单词之间循环,例如,点击
->热
->点
->热
->点
。。。您可以在代码中输入一些控制台输出,以查看它实际处理的单词。@JeremyFisher:您正在检查前一个单词,但它是否也捕获了此循环,因为它需要查看所有可能的邻居<代码>点击
->热
->点
->批
->热
->点
->批
->热
->由于没有返回最小路径,所以得到了错误的答案。您返回的路径可能不是最优的
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;
}