Flatten Binary Tree to Linked List

题目描述:

Given a binary tree, flatten it to a linked list in-place.

For example,
Given

         1
        / \
       2   5
      / \   \
     3   4   6

The flattened tree should look like:
   1
    \
     2
      \
       3
        \
         4
          \
           5
            \
             6

click to show hints.

Hints:

If you notice carefully in the flattened tree, each node's right child points to the next node of a pre-order traversal.

对于这样的题目,二叉树与链表之间的关系是很微妙的,遇到了很多的关于二叉树转换为链表的方式,那么就对上面的这个题做一些简单的介绍。

Trail 1 : 根据Hint可以知道,只要我们弄清楚了先序遍历时各个节点的访问顺序,将其保存为一个队列,在先序遍历完成之后,直接使用这些节点的right指针将它们串联起来即可。

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    void flatten(TreeNode *root) {
        if(root == NULL)return;
        TreeNode *temp = root;
        stack<TreeNode *> myStack;
        queue<TreeNode *> myQueue;
        
        while(temp || (!(myStack.empty())))
        {
            while(temp)
            {
                myQueue.push(temp);
                myStack.push(temp);
                temp = temp->left;
            }
            temp = myStack.top();
            myStack.pop();
            temp = temp->right;
        }
        TreeNode *temp2 = NULL;
        while(!myQueue.empty())
        {
            temp = myQueue.front();
            myQueue.pop();
            if(!myQueue.empty())
                temp2 = myQueue.front();
            temp->right = temp2;
            //temp = temp2;
        }
    }
};

出现超时错误,虽然我老是觉得它的时间复杂度并没有很高,可是在很小的例子上也会超时。

Trail 2 :涉及到树的问题,很多时候我们会想到递归,刚刚拿到题我想到的也是递归,可是代码老是调不对,我就使用了上面的Trial 1, 结果超时了,因此还是转战到了递归的方式。

首先,root指向左子树flatten之后的链表,然后再链接到右子树flatten之后的链表,由于左右子树也还是二叉树,因此只需要对左右子树分别递归调用即可。

class Solution {
public:
    void flatten(TreeNode *root) {
        if(root == NULL)return;
        TreeNode *tempL = NULL, *tempR = NULL;
        tempL = root->left;
        tempR = root->right;
        root->left = NULL;
        flatten(tempL);
        root->right = tempL;
        TreeNode *pre = root;
        while(tempL)
        {
            pre = tempL;
            tempL = tempL->right;
        }
        flatten(tempR);
        if(pre) pre->right = tempR;
    }
};
上述关键部分是在找到root节点连接到左子树之后的最终的节点的位置。

总结:递归依旧是我的一个弱点,思想很明白,可是代码对于我来说却是很难的。


你可能感兴趣的:(list,tree,binary,linked,flatten)