[程序员面试金典]1001.字符串变换
2015-08-11 22:34
489 查看
题目描述
现有一个字典,同时给定字典中的两个字符串s和t,给定一个变换,每次可以改变字符串中的任意一个字符,请设计一个算法,计算由s变换到t所需的最少步数,同时需要满足在变换过程中的每个串都是字典中的串。
给定一个string数组dic,同时给定数组大小n,串s和串t,请返回由s到t变换所需的最少步数。若无法变换到t则返回-1。保证字符串长度均小于等于10,且字典中字符串数量小于等于500。
测试样例:
[“abc”,”adc”,”bdc”,”aaa”],3,”abc”,”bdc”
返回:2
思路
最短搜索路径,所以是广度优先搜索(BFS)。
按照定义,存在一个字母差异的单词为邻居,因此采用逐位替换字母并查找字典的方法寻找邻居。
对队列中的每个单词记录路径长度。queue
现有一个字典,同时给定字典中的两个字符串s和t,给定一个变换,每次可以改变字符串中的任意一个字符,请设计一个算法,计算由s变换到t所需的最少步数,同时需要满足在变换过程中的每个串都是字典中的串。
给定一个string数组dic,同时给定数组大小n,串s和串t,请返回由s到t变换所需的最少步数。若无法变换到t则返回-1。保证字符串长度均小于等于10,且字典中字符串数量小于等于500。
测试样例:
[“abc”,”adc”,”bdc”,”aaa”],3,”abc”,”bdc”
返回:2
思路
最短搜索路径,所以是广度优先搜索(BFS)。
按照定义,存在一个字母差异的单词为邻居,因此采用逐位替换字母并查找字典的方法寻找邻居。
对队列中的每个单词记录路径长度。queue
/*--------------------------------------- * 日期:2015-08-11 * 作者:SJF0115 * 题目:1001.字符串变换 * 来源:程序员面试金典 * 网址:http://www.nowcoder.com/practice/4818ae796bbc4a85a8cdd8e155c06d46?rp=4&ru=/ta/cracking-the-coding-interview -----------------------------------------*/ #include <iostream> #include <vector> #include <algorithm> #include <unordered_set> #include <queue> using namespace std; class Change { public: int countChanges(vector<string> dic, int n, string s, string t) { vector<string>::iterator ite = find(dic.begin(),dic.end(),s); int result = BFS(s,t,dic); if(ite != dic.end()){ --result; }//if return result; } private: int BFS(string start,string end,vector<string> &dict){ if(start == end){ return 0; }//if // 存放单词和单词所在层次 queue<pair<string,int> > q; q.push(make_pair(start,1)); // 判断是否访问过 vector<string> visited; visited.push_back(start); while(!q.empty()){ pair<string,int> cur = q.front(); q.pop(); string word = cur.first; int size = word.size(); // 穷尽所有可能的变换 for(int i = 0;i < size;++i){ string newWord(word); // 每次只变换一个字符 有26种可能 for(int j = 0;j < 26;++j){ newWord[i] = 'a'+j; // 找到目标返回 if(newWord == end){ return cur.second + 1; }//if // 判断之前访问过或者是否在字典里 vector<string>::iterator ite = find(dict.begin(),dict.end(),newWord); vector<string>::iterator ite2 = find(visited.begin(),visited.end(),newWord); if(ite2 == visited.end() && ite != dict.end()){ visited.push_back(newWord); q.push(make_pair(newWord,cur.second+1)); }//if }//for }//for }//while return -1; } }; int main() { Change s; //vector<string> set = {"vvz","bbaa","f","bbba","bbaa","baoa","btoa","bbba","dcki","bbbb","ge","atoj","baaa","btoj","ae"}; vector<string> set = {"abc","adc","bdc","aaa"}; string start("abc"); string end("bdc"); int result = s.countChanges(set,5,start,end); // 输出 cout<<result<<endl; return 0; }
相关文章推荐
- 程序员装逼指南 (转)
- 黑马程序员——继承
- [程序员面试金典]1002.下一个较大元素
- 黑马程序员——self使用
- 黑马程序员——Java基础---常用类,基本类型包装类,正则表达式
- 【黑马程序员】protocol的概念及基本使用
- 黑马程序员——Java基础---IO、File类、Properties类、打印流、序列流(合并流)
- 黑马程序员——类方法与self关键字
- 码农成长篇——新员工怎样快速脱颖而出
- 黑马程序员 oc随记 协议与代理模式
- 程序员扩大影响力之如何写博客
- 黑马程序员
- 黑马程序员——弱语法与类方法
- 黑马程序员——封装
- 高效程序员的狂暴之路
- 高效程序员的狂暴之路
- 高效程序员的狂暴之路
- php常见的面试题目
- 新浪php面试题
- 黑马程序员——详细的类的声明和实现