给了A、B两个单词和一个单词集合Dict,每个的长度都相同。我们希望通过若干次操作把单词A变成单词B,
每次操作可以改变单词中的一个字母,同时,新产生的单词必须是在给定的单词集合Dict中。
求所有行得通步数最少的修改方法。
Given:
A = "hit"
B = "cog"
Dict = ["hot","dot","dog","lot","log"]
Return
[
["hit","hot","dot","dog","cog"],
["hit","hot","lot","log","cog"]
]
把字符串A = "hit"转变成字符串B = "cog",有以下两种可能:
"hit" -> "hot" -> "dot" -> "dog" -> "cog";
"hit" -> "hot" -> "lot" -> "log" ->"cog"。
效率是个问题,改进中。
思路是拿字典里的单词不断的与已经保存成功的比较,如果符合相差一个字母的要求,则加在已保存的other中.
根本没考虑啥效率问题。还得再想好办法
class Solution
{
public:
vector<vector<string>> findLadders(string start, string end, set<string>& dict)
{
m_DictHead = NULL;
vector<vector<string>> ret;
if(start == end)
return ret;
if(isMatch(start,end)){
vector<string> vs;
vs.push_back(start);
vs.push_back(end);
ret.push_back(vs);
return ret;
}
AddWord(start,end);
for(set<string>::iterator it=dict.begin();it!=dict.end();it++){
if((*it)!=start && (*it)!=end)
AddWord(*it,end);
}
bool breput=true;
int oldsize=-1;
while(breput){ //处理没有匹配上的
if(m_vectorWait.size() == 0)
break;
if(oldsize == m_vectorWait.size())
break;
oldsize = m_vectorWait.size();
vector<string> vectorDelete;
for(vector<string>::iterator it = m_vectorWait.begin();it!=m_vectorWait.end();it++){
if(AddWord(*it,end)){
breput = true;
vectorDelete.push_back(*it);
}
}
for(unsigned int i=0;i<vectorDelete.size();i++){
for (vector<string>::iterator it=m_vectorWait.begin();it!=m_vectorWait.end();it++){
if(vectorDelete[i]==(*it)){
m_vectorWait.erase(it);
break;
}
}
}
}
if(!AddWord(end,end))
return ret;
unsigned int min=UINT_MAX;
for(unsigned int i=0;i<m_FindResult.size();i++){
if(m_FindResult[i].size()<min){
min = m_FindResult[i].size();
ret.clear();
ret.push_back(m_FindResult[i]);
}else if(m_FindResult[i].size() == min)
{
ret.push_back(m_FindResult[i]);
}
}
for (unsigned int i=0;i<ret.size();i++){
unsigned int j=0;
unsigned int k=ret[i].size()-1;
while(j<k)
swap(ret[i][j++],ret[i][k--]);
}
return ret;
}
~Solution(){
stack<s_dict*> nodeBuffer;
s_dict* pNode = m_DictHead;
nodeBuffer.push(pNode);
bool bmatch = false;
while (!nodeBuffer.empty()){
s_dict* node = nodeBuffer.top();
nodeBuffer.pop();
if(node->dict_other.size()!=0){
for (vector<s_dict*>::iterator it = node->dict_other.begin();
it!=node->dict_other.end();it++){
nodeBuffer.push(*it);
}
}
delete node;
}
}
private:
bool isMatch(string str1,string str2)
{
int ncount=0;
for(unsigned int i=0;i<str1.length();i++)
{
if(str1[i]!=str2[i])
ncount++;
if(ncount>=2)
break;
}
return ncount==1?true:false;
}
bool AddWord(string strWord,string end)
{
if(m_DictHead == NULL){
m_DictHead=new s_dict;
m_DictHead->dict_word = strWord;
return true;
}
stack<s_dict*> nodeBuffer;
s_dict* pNode = m_DictHead;
nodeBuffer.push(pNode);
bool bmatch = false;
while (!nodeBuffer.empty()){
s_dict* node = nodeBuffer.top();
nodeBuffer.pop();
if(node->dict_other.size()!=0){
for (vector<s_dict*>::iterator it = node->dict_other.begin();
it!=node->dict_other.end();it++){
nodeBuffer.push(*it);
}
}
if(isMatch(node->dict_word,strWord)){
bmatch = true;
s_dict* temp=new s_dict;
temp->dict_parent = node;
temp->dict_word = strWord;
node->dict_other.push_back(temp);
if(strWord == end){
s_dict* pNext = temp;
vector<string> vecttemp;
do{
vecttemp.push_back(pNext->dict_word);
pNext = pNext->dict_parent;
}while(pNext->dict_parent!=NULL);
vecttemp.push_back(pNext->dict_word);
m_FindResult.push_back(vecttemp);
}
}
}
if(!bmatch){
unsigned int i=0;
for(i=0;i<m_vectorWait.size();i++){
if(m_vectorWait[i] == strWord)
break;
}
if(i == m_vectorWait.size())
m_vectorWait.push_back(strWord);
}
return bmatch;
}
vector<string> m_vectorWait;
vector<vector<string>> m_FindResult;
struct s_dict{
string dict_word;
s_dict* dict_parent;
vector<s_dict*> dict_other;
s_dict(){dict_parent=NULL;}
};
s_dict* m_DictHead;
};