Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that:
- Only one letter can be changed at a time
- Each intermediate word must exist in the dictionary
Notice
- Return 0 if there is no such transformation sequence.
- All words have the same length.
- All words contain only lowercase alphabetic characters.
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
.
public int ladderLength(String start, String end, Set<String> dict)
算法:层级遍历的BFS. 1.while循环每一层 2. for循环层内每一个单词 3.对每个单词都二重循环 length() * 26,试着把每个位置都试着换成a-z里的每一种。 对这每一种可能都判断符合最终要求没?合格就溜啦。虽然不合格但不重复的话就加入备胎queue下次再试后续可能性了。
数据结构:Queue + Set + int size + int steps
细节:1.注意每次换字母不是很功利地把最终目标string身上对应位置的字母拿过来换,而是要26个字母都试着换换,万一你可以经过dict里迂回的路径到达目标呢? 2.换字母方法有时间复杂度区分。用substring拼接要开辟四次,很花时间,string想+的时候尽量别+,用StringBuilder, sb.append, sb.toString。还有一种做法是先转char[],数组里替换了后再转回去new String (char[])。 3.小心一下start == end的corner case,这时候应该返回1。
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 (dict == null || dict.size() == 0 || start == null || end == null || start.length() != end.length()) { return 0; } // 注意这个corner case if (start.equals(end)) { return 1; } Queue<String> queue = new LinkedList<String>(); Set<String> set = new HashSet<String>(); queue.offer(start); set.add(start); int steps = 2; while (!queue.isEmpty()) { int size = queue.size(); for (int i = 0; i < size; i++) { String string = queue.poll(); // 注意每次换字母不是只能换成end身上的!而是26个字母都可以换,不用那么功利直接往终点凑,可以往中间的词典词凑 for (int idx = 0; idx < string.length(); idx++) { for (char letter = 'a'; letter <= 'z'; letter++) { // 注意如果用A写法替换字母的话,过不了时间复杂度,BC可以 // A) // String newStr = string.substring(0,idx) + letter + string.substring(idx + 1, string.length()); // B) // char[] chars = string.toCharArray(); // chars[idx] = letter; // String newStr = new String(chars); // C) StringBuilder sb = new StringBuilder(); sb.append(string.substring(0,idx)); sb.append(letter); sb.append(string.substring(idx + 1, string.length())); String newStr = sb.toString(); if (newStr.equals(end)) { return steps; } else if (dict.contains(newStr) && !set.contains(newStr)) { queue.offer(newStr); set.add(newStr); } } } } steps++; } return 0; } }