您的位置:首页 > 其它

Word Ladder II | LeetCode

2014-10-22 22:09 288 查看
Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:

Only one letter can be changed at a time

Each intermediate word must exist in the dictionary

For example,

Given:
start =
"hit"

end =
"cog"

dict =
["hot","dot","dog","lot","log"]


Return

[
["hit","hot","dot","dog","cog"],
["hit","hot","lot","log","cog"]
]


Note:

All words have the same length.

All words contain only lowercase alphabetic characters.

  本题是求路径的,立刻会联想到两种比较常见的求路径的方法,深搜和广搜。使用深搜一般问题都会有递归的特质,当答案生成到一半时,就进行判断,抛弃不满足要求的答案,所以深搜会比暴力搜索法要快。本题的话,很难找到一个递归函数去求所有的解。因此我们选用广搜,一般广搜没有什么特征,如果是树或者是图,概率更大。求路径的长度,状态里面需要存路径的长度;如果是求路径本身或者动作序列,需要一棵树存储广搜过程中的路径,如果能够预估状态个数的上限,就开一个大数组,用树的双亲表示法。如果不能预估状态总数,则要用一棵通用的树。本题的话,我是使用了一个LinkedList来保存搜索过程中路径。除此之外,广搜需要一个队列,用于一层一层的扩展。在本题中,queue保存的是有效状态,用题目的给的条件举个具体的例子,queue最先保存的是“hit”,这也是我们所谓的第一层,接着往下继续执行,“hit”出队列,“hot”进队列,这是第二层,第三层queue里面就是{"dot","lot"}...我们用一个HashMap用于记录搜索过程中的中间状态,提高搜索的效率。最后,递归的将每一组有效的路径写进最后的数组中。

class Node
{
int level;
String value;
LinkedList<Node> prev;

public Node(int level, String value)
{
this.level = level;
this.value = value;
}

void addPrev(Node node)
{
if (prev == null || prev.size() == 0)
{
prev = new LinkedList<Node>();
}
prev.add(node);
}
}

public class Solution
{
ArrayList<ArrayList<String>> result = new ArrayList<ArrayList<String>>();

public void findPath(Node endNode, ArrayList<String> current, String start)
{
if (endNode.value.equals(start))
{
result.add(current);
return;
}

ArrayList<String> tempList;
for (Node node : endNode.prev)
{
tempList = new ArrayList<String>(current);
tempList.add(0, node.value);
findPath(node, tempList, start);
}
}

public ArrayList<ArrayList<String>> findLadders(String start, String end,
Set<String> dict)
{
HashMap<String, Node> hashMap = new HashMap<String, Node>();
Queue<Node> queue = new LinkedList<Node>();
Node node = new Node(0, start);
queue.add(node);
Node endNode = null;
hashMap.put(start, node);
boolean isFound = false;
boolean flag = false;
while (queue.size() > 0 && !isFound)
{
int queueLength = queue.size();
for (int k = 0; k < queueLength; k++)
{
node = queue.poll();
for (int i = 0; i < node.value.length(); i++)
{
StringBuilder word = new StringBuilder(node.value);
for (char j = 'a'; j <= 'z'; j++)
{
word.setCharAt(i, j);
if (word.toString().equals(end))
{
if (!flag)
{
Node temp = new Node(node.level + 1, word.toString());
flag = true;
temp.addPrev(node);
endNode = temp;
isFound = true;
}else {
endNode.addPrev(node);
isFound = true;
}
}
if (dict.contains(word.toString()))
{
Node newNode = hashMap.get(word.toString());
if (newNode == null)
{
Node addNode = new Node(node.level + 1,
word.toString());
addNode.addPrev(node);
hashMap.put(word.toString(), addNode);
queue.add(addNode);
} else
{
if (newNode.level == node.level + 1)
{
newNode.addPrev(node);
}
}
}
}
}
}
}
if (endNode != null )
{
findPath(endNode, new ArrayList<String>(Arrays.asList(end)),
start);
}
return result;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: