You are given a perfect binary tree where all leaves are on the same level, and every parent has two children. The binary tree has the following definition:javascript
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
.html
Initially, all next pointers are set to NULL
.java
Example:node
Input: {"$id":"1","left":{"$id":"2","left":{"$id":"3","left":null,"next":null,"right":null,"val":4},"next":null,"right":{"$id":"4","left":null,"next":null,"right":null,"val":5},"val":2},"next":null,"right":{"$id":"5","left":{"$id":"6","left":null,"next":null,"right":null,"val":6},"next":null,"right":{"$id":"7","left":null,"next":null,"right":null,"val":7},"val":3},"val":1} Output: {"$id":"1","left":{"$id":"2","left":{"$id":"3","left":null,"next":{"$id":"4","left":null,"next":{"$id":"5","left":null,"next":{"$id":"6","left":null,"next":null,"right":null,"val":7},"right":null,"val":6},"right":null,"val":5},"right":null,"val":4},"next":{"$id":"7","left":{"$ref":"5"},"next":null,"right":{"$ref":"6"},"val":3},"right":{"$ref":"4"},"val":2},"next":null,"right":{"$ref":"7"},"val":1} Explanation: Given the above perfect binary tree (Figure A), your function should populate each next pointer to point to its next right node, just like in Figure B.
Note:app
對於滿二叉樹的每一層,將當前層每個結點的next域指向該層的右邊一個結點;若是已是當前層的最右結點,則指向null。(限制只能使用\(O(1)\)的額外空間,若是使用遞歸,則系統棧不計入額外空間)this
若是不限制額外空間大小,最簡單的作法是層序遍歷處理。spa
兩種使用遞歸的方法:code
另有一種只須要\(O(1)\)空間的迭代方法:
用head指向每一層的最左側結點,用cur從左到右遍歷(經過next鏈接)該層全部結點,在遍歷過程當中將每一個結點的左右子結點與右兄弟結點的左子結點相連。迭代head處理全部層。htm
class Solution { public Node connect(Node root) { if (root == null) { return null; } connect(root.left, root.right); return root; } private void connect(Node x, Node y) { if (x == null || y == null) { return; } x.next = y; // 分三種狀況處理子樹鏈接 connect(x.left, x.right); connect(x.right, y.left); connect(y.left, y.right); } }
class Solution { public Node connect(Node root) { rConnect(root); return root; } private void rConnect(Node x) { if (x == null) { return; } // 滿二叉樹的性質,若是存在左子樹則必然存在右子樹,且若存在兄弟結點,則兄弟結點也必存在左子樹 if (x.left != null) { x.left.next = x.right; if (x.next != null) { x.right.next = x.next.left; } } rConnect(x.left); rConnect(x.right); } }
class Solution { public Node connect(Node root) { if (root == null) { return null; } Node head = root; while (head.left != null) { Node cur = head; while (cur != null) { cur.left.next = cur.right; if (cur.next != null) { cur.right.next = cur.next.left; } cur = cur.next; } head = head.left; } return root; } }
class Solution { public Node connect(Node root) { if (root == null) { return null; } Queue<Node> q = new ArrayDeque<>(); q.offer(root); while (!q.isEmpty()) { int size = q.size(); Node[] level = q.toArray(new Node[size]); for (int i = 0; i < size; i++) { if (i != size - 1) { level[i].next = level[i + 1]; } Node cur = q.poll(); if (cur.left != null) q.offer(cur.left); if (cur.right != null) q.offer(cur.right); } } return root; } }
/** * @param {Node} root * @return {Node} */ var connect = function (root) { let q = [] if (root) { q.push(root) } while (q.length) { let pre = null let size = q.length for (let i = 0; i < size; i++) { if (i == 0) { pre = q.shift() } else { let cur = q.shift() pre.next = cur pre = cur } if (pre.left) q.push(pre.left) if (pre.right) q.push(pre.right) } } return root }
參考blog