[牛客0042-Leetcode]#树中populating-next-right-pointers-in-each-node-ii

Populating -next-right-pointers-in-each-node-ii populating-next-right-pointers-in-each-node-ii

タイトル説明

「各ノードに次の右ポインタを配置する」について引き続き考えてください。この質問で
は、指定されたツリーが任意のバイナリツリーである場合はどうなりますか?以前のアルゴリズムは引き続き有効ですか?
注:
使用できる追加のメモリスペースは
、次のようになります。
次のように与えられたバイナリツリーは次のとおりです。
1↵/↵23↵/↵4 5 7後は
あなたが与える関数を呼び出し、木になる必要があります:
1 - >NULL↵/↵2 - > 3 - >NULL↵/↵4 -> 5-> 7-> NULL

問題「各ノードに次の右ポインタを配置する」のフォローアップ。
与えられたツリーが任意の二分木である可能性がある場合はどうなりますか?以前のソリューションは引き続き機能しますか?

注意:

一定の余分なスペースのみを使用できます。

たとえば
、次の二分木があるとすると、

     1↵       /  ↵      2    3↵     /     ↵    4   5    7↵

関数を呼び出すと、ツリーは次のようになります。

     1 -> NULL↵       /  ↵      2 -> 3 -> NULL↵     /     ↵    4-> 5 -> 7 -> NULL

問題解決のアイデア

アイデア1:レベルトラバーサル

各レイヤーをトラバースするときは、cur配列を使用してレイヤーのすべてのノードを保存し、各レイヤーをトラバースした後、cur配列を再度トラバースして、レイヤーの各ノードを右の兄弟にリンクします。
右の兄弟は必ずしも厳密に隣接している必要はなく、複数のノードを分離できます。つまり、ノードBが同じレイヤーのノードAの右側にある限り、ノードBはの右兄弟であると言われます。ノードA

最後のノードにはライト兄弟がいないため、レイヤーの最後のノードに到達するかどうかを区別するように注意してください

/**
 * Definition for binary tree with next pointer.
 * struct TreeLinkNode {
 *  int val;
 *  TreeLinkNode *left, *right, *next;
 *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    void connect(TreeLinkNode *root) {
    
    
        if(root == NULL) return ;
        queue<TreeLinkNode *> myque;
        myque.push(root);  //根节点入队
        
        while(!myque.empty()) {
    
    
            vector<TreeLinkNode*> cur;  //保存每一层所有的节点
            int size = myque.size();  //记录每一层的节点数
            //对每一层的节点进行操作
            for(int i = 0; i < size; i ++) {
    
    
                TreeLinkNode* p = myque.front();
                myque.pop();
                cur.push_back(p);
                if(p -> left) myque.push(p -> left);
                if(p -> right) myque.push(p -> right);
            }
            //将该层的每一个节点链接到右兄弟中
            int cur_size = cur.size();
            for(int i = 0; i < cur_size - 1; i ++) {
    
    
                cur[i] -> next = cur[i + 1];
            }
        }
    }
};

改善:レイヤーの各ノードで操作する場合、cur配列にストレージを追加することなく、キュー内の右の兄弟に直接リンクされます。

/**
 * Definition for binary tree with next pointer.
 * struct TreeLinkNode {
 *  int val;
 *  TreeLinkNode *left, *right, *next;
 *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    void connect(TreeLinkNode *root) {
    
    
        if(root == NULL) return ;
        queue<TreeLinkNode *> myque;
        myque.push(root);  //根节点入队
        
        while(!myque.empty()) {
    
    
            vector<TreeLinkNode*> cur;  //保存每一层所有的节点
            int size = myque.size();  //记录每一层的节点数
            //对每一层的节点进行操作
            for(int i = 0; i < size; i ++) {
    
    
                TreeLinkNode* p = myque.front();
                myque.pop();
                cur.push_back(p);
                if(p -> left) myque.push(p -> left);
                if(p -> right) myque.push(p -> right);
                
                if(i < size - 1) {
    
      //如果没有到达该层最后一个节点,则链接右兄弟
                    p -> next = myque.front();
                }
            }
        }
    }
};

アイデア2:リンクリスト

  • 現在の層のすべてのノードの次のポインタが設定されている場合、これに従って、次の層のすべてのノードの次のポインタも順番に設定できます。
  • アイデア:各レイヤーをリンクリストと見なし、curを使用して現在のレイヤーをトラバースします。トラバース中、curが指すノードのすべての子ノード(つまり、次のレイヤー)はすべて、が指すリンクリストに文字列化されます。 pによって。
  • head.next次のレイヤーの最初のノードを保持することにより、仮想ヘッドノードヘッドを作成します。使用できるのはポインターのみであることに注意してください。head->next
/**
 * Definition for binary tree with next pointer.
 * struct TreeLinkNode {
 *  int val;
 *  TreeLinkNode *left, *right, *next;
 *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 * };
 */
class Solution {
    
    
public:
    void connect(TreeLinkNode *root) {
    
    
        while(root) {
    
    
            TreeLinkNode head(-1), *p; //创建一个虚拟头结点
            p = &head;
            for(auto cur = root; cur; cur = cur -> next) {
    
    
            	//将当前层的所有孩子节点串到下一层的链表中
                if(cur -> left) {
    
    
                    p -> next = cur -> left;
                    p = p -> next;
                }
                if(cur -> right) {
    
    
                    p -> next = cur -> right;
                    p = p -> next;
                }
            }
            root = head.next;
        }
    }
};

おすすめ

転載: blog.csdn.net/cys975900334/article/details/106870150