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;
    }