LeetCode - 解题笔记 - 117 - Populating Next Right Pointers in Each Node II

龙默
2023-12-01

Solution 1

对于前一个题 0116. Populating Next Right Pointers in Each Node ,其方法一对于树的内部结构是无关的,因此可以直接拿过来用

  • 时间复杂度: O ( N ) O(N) O(N),其中 N N N为输入序列的节点个数,线性遍历处理输入
  • 空间复杂度: O ( 2 ⌊ log ⁡ N ⌋ ) O(2^{\lfloor \log N \rfloor}) O(2logN),其中 N N N为输入序列的节点个数,因为最坏情况下,最后一层全满,整个队列最大占用就是最后一层
/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* left;
    Node* right;
    Node* next;

    Node() : val(0), left(NULL), right(NULL), next(NULL) {}

    Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}

    Node(int _val, Node* _left, Node* _right, Node* _next)
        : val(_val), left(_left), right(_right), next(_next) {}
};
*/

class Solution {
public:
    Node* connect(Node* root) {
        if (root != nullptr) {
            queue<Node*> q;
            q.push(root);
            
            // cout << "ROOT " << root->val << endl;
            
            while (!q.empty()) {
                int numNodeLevel = q.size();
                
                
                for(int i = 0; i < numNodeLevel; i++) {
                    auto now = q.front();
                    q.pop();
                    // cout << "NOW " << now->val << endl;
                    
                    if (i < numNodeLevel - 1) {
                        // 最后一个不链接
                        now->next = q.front();
                    }
                    
                    
                    auto left = now->left;
                    if (left != nullptr) {
                        // cout << "LEFT " << left->val << endl;
                        q.push(left);
                    }

                    auto right = now->right;
                    if (right != nullptr) {
                        // cout << "RIGHT " << right->val << endl;
                        q.push(right);
                    }
                }
            }
        }

        return root;
    }
};

Solution 2

针对上一题的官方改进解法进行调整,一个是下一层第一个节点的确定,一个是保留下一层遍历的前驱节点进行next链接

  • 时间复杂度: O ( N ) O(N) O(N),其中 N N N为输入序列的节点个数,线性遍历处理输入
  • 空间复杂度: O ( 1 ) O(1) O(1),仅维护常数个线性变量
/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* left;
    Node* right;
    Node* next;

    Node() : val(0), left(NULL), right(NULL), next(NULL) {}

    Node(int _val) : val(_val), left(NULL), right(NULL), next(NULL) {}

    Node(int _val, Node* _left, Node* _right, Node* _next)
        : val(_val), left(_left), right(_right), next(_next) {}
};
*/

class Solution {
public:
    Node* connect(Node* root) {
        if (root != nullptr) {
            auto nodeRoot = root; // 同层的最左节点,第一个节点
		        while (nodeRoot != nullptr) {
		            
		            // 遍历这一层节点组织成的链表,为下一层的节点更新 next 指针
		            auto now = nodeRoot;
		            
                Node* nextLevel = nullptr;
                Node* ready = nullptr; // 准备进行链接的节点
		            while (now != nullptr) {
		                
		                
		                if (now->left != nullptr) {
                          // 在同层遍历的过程中,确定下一层的头节点
                          if (nextLevel == nullptr) {
                              nextLevel = now->left;
                          }
                          
                          if (ready == nullptr) {
                              ready = now->left;    
                          } else {
                              ready->next = now->left;
                              ready = ready->next;
                          }
                      }
                      
                      if (now->right != nullptr) {
                          // 在同层遍历的过程中,确定下一层的头节点
                          if (nextLevel == nullptr) {
                              nextLevel = now->right;
                          }
                          
                          if (ready == nullptr) {
                              ready = now->right;    
                          } else {
                              ready->next = now->right;
                              ready = ready->next;
                          }
                      }
		                
		                now = now->next; // 考察下一个节点
		            }
		            
		            nodeRoot = nextLevel; // 前往下一层,直接去最左节点的做节点(下一层的最左节点)
		        }
        }

        return root;
    }
};

Solution 3

Solution 1的Python实现

"""
# Definition for a Node.
class Node:
    def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None):
        self.val = val
        self.left = left
        self.right = right
        self.next = next
"""

class Solution:
    def connect(self, root: 'Node') -> 'Node':
        if root is not None:
            q = collections.deque([root])
            
            while q:
                numNodeLevel = len(q)
                
                for i in range(numNodeLevel):
                    
                    now = q.popleft()

                    if i < numNodeLevel - 1:
                        now.next = q[0]
                    
                    left, right = now.left, now.right
                    if left is not None:
                        q.append(left)
                    if right is not None:
                        q.append(right)
                        
                    
        return root

Solution 4

Solution 2的Python实现

"""
# Definition for a Node.
class Node:
    def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None):
        self.val = val
        self.left = left
        self.right = right
        self.next = next
"""

class Solution:
    def connect(self, root: 'Node') -> 'Node':
        if root is not None:
            nodeRoot = root
            
            while nodeRoot is not None:
                now = nodeRoot
                
                nextLevel = None
                ready = None
                
                while now is not None:
                    
                    if now.left is not None:
                        if nextLevel is None: nextLevel = now.left
                            
                        if ready is None: 
                            ready = now.left
                        else:
                            ready.next = now.left
                            ready = ready.next
                            
                    if now.right is not None:
                        if nextLevel is None: nextLevel = now.right
                            
                        if ready is None: 
                            ready = now.right
                        else:
                            ready.next = now.right
                            ready = ready.next
     
                    now = now.next
                    
                nodeRoot = nextLevel
                    
        return root
 类似资料: