Leetcode.126. 单词接龙 II 双bfs+dfs

双BFS+DFS
题目https://leetcode-cn.com/problems/word-ladder-ii/
一开始的想法可以像单词接龙I一样双bfs就行了,就是每次记录的是一个链表,每次判断就取最后一个单词,但是那样的话就要遍历另一个的所有,太慢了。
于是我们就用双bfs先保存每个单词的下一层单词们,这样的话我们就不用遍历这个序列了,只要直接从beginWord开始用dfs往下遍历,到目标终点时,我们就把它加进结果里面。
代码:

class Solution {
    int n;
    public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
        List<List<String>> ans=new ArrayList<>();
        //所有的单词集合
        Set<String> wordSet=new HashSet<>(wordList);
        if(!wordSet.contains(endWord)) return ans;
        this.n=beginWord.length();
        //每一个单词的下一个单词集
        Map<String,List<String>> maptree=new HashMap<>();
        Set<String> begin=new HashSet();
        Set<String> end=new HashSet();
        begin.add(beginWord);
        end.add(endWord);
        if(bfs(wordSet,begin,end,maptree,true)){
            dfs(ans,beginWord,endWord,maptree,new LinkedList());
        }
        return ans;
    }
    boolean bfs(Set<String> wordSet,Set<String> begin,Set<String> end,Map<String,List<String>> maptree,boolean isValue){
        if(begin.size()==0) return false;
        //始终以少的开始遍历
        if(begin.size()>end.size())
            return bfs(wordSet,end,begin,maptree,!isValue);	 //isValue这个变量代表是从上往下,还是从下往上
        wordSet.removeAll(begin);
        boolean ismeet=false;
        //记录这一层访问过的
        Set<String> next=new HashSet();
        for(String str:begin)
            for(int i=0;i<n;i++){
                char[] char1=str.toCharArray();
                for(char c='a';c<='z';c++){
                    char1[i]=c;
                    String cur=new String(char1);
                    if(!wordSet.contains(cur)) continue;
                    next.add(cur);
                    if(end.contains(cur)) ismeet=true;
                    String up=isValue?str:cur;
                    String down=isValue?cur:str;
                    if(!maptree.containsKey(up))
                        maptree.put(up,new ArrayList<>());
                    maptree.get(up).add(down);
                }
        }
        if(ismeet) return true;
        return bfs(wordSet,next,end,maptree,isValue);
    }
    void dfs(List<List<String>> ans,String beginWord,String endWord,Map<String,List<String>> maptree,LinkedList<String> List){
        List.add(beginWord) ;
        if(beginWord.equals(endWord)){
            ans.add(new ArrayList<>(List));
            List.removeLast();
            return;
        }
        if(maptree.containsKey(beginWord)){
            for(String str:maptree.get(beginWord)){
                dfs(ans,str,endWord,maptree,List);
            }
        }
        List.removeLast();
    }
}

bfs的作用就是找到最短的路径,dfs就是将路径重现出来,
bfs先减小dfs的搜索量,将整棵树剪枝,这样就减少复杂度。
Leetcode.126. 单词接龙 II 双bfs+dfs_第1张图片

你可能感兴趣的:(Leetcode.126. 单词接龙 II 双bfs+dfs)