📌  相关文章
📜  打印所有可能的最短链以达到目标词

📅  最后修改于: 2021-05-17 02:59:04             🧑  作者: Mango

给定两个字符串starttarget (长度相同)和字符串列表str [] ,任务是打印从starttarget的所有可能的最小序列(如果存在),以使序列中的相邻单词相差仅一个字符,序列中的每个单词都出现在给定列表中。
注意:可以假定目标单词出现在列表中,并且所有单词的长度都相同。如果出现多个序列,请打印所有序列。

例子:

方法:使用BFS可以解决问题,这里最棘手的部分是执行路径的BFS而不是单词。请按照以下步骤解决问题:

  1. 初始化一个变量,例如res ,以存储所有可能的最短路径。
  2. 创建一个Set来存储当前路径中的所有已访问单词,并在完成当前路径后擦除所有已访问的单词。
  3. 对于每个当前单词,通过将每个字符从’a’更改为’z’来找到str []中可能存在的下一个单词,并找到所有可能的路径。
  4. 最后,打印所有可能的路径。
C++
// C++ Program to implememnt
// the above approach
#include 
using namespace std;
 
// Function to print all possible shortest
// sequences starting from start to target.
void displaypath(vector >& res)
{
    for (int i = 0; i < res.size(); i++) {
        cout << "[ ";
        for (int j = 0; j < res[0].size(); j++) {
            cout << res[i][j] << ", ";
        }
        cout << " ]\n";
    }
}
// Find words differing by a single
// character with word
vector addWord(
    string word,
    unordered_set& dict)
{
    vector res;
 
    // Find next word in dict by changing
    // each element from 'a' to 'z'
    for (int i = 0; i < word.size(); i++) {
        char s = word[i];
        for (char c = 'a'; c <= 'z'; c++) {
            word[i] = c;
            if (dict.count(word))
                res.push_back(word);
        }
        word[i] = s;
    }
    return res;
}
 
// Function to get all the shortest possible
// sequences starting from 'start' to 'target'
vector > findLadders(
    vector& Dict,
    string beginWord,
    string endWord)
{
    // Store all the shortest path.
    vector > res;
 
    // Store visited words in list
    unordered_set visit;
 
    // Queue used to find the shortest path
    queue > q;
 
    // Stores the distinct words from given list
    unordered_set dict(Dict.begin(),
                               Dict.end());
    q.push({ beginWord });
 
    // Stores whether the shortest
    // path is found or not
    bool flag = false;
 
    while (!q.empty()) {
        int size = q.size();
        for (int i = 0; i < size; i++) {
 
            // Explore the next level
            vector cur = q.front();
            q.pop();
            vector newadd;
 
            // Find words differing by a
            // single character
            newadd = addWord(cur.back(), dict);
 
            // Add words to the path.
            for (int j = 0; j < newadd.size(); j++) {
                vector newline(cur.begin(),
                                       cur.end());
 
                newline.push_back(newadd[j]);
 
                // Found the target
                if (newadd[j] == endWord) {
                    flag = true;
                    res.push_back(newline);
                }
 
                visit.insert(newadd[j]);
                q.push(newline);
            }
        }
 
        // If already reached target
        if (flag) {
            break;
        }
 
        // Erase all visited words.
        for (auto it : visit) {
            dict.erase(it);
        }
 
        visit.clear();
    }
    return res;
}
 
// Driver Code
int main()
{
    vector str{ "ted", "tex", "red",
                        "tax", "tad", "den",
                        "rex", "pee" };
    string beginWord = "red";
    string endWord = "tax";
 
    vector > res
        = findLadders(str, beginWord, endWord);
 
    displaypath(res);
}


Python3
# Python Program to implememnt
# the above approach
from collections import deque
from typing import Deque, List, Set
 
# Function to print all possible shortest
# sequences starting from start to target.
def displaypath(res: List[List[str]]):
    for i in res:
        print("[ ", end="")
        for j in i:
            print(j, end=", ")
        print("]")
 
# Find words differing by a single
# character with word
def addWord(word: str, Dict: Set):
    res: List[str] = []
    wrd = list(word)
     
    # Find next word in dict by changing
    # each element from 'a' to 'z'
    for i in range(len(wrd)):
        s = wrd[i]
        c = 'a'
        while c <= 'z':
            wrd[i] = c
            if ''.join(wrd) in Dict:
                res.append(''.join(wrd))
            c = chr(ord(c) + 1)
        wrd[i] = s
    return res
 
# Function to get all the shortest possible
# sequences starting from 'start' to 'target'
def findLadders(Dictt: List[str], beginWord: str, endWord: str):
 
    # Store all the shortest path.
    res: List[List[str]] = []
 
    # Store visited words in list
    visit = set()
 
    # Queue used to find the shortest path
    q: Deque[List[str]] = deque()
 
    # Stores the distinct words from given list
    Dict = set()
    for i in Dictt:
        Dict.add(i)
    q.append([beginWord])
 
    # Stores whether the shortest
    # path is found or not
    flag = False
    while q:
        size = len(q)
        for i in range(size):
 
            # Explore the next level
            cur = q[0]
            q.popleft()
            newadd = []
 
            # Find words differing by a
            # single character
            newadd = addWord(cur[-1], Dict)
 
            # Add words to the path.
            for j in range(len(newadd)):
                newline = cur.copy()
                newline.append(newadd[j])
 
                # Found the target
                if (newadd[j] == endWord):
                    flag = True
                    res.append(newline)
 
                visit.add(newadd[j])
                q.append(newline)
 
        # If already reached target
        if (flag):
            break
 
        # Erase all visited words.
        for it in visit:
            Dict.remove(it)
        visit.clear()
    return res
 
# Driver Code
if __name__ == "__main__":
 
    string = ["ted", "tex", "red", "tax", "tad", "den", "rex", "pee"]
    beginWord = "red"
    endWord = "tax"
 
    res = findLadders(string, beginWord, endWord)
 
    displaypath(res)
 
# This code is contributed by sanjeev2552


输出:
[ red, ted, tad, tax,  ]
[ red, ted, tex, tax,  ]
[ red, rex, tex, tax,  ]

时间复杂度: O(N²* M),其中M是给定列表中的字符串数, N是每个字符串的长度。

辅助空间: O(M * N)