【LeetCode OJ】Word Ladder I

Problem Link:

http://oj.leetcode.com/problems/word-ladder/

Two typical techniques are inspected in this problem:

  1. Hash Table. One hash set is the words dictionary where we can check if a
    word is in the dictionary in O(1) time. The other hash set is used to store
    all visited words we already checked.

  2. Double-direction BFS. To accelerate the process that finds the shortest
    path between start word and end word, we need carry on a special BFS from both
    start word and end word. If there exists a path between start word and end
    word, then two fronts must meet at some time.

One simple solution for this problem is BFS from the start word, we keep a
list of edge words (the last word of each path). Each time, we search all
unvisited words next to the edge words, and add these new found
words into the new edge list. The program return the length of the path when the
end words is reached, or return 0 if no unvisited words can be found.

However, I implemented this BFS but got a TLE. So I adapted a
double-direction BFS which may half the running time, and is
accepted by the leetcode judge. The algorithm can go as follows.

Let start_front be the list of edge words of BFS paths from the start word
Let end_front be the list of edge words of BFS paths from the end word
Initialize start_front = [start] and end_front = [end]
Start a double direction BFS loop, in each iteration we extend the two fronts as follows:
  For each word w in start_front
    Find all transformable words of w those are not visited yet
  Let all new found words be the new start_font, return 0 if no new words found
  If two fronts meet, then return the number of transforms
  For each word w in end_front
    Find all transformable words of w those are not visited yet
  Let all new found words be the new end_front, return 0 if no new words found
  If two fronts meet, then return the number of transforms

The following code is the python implementatation which is accepted by
leetcode.com.

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

class
Solution:

    # @param start, a string

    # @param end, a string

    # @param dict, a set of string

    # @return an integer

    def
ladderLength(self, start, end, dict):

        """

        Suppose start, end, and all words in dict are of the same length.

        Then we apply BFS from both start and end, and keep track of the two front edges.

        If the two front meet, then there is a path from start to end.

        The algorithm can go as follows.

        1) Let start_front be the list of words on the edge BFS from start word;

        2) Let end_front be the list of words on the edge BFS from end word;

        3) Initialize start_front = [start] and end_front = [end]

        4) Start a loop where each iteration we do extend two fronts and check if they meet:

                1a) Extend the start front to unvisited words

                1b) If the start front cannot be extent, it means there is no path between start and end,

                    then return 0.

                1c) If the two fronts meet, then return (transform_number + 1)

                2a) Extend the end front to unvisited words

                2b) If the end front cannot be extent, then return 0

                2c) If the two front meet, then return (transform_number + 1)

        """

        # Special cases

        if
start ==
end:

            return
1

        # The length of words

        WORD_LENGTH =
len(start)

        # Initialize the two fronts

        start_front =
[start]

        end_front =
[end]

        # Initialize the number of transforms

        counter =
0

        # Initialize the set of visited words

        visited =
set()

        visited.add(start)

        visited.add(end)

        # Extend the two fronts and check if they can meet

        while
True:

            # Extend the start front

            new_front =
[]

            # Suppose the start front can extend

            counter +=
1

            # Check all unvisited words transformed from the start front

            for
w in
start_front:   # Each word in the start front

                for
i in
xrange(WORD_LENGTH):   # Each character in the word

                    for
candidate in
[w[:i]+chr(97+c)+w[i+1:] for
c in
xrange(26)]:

                        # Check if two fronts can meet

                        if
candidate in
end_front:

                            return
counter +
1

                        # Find all unvisited words from the front and add them as new front

                        if
candidate in
dict and candidate not
in visited:

                            new_front.append(candidate)

                            visited.add(candidate)

            # Check if there exists any word for the new front

            if
new_front:

                start_front =
new_front

            else:

                return
0

            # Extend the end front

            new_front =
[]

            # Suppose the end front can extend

            counter +=
1

            # Check all unvisited words transformed from the end front

            for
w in
end_front:     # Each word in the end front

                for
i in
xrange(WORD_LENGTH):   # Each character in the word

                    for
candidate in
[w[:i]+chr(97+c)+w[i+1:] for
c in
xrange(26)]:

                        # Check if two fronts can meet

                        if
candidate in
start_front:

                            return
counter +
1

                        # Find all unvisited words from the front and add them as new front

                        if
candidate in
dict and candidate not
in visited:

                            new_front.append(candidate)

                            visited.add(candidate)

            # Check if there exists any word for the new front

            if
new_front:

                end_front =
new_front

            else:

                return
0

【LeetCode OJ】Word Ladder I,布布扣,bubuko.com

时间: 2024-10-25 17:15:47

【LeetCode OJ】Word Ladder I的相关文章

【LeetCode OJ】Sum Root to Leaf Numbers

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 # Definition for a  binary tree node # class TreeNode: #     def __init__(self, x): #         self.val = x #         self.left = No

【LeetCode OJ】Longest Consecutive Sequence

Problem Link: http://oj.leetcode.com/problems/longest-consecutive-sequence/ This problem is a classical problem where we can reduce the running time by the help of hash table. By given a list of numbers, we can find the longest consecutive sequence b

【LeetCode OJ】Longest Palindromic Substring

题目链接:https://leetcode.com/problems/longest-palindromic-substring/ 题目:Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. 解题思路:p

【LeetCode OJ】Median of Two Sorted Arrays

题目链接:https://leetcode.com/problems/median-of-two-sorted-arrays/ 题目:There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). 解题思路:将两个有序数

【LeetCode OJ】Remove Element

题目:Given an array and a value, remove all instances of that value in place and return the new length. The order of elements can be changed. It doesn't matter what you leave beyond the new length. 代码: class Solution { public: int removeElement(int A[]

【LeetCode OJ】Swap Nodes in Pairs

题目:Given a linked list, swap every two adjacent nodes and return its head. For example, Given 1->2->3->4, you should return the list as 2->1->4->3. Your algorithm should use only constant space. You may not modify the values in the list,

【LeetCode OJ】Two Sum

题目:Given an array of integers, find two numbers such that they add up to a specific target number. The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note th

【LeetCode OJ】Same Tree

题目:Given two binary trees, write a function to check if they are equal or not. Two binary trees are considered equal if they are structurally identical and the nodes have the same value. 解题思路:这题的基本意思就是要判断两个二叉树是否相同,因为递归思想不是很熟练,所以一开始用非递归的方法写的,但是老有一个cas

【LeetCode OJ】Merge Two Sorted Lists

题目:Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; ListNode *mergeTwoL