Question

Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:

  1. Only one letter can be changed at a time
  2. Each intermediate word must exist in the word list

For example,

Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.

Note:

    • Return 0 if there is no such transformation sequence.
    • All words have the same length.
    • All words contain only lowercase alphabetic characters.

Solution 1 -- BFS

 class WordNode{
String word;
int numSteps; public WordNode(String word, int numSteps){
this.word = word;
this.numSteps = numSteps;
}
} public class Solution {
public int ladderLength(String beginWord, String endWord, Set<String> wordList) {
Queue<WordNode> queue = new LinkedList<WordNode>();
queue.add(new WordNode(beginWord, 1)); wordList.add(endWord); // 由于这里纪录了每个词的最小步数,所以不用两个list
while (queue.size() > 0) {
WordNode topNode = queue.remove();
String current = topNode.word; if (current.equals(endWord))
return topNode.numSteps; char[] arr = current.toCharArray();
// 穷举法
for (int i = 0; i < arr.length; i++) {
for (char c = 'a'; c <= 'z'; c++) {
char tmp = arr[i];
if (arr[i] != c)
arr[i] = c; String newWord = new String(arr);
if (wordList.contains(newWord)) {
queue.add(new WordNode(newWord, topNode.numSteps + 1));
wordList.remove(newWord);
}
arr[i] = tmp;
}
}
}
return 0;
}
}

Solution 2 -- BFS & Adjacency List

Basic idea is: 1. construct adjacency list 2. BFS

Constructing adjacency list uses O(n2) time, and BFS is O(n). Total time complexity is O(n2), when testing in leetcode, it reports "time limit exceeded".

 public class Solution {
public int ladderLength(String beginWord, String endWord, Set<String> wordList) {
if (wordList == null)
return -1;
int step = 1;
if (beginWord.equals(endWord))
return 1;
// Construct adjacency lists for words
// Do not forget start word and end word
wordList.add(beginWord);
wordList.add(endWord);
Map<String, List<String>> adjacencyList = new HashMap<String, List<String>>();
Map<String, Boolean> visited = new HashMap<String, Boolean>();
int length = wordList.size();
String[] wordList2 = new String[length];
int i = 0;
for (String current : wordList) {
wordList2[i] = current;
i++;
}
// Initialization
for (i = 0; i < length; i++) {
adjacencyList.put(wordList2[i], new ArrayList<String>());
visited.put(wordList2[i], false);
} for (i = 0; i < length; i++) {
String current = wordList2[i];
// Construct adjacency list for each element
for (int j = i + 1; j < length; j++) {
String next = wordList2[j];
if (isAdjacent(current, next)) {
List<String> list1 = adjacencyList.get(current);
list1.add(next);
adjacencyList.put(current, list1);
List<String> list2 = adjacencyList.get(next);
list2.add(current);
adjacencyList.put(next, list2);
}
}
} // BFS
List<String> current = new ArrayList<String>();
List<String> next;
current.add(beginWord);
visited.put(beginWord, true);
while (current.size() > 0) {
step++;
next = new ArrayList<String>();
for (String currentString : current) {
List<String> neighbors = adjacencyList.get(currentString);
if (neighbors == null)
continue;
for (String neighbor : neighbors) {
if (neighbor.equals(endWord))
return step;
if (!visited.get(neighbor)) {
next.add(neighbor);
visited.put(neighbor, true);
}
}
}
current = next;
}
return -1; } private boolean isAdjacent(String current, String next) {
if (current.length() != next.length())
return false;
int length = current.length();
int diff = 0;
for (int i = 0; i < length; i++) {
char a = current.charAt(i);
char b = next.charAt(i);
if (a != b)
diff++;
}
if (diff == 1)
return true;
return false;
}
}

Python version

 from collections import deque
