StackOverflowException尽管基本情况

时间:2016-10-17 21:07:18

标签: java algorithm

我正在练习面试问题,您希望通过一次更改一个字母来返回beginWordendWord的最短路径,并且每个新单词必须位于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;
    }

0 个答案:

没有答案