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