1. 程式人生 > 其它 >LeetCode-114. 二叉樹展開為連結串列

LeetCode-114. 二叉樹展開為連結串列

題目來源

114. 二叉樹展開為連結串列

題目描述

給你二叉樹的根結點 root ,請你將它展開為一個單鏈表:

  • 展開後的單鏈表應該同樣使用 TreeNode ,其中 right 子指標指向連結串列中下一個結點,而左子指標始終為 null
  • 展開後的單鏈表應該與二叉樹 先序遍歷 順序相同。

示例 1:

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

示例 2:

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

示例 3:

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

提示:

  • 樹中結點數在範圍 [0, 2000]
  • -100 <= Node.val <= 100

進階: 你可以使用原地演算法(O(1) 額外空間)展開這棵樹嗎?

題解分析

解法一:後序遍歷

  1. 本題很容易看出來是使用後序遍歷進行求解,即我們需要先展開左右子樹,再將右子樹接到左子樹上,接著將左子樹設定為根節點的右子樹。
  2. 題目的一個難點就是,如何將右子樹接到左子樹的右邊。因為我們使用的是後序遍歷,遍歷回來時,我們只能拿到展開後的左右子樹跟,而如果需要將右子樹接到左子樹右邊則需要知道左子樹的最後一個結點。
  3. 既然我們需要左子樹的最後一個結點,那我們可以在遞迴結束後遍歷左子樹直到最後一個結點,這樣的話我們就拿到了左子樹的尾結點,進而可以完成我們的拼接。
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public void flatten(TreeNode root) {
        if(root == null){
            return;
        }

        // 分別展開左右子樹
        flatten(root.left);
        flatten(root.right);

        TreeNode left = root.left;
        TreeNode right = root.right;

        // 左子樹接到右邊
        root.left = null;
        root.right = left;

        // 右子樹接到左子樹右邊
        left = root;// 注意這裡的賦值
        while(left.right != null){
            left = left.right;
        }
        left.right = right;
    }
}