Word Ladder

https://oj.leetcode.com/problems/word-ladder/node

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:markdown

start = 「hit」ui

end = 「cog」this

dict = [「hot」,」dot」,」dog」,」lot」,」log」]spa

As one shortest transformation is 「hit」 -> 「hot」 -> 「dot」 -> 「dog」 -> 「cog」,code

return its length 5.orm

Note:leetcode

* Return 0 if there is no such transformation sequence.


* All words have the same length.


* All words contain only lowercase alphabetic characters.

題意:給定兩個字符串,分別表示初始字符串和目標字符串,再給定一個set,要求每次只能變更一個字符,且變更後的字符串存在於set中,找出最短的轉換次數

思路:
一、第一種方法,能夠先根據兩個字符傳可否一次性轉化列一個二維陣列,而後根據二維陣列進行BFS搜索最短路徑。但若是這樣作,算法複雜的最大的部分出如今造成二維陣列的時候,複雜度爲O(n²),因此確定會超時
二、把造成二位陣列的過程去掉,由於其實不少比較根本用不到,能夠放到實際須要進行兩個數組比較的時候再比較是否可否轉換。還有就是每次進行比較的過程,若是一一進行比較,就算每次去重,複雜度也是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;
     }

}
相關文章
相關標籤/搜索