1. 程式人生 > 實用技巧 >單詞接龍

單詞接龍

給定兩個單詞(beginWord和 endWord)和一個字典,找到從beginWord 到endWord 的最短轉換序列的長度。轉換需遵循如下規則:

每次轉換隻能改變一個字母。
轉換過程中的中間單詞必須是字典中的單詞。
說明:

如果不存在這樣的轉換序列,返回 0。
所有單詞具有相同的長度。
所有單詞只由小寫字母組成。
字典中不存在重複的單詞。
你可以假設 beginWord 和 endWord 是非空的,且二者不相同。
示例1:

輸入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

輸出: 5

解釋: 一個最短轉換序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog",
返回它的長度 5。
示例 2:

輸入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

輸出:0

解釋:endWord "cog" 不在字典中,所以無法進行轉換。

class Solution {
    //1.通過使用虛擬節點進行建圖
    //2.最近距離問題一般採用廣度優先演算法進行相應的處理
public:
    unordered_map<string
,int> wordId; vector<vector<int>> edge; int nodeNum = 0; void addWord(string& word){ if(!wordId.count(word)){ wordId[word] = nodeNum++; edge.emplace_back(); //先預留一個vector,供其他函式插入操作使用 } } void addEdge(string& word){ addWord(word);
int id1 = wordId[word]; for(char& it:word){ char tmp = it; it = '*'; addWord(word); int id2 = wordId[word]; edge[id1].push_back(id2); edge[id2].push_back(id1);//插入虛擬節點 it = tmp;//還原word } } int ladderLength(string beginWord, string endWord, vector<string>& wordList) { for(string& word: wordList){ addEdge(word); } addEdge(beginWord); if(!wordId.count(endWord)){ return 0;//序列中沒有終點,直接返回0 } vector<int> dis(nodeNum,INT_MAX); //準備開始進行廣度優先搜尋 int beginId = wordId[beginWord],endId = wordId[endWord]; dis[beginId] = 0; queue<int> que; que.push(beginId); while(!que.empty()){ int x = que.front(); que.pop(); if(x == endId){ return dis[endId]/2 +1;//找到最終的節點 //由於加了虛擬節點,所以路徑的長度等於擴大了一倍 //同時由於計算的應該是節點的個數,所以/2後還需要再進行加1操作 } for(int& it:edge[x]){ if(dis[it] == INT_MAX){ dis[it] = dis[x]+1; que.push(it); } } } return 0; } };

注意:

1.最短路徑問題想到使用廣度優先演算法。

2.注意使用虛擬節點的方法。