Leetcode--Flatten Binary Tree to Linked List

好久都没刷leetcode的啦!这个周末终于有属于自己的时间了,就来做一下题吧~

首先,我的思路是比较直接的,利用递归的思想,先修改当前结点的左子树,记录下当前结点的左子树的最右下结点,再修改当前结点的右子树,将最右下结点与当前结点的左结点链接起来就可以了。

具体代码:

TreeNode* leaf;
TreeNode *dfs(TreeNode* rt)
    {
        if(rt==NULL)
        {
            return rt;
        }
        else
        {
            leaf=rt;
            TreeNode* left=dfs(rt->left);
            leaf->right=rt->right;
            TreeNode* right=dfs(rt->right);
            if(left==NULL&&right==NULL)// is leaf
            {
                //cout<<"leaf is :"<<leaf->val<<endl;
                return rt;
            }
            if(right==NULL)
            {
                rt->right=left;
                rt->left=NULL;
            }
            else
            {
                if(rt->left)
                {
                    rt->right=left;
                    rt->left=NULL;
                }
            }
            return rt;
        }
    }

AC后,看下了运行时间并不理想,就到讨论区看了下,发现大神的思想还是需要我膜拜的~

大神的思想:采用了后序遍历树的方法,遍历当前结点的右子树,左子树,使当前结点的右子树链接上之前保存的pre。这样简洁的思路是需要我自己学习的~

具体代码:

private TreeNode prev = null;

public void flatten(TreeNode root) {
    if (root == null)
        return;
    flatten(root.right);
    flatten(root.left);
    root.right = prev;
    root.left = null;
    prev = root;
}

在讨论区还看到了另一种方法,大致的思想跟我自己的思想差不多,是非递归的。将当前结点的左子树上的结点的最右下结点与当前结点的左孩子结点链接,然后将整个左子树移到右子树上。再取当前结点的右孩子结点,成为下一个被处理的结点。

具体代码:

class Solution {
public:
    void flatten(TreeNode *root) {
        TreeNode*now = root;
        while (now)
        {
            if(now->left)
            {
                //Find current node's prenode that links to current node's right subtree
                TreeNode* pre = now->left;
                while(pre->right)
                {
                    pre = pre->right;
                }
                pre->right = now->right;
                //Use current node's left subtree to replace its right subtree(original right 
                //subtree is already linked by current node's prenode
                now->right = now->left;
                now->left = NULL;
            }
            now = now->right;
        }
    }
};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值