题目:单词接龙


给出两个单词(start和end)和一个字典,找到从start到end的最短转换序列

比如:


1.每次只能改变一个字母。

2.变换过程中的中间单词必须在字典中出现。

您在真实的面试中是否遇到过这个题?

Yes





样例

给出数据如下:

start = "hit"

end = "cog"

dict = ["hot","dot","dog","lot","log"]

一个最短的变换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog",

返回它的长度 5

注意

•如果没有转换序列则返回0。

•所有单词具有相同的长度。

•所有单词都只包含小写字母。
标签 Expand   



相关题目 Expand 

解题思路:

1.宽度优先搜索,BFS。超时。
public class Solution {
    /**
      * @param start, a string
      * @param end, a string
      * @param dict, a set of string
      * @return an integer
      */
    public int ladderLength(String start, String end, Set<String> dict) {
        // write your code here
        if (start.length() != end.length())
               return 0;
          Set<String> visited = new HashSet<>();
          visited.add(start);
          Queue<String> curQueue = new LinkedList<>();
          curQueue.add(start);
          int res = 0;
          while (curQueue != null&&curQueue.size()>0) {
               res++;
               Queue<String> nextQueue = new LinkedList<>();
               while(curQueue!=null&&curQueue.size()>0){
                    String curstr = curQueue.poll();
                    visited.add(curstr);
                    for(String dictstr:dict){
                         if(!visited.contains(dict)&&diffOneword(dictstr, curstr)){
                              if(diffOneword(end, curstr)){
                                   return res+1;
                              }
                              nextQueue.add(dictstr);
                         }
                    }
               }
               curQueue = nextQueue;
          }
          return 0;
     }
     public boolean diffOneword(String source, String s) {
          if (source.length() != s.length())
               return false;
          int count = 0;
          for (int i = 0; i < source.length(); i++) {
               if (source.charAt(i) != s.charAt(i)) {
                    count++;
               }
          }
          if (1 == count) {
               return true;
          } else {
               return false;
          }
    }
}
优化算法:在进行选择下一层节点时候,可以将该字符串的没一个字符修改为a-z,这样每次选择时候,时间复杂度是O(26*O(curstr.length)),没有优化时候是O(O(dict.length)*O(curstr.length))

public class Solution {
    /**
      * @param start, a string
      * @param end, a string
      * @param dict, a set of string
      * @return an integer
      */
    public int ladderLength(String start, String end, Set<String> dict) {
        // write your code here
        if (start == null || end == null || start.equals(end)
                    || start.length() != end.length()){
               return 0;
          }
          Queue<String> queue=new LinkedList<String>();
          HashMap<String,Integer> dist=new HashMap<String,Integer>();              
          queue.add(start);
          dist.put(start, 1);              
          while(!queue.isEmpty()){
               String head=queue.poll();                   
               int headDist=dist.get(head);
               //从每一个位置开始替换成a~z
               for(int i=0;i<head.length();i++){
                    for(char j='a';j<'z';j++){
                         if(head.charAt(i)==j) continue;                             
                         StringBuilder sb=new StringBuilder(head);
                         sb.setCharAt(i, j);                             
                         if(sb.toString().equals(end)) return headDist+1;                             
                         if(dict.contains(sb.toString())&&!dist.containsKey(sb.toString())){
                              queue.add(sb.toString());
                              dist.put(sb.toString(), headDist+1);
                         }
                    }
               }
          }
          return 0;
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值