題目描述(中等難度)
給定一個滿二叉樹,每個節點多了一個next
指針,然後將所有的next
指針指向它的右邊的節點。並且要求空間複雜度是O(1)
。
解法一 BFS
如果沒有要求空間複雜度這道題就簡單多了,我們只需要用一個隊列做BFS
,BFS
參見 102 題。然後按順序將每個節點連起來就可以了。
public Node connect(Node root) {
if (root == null) {
return root;
}
Queue<Node> queue = new LinkedList<Node>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
Node pre = null;
for (int i = 0; i < size; i++) {
Node cur = queue.poll();
//從第二個節點開始,將前一個節點的 pre 指向當前節點
if (i > 0) {
pre.next = cur;
}
pre = cur;
if (cur.left != null) {
queue.offer(cur.left);
}
if (cur.right != null) {
queue.offer(cur.right);
}
}
}
return root;
}
解法二 迭代
當然既然題目要求了空間複雜度,那麼我們來考慮下不用隊列該怎麼處理。只需要解決三個問題就夠了。
-
每一層怎麼遍歷?
之前是用隊列將下一層的節點保存了起來。
這裏的話,其實只需要提前把下一層的
next
構造完成,到了下一層的時候就可以遍歷了。 -
什麼時候進入下一層?
之前是得到當前隊列的元素個數,然後遍歷那麼多次。
這裏的話,注意到最右邊的節點的
next
爲null
,所以可以判斷當前遍歷的節點是不是null
。 -
怎麼得到每層開頭節點?
之前隊列把當前層的所以節點存了起來,得到開頭節點當然很容易。
這裏的話,我們額外需要一個變量把它存起來。
三個問題都解決了,就可以寫代碼了。利用三個指針,start
指向每層的開始節點,cur
指向當前遍歷的節點,pre
指向當前遍歷的節點的前一個節點。
如上圖,我們需要把 pre
的左孩子的 next
指向右孩子,pre
的右孩子的next
指向cur
的左孩子。
如上圖,當 cur
指向 null
以後,我們只需要把 pre
的左孩子的 next
指向右孩子。
public Node connect(Node root) {
if (root == null) {
return root;
}
Node pre = root;
Node cur = null;
Node start = pre;
while (pre.left != null) {
//遍歷到了最右邊的節點,要將 pre 和 cur 更新到下一層,並且用 start 記錄
if (cur == null) {
//我們只需要把 pre 的左孩子的 next 指向右孩子。
pre.left.next = pre.right;
pre = start.left;
cur = start.right;
start = pre;
//將下一層的 next 連起來,同時 pre、next 後移
} else {
//把 pre 的左孩子的 next 指向右孩子
pre.left.next = pre.right;
//pre 的右孩子的 next 指向 cur 的左孩子。
pre.right.next = cur.left;
pre = pre.next;
cur = cur.next;
}
}
return root;
}
分享下 leetcode
的高票回答的代碼,看起來更簡潔一些,C++
寫的。
void connect(TreeLinkNode *root) {
if (root == NULL) return;
TreeLinkNode *pre = root;
TreeLinkNode *cur = NULL;
while(pre->left) {
cur = pre;
while(cur) {
cur->left->next = cur->right;
if(cur->next) cur->right->next = cur->next->left;
cur = cur->next;
}
pre = pre->left;
}
}
我的代碼裏的變量和他的變量對應關係如下。
我的 start pre cur
| | |
他的 pre cur cur.next
除了變量名不一樣,算法本質還是一樣的。
總
題目讓我們初始化 next
指針,初始化過程中我們又利用到了next
指針,很巧妙了。
更多詳細通俗題解詳見 leetcode.wang 。