Word Ladder

来源:互联网 发布:js获取所有data属性 编辑:程序博客网 时间:2024/06/04 19:05

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 time1. 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;     }}
0 0