今是昨非

今是昨非

日出江花红胜火,春来江水绿如蓝

在每個節點中填充下一個右指針的演算法

在每個節點中填充下一個右指針的演算法#

給定一個完美的二元樹,其中所有的葉子節點都在同一層,並且每個父節點都有兩個子節點。該二元樹具有以下定義:

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

將每個 next 指針指向其下一個右節點。如果沒有下一個右節點,則 next 指針應該設置為 NULL。

最初,所有的 next 指針都被設置為 NULL。

範例 1:

輸入: root = [1,2,3,4,5,6,7]
輸出: [1,#,2,3,#,4,5,6,7,#]

解釋:給定上面的完美二元樹(圖 A),您的函數應該將每個 next 指針填充為指向其下一個右節點,就像圖 B 中的一樣。序列化的輸出按照 next 指針連接的層次順序,其中 '#' 表示每個層次的結束。

範例 2:

輸入: root = []
輸出: []

解法#

這個問題我不會,看了解法還是不懂,所以去找了個視頻,POPULATING NEXT RIGHT POINTERS IN EACH NODE (Leetcode) - Code & Whiteboard,視頻裡講的是 Python 的代碼,但是邏輯很清晰,翻譯成 Swift 也可以用。

簡單理解如下:

  • 完美二元樹,所以有 left 一定有 right,故而遍歷時通過判斷 node.left 是否存在,即可知道是否有下一級
  • 所有的 next 指針都被設置為 NULL,初始時所有 node 的 next 都是 nil
  • 同一個父節點的 left 和 right 設置 next 關係,即 node.left.next = node.right,比如 2 和 3、4 和 5、6 和 7
  • 不同父節點的設置 next 關係,則需要判斷父節點的 next 是否存在,存在則設置 node.right.next = node.next.left,比如 5 和 6

代碼如下:


/**
 * Definition for a Node.
 * public class Node {
 *     public var val: Int
 *     public var left: Node?
 *     public var right: Node?
 *	   public var next: Node?
 *     public init(_ val: Int) {
 *         self.val = val
 *         self.left = nil
 *         self.right = nil
 *         self.next = nil
 *     }
 * }
 */

class Solution {
    func connect(_ root: Node?) -> Node? {
        // 錯誤檢查
        if root == nil {
            return nil
        }
        
        var leftMostNode = root
        // 遍歷左子樹
        while (leftMostNode?.left != nil) {
            var cur = leftMostNode
            while (cur?.left != nil) {
                cur?.left?.next = cur?.right
                if (cur?.next != nil) {
                    cur?.right?.next = cur?.next?.left
                }
                cur = cur?.next
            }
            leftMostNode = leftMostNode?.left
        }
        return root
    }
}

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。