LeetCode :Word Ladder II My Solution


Word Ladder II

 Total Accepted: 11755 Total Submissions: 102776My Submissions

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.
这个题目着有用了不少时间,中间做了两个取巧的处理:

1.把end放到dict里面这种优点就是在BFS建立图的时候 能够直接获取end的前继,全部.这样能够降低最后处理的麻烦

2.把dfs中处理进行优化,能够直接处理到当前继没有的时候,这个时候最后一个节点一定是start

3.中间建立一个MAP map中保存不同的str相应的前继

4.假设一个串被发现了,那么要看一下是不是distance和之前的str差一个,这个是为了保证不出现绕环

5.对str的每一位做变换,使时间复杂度下来.而刚開始的时候是比較有一个位不同样,可是对海量的处理的时候反而会减少速度.

6.对最后结果要把新的放在0位,oneAnswer.add(0,end).由于是从后往前扫


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

		if (start == null || end == null || start.length() != end.length()) {
			return result;
		}
		Map<String, MyNode> map = new HashMap<String, MyNode>();
		Queue<String> queue = new LinkedList<String>();
		queue.offer(start);
		map.put(start, new MyNode(start, 1));
		while (!queue.isEmpty()) {
			String cur = queue.poll();

			if (reachEnd(cur, end)) {
				outputResult(end, new ArrayList<String>(), map, result);
				return result;
			}

			for (int i = 0; i < cur.length(); i++) {
				for (char c = 'a'; c <= 'z'; c++) {
					String changeStr = getOneDiff(cur, i, c);

					if (dict.contains(changeStr)) {
						MyNode curNode = map.get(cur);
						int curDist = curNode.distance;
						int newDist = curDist + 1;

						if (!map.containsKey(changeStr)) {
							MyNode newNode = new MyNode(changeStr, newDist);
							newNode.pre.add(curNode);
							queue.offer(changeStr);

							map.put(changeStr, newNode);

						} else {
							MyNode preNode = map.get(changeStr);
							int preDist = preNode.distance;
							if (newDist == preDist) {
								preNode.pre.add(curNode);
							}
						}
					}
				}
			}
		}
		return result;

	}

	private void outputResult(String end, ArrayList<String> oneAnswer,
			Map<String, MyNode> map, ArrayList<ArrayList<String>> result) {

		MyNode curNode = map.get(end);
		oneAnswer.add(0, end);
		if (curNode.pre.isEmpty()) {
			result.add(new ArrayList<String>(oneAnswer));
			return;
		}
		for (MyNode eachNode : curNode.pre) {
			outputResult(eachNode.val, oneAnswer, map, result);
			oneAnswer.remove(0);
		}
	}

	private void getPaths(MyNode myNode, Map<String, MyNode> map,
			ArrayList<String> curPath, ArrayList<ArrayList<String>> paths) {
		if (myNode == null) {
			paths.add(curPath);
			return;
		}

		curPath.add(0, myNode.val);
		if (!myNode.pre.isEmpty()) {
			for (MyNode prevNode : myNode.pre) {
				getPaths(prevNode, map, new ArrayList<String>(curPath), paths);
			}
		} else {
			getPaths(null, map, curPath, paths);
		}
	}

	boolean reachEnd(String left, String right) {
		if (left.equals(right)) {
			return true;
		}
		return false;
	}

	String getOneDiff(String str, int pos, char c) {
		StringBuffer sb = new StringBuffer(str);
		sb.setCharAt(pos, c);
		return sb.toString();
	}

}

class MyNode {
	String val;
	int distance;
	LinkedList<MyNode> pre;

	MyNode(String v, int distance) {
		this.val = v;
		this.distance = distance;
		pre = new LinkedList<MyNode>();

	}

	void addPre(MyNode p) {
		pre.add(p);
	}
}



不得不说,这个题做的确实痛苦,可是做AC了之后感觉非常爽!

也不知道各位大神有什么更好的办法,反正我做的时候确实感觉到非常挑战,但非常有意思.

过瘾!

posted @ 2016-02-04 18:52  mfrbuaa  阅读(179)  评论(0编辑  收藏  举报