LeetCode117:填充每個節點的下一個右側節點指針 II

  • 2020 年 2 月 26 日
  • 筆記

LeetCode117:填充每個節點的下一個右側節點指針 II Populating Next Right Pointers in Each Node II

題目:

給定一個二叉樹

Given a binary tree

struct Node {    int val;    Node *left;    Node *right;    Node *next;  }  

填充它的每個 next 指針,讓這個指針指向其下一個右側節點。如果找不到下一個右側節點,則將 next 指針設置為 NULL

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.

初始狀態下,所有 next 指針都被設置為 NULL

Initially, all next pointers are set to NULL.

進階:

  • 你只能使用常量級額外空間。
  • 使用遞歸解題也符合要求,本題中遞歸程式佔用的棧空間不算做額外的空間複雜度。

Follow up:

  • You may only use constant extra space.
  • Recursive approach is fine, you may assume implicit stack space does not count as extra space for this problem.

示例:

img

輸入:root = [1,2,3,4,5,null,7]  輸出:[1,#,2,3,#,4,5,7,#]  解釋:給定二叉樹如圖 A 所示,你的函數應該填充它的每個 next 指針,以指向其下一個右側節點,如圖 B 所示。  

提示:

  • 樹中的節點數小於 6000
  • -100 <= node.val <= 100 Constraints:
  • The number of nodes in the given tree is less than 6000.
  • -100 &lt;= node.val &lt;= 100

解題思路:

與上一題的唯一區別就是該二叉樹不是完美二叉樹。對於完美二叉樹的思路:

  • 一個結點的左孩子的 next 指針指向該結點的右孩子
  • 一個結點的右孩子的 next 指針指向該結點的 next 結點的左孩子

不再適用,因為一個結點可能沒有左孩子或者沒有右孩子。只需稍微轉變一下思路即可:

先設置一個頭結點 temp,作為每層的最左側結點。再設置一個前驅結點 prev = temp,該結點的 next 指針指向最鄰近的右側結點,然後刷新前驅結點:prev = prev.next 。繼續查找 prev 結點最鄰近的右側結點,重複上述操作,直到該層結束。而此時 頭結點 temp.next 就是下一層的最左側結點。

Java:

class Solution {      public Node connect(Node root) {            if (root == null)              return root;          Node temp = new Node(0); // 虛擬頭結點          Node curr = root, prev = temp; // 當前結點和前驅結點            while (curr != null) {              if (curr.left != null) {                  prev.next = curr.left;                  prev = prev.next;              }              if (curr.right != null) {                  prev.next = curr.right;                  prev = prev.next;              }              curr = curr.next;              // curr 為 null 時,該層連接完成。              if (curr == null) {                  curr = temp.next; // 當前結點改為下一層的最左側結點                  temp.next = null; // 虛擬結點 next 指針指向 null                  prev = temp; // 前驅結點重新設置為虛擬頭結點              }          }          return root;      }  }  

Python:

class Solution:      def connect(self, root: 'Node') -> 'Node':          if not root:              return root          temp = Node(0) # 虛擬頭結點          prev,curr = temp,root # 當前結點和前驅結點            while curr:              if curr.left:                  prev.next = curr.left                  prev = prev.next              if curr.right:                  prev.next = curr.right                  prev = prev.next              curr = curr.next              # curr 為 null 時,該層連接完成              if not curr:                  curr = temp.next # 當前結點改為下一層的最左側結點                  temp.next = None # 虛擬結點 next 指針指向 null                  prev = temp # 前驅結點重新設置為虛擬頭結點          return root