LeetCode 126 Word Ladder II

本文介绍了一种算法,用于寻找两个单词之间的最短转换路径。利用广度优先搜索(BFS)建立路径映射,并通过深度优先搜索(DFS)找出所有可能的最短路径。适用于单词长度相同且仅允许每次更改一个字母的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:

  1. Only one letter can be changed at a time
  2. Each intermediate word must exist in the word list

For example,

Given:
beginWord = "hit"
endWord = "cog"
wordList = ["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.

Runtime: 28 ms beats 99.16% of java submissions.

先用HashMap<String, ArrayList<String>> map 通过bfs广度优先,存下最短路径的形成过程,map类似于一个有起点和终点的图,然后dfs深度优先,寻找起点到终点的具体路径。

	public List<List<String>> findLadders(String beginWord, String endWord, Set<String> wordList) {
		HashMap<String, ArrayList<String>> map = new HashMap();
		Set<String> start = new HashSet(), end = new HashSet();
		start.add(beginWord);
		end.add(endWord);
		BFS(start, end, wordList, map, true);
		List<List<String>> result = new ArrayList();
		List<String> cur = new ArrayList();
		cur.add(beginWord);
		DFS(beginWord, endWord, map, cur, result);
		return result;
	}


	private void BFS(Set<String> start, Set<String> end, Set<String> wordList, HashMap<String,
			ArrayList<String>> map, boolean forward) {
		if (start.size() > end.size()) {//为了提高效率 
			BFS(end, start, wordList, map, !forward);//forward 是正向,还是从end开始反向
			return;
		}
		wordList.removeAll(start);
		wordList.removeAll(end);
		boolean connected = false;
		Set<String> set = new HashSet();
		for (String s : start) {
			char[] chars = s.toCharArray();
			for (int i = 0, len = chars.length; i < len; i++) {
				char ch = chars[i];
				for (char x = 'a'; x <= 'z'; x++) {
					chars[i] = x;
					String word = new String(chars);
					if (end.contains(word) || (!connected && wordList.contains(word))) {
						if (end.contains(word)) connected = true;//找到最短的梯子,结束递归
						else set.add(word);
						if (forward) {
							ArrayList<String> cur = map.getOrDefault(s, new ArrayList<>());
							cur.add(word);
							map.put(s, cur);
						} else {
							ArrayList<String> cur = map.getOrDefault(word, new ArrayList<>());
							cur.add(s);
							map.put(word, cur);
						}
					}
					chars[i] = ch;
				}
			}
		}
		if (!connected && !set.isEmpty())
			BFS(set, end, wordList, map, forward);
	}

	private void DFS(String start, String end, HashMap<String, ArrayList<String>> map, List<String>
			cur, List<List<String>> result) {
		if (start.equals(end)) {
			result.add(new ArrayList(cur));//此处必须new ArrayList,因为cur是形参,会在递归中变化
			return;
		}
		if (!map.containsKey(start)) return;
		List<String> next = map.get(start);
		for (String i : next) {
			cur.add(i);
			DFS(i, end, map, cur, result);
			cur.remove(cur.size() - 1);
		}
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值