127. Word Ladder
A transformation sequence from word beginWord to word endWord using a dictionary wordList is a sequence of words beginWord -> s1 -> s2 -> ... -> sk such that:
- Every adjacent pair of words differs by a single letter.
- Every si for 1 <= i <= k is in wordList. Note that beginWord does not need to be in wordList.
- sk == endWord
Given two words, beginWord and endWord, and a dictionary wordList, return the number of words in the shortest transformation sequence from beginWord to endWord, or 0 if no such sequence exists.
Example 1:
Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
Output: 5
Explanation: One shortest transformation sequence is "hit" -> "hot" -> "dot" -> "dog" -> cog", which is 5 words long.
Example 2:
Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
Output: 0
Explanation: The endWord "cog" is not in wordList, therefore there is no valid transformation sequence.
Constraints:
- 1 <= beginWord.length <= 10
- endWord.length == beginWord.length
- 1 <= wordList.length <= 5000
- wordList[i].length == beginWord.length
- beginWord, endWord, and wordList[i] consist of lowercase English letters.
- beginWord != endWord
- All the words in wordList are unique.
From: LeetCode
Link: 127. Word Ladder
Solution:
Ideas:
- Start with beginWord "hit" and level 1.
- Queue = ["hit"]
- Dequeue "hit" and explore its neighbors:
- Check each word in wordList to find neighbors of "hit" (words that are one letter different and unvisited).
- "hot" is a neighbor. Mark "hot" as visited and enqueue it.
- Queue = ["hot"]
- Increase level to 2.
- Dequeue "hot" and explore its neighbors:
- Find neighbors of "hot" (unvisited words in wordList that are one letter different).
- "dot" and "lot" are neighbors. Mark them as visited and enqueue them.
- Queue = ["dot", "lot"]
- Increase level to 3.
- Dequeue "dot" and explore its neighbors:
- Find neighbors of "dot".
- "dog" is a neighbor. Mark "dog" as visited and enqueue it.
- Queue = ["lot", "dog"]
- Dequeue "lot" and explore its neighbors:
- Find neighbors of "lot".
- "log" is a neighbor. Mark "log" as visited and enqueue it.
- Queue = ["dog", "log"]
- Increase level to 4.
- Dequeue "dog" and explore its neighbors:
- Find neighbors of "dog".
- "cog" is a neighbor. Mark "cog" as visited and enqueue it.
- Queue = ["log", "cog"]
- Dequeue "log" and explore its neighbors:
- Find neighbors of "log".
- No unvisited neighbors.
- Queue = ["cog"]
- Dequeue "cog" and explore its neighbors:
- "cog" is the endWord.
- Return level which is 5, representing the shortest transformation sequence: "hit" -> "hot" -> "dot" -> "dog" -> "cog".
Code:
c
bool isOneLetterDiff(char *a, char *b) {
int diffCount = 0;
while (*a) {
if (*(a++) != *(b++)) diffCount++;
if (diffCount > 1) return false;
}
return diffCount == 1;
}
int ladderLength(char *beginWord, char *endWord, char **wordList, int wordListSize) {
if (!beginWord || !endWord || !wordList || wordListSize == 0) return 0;
bool *visited = (bool *)calloc(wordListSize, sizeof(bool));
char **queue = (char **)malloc(sizeof(char *) * (wordListSize + 1));
int front = 0, rear = 0;
queue[rear++] = beginWord;
int level = 1;
while (front < rear) {
int size = rear - front;
for (int i = 0; i < size; i++) {
char *word = queue[front++];
if (strcmp(word, endWord) == 0) {
free(visited);
free(queue);
return level;
}
for (int j = 0; j < wordListSize; j++) {
if (!visited[j] && isOneLetterDiff(word, wordList[j])) {
visited[j] = true;
queue[rear++] = wordList[j];
}
}
}
level++;
}
free(visited);
free(queue);
return 0;
}