###### tags: `Leetcode` `medium` `tree` `pointer` `python` # 117. Populating Next Right Pointers in Each Node II ## [題目連結:] https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/ ## 題目: Given a binary tree ``` struct Node { int val; Node *left; Node *right; Node *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```. **Follow-up:** * You may only use constant extra space. * The recursive approach is fine. You may assume implicit stack space does not count as extra space for this problem. ![](https://i.imgur.com/oTgi4sU.png) ![](https://i.imgur.com/Ndn62xK.png) #### [圖片來源:] https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/ ## 解題想法: 同類型題目: [116. Populating Next Right Pointers in Each Node](/ycdkTjYJT26U898X_34enw) * 題目為要求把一顆完全二元樹的每層node之間順序連接 * 此題要求constant extra space * 使用pointer * 想法: * 每次處理當前node的下一層進行next連結 * cur=root: * 紀錄當前root * 每次向右同層遍歷: cur=cur.next * 若cur==None,則cur=head,進入下一層 * head=None: * 用來指向下一層的最左node(第一個node) * 每當該層走完,cur便會指向head * pre=None: * 用來連結next的,若當前root右邊有node,則next連結,然後pre向右移動 * 示意圖: ![](https://i.imgur.com/oIwPYgM.png) ``` 說明: loop1:紅 開始cur=1,head=None,pre=None * 因為cur.left存在,且pre=None,表示下一層還沒開始連結 * 所以head=cur.left,即head=2 * 將pre=cur.left,即pre=2 * 因為cur.right存在,且pre!=None 所以將pre連接cur.right,即2->3 且將pre=pre.next,pre=3 * 此cur左右子都遍歷完了,將cur=cur.next 因為cur=None 所以表示該層結束,cur=head移動到下層, 同時清除head跟pre,重設為None loop2:藍 cur=2,head=None,pre=None * 因為cur.left存在,且pre=None * head=4,pre=4 * 因為cur.right=5存在 4->5,pre=pre.next,pre=5 * cur左右子遍歷完,cur=cur.next loop3: 黑 cur=3 ,head=4,pre=5 * cur.right存在 * 5->7 ,pre=pre.next,pre=7 * cur=cur.next 因為cur=None 移到下層,重設head,pre loo4~end: 紅 因為cur=4沒子樹,所以cur=cur.next,cur=5 5也沒子樹,cur=7,7也沒子樹,cur=cur.next=None 連完邊end ``` ## Python: * 此題真的很燒腦 :cry: * 直接代碼上標注trace過程 ``` python= #可同時解116 class Node(object): def __init__(self, val=0, left=None, right=None, next=None): self.val = val self.left = left self.right = right self.next = next def insertLeft(self,node): if self.left==None: self.left=Node(node) else: self.left.insertLeft(node) def insertRight(self,node): if self.right==None: self.right=Node(node) else: self.right.insertRight(node) def printTree(self): root=self stack=[root] res=[] while stack: root=stack.pop(0) res.append(root.val) if root.left: stack.append(root.left) if root.right: stack.append(root.right) print(res) class Solution(object): def connect(self, root): """ :type root: Node :rtype: Node """ cur=root #head用來指向下一層的最左node #當每層走完 cur便會指向head head=None #pre用來連結當前遍歷到的右邊node #用以遍歷同時連結next pre=None while cur: #loop1: cur=1 #loop2: cur=2 if cur.left: #loop1: 2存在 #loop2: 4存在 #若pre有值,則將pre.next連結到當前的node if pre: pre.next=cur.left pre=pre.next else: #pre=None 表示下一行還沒開始遍歷 head=cur.left #loop1:head=2 #loop2:head=4 pre=cur.left #loop1:pre=2 #loop2:pre=2 if cur.right: #loop1: 3存在 #loop2: 5存在 if pre: #loop1: 因為pre=2 !=None pre.next=cur.right #loop1: 將pre.next=3 即2->3 #loop2: 將pre.next=5 即4->5 pre=pre.next #loop1: pre=3 #loop2: pre=5 else: head=cur.right pre=cur.right #遍歷完左右子樹,cur移動到他的兄弟node cur=cur.next #loop1: 1.next=None #cur=3 #若cur==None 表示該行已遍歷完 if cur==None: cur=head #loop1: 遍歷下一行 head=None #loop1:清空head pre pre=None return root root = Node(1) root.insertLeft(2) root.insertRight(3) root.left.insertLeft(4) root.left.insertRight(5) root.right.insertLeft(6) root.right.insertRight(7) root.printTree() result = Solution() ans = result.connect(root) root.printTree() ```