1. 程式人生 > 實用技巧 >leetcode 117. 填充每個節點的下一個右側節點指標 II(二叉樹,DFS)

leetcode 117. 填充每個節點的下一個右側節點指標 II(二叉樹,DFS)

題目連結

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;
    }