总是在看完别人的代码之后,才发现自己的差距!

我的递归:

先把左侧扁平化,再把右侧扁平化。

然后找到左侧最后一个节点,把右侧移动过去。

然后把左侧整体移到右侧,左侧置为空。

很复杂吧!

如果节点很长的话,这个耗时是很大的。O(n^2) ?差不多了!

菜逼啊!时间估计都错了!!!

时间是多少呢?

while 最左侧的数,会不断被遍历!是这样的。大概会被遍历o(n)次

所以还是O(n^2)?

反正是复杂了。

void flatten(struct TreeNode* root) {
    if(root == NULL)    return;
    
    flatten(root->left);
    
    flatten(root->right);
    
    if(root->left)
    {
        struct TreeNode *p = root->left;
        while(p -> right)
        {
            p = p->right;
        }
        p->right = root->right;
        root->right = root->left;
        root->left = NULL;
    }
    return root;
}

看看人家多么行云流水的操作!代码简洁,效率高!没有重复操作!厉害啊!

 

struct TreeNode *pre = NULL;

void convert(struct TreeNode* root)
{
    if(root == NULL)    return;
    
    convert(root->right);
    convert(root->left);
    
    root->right = pre;
    root->left = NULL;
    pre = root;
}

void flatten(struct TreeNode *root)
{
    pre = NULL;
    convert(root);
}

什么思路?

先把右侧变成一个链表,记录下表头。

再把左侧变成链表,右侧的表头作为尾部。

右子树变成左子树的最右儿子的右儿子。

巧妙啊。。。

另外,要注意全局变量每次使用前都要重新初始化。所以外面套了一层。

posted on 2017-12-15 10:45  newbird2017  阅读(111)  评论(0编辑  收藏  举报