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. grep命令实例

    grep一般用于查找文件中含有某些字符串的行,其命名格式如下 grep [OPTIONS] PATTERN [FILE...] 下面例举grep在linux使用过程中其常用使用实例: 1.grep递归 ...

  2. MySQL的备份和还原

    MySQL的备份和还原 备份:副本    RAID1,RAID10:保证硬件损坏而不会业务中止:        DROP TABLE mydb.tb1; 备份类型:        热备份.温备份和冷备 ...

  3. Android学习笔记__3__Android应用程序组成

    Android开发必须要了解构造块,Android应用程序是由里有六个重要组成部分组成的,这六种构造块如下:  ◆Activity ◆Intent Receiver ◆Service ◆Content ...

  4. Handler消息机制实现更新主UI

    如下实现的是简单的更新主UI的方法,用Handler消息机制 将textview的内容每隔一秒实现num++ /* * handler消息机制 * asynctask异步任务 *  * httpcli ...

  5. poj 2697 A Board Game(bfs+hash)

    Description Dao was a simple two-player board game designed by Jeff Pickering and Ben van Buskirk at ...

  6. PHP商城购物车类

    <?php /* 购物车类 */ // session_start(); class Cart { //定义一个数组来保存购物车商品 private $iteams; private stati ...

  7. 《招聘一个靠谱的iOS》面试题参考答案(下)

    相关文章: <招聘一个靠谱的iOS>面试题参考答案(上) 说明:面试题来源是微博@我就叫Sunny怎么了的这篇博文:<招聘一个靠谱的 iOS>,其中共55题,除第一题为纠错题外 ...

  8. css-下拉菜单案例

    <!DOCTYPE html>CSS4-布局2-display下拉菜单案例 <style>.xiala{width:200px;background:#ddd;}.xiala ...

  9. Android Path

    外置SDCard(TF卡) 1. SDCard的挂载路径(根据系统不同的ROM挂载的路径不同,以下列举几个是从旧系统到新系统的表现形式) /sdcard/external_sd /mnt/extSdC ...

  10. Android Studio稍微较新的版本下载

    ALL ANDROID STUDIO PACKAGES-V1.4.1.2422023 Select a specific Android Studio package for your platfor ...