LeetCode114 二叉树展开为链表

62 阅读1分钟

leetcode.cn/problems/fl…

image.png

解法一:基于分解子问题思维模式的递归

flatten 函数的定义如下:

给 flatten 函数输入一个节点 root,那么以 root 为根的二叉树就会被拉平为一条链表

如何利用这个定义来完成算法?你想想怎么把以 root 为根的二叉树拉平为一条链表?

很简单,流程如下:

  1. 将 root 的左子树和右子树拉平。
  2. 将拉平后的左子树接到 root 的下方, 然后将拉平后的右子树接到现在右子树的下方。
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func flatten(root *TreeNode)  {
    if root == nil{
        return
    }
    // 先展开左右子树
    flatten(root.Left)
    flatten(root.Right)
    flatLeft := root.Left
    flatRight := root.Right
    // 将拉平后的左子树接到当前节点的右边
    root.Left = nil
    root.Right = flatLeft
    // 将原先的右子树接到当前右子树(即拉平后的原左子树)的后面
    p := root
    for p.Right != nil{
        p = p.Right
    }
    p.Right = flatRight
}

解法二:基于遍历思维模式的递归(dfs, 链表头插法)

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func flatten(root *TreeNode)  {
    var head *TreeNode
    traverse(root, &head)
}

func traverse(root *TreeNode, head **TreeNode){
    if root == nil{
        return
    }
    traverse(root.Right, head)
    traverse(root.Left, head)
    root.Left = nil
    root.Right = *head
    *head = root
}

也可以写成函数包函数

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func flatten(root *TreeNode)  {
    var head *TreeNode
    var dfs func(*TreeNode)
    dfs = func(node *TreeNode) {
        if node == nil {
            return
        }
        dfs(node.Right)
        dfs(node.Left)
        node.Left = nil
        node.Right = head // 头插法,相当于链表的 node.Next = head
        head = node       // 现在链表头节点是 node
    }
    dfs(root)
}