1. 程式人生 > >leetcode 之Populating Next Right Pointers in Each Node解題思路

leetcode 之Populating Next Right Pointers in Each Node解題思路

題目如下:

Given a binary tree

    struct TreeLinkNode {
      TreeLinkNode *left;
      TreeLinkNode *right;
      TreeLinkNode *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

.

Note:

  • You may only use constant extra space.
  • You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).

For example,
Given the following perfect binary tree,

         1
       /  \
      2    3
     / \  / \
    4  5  6  7

After calling your function, the tree should look like:

         1 -> NULL
       /  \
      2 -> 3 -> NULL
     / \  / \
    4->5->6->7 -> NULL

題目的大體意思就是將一顆滿二叉樹轉變成三叉樹,每一個節點的next值指向它右邊的節點,如果右邊沒有節點的話,置為Null,初始值都為null。

下面給出解題思路:

從圖上的例子就可以看出,新增next屬性是按層次新增的,所以該題有點類似於層次遍歷。因此可以採用一個輔助資料結構--佇列。


節點4的next節點就指向其後面的節點。節點5,6依次如此。

和層次遍歷不同的是,這裡需要記錄每個節點所屬的層次,否則如果7後面添加了下一層次的節點,按照上面的演算法節點7的next節點將會指向其後面的節點,就是錯誤的。

那如何記錄每一個節點的層次呢?

其實也不用額外開闢空間記錄每個節點的層次,這裡我們只需要記錄每一層有多少節點,那我們就會更改(節點個數 - 1)個next指標。如上圖,該層次有4個節點,只要更改3個next指標即可,所以用一層while迴圈控制就ok了。每次獲取一對節點,因此第一個節點用刪除頭結點的方式,第二個節點用獲取頭節點但是不刪除的方式。直到剩下最後一對節點,用同時刪除兩個頭結點的方式。

每一層的節點數是2的次冪,比較容易計算。

/**
 * Definition for binary tree with next pointer.
 * public class TreeLinkNode {
 *     int val;
 *     TreeLinkNode left, right, next;
 *     TreeLinkNode(int x) { val = x; }
 * }
 */
public class Solution {
    public void connect(TreeLinkNode root) {
        if(root == null || (root.left == null && root.right == null)) return;
        Queue<TreeLinkNode> queue = new LinkedList<TreeLinkNode>();
        int level = 1;
        queue.add(root.left);
        queue.add(root.right);
        while(queue.peek() != null){//如果佇列不為空,即進行迴圈
            int times = (int)Math.pow(2,level) - 1;//記錄每一層的節點個數
            TreeLinkNode first = null;
            TreeLinkNode second = null;
            while(times > 1){
                first = queue.remove();//先刪除頭結點
                second = queue.element();//獲取頭結點但不刪除
                first.next = second;
                queue.add(first.left);
                queue.add(first.right);
                times--;
            }
            //剩下最後一對節點,同時刪除頭結點
            first = queue.remove();
            second = queue.remove();
            first.next = second;
            queue.add(first.left);
            queue.add(first.right);
            queue.add(second.left);
            queue.add(second.right);
            level++;//當一層結束之後,層次增加
        }
    }
}