題目描述
給你二叉樹的根結點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 將根節點和其右子節點斷開,把原右子節點連到原...