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; } }