写二叉树的算法题,都是基于递归框架的,我们先要搞清楚
root
节点它自己要做什么,然后根据题目要求选择使用前序,中序,后续的递归框架。二叉树题目的难点在于如何通过题目的要求思考出每一个节点需要做什么,这个只能通过多刷题进行练习了。
题目链接:
leetcode114 二叉树展开为链表
本题思路:
函数签名如下:
void flatten(TreeNode root);
我们尝试给出这个函数的定义:
给 flatten
函数输入一个节点 root
,那么以 root
为根的二叉树就会被拉平为一条链表。
我们再梳理一下,如何按题目要求把一棵树拉平成一条链表?很简单,以下流程:
1、将 root
的左子树和右子树拉平。
2、将 root
的右子树接到左子树下方,然后将整个左子树作为右子树。
上面三步看起来最难的应该是第一步对吧,如何把 root
的左右子树拉平?其实很简单,按照 flatten
函数的定义,对 root
的左右子树递归调用 flatten
函数即可:
Java版
// 定义:将以 root 为根的树拉平为链表
void flatten(TreeNode root) {
// base case
if (root == null) return;
// 先把左右子树捋直
flatten(root.left);
flatten(root.right);
/**** 后序遍历位置 ****/
// 左右子树已经被拉平成一条链表
TreeNode tmp = root.right; // 把捋直的右子树备份一下
root.right = root.left; // 把捋直的左子树放到右边
root.left = null; // 记得把左子树置空
// 将原先的右子树接到当前右子树的末端
while(root.right != null) { // 找到当前右子树的最后一个node
root = root.right;
}
root.right = tmp; // 把捋直的原来的右子树接上去
}
Python版
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def flatten(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
if not root :
return root
self.flatten(root.left)
self.flatten(root.right)
tmp = root.right
root.right = root.left
root.left = None
while(root.right):
root = root.right
root.right = tmp
注意递归框架是后序遍历,因为我们要先拉平左右子树才能进行后续操作。