[牛客网-Leetcode] #树 简单 populating-next-right-pointers-in-each-node

填充节点的右兄弟指针 populating-next-right-pointers-in-each-node

题目描述

给定一个二叉树
struct TreeLinkNode {↵ TreeLinkNode *left;↵ TreeLinkNode *right;↵ TreeLinkNode *next;↵ }
填充所有节点的next指针,指向它右兄弟节点。如果没有右兄弟节点,则应该将next指针设置为NULL。
初始时,所有的next指针都为NULL
注意:
你只能使用常量级的额外内存空间
可以假设给出的二叉树是一个完美的二叉树(即,所有叶子节点都位于同一层,而且每个父节点都有两个孩子节点)。
例如:给出如下的完美二叉树
1↵ / ↵ 2 3↵ / / ↵ 4 5 6 7↵

调用完你给出的函数以后,这颗二叉树应该 变成:

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

Given a binary tree
struct TreeLinkNode {↵ TreeLinkNode *left;↵ TreeLinkNode *right;↵ TreeLinkNode *next;↵ }↵

Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL.

Initially, all next pointers are set to NULL.

Note:

You may only use constant extra space.
You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).

For example,
Given the following perfect binary tree,

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

After calling your function, the tree should look like:

     1 -> NULL↵       /  ↵      2 -> 3 -> NULL↵     /   / ↵    4->5->6->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:递归

/**
 * 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 ;
        if(root -> left && root -> right) {
    
    
            root -> left -> next = root -> right;
        }
        if(root -> right && root -> next) {
    
    
            root -> right -> next = root -> next -> left;
        }
        connect(root -> left);
        connect(root -> right);
    }
};

思路3:链表

  • 如果当前层所有结点的next 指针已经设置好了,那么据此,下一层所有结点的next指针也可以依次被设置。
  • 思路:将每一层看成链表,用cur遍历当前层,遍历的过程中,将cur指向节点的所有孩子节点(即下一层)全部串到p指向的链表中。
  • 创建一个虚拟头结点head,通过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/106869350
今日推荐