LeetCode-126. Word Ladder II [C++][Java]

LeetCode-126. Word Ladder IILeetCode-126. Word Ladder II [C++][Java]https://leetcode.com/problems/word-ladder-ii/

题目描述

transformation sequence from word beginWord to word endWord using a dictionary wordList is a sequence of words beginWord -> s1 -> s2 -> ... -> sk such that:

  • Every adjacent pair of words differs by a single letter.
  • Every si for 1 <= i <= k is in wordList. Note that beginWord does not need to be in wordList.
  • sk == endWord

Given two words, beginWord and endWord, and a dictionary wordList, return all the shortest transformation sequences from beginWord to endWord, or an empty list if no such sequence exists. Each sequence should be returned as a list of the words [beginWord, s1, s2, ..., sk].

Example 1:

Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
Output: [["hit","hot","dot","dog","cog"],["hit","hot","lot","log","cog"]]
Explanation: There are 2 shortest transformation sequences:
"hit" -> "hot" -> "dot" -> "dog" -> "cog"
"hit" -> "hot" -> "lot" -> "log" -> "cog"

Example 2:

Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
Output: []
Explanation: The endWord "cog" is not in wordList, therefore there is no valid transformation sequence.

Constraints:

  • 1 <= beginWord.length <= 5
  • endWord.length == beginWord.length
  • 1 <= wordList.length <= 1000
  • wordList[i].length == beginWord.length
  • beginWordendWord, and wordList[i] consist of lowercase English letters.
  • beginWord != endWord
  • All the words in wordList are unique.

解题思路

【C++解法】

1. BFS:set + queue + vector

//这里再用map + vector就不合适了

        unordered_map<string, vector<string>> mp;
        for (string& w:wordList) 
            for(int i=0; i<w.size(); i++) 
                mp[w.substr(0, i) + "#" + w.substr(i+1)].push_back(w);

....

       mp.erase(key);

很明显dog log都和#og相关,erase会导致另一条路不能再走。

class Solution {
public:
    vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
        vector< vector<string>> res;
        unordered_set<string> dict(wordList.begin(),wordList.end());
        if (dict.find(endWord) == dict.end()) {return res;}
        queue<vector<string>> q; 
        q.push({beginWord});
		bool flag = false; 
        while (!q.empty()){
            int size = q.size();
            while (size--){
                vector<string> curPath = q.front(); q.pop();
                string last = curPath.back();
                if (last == endWord) {
                    res.push_back(curPath);
					flag = true;
					continue;
                }
                dict.erase(last);
                for (int i=0; i<last.size(); i++){
                    string temp = last;
                    for (char ch='a'; ch<='z'; ch++){
                        temp[i] = ch;
                        if (dict.find(temp) != dict.end()){
                            curPath.push_back(temp);
                            q.push(curPath);
                            curPath.pop_back();
                        }
                    }
                }
            }
            if (flag) {break;}
        }
        return res;
    }
};

【Java解法】

This solution search from endWord to beginWord, firstly do bfs to get shortest path and store distance and neighbor words infomation, secondly do dfs to get the paths:
1.Use a HashMap to record the distance between every word in wordlist and the beginWord during bfs.
2.Use a HashMap to record the the neighbor words list of the word(direction: from endWord to beginWord) during bfs.
3.Do dfs to add the words on the path and generate the answer.

class Solution {
    public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
        Set<String> words = new HashSet<>(wordList);
        List<List<String>> ans = new ArrayList<>();
        if (!words.contains(endWord)) {
            return ans;
        }
        
        Map<String, List<String>> adjWords = new HashMap<>();
        Map<String, Integer> dist = new HashMap<>();
        bfs(beginWord, adjWords, dist, words);
        dfs(endWord, beginWord, adjWords, dist, new ArrayList<>(), ans);
        
        return ans;
    }
    
    public void bfs(String beginWord, Map<String, List<String>> adjWords, Map<String, Integer> dist, Set<String> words) {
        Queue<String> queue = new LinkedList<>();
        queue.offer(beginWord);
        dist.put(beginWord, 0);
        for (String word : words) {
            adjWords.put(word, new ArrayList<>());
        }
        
        while (!queue.isEmpty()) {
            String cur = queue.poll();
            List<String> neighbors = neighbors(cur, words);
            for (String next : neighbors) {
                adjWords.get(next).add(cur);
                if (!dist.containsKey(next)) {
                    dist.put(next, dist.get(cur) + 1);
                    queue.offer(next);
                }
            }
        }
    } 
    
    public void dfs(String curWord, String beginWord,Map<String, List<String>> adjWords, Map<String, Integer> dist, List<String> path, List<List<String>> ans) {
        path.add(curWord);
        if (curWord.equals(beginWord)) {
            Collections.reverse(path);
            ans.add(new ArrayList<>(path));
            Collections.reverse(path);
        } else {
            for (String next : adjWords.get(curWord)) {
                if (dist.containsKey(next) && dist.get(curWord) == dist.get(next) + 1) {
                    dfs(next, beginWord, adjWords, dist, path, ans);
                }
            }
        }
        
        path.remove(path.size() - 1);
    }
    
    public List<String> neighbors(String word, Set<String> words) {
        List<String> ans = new ArrayList<>();
        char[] sc = word.toCharArray();
        for (int i = 0; i < sc.length; i++) {
            char cur = sc[i];
            for (char c = 'a'; c <= 'z'; c++) {
                sc[i] = c;
                String temp = new String(sc);
                if (words.contains(temp)) {
                    ans.add(temp);
                }
            }
            sc[i] = cur;
        }
        
        return ans;
    }
}

上一篇:html相对路径和绝对路径


下一篇:K8S和docker的镜像不一致