Leetcode.com problem 127: "Word-Ladder-I"

James S. Plank

Mon Aug 15 00:45:51 EDT 2022

In case Leetcode's servers are down

You are to write a method in the class Solution with the following prototype:

int ladderLength(string b, string e, vector<string>& wordList);

All of the strings (b, e and all the words in wordList) are the same size, between 1 and 10 characters.

Your job is to convert b to e by a sequence of "transformations." You can tranform a word x to a word y if y is in wordList, and x and y differ by exactly one character. Your goal is to convert b to e with a minimum number of transformations. Return that number plus one, if it's possible. If it's impossible, then return 0.

It's ok for b not to be in wordList. However, since the second word in a transformation has to be in wordList, e must be in wordList, or you'll return 0.

Constraints:

The testing program in skeleton.cpp reads b, then e, then all the words in wordList. So:

UNIX> echo hit cog hot dot dog lot log cog | ./a.out    # One sequence is hit -> hot -> dot -> dog -> cog
5
UNIX> echo hit cog hot dot dog lot log | ./a.out        # "cog" is not in wordList
0
UNIX> 
In the example files, the second number is the answer, so:
UNIX> ./a.out < ex-1-8.txt
8
UNIX> ./a.out < ex-2-6.txt
6
UNIX> 

Hints

I'm hoping that you can easily see that this is an unweighted shortest path problem. That means you can solve it with a breadth-first search. In the first example above, here's the graph in ASCII art:

hit -- hot -- dot -- dog
        |   /      /  |
        |  /      /   |
        | /      /    |
        |/      /     |
       lot -- log -- cog

So, step one should be to convert the word list into a graph:

Here's the example above. You'll note that "hit" wasn't on the word list, so I appended it there. That's why it is node 6.
UNIX> echo hit cog hot dot dog lot log cog | ./a.out
 0 hot:  1  3  6
 1 dot:  0  3  2
 2 dog:  4  5  1
 3 lot:  0  1  4
 4 log:  2  5  3
 5 cog:  2  4
 6 hit:  0
UNIX> 
Now, write the BFS. If you're not experienced yet with writing a BFS, this is a good time to get experience. The CS302 lecture notes for BFS are here.

You can now test your answer on the examples. The first 8 will run quickly, but the last three will be too slow.


Making your program fast enough

The reason your program is too slow is the way that you are creating the adjacency lists. It is O(n2), where n is the size of the word list. Since n can be as big as 5000, O(n2) won't do.

It's not a bad idea to pause for a moment, and try to think of how to create the adjacency lists faster. Think about how you can employ a map. Scroll down to see my approach.










Here was my approach. Let's first look for all words who differ only by the first character. For each word in the list, create a string which is the word missing the first character. If two words differ by only the first character, then their strings will match! So, insert each of these strings into the map. The val part of the map will be an array of node indices. In the example above, the map will be:

{ ("it",[6]), ("og",[2,4,5]), ("ot",[0,1,3]) }

Now you can put the following nodes onto the adjacency list:

Now, do this for the second character, then the third, etc. Clear the map each time before you start.

What's the running time complexity? Let's let m be the word size. It's O(m2 n log n). Why m2? Because you run the outer loop for m iterations, and then creating the string is also O(m). Since m is capped at 10, this is much faster than the O(n2) loop above.

That should give you enough tools to solve this and have it be fast enough!