题意

  给出两个单词(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. 2017-2018-2 165X 『Java程序设计』课程 助教总结

    2017-2018-2 165X 『Java程序设计』课程 助教总结 本学期完成的助教工作主要包括: 编写300道左右测试题,用于蓝墨云课下测试: 发布博客三篇:<2017-2018-2 165 ...

  2. 安装python3后使用pip和pip3的区别是什么?

    安装python3后使用pip和pip3的区别是什么? 1.其实这两个命令效果是一样的,没有区别: (1)比如安装库numpy,pip3  install  numpy或者pip  install   ...

  3. HTML学习笔记08-表格

    HTML表格 表格由<table>标签来定义,表格的行由<tr>标签来定义,表格的列由<td>标签来定义 <!DOCTYPE html> <htm ...

  4. UDP template 代码

    服务端 from socket import * import json,struct client= socket(AF_INET,SOCK_STREAM) client.connect(('127 ...

  5. 转:vue+element实现树形组件

    项目中需要用到树形组件,在网上发现一个用vue+element实现的树形组件,现在记录下: demo地址:https://github.com/wilsonIs/vue-treeSelect

  6. 20175225 《Arrays和String单元测试》

    ---恢复内容开始--- 题目 在IDEA中以TDD的方式对String类和Arrays类进行学习,测试相关方法的正常,错误和边界情况 - String类 - charAt - split - Arr ...

  7. 教你构建好 SpringBoot + SSM 框架

    来源:Howie_Y https://juejin.im/post/5b53f677f265da0f8f203914 目前最主流的 java web 框架应该是 SSM,而 SSM 框架由于更轻便与灵 ...

  8. C++ code:剩余串排列

    方法一: 一种直观的解是,先对第一个字串排序,然后逐个字符在第二个字串中搜索,把搜索不到的字符输出,就是所要的结果. 然而,算法库中有一个集合差运算set_difference,而且要求两个集合容器是 ...

  9. wpf 自定义属性的默认值

    public int MaxSelectCount { get { return (int)GetValue(MaxSelectCountProperty); } set { SetValue(Max ...

  10. Laravel Form 表单的数据校验

    例如,要使用手机号加验证码的方式提供登录网站的功能,那么在处理前端提交的 form 表单时,就不得不对提交的手机号及验证码做基本的数据校验. 手写规则,非常浪费时间.使用 laravel 内置的 va ...