leetcode 117. 填充每個節點的下一個右側節點指標 II(二叉樹,DFS)
阿新 • • 發佈:2021-01-19
題目連結
https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/
題目大意
給定一個二叉樹
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每個 next 指標,讓這個指標指向其下一個右側節點。如果找不到下一個右側節點,則將 next 指標設定為 NULL。
初始狀態下,所有next 指標都被設定為 NULL。
進階:
你只能使用常量級額外空間。
使用遞迴解題也符合要求,本題中遞迴程式佔用的棧空間不算做額外的空間複雜度。
給一顆二叉樹,要求每個節點與最右邊的節點相連線,注意區別:這題和116題意思不太相同,116題還可以保證每個節點的左右子樹都存在(除非葉子節點)。
其次,本題難點還在於要求常數的記憶體空間,這就排除了使用佇列進行層次遍歷的做法
最後,本題對於遞迴遍歷的順序還有要求:即需要先遍歷右子樹,再遍歷左子樹
在這幅圖中,如果先遍歷左子樹,再遍歷右子樹,那麼從9---1之間的指標在遍歷以2為根節點的左子樹時沒有被連線,這樣會造成以7為根節點的右子樹0,無法找到右邊相鄰的8
//本題將條件限制為 二叉樹 //與116題注意區分,不一定左子樹存在 //注意遞迴左右子樹的區別 class Solution { public: Node *getnext(Node *root){ if(!root) return root; if(root->left) return root->left; if(root->right) return root->right; return getnext(root->next); } Node* connect(Node* root) { if(!root) return root; if(root->left && root->right) root->left->next=root->right; if(root->left && !root->right) root->left->next=getnext(root->next); if(root->right) root->right->next=getnext(root->next); //無論左子樹是否為空,均需要找到相鄰的右子樹 // if(!root->left && root->right) root->right->next=getnext(root->next); connect(root->right); connect(root->left); return root; } }
初次的做法:
Node* connect(Node* root) {//注意需要判空 節點位置的資訊可能為空 //怎麼維護左邊起的第二個節點?? // if(!root || !root->left) return root; if(!root) return root; if(root->left){ Node *tmp=NULL, *start=root; if(start->right) tmp=start->right; else{ while(start->next){ if(start->next->left) { tmp=start->next->left; break; } else if(start->next->right){ tmp=start->next->right; break; } else{ start=start->next; } } } root->left->next=tmp; } if(root->next){ if(root->right){ if(root->next->left) root->right->next=root->next->left; else root->right->next=root->next->right; } } connect(root->right); connect(root->left); return root; }