题意

  给出两个单词(start和end)和一个字典,找出所有从start到end的最短转换序列

  比如:

    1、每次只能改变一个字母。

    2、变换过程中的中间单词必须在字典中出现。

注意事项

  • 所有单词具有相同的长度。
  • 所有单词都只包含小写字母。

样例

  给出数据如下:

  start = "hit"

  end = "cog"

  dict = ["hot","dot","dog","lot","log"]

  返回

  [

      ["hit","hot","dot","dog","cog"],

      ["hit","hot","lot","log","cog"]

  ]

解题思路

  根据每两个单词是否只差一个字母,进行建图,然后如下。

  1.深搜 + 回溯 + 记忆化(记录每个节点到 终结点 的最短转换序列),超时啦。。。

  2.通过广搜 计算出终结点到各个节点的最短距离(包括源节点到终结点的最短距离,也就是和 最短转换序列的长度对应)

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 here
Map<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);//超时了,不知道怎么优化 List<List<String>> result = new ArrayList<>();
dist = new HashMap<>();
dfs(result, new LinkedList<String>(), g, start, end, bfs(g, end, start));
return result;
} //通过bfs计算 终结点 到 源结点 的最短转换长度,以及 终结点到各个结点的最短距离(在通过 dfs寻找 最短转换序列的时候用到)
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);
} @Deprecated
private 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;
} //记忆化搜索 每个节点到终点的最小步数的路径
private Map<String, List<List<String>>> resultMap;
//每个节点的访问的情况
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;
}
}

lintcode 单词接龙II的更多相关文章

  1. Leetcode 126.单词接龙II

    单词接龙II 给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列.转换需遵循如下规则: 每次转换只能 ...

  2. Java实现 LeetCode 126 单词接龙 II

    126. 单词接龙 II 给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列.转换需遵循如下规则: ...

  3. LeetCode 126. Word Ladder II 单词接龙 II(C++/Java)

    题目: Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transfo ...

  4. [Swift]LeetCode126. 单词接龙 II | Word Ladder II

    Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformat ...

  5. [LeetCode] 126. 单词接龙 II

    题目链接 : https://leetcode-cn.com/problems/word-ladder-ii/ 题目描述: 给定两个单词(beginWord 和 endWord)和一个字典 wordL ...

  6. 126. 单词接龙 II

    题目: 链接:https://leetcode-cn.com/problems/word-ladder-ii/ 给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出 ...

  7. 图-搜索-BFS-DFS-126. 单词接龙 II

    2020-03-19 13:10:35 问题描述: 给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序 ...

  8. 单词接龙(dragon)(BFS)

    单词接龙(dragon) 时间限制: 1 Sec  内存限制: 64 MB提交: 12  解决: 5[提交][状态][讨论版] 题目描述 单 词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已 ...

  9. NOIP2000单词接龙[DFS]

    题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合 ...

随机推荐

  1. C. Trailing Loves (or L'oeufs?)

    题目链接:http://codeforces.com/contest/1114/problem/C 题目大意:给你n和b,让你求n的阶乘,转换成b进制之后,有多少个后置零. 具体思路:首先看n和b,都 ...

  2. js数组的操作push,pop,shift,unshift

    push(args)可以每次压入多个元素,并返回更新后的数组长度. var oldArr=[1,2,3]; alert(oldArr.push(4,[5,6]))–>5(这里只会将[5,6]当做 ...

  3. nginx异常处理

    1.nginx不转发消息头header问题 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_se ...

  4. sublime汉化步骤记录

    1.下载sublime编辑器,下载地址:http://www.sublimetext.com/ 2.安装sublime 3.首先安装“Package Control”(如果已经安装过可以跳过此步骤) ...

  5. CentOS6.5环境使用keepalived实现nginx服务的高可用性及配置详解

    keepalived基础概念    Keepalived是一个基于VRRP协议来实现的WEB服务高可用方案,可以利用其来避免单点故障.一个WEB服务至少会有2台服务器运行Keepalived,一台为主 ...

  6. 罗克韦尔 Allen-Bradley MicroLogix 1400 查看、设置IP

    =============================================== 2019/4/14_第1次修改                       ccb_warlock == ...

  7. 用jquery添加新元素很容易,面对jquery append 动态添加的元素事件on 不起作用我们该如何解决呢?

    用jquery添加新元素很容易,面对jquery append 动态添加的元素事件on 不起作用我们该如何解决呢?on方法中要先找到原选择器(如例.info),再找到动态添加的选择器(如列.delet ...

  8. js十大排序算法详解

    十大经典算法导图  图片名词解释:n: 数据规模k:“桶”的个数In-place: 占用常数内存,不占用额外内存Out-place: 占用额外内存 1.冒泡排序 1.1  原始人冒泡排序 functi ...

  9. LeetCode(8):字符串转整数(atoi)

    Medium! 题目描述: 实现 atoi,将字符串转为整数. 在找到第一个非空字符之前,需要移除掉字符串中的空格字符.如果第一个非空字符是正号或负号,选取该符号,并将其与后面尽可能多的连续的数字组合 ...

  10. TensorFlow 框架

    TensorFlow TensorFlow核心程序由2个独立部分组成:   a:Building the computational graph构建计算图   b:Running the comput ...