lintcode 单词接龙II
题意
给出两个单词(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的更多相关文章
- Leetcode 126.单词接龙II
单词接龙II 给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列.转换需遵循如下规则: 每次转换只能 ...
- Java实现 LeetCode 126 单词接龙 II
126. 单词接龙 II 给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列.转换需遵循如下规则: ...
- LeetCode 126. Word Ladder II 单词接龙 II(C++/Java)
题目: Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transfo ...
- [Swift]LeetCode126. 单词接龙 II | Word Ladder II
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformat ...
- [LeetCode] 126. 单词接龙 II
题目链接 : https://leetcode-cn.com/problems/word-ladder-ii/ 题目描述: 给定两个单词(beginWord 和 endWord)和一个字典 wordL ...
- 126. 单词接龙 II
题目: 链接:https://leetcode-cn.com/problems/word-ladder-ii/ 给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出 ...
- 图-搜索-BFS-DFS-126. 单词接龙 II
2020-03-19 13:10:35 问题描述: 给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序 ...
- 单词接龙(dragon)(BFS)
单词接龙(dragon) 时间限制: 1 Sec 内存限制: 64 MB提交: 12 解决: 5[提交][状态][讨论版] 题目描述 单 词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已 ...
- NOIP2000单词接龙[DFS]
题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合 ...
随机推荐
- C语言文件操作详解
C语言中没有输入输出语句,所有的输入输出功能都用 ANSI C提供的一组标准库函数来实现.文件操作标准库函数有: 文件的打开操作 fopen 打开一个文件 文件的关闭操作 fclose 关闭一个文件 ...
- oracle数据文件迁移
这篇文章是从网络上获取的,然后根据内容一步步操作, 1.目前的疑问:移动日志文件的时候,为何要先进行切换? 2.move操作后,再进行rename操作的原理 --------------------- ...
- centos6.5生产环境编译安装nginx-1.11.3并增加第三方模块ngx_cache_purge、nginx_upstream_check、ngx_devel_kit、lua-nginx
1.安装依赖包 yum install -y gcc gcc-c++ pcre-devel openssl-devel geoip-devel 2.下载需要的安装包 LuaJIT-2.0.4.zip ...
- 通达OA在centos系统中快速部署文档(web和数据库)
通达OA2008从windows环境移植到linux中(centos5.5及以上版本) 如果安装好了,还是无法访问,则需要清空浏览器缓存即可 1.安装lamp环境,这里用的是xampp集成安装包xam ...
- ajax post 传递数组参数
1.前言 此文章仅作为记录,方便查阅. 2.代码 javascript: var idArr = ['one','two','Three']; $.ajax({ type: 'POST', data ...
- PYTHON-模块 json pickle shelve xml
""" pickle 和 shevle 序列化后得到的数据 只有python才能解析 通常企业开发不可能做一个单机程序 都需要联网进行计算机间的交互 我们必须保证这个数据 ...
- Java连接oracle数据库的两种常用方法
1. 使用thin连接 由于thin驱动都是纯Java代码,并且使用TCP/IP技术通过java的Socket连接上Oracle数据库,所以thin驱动是与平台无关的,你无需安装Oracle客户端,只 ...
- SpringMVC(2):Spring MVC入门
原文出处: 张开涛 2.1.Spring Web MVC是什么 spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思 ...
- 并发之synchronized关键字的应用
并发之synchronized关键字的应用 synchronized关键字理论基础 前两章我们学习了下java内存模型的相关知识, 现在我们来讲讲逢并发必出现的synchronized关键字. 作用 ...
- hdu4768二分答案
/* 如果发的传单是偶数,那么所有人都收到双数张. 仅考虑发了单数张传单,二分答案x,如果x左边是偶数,那么答案在右侧,如果x左边是奇数,那么答案在左侧 */ #include<iostream ...