题目来源:110. 字符串接龙
C++题解1:深度搜索。一条路径走到黑,并且记录到达当前节点的最短路径长度,不断更新,如果不是最短路径就不用再遍历那条路。
#include <iostream>
#include <vector>
#include <string>
#include <queue>
using namespace std;
void dfs(vector<string> &strList, vector<int> &visited, int m, int n){
if(n == strList.size()){ // 超出范围 返回
return;
}
if(strList[m].size() != strList[n].size()) return; // 长度不等 返回
if(strList[m] == strList[n]) return; // 循环遇到自己 返回
int count = 0;
for(int j = 0; j < strList[m].size(); j++){
if(strList[m][j] != strList[n][j]) count++;
if(count > 1) return; // 不止转变1个字符 返回
}
if(visited[n] < visited[m] + 1) return; // 路径比原来的大,不是最短路径 返回
else visited[n] = visited[m] + 1; // 路径比原来的小,符合要求,更新路径长度
for(int i = 1; i < strList.size(); i++){
dfs(strList, visited, n, i); // 寻找路径的头与尾,进行遍历
}
return;
}
int main(){
// 输入
int N; cin>>N;
vector<string> strList(N+2,"");
cin>>strList[0]>>strList[N+1];
if(strList[0].size() != strList[N+1].size()) {
cout<<0;
return 0;
}
for(int i = 1; i <= N; i++){
cin>>strList[i];
}
vector<int> visited(N+2, N+2); // 存放路径长度
visited[0] = 1; // 出发点长度为1
for(int i = 0; i < N+1; i++){
dfs(strList, visited, 0, i); // 从出发点开始遍历
}
if(visited[N+1] == N+2) cout<<0;
else cout<<visited[N+1];
return 0;
}
C++题解2:广度搜索(来源代码随想录)。它的循环是str的每个字符,每个字符的26个字母。
#include <iostream>
#include <vector>
#include <string>
#include <unordered_set>
#include <unordered_map>
#include <queue>
using namespace std;
int main() {
string beginStr, endStr, str;
int n;
cin >> n;
unordered_set<string> strSet;
cin >> beginStr >> endStr;
for (int i = 0; i < n; i++) {
cin >> str;
strSet.insert(str);
}
// 记录strSet里的字符串是否被访问过,同时记录路径长度
unordered_map<string, int> visitMap; // <记录的字符串,路径长度>
// 初始化队列
queue<string> que;
que.push(beginStr);
// 初始化visitMap
visitMap.insert(pair<string, int>(beginStr, 1));
while(!que.empty()) {
string word = que.front();
que.pop();
int path = visitMap[word]; // 这个字符串在路径中的长度
// 开始在这个str中,挨个字符去替换
for (int i = 0; i < word.size(); i++) {
string newWord = word; // 用一个新字符串替换str,因为每次要置换一个字符
// 遍历26的字母
for (int j = 0 ; j < 26; j++) {
newWord[i] = j + 'a';
if (newWord == endStr) { // 发现替换字母后,字符串与终点字符串相同
cout << path + 1 << endl; // 找到了路径
return 0;
}
// 字符串集合里出现了newWord,并且newWord没有被访问过
if (strSet.find(newWord) != strSet.end()
&& visitMap.find(newWord) == visitMap.end()) {
// 添加访问信息,并将新字符串放到队列中
visitMap.insert(pair<string, int>(newWord, path + 1));
que.push(newWord);
}
}
}
}
// 没找到输出0
cout << 0 << endl;
}