【Leetcode】116. 填充同一層的兄弟節點

題目

給定一個完美二叉樹,其全部葉子節點都在同一層,每一個父節點都有兩個子節點。二叉樹定義以下:node

struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每一個 next 指針,讓這個指針指向其下一個右側節點。若是找不到下一個右側節點,則將 next 指針設置爲 NULL。面試

初始狀態下,全部 next 指針都被設置爲 NULL。算法

示例:分佈式

image

輸入:{"$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}

輸出:{"$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}

解釋:給定二叉樹如圖 A 所示,你的函數應該填充它的每一個 next 指針,以指向其下一個右側節點,如圖 B 所示。

題解

方法一: 層序遍歷

使用層序遍歷,遍歷的時候把同層的節點鏈接起來;函數

image
image

class Solution {
    public Node connect(Node root) {
        if (root == null) return null;
        Queue<Node> queue = new LinkedList<>();
        queue.add(root);
        while (!queue.isEmpty()) {
            int size = queue.size();
            Node current = null;
            while (size > 0) {
                Node node = queue.poll();
                if (node.right != null) queue.add(node.right);
                if (node.left != null) queue.add(node.left);
                node.next = current;
                current = node;
                size--;
            }
        }
        return root;
    }
}

方法二:遞歸

遞歸的時候咱們一般就分解爲遞歸子問題和遞歸結束條件。spa

遞歸子問題指針

  • 左右子樹分別連起來

遞歸結束條件code

  • node == null, 直接返回
  • node.left != null, 把left.next連到node.right
  • node.right != null && node.next != null, 把node的right 連到 node.next的left。例如遍歷到2這個節點,把5鏈接到6.

image.png

image.png

class Solution {
    public Node connect(Node root) {
        // o(1) space.
        if (root == null) return null;
        if (root.left != null) root.left.next = root.right;
        if (root.right != null && root.next != null) root.right.next = root.next.left;
        connect(root.left);
        connect(root.right);    
        return root;
    }
}

方法三: 層序遍歷 o(1)空間複雜度

層序遍歷咱們以前用隊列來作,可是有時候咱們會要求層序遍歷用常數的空間複雜度來解。這種方法最關鍵的地方在於理解如何從上一層切換到下一層的。dummy的做用用於記錄上一層的第一個節點是誰,每當遍歷完一層以後,切到下一層.
image遞歸

class Solution {
    public Node connect(Node root) {
        Node dummy = new Node(0);
        Node pre = dummy;
        Node currentRoot = root;
        while (currentRoot != null) {
            if (currentRoot.left != null) {
                pre.next = currentRoot.left;
                pre = pre.next;
            }
            if (currentRoot.right != null) {
                pre.next = currentRoot.right;
                pre = pre.next;
            }
            currentRoot = currentRoot.next;
            if (currentRoot == null) {
                // 切換層.
                pre = dummy;
                currentRoot = dummy.next;
                dummy.next      = null;
            }
        }
        return root;
    }
}

熱門閱讀

Leetcode名企之路

有問題加手撕代碼羣討論

相關文章
相關標籤/搜索