您的位置:首页 > 编程语言 > Python开发

LeetCode 114.二叉树展开为链表(Python实现)

2019-04-03 20:47 411 查看

题目介绍

题目给定一个二叉树,要求原地将它展开为链表。
例如,给定二叉树

将其展开为:

题目解读

在Python中,树的实现一般为:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

而链表的实现形式为:

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

也就是说,在本题中,我们要通过某种方式将树中所有节点的左子树都接到右子树的位置,然后令左子树为None。最后,所有的节点都会表现为左子树为None,右子树相连的情况,以此代替链表中的self.next 。

代码解析

下面我们来结合代码,分析一下这是怎么实现的。

def flatten(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
# 鲁棒性
if not root:
return None
# 递归(后序遍历)
self.flatten(root.left)
self.flatten(root.right)
if root.left:
#左树接右位
right = root.right
root.right = root.left
root.left = None
#右树接最后
while root.right:
root = root.right
root.right = right

Q&A

有很多刚接触递归的朋友都可能不太了解,下面这两句是什么意思。

self.flatten(root.left)
self.flatten(root.right)
  • 其实每层的递归到了这里就会进入下一层,这两行以下的代码在这个过程中完全不会触发
  • 直到最后一层触发了鲁棒性条件,才会回来,实际上是一个从上到下再到上的过程
  • 那么这里是不是很像二叉树的后序遍历呢?因为也是一个访问左右节点再向上的过程。

接下来的代码也不难理解,就是前面说的将左树移到右边,然后右树接到后面的过程。

有小伙伴可能又要问了,为什么不直接像以下这样操作呢?

if root.left:
temp = root.right
root.right = root.left
root.left = None
root.right.right = temp

这不是刚好原来的右树接到原来左树后吗?我一开始写的时候也犯了这个错误,让我们来结合图示看一下。

第一次递归回去,好像是对的。

但第二次递归回去就明显不对了,这是因为我们将原来的右树直接接在原来的左树上,丢失了3和4节点。因此,我们要在这里加一个while循环,确保接到最后面的节点,即本题的节点4,这样才正确。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: