📜  门| GATE CS 2019 |第 60 题(1)

📅  最后修改于: 2023-12-03 15:42:11.999000             🧑  作者: Mango

题目描述

给定一棵二叉树,你需要将这棵二叉树中所有的叶子节点从左到右连接在一起,构成一个链表。

函数描述

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def flatten(root: TreeNode) -> None:
    """
    Do not return anything, modify root in-place instead.
    """
输入描述
  • 参数:root 二叉树根节点。

    类型:TreeNode

输出描述
  • 原地修改树,使得树的左边结点指向 None,右边结点指向下一个节点的指针。
示例
输入
输入:[1,2,5,3,4,null,6]
      1
     / \
    2   5
   / \   \
  3   4   6
输出
输出:[1,null,2,null,3,null,4,null,5,null,6]
     1
      \
       2
        \
         3
          \
           4
            \
             5
              \
               6  

解法

这道题要求我们把二叉树展开成链表,核心思路就是把当前节点的右子树接到左子树的最右边节点上,同时当前节点变为当前节点的左叶子节点。

class Solution:
    def flatten(self, root):
        """
        :type root: TreeNode
        :rtype: void Do not return anything, modify root in-place instead.
        """
        # 右子树放到左子树最右边节点后
        # 接着处理新的左子树
        while root:
            if root.left is not None:
                # 找到左子树最右边的节点,将root.right接到上面
                pre = root.left
                while pre.right is not None:
                    pre = pre.right
                pre.right = root.right
                # 把左子树拿过来当做右子树
                root.right = root.left
                root.left = None
            root = root.right

此外,还总结出了以下两种方法实现:

先序遍历整棵树

通过先序遍历整棵树,将所有节点存储在一个数组中。然后再遍历这个数组,对于每个节点,将其左指针设为空,右指针设为下一个节点。

class Solution:
    def flatten(self, root):
        nodes = []

        def preorder(node):
            if node: 
                nodes.append(node)
                preorder(node.left)
                preorder(node.right)
        
        preorder(root)
        for i in range(1, len(nodes)):
            prev, curr = nodes[i - 1], nodes[i]
            prev.left = None
            prev.right = curr
递归展开左右子树

递归函数 flattenTree 会展开左子树和右子树,并返回展开后的最后一个节点。然后我们将左子树接到根节点的右侧,再将右子树接到左子树之后展开的最后一个节点的右侧。

class Solution:
    def flatten(self, root):
        """
        :type root: TreeNode
        :rtype: void Do not return anything, modify root in-place instead.
        """
        if not root:
            return None

        def flattenTree(node):
            # 展开以 node 为根的树,并返回展开后的最后一个节点
            if not node.left and not node.right:
                return node
            if not node.left:
                return flattenTree(node.right)
            if not node.right:
                leftLast = flattenTree(node.left)
                node.left, node.right = None, node.left
                return leftLast
            leftLast, rightLast = flattenTree(node.left), flattenTree(node.right)
            leftLast.right, node.left, node.right = node.right, None, node.left
            return rightLast

        flattenTree(root)