首页 > 其他 > 详细

LeetCode | Word Ladder II

时间:2014-02-22 14:36:40      阅读:340      评论:0      收藏:0      [点我收藏+]

题目

Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:

  1. Only one letter can be changed at a time
  2. 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.
分析

整个过程可以分成两个部分:先通过BFS从start找到end,在找的过程中需要记录前驱单词,再用DFS反向找回完整路径。

但是用Java实现上述过程会遇到TLE。为了能让用时尽可能短,有如下几点需要注意的地方:

1. 由于最后生成路径的时候,需要从end找到start构造ArrayList,即使用LinkList来协助构造,性能也不好。解决办法:不从start找end了,反过来从end找start,找到后,再从start往end构造路径,性能会有明显提升。

2. 在BFS过程中,需要替换String的每一位字符,先转换成char数组再操作,性能也会有明显提升。

3. 在BFS过程中,注意避免一些不必要的搜索,具体细节参考如下代码。

最终在LeetCode测试中,Java实现达到了800ms用时。

此外,双向BFS也可以用来提升性能,而且效果会十分显著,这里没有具体实现。

代码

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;

public class WordLadderII {
	class WordWithLevel {
		String word;
		int level;

		public WordWithLevel(String word, int level) {
			this.word = word;
			this.level = level;
		}
	}

	private String end;
	private ArrayList<ArrayList<String>> result;
	private Map<String, List<String>> nextMap;

	public ArrayList<ArrayList<String>> findLadders(String start, String end,
			HashSet<String> dict) {
		result = new ArrayList<ArrayList<String>>();
		this.end = end;

		// unvisited words set
		Set<String> unVisited = new HashSet<String>();
		unVisited.addAll(dict);
		unVisited.add(start);
		unVisited.remove(end);

		// used to record the map info of <word : the words of next level>
		nextMap = new HashMap<String, List<String>>();
		for (String e : unVisited) {
			nextMap.put(e, new ArrayList<String>());
		}

		// BFS to search from the end to start
		Queue<WordWithLevel> queue = new LinkedList<WordWithLevel>();
		queue.add(new WordWithLevel(end, 0));
		boolean found = false;
		int finalLevel = Integer.MAX_VALUE;
		int currentLevel = 0;
		int preLevel = 0;
		Set<String> visitedWordsInThisLevel = new HashSet<String>();
		while (!queue.isEmpty()) {
			WordWithLevel wordWithLevel = queue.poll();
			String word = wordWithLevel.word;
			currentLevel = wordWithLevel.level;
			if (found && currentLevel > finalLevel) {
				break;
			}
			if (currentLevel > preLevel) {
				unVisited.removeAll(visitedWordsInThisLevel);
			}
			preLevel = currentLevel;
			char[] wordCharArray = word.toCharArray();
			for (int i = 0; i < word.length(); ++i) {
				char originalChar = wordCharArray[i];
				boolean foundInThisCycle = false;
				for (char c = ‘a‘; c <= ‘z‘; ++c) {
					wordCharArray[i] = c;
					String newWord = new String(wordCharArray);
					if (c != originalChar && unVisited.contains(newWord)) {
						nextMap.get(newWord).add(word);
						if (newWord.equals(start)) {
							found = true;
							finalLevel = currentLevel;
							foundInThisCycle = true;
							break;
						}
						if (visitedWordsInThisLevel.add(newWord)) {
							queue.add(new WordWithLevel(newWord,
									currentLevel + 1));
						}
					}
				}
				if (foundInThisCycle) {
					break;
				}
				wordCharArray[i] = originalChar;
			}
		}

		if (found) {
			// dfs to get the paths
			ArrayList<String> list = new ArrayList<String>();
			list.add(start);
			getPaths(start, list, finalLevel + 1);
		}
		return result;
	}

	private void getPaths(String currentWord, ArrayList<String> list, int level) {
		if (currentWord.equals(end)) {
			result.add(new ArrayList<String>(list));
		} else if (level > 0) {
			List<String> parentsSet = nextMap.get(currentWord);
			for (String parent : parentsSet) {
				list.add(parent);
				getPaths(parent, list, level - 1);
				list.remove(list.size() - 1);
			}
		}
	}
}


LeetCode | Word Ladder II

原文:http://blog.csdn.net/perfect8886/article/details/19645691

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!