For example,
Given
1 / \ 2 5 / \ \ 3 4 6The flattened tree should look like:
1 \ 2 \ 3 \ 4 \ 5 \ 6
这个题目也属于serialize tree的问题, 把tree serialize 成single linklist。 对于把tree
serialize 成single linklist 或者 double linklist的算法是相似的, 基本思路: 都是运用一种tree
traversal 的方法,当遍历到一个Node的时候, 对该node和previous node 进行指针的操作,
需要对整个过程定义一个linklist的head指针, 然后需要有一个 pre指针,指向tree traversal
结果的previous的node,在当前层对current root 和 previous node指针进行操作。
当然对于不同的题目要求做法也有些不同。
这个题目观察发现,其实是对tree进行了pre-order traversal,所以可以用pre-order traversal
的过程来convert, 如果 pre = NULL,此时root -》head, 否则, pre-》right = root, pre->left = NULL
但是这样的话会有一个问题,在进行pre-》right=root的时候其实就改变了root-》right的值,所以
我们需要提前将root-》right的值保存在tmp里面,在对right subtree进行serialize的时候直接利用就可以
了。
class Solution { private: void helper(TreeNode* root, TreeNode* &head, TreeNode* &pre) { //base case if (root == NULL) return; TreeNode* tmp = root->right; if (pre == NULL) { head = root; } else { pre->right = root; pre->left = NULL; } pre = root; helper(root->left, head,pre); helper(tmp,head,pre); } public: //pre order void flatten(TreeNode* root) { TreeNode* head = NULL; TreeNode* pre = NULL; helper(root, head,pre); root = head; return; } };
time complexity: O(n)
space complexity: O(logn) //stack size
同样类似的题目有: convert binary tree to double linklist
这里采用preorder, inorder, postorder的顺序都可以,以inorder为例,
//simple recursion to convert the tree to double linked list
void SerializeTree(TreeNode* root, TreeNode* &head) {
//base case
if (root == NULL) return;
//pre points to the previous node in inorder traversal ordering
static TreeNode* pre = NULL;//staic here equals to global variable
SerializeTree(root->left,head);
if (pre == NULL) {
head = root;
} else {
pre->right = root;
root->left = pre;
}
pre = root;
SerializeTree(root->right,head);
}time complexity: O(n)
space complexity: O(logn)
No comments:
Post a Comment