單詞接龍
阿新 • • 發佈:2020-11-05
給定兩個單詞(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.注意使用虛擬節點的方法。