给定两个字符串start和target (长度相同)以及字符串列表str[] ,任务是打印从start到target 的所有可能的最小序列(如果存在),这样序列中的相邻单词仅相差单个字符,序列中的每个单词都出现在给定的列表中。
注意:可以假设目标词存在于列表中并且所有词的长度相同。如果出现多个序列,则打印所有序列。
例子:
Input: str[] = {poon, plee, same, poie, plea, plie, poin}, start = “toon”, target = “plea”
Output: [[toon, poon, poin, poie, plee, plea]]
Explanation: toon → poon → poin → poie → plee → plea
Input: str[] = { ted, tex, red, tax, tad, den, rex, pee}, start = “red”, target = “tax”
Output [[“red”, “ted”, “tad”, “tax”], [“red”, “ted”, “tex”, “tax”], [“red”, “rex”, “tex”, “tax”]]
方法:问题可以用BFS解决。这里比较棘手的部分是做路径的BFS而不是单词。请按照以下步骤解决问题:
- 初始化一个变量,比如res ,以存储所有可能的最短路径。
- 创建一个 Set 来存储当前路径中所有访问过的词,一旦当前路径完成,擦除所有访问过的词。
- 对于每个当前单词,通过将每个字符从 ‘a’ 更改为 ‘z’ 并找到所有可能的路径,找到str[] 中可能出现的下一个单词。
- 最后,打印所有可能的路径。
C++
// C++ Program to implement
// 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 implement
# 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)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live