赞
踩
- 给定一个起始字符串和一个终止字符串,以及一个单词表,求是否可以将起始字符串酶促改一个字符,
- 直到改成终止字符串,且所有中间的修改过程表示的字符串都可以在单词表里面找到.若存在,输出
- 需要修改次数最少的所有更改方式.
-
- 示例 1
- Input:beginWord="hit",endWord="cog",wordList=["hot","dot","lot","log","cog"]
- Output:[["hit","hot","dog","cog"],
- ["hit","hot",log","cog"]]
- 解题思路:
- 我们可以把起始字符串,终止字符串,以及单词表里面所有的字符串想象成节点.若两个字符串只有一个字符不同,
- 那么它们相连.因为题目需要输出修改次数最少的所有修改方式,因此可以使用广度优先搜索,求得起始节点到
- 终止节点的最短距离.
- 同时还使用一个小技巧:并不是直接从起始节点进行广度优先搜索,直到找到终止节点为止:而是从起始节点和
- 终止节点分别进行广度优先搜索,每次只延展当前层节点数最少的那一端,这样可以减少搜索的总结点数.举例来说,
- 假设最短距离为4,如果只从一端搜索4层,总遍历节点数最多是1+2+4+8+16=31;而如果从两端各搜索两层,总
- 遍历节点数最多只有2x(1+2+4)=14;
- 在搜索结束后,还需要通过回溯法来重建所有可能的路径.
- #include <iostream>
- #include <vector>
- #include <unordered_set>
- #include <unordered_map>
- #include <algorithm>
-
- using namespace std;
-
- class Solution{
- public:
- vector<vector<string>> findLadders(string beginWord,string endWord,vector<string>& wordList){
- vector<vector<string>> ans;
- unordered_set<string> dict;
- for(const auto&w:wordList)
- dict.insert(w);
- if(!dict.count(endWord))/*set容器查找,返回0或者1*/
- return ans;
- dict.erase(beginWord);
- dict.erase(endWord);
- unordered_set<string> q1{beginWord},q2{endWord};
- unordered_map<string,vector<string>> next;
- bool reversed=false,found=false;
- /*广度优先遍历*/
- while(!q1.empty()){
- unordered_set<string> q;
- for(const auto&w:q1){
- string s=w;
- for(size_t i=0;i<s.size();i++){
- char ch=s[i];
- for(size_t j=0;j<26;j++){
- s[i]=j+'a';
- if(q2.count(s)){
- reversed?next[s].push_back(w):next[w].push_back(s);
- found=true;
- }
- if(dict.count(s)){
- reversed?next[s].push_back(w):next[w].push_back(s);
- cout<<s<<endl;
- q.insert(s);
- }
- }
- s[i]=ch;
- }
- }
- if(found){
- break;
- }
- for(const auto& w:q){
- dict.erase(w);
- }
- if(q.size()<=q2.size()){
- q1=q;
- }else{
- reversed=!reversed;
- q1=q2;
- q2=q;
- }
- }
- /*回溯符合条件的路径*/
- if(found){
- vector<string> path={beginWord};
- backtrack(beginWord,endWord,next,path,ans);
- }
- return ans;
- }
-
- private:
- void backtrack(const string& src,const string& dst,unordered_map<string,
- vector<string>>&next,vector<string>&path,vector<vector<string>>& ans){
- if(src==dst){
- ans.push_back(path);
- return;
- }
- for(const auto&s:next[src]){
- path.push_back(s);
- backtrack(s,dst,next,path,ans);
- path.pop_back();
- }
- }
- };
-
- int main(int argc,char* argv[]){
- string beginWord="hit",endWord="cog";
- vector<string> wordList={"hot","dot","lot","log","cog"};
- vector<vector<string>> ans=Solution().findLadders(beginWord,endWord,wordList);
- for_each(ans.begin(),ans.end(),[](vector<string>& res){
- cout<<"[ ";
- for(const auto&i:res)
- cout<<i<<" ";
- cout<<"]";
- });
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。