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]
题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合 ...
随机推荐
- yield函数的理解
1.https://blog.csdn.net/qq_33472765/article/details/80839417
- C++11 多线程编程
http://blog.csdn.net/column/details/ccia.html?&page=1
- 基于XML搭建Dubbo项目
(1).新建一个普通Maven项目,用于存放一些公共服务接口及公共的Bean等. 公共Bean: package cn.coreqi.entities; import java.io.Serializ ...
- 在手机的浏览器上通过连接打开App
Android系统中实现 1.在系统系统自带的浏览器中 首先做成HTML的页面,页面内容格式如下: <a href="[scheme]://[host]/[path]?[query]& ...
- STM32F103X datasheet学习笔记---RCC(reset and clock control)
1.前言 本文主要记录stm32 关于reset 和 clock部分 datasheet的内容. 2.reset 有三种类型的reset:system reset, power reset, back ...
- linux系统的休眠与唤醒简介
转自:http://blog.csdn.net/haomcu/article/details/7398703 系统挂起(Suspend)是电源管理(APM&ACPI)的一个特性,给用户带来了很 ...
- mysql系列八、mysql数据库优化、慢查询优化、执行计划分析
mysql的性能优化无法一蹴而就,必须一步一步慢慢来,从各个方面进行优化,最终性能就会有大的提升. 一.介绍 对mysql优化是一个综合性的技术,主要包括 表的设计合理化(符合3NF) 添加适当索引( ...
- 转载:磁盘目录(1.3.3)《深入理解Nginx》(陶辉)
原文:https://book.2cto.com/201304/19614.html 要使用Nginx,还需要在Linux文件系统上准备以下目录. (1)Nginx源代码存放目录 该目录用于放置从官网 ...
- 不同系统与程序修改java.library.path的位置(转)
原文地址:http://blog.csdn.net/quqibing001/article/details/51201768 Linux环境 系统变量LD_LIBRARY_PATH来添加Java.li ...
- Unicode范围预览
链接: https://www.zhangxinxu.com/study/201611/show-character-by-charcode.php?range=4E00-9FBB 备注: Unico ...