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. Merge Sorted Array 解答

    Question Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array ...

  2. 单源最短路径—Bellman-Ford和Dijkstra算法

    Bellman-Ford算法:通过对边进行松弛操作来渐近地降低从源结点s到每个结点v的最短路径的估计值v.d,直到该估计值与实际的最短路径权重相同时为止.该算法主要是基于下面的定理: 设G=(V,E) ...

  3. 【强烈推荐】《剑指Offer:名企面试官精讲典型编程题》一书中IT名企经典面试题

    各位程序猿:         <剑指Offer>一书源自该书作者何海涛坚持更新与编写的博客(http://zhedahht.blog.163.com/),该博客收集整理了大量如微软.Goo ...

  4. 页面动态数据的滚动效果——jquery滚动组件(vticker.js)

    <script language="javascript" src="lirms/Test/jquery-1.4.2.js"></script ...

  5. 如何利用 Bootstrap 进行快速 Web 开发

    原文出处: IBM developerworks 了解如何使用 Bootstrap 快速开发网站和 Web 应用程序(包括移动友好型应用程序).Bootstrap 以 LESS 项目为基础,由 Twi ...

  6. Android开发实现透明通知栏

    这个特性是andorid4.4支持的,最少要api19才可以使用,也就是说如果Android的机子是低于4.4,沉浸通知栏是没有效果的.下面介绍一下使用的方法,非常得简单. public void i ...

  7. 几句话弄清楚Java参数传值还是传引用

    最近刷题做了一些算法题,对于在递归函数调用的时候什么时候传入值,什么时候传入引用有疑问,在网上搜索了一下,得出了一下三条总结: 1.对象就是传引用 2.原始类型就是传值 3.String,Intege ...

  8. KVC与KVO的理解

    KVC与KVO是Objective C的关键概念. Key—Value Coding (KVC) 即是指NSKeyValueCoding,一个非正式的Protocol,提供一种机制间接访问对象的属性. ...

  9. C#读写word

    操作word之前需要在COM引入Microsoft Office 12.0 Object Library(文件库可能不一样) 然后添加using Microsoft.Office.Interop.Wo ...

  10. RBAC 基于角色的权限管理的简单实现

    1.什么是权限管理,权限管理就是对后台功能的细分,和对不同工作人员划分不同的工作的管理 RBAC是如何实现的,通过对不同控制器和控制器不同方法的限制,实现的管理. 要实现RBAC需要三张表,一张用户表 ...