lintcode 单词接龙II
題意
給出兩個(gè)單詞(start和end)和一個(gè)字典,找出所有從start到end的最短轉(zhuǎn)換序列
比如:
1、每次只能改變一個(gè)字母。
2、變換過程中的中間單詞必須在字典中出現(xiàn)。
注意事項(xiàng)
- 所有單詞具有相同的長度。
- 所有單詞都只包含小寫字母。
樣例
給出數(shù)據(jù)如下:
start =?"hit"
end =?"cog"
dict =?["hot","dot","dog","lot","log"]
返回
[
? ? ["hit","hot","dot","dog","cog"],
? ? ["hit","hot","lot","log","cog"]
? ]
?
解題思路
根據(jù)每兩個(gè)單詞是否只差一個(gè)字母,進(jìn)行建圖,然后如下。
1.深搜 + 回溯 + 記憶化(記錄每個(gè)節(jié)點(diǎn)到 終結(jié)點(diǎn) 的最短轉(zhuǎn)換序列),超時(shí)啦。。。
2.通過廣搜 計(jì)算出終結(jié)點(diǎn)到各個(gè)節(jié)點(diǎn)的最短距離(包括源節(jié)點(diǎn)到終結(jié)點(diǎn)的最短距離,也就是和 最短轉(zhuǎn)換序列的長度對(duì)應(yīng))
public class Solution {/*** @param start, a string* @param end, a string* @param dict, a set of string* @return a list of lists of string*/public List<List<String>> findLadders(String start, String end, Set<String> dict) {// write your code hereMap<String, List<String>> g = new HashMap<>();Set<String> words = new HashSet<>(dict);words.add(start);words.add(end);String[] wordArray = words.toArray(new String[0]);for (int i = 0; i < wordArray.length - 1; ++i) {for (int j = i + 1; j < wordArray.length; ++j) {String first = wordArray[i], second = wordArray[j];if (this.wordDiffCnt(first, second) == 1) {if (!g.containsKey(first)) {List<String> newList = new ArrayList<>();g.put(first, newList);}g.get(first).add(second);if (!g.containsKey(second)) {List<String> newList = new ArrayList<>();g.put(second, newList);}g.get(second).add(first);}}}resultMap = new HashMap<>();visit = new HashSet<>();// return dfs(g, start, end);//超時(shí)了,不知道怎么優(yōu)化 List<List<String>> result = new ArrayList<>();dist = new HashMap<>();dfs(result, new LinkedList<String>(), g, start, end, bfs(g, end, start));return result;}//通過bfs計(jì)算 終結(jié)點(diǎn) 到 源結(jié)點(diǎn) 的最短轉(zhuǎn)換長度,以及 終結(jié)點(diǎn)到各個(gè)結(jié)點(diǎn)的最短距離(在通過 dfs尋找 最短轉(zhuǎn)換序列的時(shí)候用到)private Map<String, Integer> dist;private int bfs(Map<String, List<String>> g, String start, String end) {Queue<String> queue = new LinkedList<>();visit.add(start);queue.add(start);dist.put(start, 1);int minLen = 0;while(!queue.isEmpty()) {start = queue.poll();if(start.equals(end)) {if(minLen == 0) {minLen = dist.get(start);}}if(g.containsKey(start)) {for (String next : g.get(start)) {if(visit.contains(next)) continue;visit.add(next);queue.add(next);dist.put(next, dist.get(start)+1);}}}visit.clear();return minLen;}private void dfs(List<List<String>> result, List<String> tmp, Map<String, List<String>> g, String start, String end, int minLen) {if(tmp.size()+dist.get(start)-1 >= minLen) return;if (start.equals(end)) {result.add(new ArrayList<>(tmp));result.get(result.size() - 1).add(end);return;}visit.add(start);tmp.add(start);if (g.containsKey(start)) {for (String next : g.get(start)) {if(visit.contains(next)) continue;dfs(result, tmp, g, next, end, minLen);}}visit.remove(start);tmp.remove(tmp.size()-1);}@Deprecatedprivate List<List<String>> dfs(Map<String, List<String>> g, String start, String end) {List<List<String>> result = new ArrayList<>();if (start.equals(end)) {List<String> list = new ArrayList<>();list.add(end);result.add(list);resultMap.put(end, result);return result;}if (resultMap.containsKey(start)) {return resultMap.get(start);}if (!g.containsKey(start)) {resultMap.put(start, null);return null;}visit.add(start);List<List<String>> nextResult = new ArrayList<>();int minLen = Integer.MAX_VALUE;for (String next : g.get(start)) {if(visit.contains(next)) continue;List<List<String>> tmp = dfs(g, next, end);if (tmp != null) {for (List<String> list : tmp) {if(minLen > list.size()) minLen = list.size();nextResult.add(list);}}}visit.remove(start);for (List<String> list : nextResult) {if (list.size() == minLen) {List<String> tmp = new LinkedList<>(list);tmp.add(0, start);result.add(tmp);}}if(result.size() > 0) {resultMap.put(start, result);}return result;}//記憶化搜索 每個(gè)節(jié)點(diǎn)到終點(diǎn)的最小步數(shù)的路徑private Map<String, List<List<String>>> resultMap;//每個(gè)節(jié)點(diǎn)的訪問的情況private Set<String> visit;private int wordDiffCnt(String s1, String s2) {int diffCnt = 0;for (int i = 0; i < s1.length(); ++i) {if (s1.charAt(i) != s2.charAt(i)) {++diffCnt;}}return diffCnt;} }?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/hujunzheng/p/7327101.html
總結(jié)
以上是生活随笔為你收集整理的lintcode 单词接龙II的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面包的家常做法?
- 下一篇: n个结点,不同形态的二叉树(数目+生成)