from collections import defaultdict class Solution:
def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
if endWord not in wordList:
return 0
queue = deque()
queue.append((beginWord, 1))
visited = set([beginWord])
adjacency_map = defaultdict(list)
L = len(beginWord)
# Pre-process
for word in wordList:
for i in range(L):
adjacency_map[word[:i] + "*" + word[i+1:]].append(word)
# BFS
while queue:
curr_word, curr_steps = queue.popleft()
if curr_word == endWord:
return curr_steps
# List all possibilities
for i in range(L):
key = curr_word[:i] + "*" + curr_word[i+1:]
if key in adjacency_map:
neighbors = adjacency_map[key]
for neighbor in neighbors:
if neighbor == endWord:
return curr_steps + 1
if neighbor not in visited:
queue.append((neighbor, curr_steps + 1))
visited.add(neighbor)
adjacency_map[key] = {}
return 0

Word Ladder 解答的更多相关文章

  1. Word Ladder II 解答

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

  2. [LeetCode] Word Ladder 词语阶梯

    Given two words (beginWord and endWord), and a dictionary, find the length of shortest transformatio ...

  3. [LeetCode] Word Ladder II 词语阶梯之二

    Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from ...

  4. LeetCode:Word Ladder I II

    其他LeetCode题目欢迎访问:LeetCode结题报告索引 LeetCode:Word Ladder Given two words (start and end), and a dictiona ...

  5. 【leetcode】Word Ladder

    Word Ladder Total Accepted: 24823 Total Submissions: 135014My Submissions Given two words (start and ...

  6. 【leetcode】Word Ladder II

      Word Ladder II Given two words (start and end), and a dictionary, find all shortest transformation ...

  7. 18. Word Ladder && Word Ladder II

    Word Ladder Given two words (start and end), and a dictionary, find the length of shortest transform ...

  8. [Leetcode][JAVA] Word Ladder II

    Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from ...

  9. LeetCode127:Word Ladder II

    题目: Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) ...

随机推荐

  1. poj 2481 Cows(数状数组 或 线段树)

    题意:对于两个区间,[si,ei] 和 [sj,ej],若 si <= sj and ei >= ej and ei - si > ej - sj 则说明区间 [si,ei] 比 [ ...

  2. QQ聊天界面的布局和设计(IOS篇)-第二季

    QQChat Layout - 第二季 本来第二季是快写好了, 也花了点功夫, 结果gitbook出了点问题, 给没掉了.有些细节可能会一带而过, 如有疑问, 相互交流进步~. 在第一季中我们完成了Q ...

  3. Centos中安装code blocks

    CentOS下面安装Codeblocks不像Ubuntu下面那样轻松,可以直接在软件中心安装.这里好多信赖我们要自己安装,也不是很麻烦. 1.先安装gcc和gcc++,这个可以直接安装 # yum i ...

  4. 《Two Days DIV + CSS》读书笔记——CSS选择器

    1.1.2 CSS选择器 CSS 选择器最基本的有四种:标签选择器.ID 选择器.类选择器.通用选择器. [标签选择器] 一个完整的 HTML 页面由很多不同的标签组成,而标签选择器,则是决定哪些标签 ...

  5. 《Java程序员面试笔试宝典》之Java与C/C++有什么异同

    Java与C++都是面向对象语言,都使用了面向对象思想(例如封装.继承.多态等),由于面向对象有许多非常好的特性(继承.组合等),使得二者都有很好的可重用性. 需要注意的是,二者并非完全一样,下面主要 ...

  6. java生成字符串md5函数类(javaSE)

    //实现生成MD5值 import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.B ...

  7. JQuery 选择器 *很重要 多记

    1)基本选择器: 跟CSS选择器类似 2) 层次选择器 div>span   紧接这div同一级下的全部span .one+div     同一等级的div #two~div    同一等级di ...

  8. uva 1291(dp)

    题意:有一台跳舞机,中间是0.上左下右分别代表1 2 3 4,初始状态人站在中间.两仅仅脚都踏在0上,然后给出一段序列以0为结束,要按顺序踩出来,从0踏到四个方向须要消耗2点能量,从一个方向到相邻的方 ...

  9. CGBitmapContextCreate函数

    CGBitmapContextCreate函数参数详解 函数原型: CGContextRef CGBitmapContextCreate ( void *data,    size_t width, ...

  10. NET基础课--开发工具实用功能

    1.浏览代码结构 类视图 2.重构功能 提取长的的方法体中的部分方法到单独函数中 路径:选择代码段,右击重构----提取方法 3.代码结构 a 代码对齐 点[编辑]-[高级]-[设置选定内容的格式] ...