二叉樹展開爲鏈表
題目大意:
將一棵樹展開爲單鏈表,順序爲前序遍歷的順序,使用右孩子指針作爲後繼指針。
思路:
① 將左、右子樹分別轉換爲一條鏈 (相同問題,遞歸解決)。
② 找到左邊這條鏈的尾結點
③左邊的這條鏈的尾結點接上右邊這條鏈的頭結點
④將根節點的右孩子更新爲左邊這條鏈。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void flatten(TreeNode* root) {
if(!root){
return;
}
flatten(root->left);
flatten(root->right);
if(root->left){
TreeNode* p = root->left;
//找到左邊這條鏈的末尾節點
while(p->right){
p = p->right;
}
p->right = root->right; //先使用後破壞
root->right = root->left;
}
root->left = nullptr;
}
};
上面的做法是用過遍歷去尋找一條鏈表的尾結點的,如果在將一棵樹展開成一條鏈表時直接返回返回尾結點也是可以的。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
void flatten(TreeNode* root) {
dfs(root);
}
TreeNode* dfs(TreeNode* root){
if(!root){
return nullptr;
}
//如果root是葉節點,直接返回root
if(!root->left && !root->right){
return root;
}
TreeNode *leftBackNode = dfs(root->left);
TreeNode *rightBackNode = dfs(root->right);
if(root->left){
leftBackNode->right = root->right;
root->right = root->left;
}
root->left = nullptr;
return rightBackNode?rightBackNode:leftBackNode;
}
};