您的位置:首页 > 其它

【Leetcode】Word Ladder II (Backtracking)

2014-11-14 01:34 344 查看
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.

这道题也是一道非常恶心的题,巨多繁琐的操作,严格的时间限制。别的不说了,直接上代码吧

public static ArrayList<ArrayList<String>> findLadders(String start,
String end, HashSet<String> dict) {

ArrayList<ArrayList<String>> result = new ArrayList<ArrayList<String>>();// results
int currLen = 0;
boolean found = false;

/**
* we need a hash set to store all unVisited words
*/

Set<String> unVisited = new HashSet<String>(dict);
unVisited.add(end);

/**
* <String, Queue> contain all the adjacent words that is discover in
* its previous level
*/

HashMap<String, Queue<String>> adjMap = new HashMap<String, Queue<String>>();
for (String word : unVisited)
adjMap.put(word, new LinkedList<String>());

/**
* we need a queue to do BFS
*/

Queue<String> queue = new LinkedList<String>();
queue.add(start);

/**
* we need a hashset to store all words at the same level
*/
Set<String> visitedThisLev = new HashSet<String>();
int currLev = 1;
int nextLev = 0;

/**
* Now begin BFS and try to finish adjMap which is stored for all
* unvisited words that are one character change from current word
*/

while (!queue.isEmpty()) {
String curLadder = queue.poll();
currLev--;

for (String nextLadder : getNextLadder(curLadder, unVisited)) {
if (visitedThisLev.add(nextLadder)) {
nextLev++;
queue.add(nextLadder);
}
adjMap.get(nextLadder).add(curLadder);

if (nextLadder.equals(end) && !found) {
found = true;
currLen += 2;
}
}

if (currLev == 0) {
if (found)
break;
unVisited.removeAll(visitedThisLev);
currLev = nextLev;
nextLev = 0;
currLen++;
}
}

/**
* if we find the path, we can construct the path now!
*/

if (found) {
LinkedList<String> p = new LinkedList<String>();
p.addFirst(end);
getLadders(start, end, p, result, adjMap, currLen);
}
return result;
}

// get all unvisited words that are one character change from current word
private static ArrayList<String> getNextLadder(String curLadder,
Set<String> unVisited) {
ArrayList<String> nextLadders = new ArrayList<String>();
StringBuffer replace = new StringBuffer(curLadder);
for (int i = 0; i < curLadder.length(); i++) {
char old = replace.charAt(i);
for (char ch = 'a'; ch <= 'z'; ch++) {
replace.setCharAt(i, ch);
String replaced = replace.toString();
if (ch != curLadder.charAt(i) && unVisited.contains(replaced)) {
nextLadders.add(replaced);
}
}
replace.setCharAt(i, old);
}
return nextLadders;
}

// DFS to get all possible path from start to end
private static void getLadders(String start, String curLadder,
LinkedList<String> p, ArrayList<ArrayList<String>> result,
HashMap<String, Queue<String>> adjMap, int length) {
if (curLadder.equals(start)) {
result.add(new ArrayList<String>(p));
} else if (length > 0) {
Queue<String> adjs = adjMap.get(curLadder);
for (String lad : adjs) {
p.addFirst(lad);
getLadders(start, lad, p, result, adjMap, length - 1);
p.removeFirst();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: