114. Flatten Binary Tree to Linked List - cocoder39/coco39_LC GitHub Wiki
114. Flatten Binary Tree to Linked List
method 1: morris preorder traversal
1 (cur)
/ \
2 5
/ \ \
3 4 6
(tail)
1
/ \
# 2 (cur)
/ \
3 4
\
5
\
6
O(n) time. similar with morris traversal. the while loop would go left then all the way right, hence each edge would only be visited once.
void flatten(TreeNode* root) {
TreeNode* cur = root;
while (cur) {
if (cur->left) {
TreeNode* tail = cur->left;
while (tail->right) {
tail = tail->right;
}
tail->right = cur->right;
cur->right = cur->left;
cur->left = nullptr;
}
cur = cur->right;
}
}
Method 2: traversal order is right -> left -> root, which is reverse of preorder, thus pre
of root is left, and pre
of left is right. flattening tree from bottom to up
O(n) time and O(height) space
class Solution {
public:
void flatten(TreeNode* root) {
if (! root) {
return;
}
flatten(root->right);
flatten(root->left);
root->right = pre;
root->left = nullptr;
pre = root;
}
private:
TreeNode* pre = nullptr;
};
solution 3: divide-and-queue
1
/ \
2 5
/ \ \
3 4 6
1
/ \
2 5
\ \
3 6
\
4
(tail)
we want to link tail (4) ->right to root->right (5), thus use helper() to return the tail of the flattened linked list. attention to corner case root, or root->left, or root->right is nullptr
class Solution {
public:
void flatten(TreeNode* root) {
helper(root);
}
private:
TreeNode* helper(TreeNode* root) {
if (! root) return nullptr;
TreeNode* leftTail = helper(root->left);
TreeNode* rightTail = helper(root->right);
TreeNode* left = root->left;
TreeNode* right = root->right;
root->left = nullptr;
if (left) {
root->right = left;
leftTail->right = right;
}
if (right) {
return rightTail;
} else if (left) {
return leftTail;
} else {
return root;
}
}
};
follow up: flatten tree inorder
class Solution {
public:
void flatten(TreeNode* root) {
auto p = helper(root);
auto node = p.first;
while (node) {
cout << node->val << " ";
node = node->right;
}
}
private:
pair<TreeNode*, TreeNode*> helper(TreeNode* root) {
if (! root) return {nullptr, nullptr};
auto left = helper(root->left);
auto right = helper(root->right);
if (left.second) {
left.second->right = root;
}
root->left = nullptr;
root->right = right.first;
TreeNode* head = left.first ? left.first : root;
TreeNode* tail = right.second ? right.second : root;
return {head, tail};
}
};