leetcode114.二叉树展开为链表 Python

题目:

给你二叉树的根结点 root ,请你将它展开为一个单链表:

展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。
展开后的单链表应该与二叉树 先序遍历 顺序相同。

示例:

输入:root = [1,2,5,3,4,null,6]
输出:[1,null,2,null,3,null,4,null,5,null,6]

在这里插入图片描述

思路:

方法1,迭代和递归

因为将二叉树展开为单链表的序列顺序就是对二叉树进行先序遍历的顺序,所以可以先对二叉树进行先序遍历,然后再遍历先序遍历序列,改变二叉树的连接结构,从而转换为单链表,这里的单链表也是一个二叉树的结构。

进行先序遍历可以分别使用迭代递归。这两种方法都占用了额外的空间。

方法2,找前驱节点

这种方法不会占用额外的空间,直接在遍历过程中将二叉树转换为单链表,我们从根节点开始,将根节点的右子树放到左子树的某个位置上,应该放在左子树中最右的位置,按照根左右的遍历顺序,最右的节点就是右子树的前驱节点,放完以后再将整个左子树移动到根节点的右子树位置上,原左子树置为空,下一次遍历到根节点的右分支节点,进行同样的操作,这样一步一步展开为单链表。

注意两种方法在遍历二叉树的过程中都要保留原根节点,使得最后能找到这个原二叉树。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def flatten(self, root):
        """
        :type root: TreeNode
        :rtype: None Do not return anything, modify root in-place instead.
        """
        # plist = []
        # # 用递归实现先序遍历
        # def preorder(root):
        #     if root:
        #         plist.append(root)
        #         preorder(root.left)
        #         preorder(root.right)
        # preorder(root)
        # l = len(plist)
        # for i in range(1,l):
        #     prev = plist[i -1]
        #     cur = plist[i]
        #     prev.left = None
        #     prev.right = cur 
        # 用迭代实现先序遍历
        # plist = []
        # stack = []
        # node = root # 要保留原根节点,后边要用的
        # while node or stack:
        #     while node:
        #         plist.append(node)
        #         stack.append(node)
        #         node = node.left
        #     node = stack.pop()
        #     node = node.right 
        # l = len(plist)
        # for i in range(1,l):
        #     prev = plist[i -1]
        #     cur = plist[i]
        #     prev.left = None
        #     prev.right = cur 
        # 以上两种方法都要占用额外空间,这里通过找前驱节点,不占用额外空间
        cur = root # 同样保留上当前节点
        while cur:
            if cur.left:
                next = cur.left # 维护这个,一会儿往右边接
                pre = cur.left # 开始往右找,找到最右边的节点就是前驱节点
                while pre.right:
                    pre = pre.right # 这样就指向了最右边的节点,而不是空
                pre.right = cur.right #把右边的接到了左边的最右边
                cur.left = None
                cur.right = next
            cur = cur.right # 往右边遍历执行同样的操作,直到最后一个节点
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值