问题
给出一个二叉树,将其原地平面化为链表。
例如,给出:
1
/
2 5
/
3 4 6
平面化后的树看起来应该是这样:
1
2
3
4
5
6
初始思路
观察例子中平面化的过程,不难发现其实就是一个二叉树前序遍历的过程。让我们复习一下二叉树前序遍历的方法,根据wiki条目Tree traversal,伪代码如下:
preorder(node)
if node == null then return visit(node) preorder(node.left) preorder(node.right)
iterativePreorder(node)
parentStack = empty stack
while not parentStack.isEmpty() or node != null
if node != null then
visit(node)
parentStack.push(node.right)
node = node.left
else
node = parentStack.pop()
这里我们实现基本照搬以上伪代码就行了,唯一一点小改动是增加了一个TreeNode*变量来记录前序遍历过程中上一个节点。这样我们在依前序遍历到第n个节点时,可以通过这个指针将第n-1个节点的right指向当前节点,left置空。选择非递归方案的代码如下:
1 class Solution { 2 public: 3 void flatten(TreeNode *root) 4 { 5 if(!root) 6 { 7 return; 8 } 9 10 previous_ = nullptr; 11 12 TreeNode* current = root; 13 14 while(current || !rightCandidates_.empty()) 15 { 16 if(!current) 17 { 18 current = rightCandidates_.top(); 19 rightCandidates_.pop(); 20 } 21 22 if(previous_) 23 { 24 previous_->right = current; 25 previous_->left = nullptr; 26 } 27 28 previous_ = current; 29 30 if(current->right) 31 { 32 rightCandidates_.push(current->right); 33 } 34 35 current = current->left; 36 } 37 } 38 39 private: 40 41 TreeNode* previous_; 42 43 std::stack<TreeNode*> rightCandidates_; 44 };
Judge Small和Judge Large都顺利通过。