1. 填充每個節點的下一個右側節點指針II
給定一個二叉樹
struct Node
{
int val;
Node* left;
Node* right;
Node* next;
}
填充它的每個next指針,讓這個指針指向其下一個右側節點。如果找不到下一個右側節點,則將next指針設置爲NULL。
初始狀態下,所有next指針都被設置爲NULL。
思路:因爲首先要判斷右邊的節點,所以要先遞歸右子樹
Node* connect(Node* root) {
if(root == nullptr)
{
return root;
}
Node* p = root -> next;
while(p)
{
if(p -> left)
{
p = p -> left;
break;
}
if(p -> right)
{
p = p -> right;
break;
}
p = p -> next;
}
if(root -> right)
{
root -> right -> next = p;
}
if(root -> left)
{
root -> left -> next = root -> right ? root -> right : p;
}
connect(root -> right);
connect(root -> left);
return root;
}
2. 單詞接龍
給定兩個單詞(beginWord和endWord)和一個詞典。找到從beginWord到endWord的最短轉換序列的長度。轉換需遵循如下規則:
- 每次轉換隻能改變一個字母
- 轉換過程中的中間單詞必須是字典中的單詞
說明:
- 如果不存在這樣的轉換序列,返回0
- 所有單詞具有相同的長度
- 所有單詞只由小寫字母組成
- 字典中不存在重複的單詞
- 可以假設beginWord和endWord是非空的,且二者不相同
思路:最短路徑問題,首選BFS
用隊列存儲經過變換能夠得到的單詞(在單詞表中也出現的),每次取隊首元素,遍歷其每個字符,將字符以此置換爲a~z,判斷置換後的新詞是否在單詞表中存在,如果存在,則將該新詞入隊,如果新詞和最後目標詞相同,那麼輸出長度。循環上述操作,知道隊列爲空時,如果還沒有任何詞和目標詞相同,那麼輸出0。
- 如何記錄變換序列的長度
通過插入在隊列中插入特殊符號“,”,經過以此變換能夠到達的單詞放在一起,經過兩次變換能夠到達的單詞放在一起,然後通過“,”將兩堆隔開,依此類推。只需要判斷掃描到的“,”的個數就知道經過了幾次字符變換。 - 快速查找?
哈希表
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
int res = 1; //beginWord本身也在路徑中
queue<string> q; //bfs問題基本少不了隊列
unordered_map<string, int> mp;
//value默認爲1,表示存在該詞
for(int i = 0; i < wordList.size(); i++)
{
mp[wordList[i]] = 1;
}
if(mp.count(endWord) == 0)
{
return 0;
}
//隊列每一層以“,”分隔
q.push(beginWord);
q.push(",");
while(!q.empty())
{
string temp = q.front();
q.pop();
if(temp != ",")
{
for(int i = 0; i < temp.size(); i++)
{
char c_temp = temp[i];
for(char c = 'a'; c <= 'z'; c++)
{
if(c == c_temp)
{
continue;
}
temp[i] = c;
if(mp[temp] != 0)
{
//單詞表中存在該單詞,將單詞加到隊列中,同時從單詞表中刪去該單詞
q.push(temp);
mp[temp] = 0;
//如果當前詞和endWord相同,輸出
if(temp == endWord)
{
return res + 1;
}
}
temp[i] = c_temp;
}
}
}
else if(!q.empty())
{
q.push(",");
res++;
}
}
return 0;
}