【Leetcode】Word Ladder II (Backtracking)

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.

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

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值