114 二叉樹展開為鍊錶

2021-10-19 11:39:46 字數 3564 閱讀 3037

題目描述

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

示例 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]

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

題解:法一:

因為鍊錶是先序遍歷結果,優先考慮先序遍歷。

如果使用遞迴的話,那麼在將左子樹接到根節點右子樹過程中,會丟失了原來右子樹的資訊,因此,遞迴先序遍歷不太現實。

考慮先序遍歷迭代方式,有兩種迭代方式實現:

第一種:

void

preorderstack

( treenode* root )

root = stk.

top();

stk.

pop();

root = root-

>right;

}}

第二種:

void

preorderstack

( treenode* root )

}

可以看到,在第一種迭代實現方式中,如果我們修改了根節點右指標指向,還是丟失右子樹節點。而第二種方式提前將右子樹節點儲存在棧中,可以防止丟失。所以,我們可以利用第二種方式來通過先序遍歷建立鍊錶。

時間複雜度:o(n

)o(n)

o(n)

額外空間複雜度:o(n

)o(n)

o(n)

/**

* definition for a binary tree node.

* struct treenode

* treenode(int x) : val(x), left(nullptr), right(nullptr) {}

* treenode(int x, treenode *left, treenode *right) : val(x), left(left), right(right) {}

* };

*/class

solution

if( root-

>right ) stk.

emplace_back

( root-

>right );if

( root-

>left ) stk.

emplace_back

( root-

>left )

; pre = root;}}

};/*記憶體:12.3mb,擊敗:88.68%

*/

法二:

先序遍歷:根節點 左子樹 右子樹

逆後序遍歷:右子樹 左子樹 根節點

兩者是逆序的關係,於是我們可以考慮逆後序遍歷,每遍歷到乙個節點就將當前節點的右指標更新為上乙個節點。

時間複雜度:o(n

)o(n)

o(n)

額外空間複雜度:o(n

)o(n)

o(n)

/**

* definition for a binary tree node.

* struct treenode

* treenode(int x) : val(x), left(nullptr), right(nullptr) {}

* treenode(int x, treenode *left, treenode *right) : val(x), left(left), right(right) {}

* };

*/class

solution

void

flatten

(treenode* root)};

/*記憶體:12.4mb,擊敗:77.11%

*/

也可以迭代實現,下面是後序遍歷的迭代版本:

void

postorderstack

(treenode* root)

cur = stk.

top();

if(!cur-

>right || cur-

>right == pre )

else cur = cur-

>right;

}}

在上面修改一下即可:

/**

* definition for a binary tree node.

* struct treenode

* treenode(int x) : val(x), left(nullptr), right(nullptr) {}

* treenode(int x, treenode *left, treenode *right) : val(x), left(left), right(right) {}

* };

*/class

solution

root = stk.

top();

if(!root-

>left || root-

>left == pre )

else root = root-

>left;}}

};/*記憶體:12.5mb,擊敗:76.24%

*/

法三:

考慮一種迭代方法:

時間複雜度:o(n

)o(n)

o(n)

額外空間複雜度:o(1

)o(1)

o(1)

/**

* definition for a binary tree node.

* struct treenode

* treenode(int x) : val(x), left(nullptr), right(nullptr) {}

* treenode(int x, treenode *left, treenode *right) : val(x), left(left), right(right) {}

* };

*/class

solution

root = root-

>right;}}

};/*記憶體:12.3mb,擊敗:94.72%

*/

114 二叉樹展開為鍊錶

首先是原地演算法的定義 演算法原地工作的含義是指不需要任何額外的輔助,演算法所需要的輔助空間不隨著問題的規模而變化,是乙個確定的值。通過觀察示例可以知道,我們可以猜想,大方向是前序遍歷。第一種思路 dfs。設定乙個全域性的指標 這種做法有點脫離原地演算法,因為多開闢了乙個指標變數 核心思想是拿到乙個...

114 二叉樹展開為鍊錶

一開始寫的 114 二叉樹展開為鍊錶 definition for a binary tree node.class treenode def init self,x self.val x self.left none self.right none class solution def flatt...

114 二叉樹展開為鍊錶

給定乙個二叉樹,原地將它展開為鍊錶。例如,給定二叉樹 1 2 5 3 4 6將其展開為 1 2 3 4 5 6思路 從題目可以看出來要求先根遍歷。從根節點開始出發,先檢測其左子結點是否存在 1 找到左子結點最後面的右子節點 如果沒有,就是左子節點本身 2 將根節點和其右子節點斷開,把原右子節點連到原...