Word Ladder

Word Ladder

Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that:

  1. Only one letter can be changed at a time
  2. Each intermediate word must exist in the dictionary

For example,

Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]

As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.

Note:

  • Return 0 if there is no such transformation sequence.
  • All words have the same length.
  • All words contain only lowercase alphabetic characters.
题目:给两个长度相同的单词start、end,和一个词典,求通过dict中的单词,start变成end需要的最少步数。

分析:

1. 一开始觉得,hit 变到 cog,肯定是每次变化一个单词,距离len+1。只要判断每一种变化的可能是否在dict中即可。 忽略了字典中很多词可以作为中间状态,例如dog就与hit没有任何字母相同。

2. Google之,BST,广度优先遍历。start到end可以看做是 点到点的一条路径,而每变化一个单词可以看做是路径+1。

如例子中,hit作为第一层,第二层则是((a-z)it ∩ dict)∪(h(a-z)t ∩ dict) ∪(hi(a-z) ∩ dict)然后除去hit本身。注意end(即cog不需要在词典中)依次往下推,如果发现了end,则直接返回当前的distance即可。因为是层序遍历,所以当前路径保证是最小的。

注意:

1. 层序遍历用queue,每层过渡节点push到队列中后,对应的dict中的单词要删掉。因为不删掉会进入死循环,如hit -> hot->lot -> hot 每次改变一个单词,会变成它的前一个节点。

2. 每层的分界线,用""

代码:

class Solution {
public:
    int ladderLength(string start, string end, unordered_set<string> &dict) {//BFS 最短路径问题
        if(start==end) return 0;
        int len=start.size();
        queue<string> qu;
        qu.push(start);
        qu.push("");//标记每一层
        int distance=1;
        while(qu.size()>1 && dict.size()>0){//每层循环 
         //distance++;
          while(qu.front()!="" && dict.size()>0){//每层内一个个元素的循环
            string tmp=qu.front();
            qu.pop();
            
            for(int i=0;i<len;i++){
                string pusht=tmp;
                for(char t='a';t<='z';t++){//a-z依次试探,看是否在dict中
                    if(pusht[i]==t) continue;//tmp本身
                    pusht[i]=t;
                    if(pusht==end) return distance+1;//找到了 便是最短的 层序遍历
                    unordered_set<string>::const_iterator it=dict.find(pusht);
                    if(it!=dict.end()){//字典中有这个单词
                        qu.push(pusht);
                        dict.erase(it);//删除字典中对应的值
                    }
                    
                }//for t
            }//for i
            
          }//while
          qu.pop();//删除""
          if(qu.empty()) return 0;
          else distance++;
          qu.push("");
        
    } //层while 
        return 0;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值