Word Ladder

https://oj.leetcode.com/problems/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


1. 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.

题意:给定两个字符串,分别表示初始字符串和目标字符串,再给定一个set,要求每次只能变动一个字符,且变动后的字符串存在于set中,找出最短的转换次数

思路:
1、第一种方法,可以先根据两个字符传能否一次性转化列一个二维阵列,然后根据二维阵列进行BFS搜索最短路径。但如果这样做,算法复杂的最大的部分出现在形成二维阵列的时候,复杂度为O(n²),所以肯定会超时
2、把形成二位阵列的过程去掉,因为其实很多比较根本用不到,可以放到实际需要进行两个数组比较的时候再比较是否能否转换。还有就是每次进行比较的过程,如果一一进行比较,就算每次去重,复杂度也是O(n²)左右,所以可以直接把字符串中的字符逐个转换,然后检查新的字符串是否出现在dict中,对于字符数比较少的字符串来说,这样的复杂度比逐一比较小很多。

实现:

public class Solution {
      public int ladderLength(String start , String end, Set<String> dict ) {
           int i = 1, j = 0;
           class Node {
              String s; //表示当前的字符串
               int id ;//表示转化过程中当前字符串处在哪一位

               public Node(String s , int id) {
                    this .s = s ;
                    this .id = id ;
              }
          }
          Set<String> use = new HashSet<String>();//用来存放已入栈的字符串,防止重复入栈
          List<Node> stack = new LinkedList<Node>();//用来存放当前搜索过程的栈
           stack.add(0, new Node(start , 1));//把第一个,也就是start入栈,作为第一个查询的元素
           use.add( start);
          Node node;
          String s;
           int id ;
           while (!stack .isEmpty()) { //直到栈空,表示没有可以了连接的下一个元素了,查找失败
               node = stack.get(0);
               s = node. s;
               id = node. id;
               stack.remove(0);
               for (i = 0; i < s .length(); i++) { //把当前栈顶元素的每一位进行转化,依次转化成a-z中的任意一个,然后与 dict中的其他元素比较,如果存在该元素,表示可以转化,入栈。
                    for (char k = 'a' ; k < 'z' ; k ++) {
                         if (s .charAt(i ) == j )
                              continue ;

                        StringBuilder sb = new StringBuilder(s );
                         sb.setCharAt( i, k);

                         if (sb .toString().equals(end ))//如果栈顶元素经过一次转化就可以得到目标字符串,则表示查找成功
                              return id + 1;

                         if (dict .contains( sb.toString())
                                  && !use .contains(sb .toString())) { //要保证一次转化后的元素出现在 dict中,而且曾经没有入栈过,才可以入栈
                              stack.add( new Node(sb .toString(), id + 1));
                              use.add( sb.toString()); //把当前入栈元素保存到use中,防止以后重复入栈,造成死循环
                        }
                   }
              }
          }
           return 0;
     }

}

转载于:https://my.oschina.net/u/3099393/blog/798343

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值