力扣深度优先搜索练习题(二叉树展开为链表、二叉树中的最大路径和)

62 阅读2分钟

二叉树展开为链表

来源:力扣(LeetCode) 链接:leetcode.cn/problems/fl…

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

  • 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。

  • 展开后的单链表应该与二叉树 先序遍历 顺序相同。

示例 1:

图片.png

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

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

示例 2:

输入:root = []

输出:[]

示例 3:

输入:root = [0]

输出:[0]

提示:

  • 树中结点数在范围 [0, 2000] 内
  • -100 <= Node.val <= 100

代码

class Solution {
    public void flatten(TreeNode root) {
        if (root == null) {
            return;
        }
        
        flatten(root.left);
        flatten(root.right);
        
        TreeNode right = root.right;
        root.right = root.left;
        root.left = null;
        
        TreeNode curr = root;
        while (curr.right != null) {
            curr = curr.right;
        }
        
        curr.right = right;
    }
}

思路分析

  1. 首先,递归地将左子树和右子树展开为链表。
  2. 将左子树展开后的链表接到根节点的右侧。
  3. 将原先的右子树接到当前链表的末尾。
  4. 将根节点的左子树设为空。

在代码实现中,我们使用递归函数flatten来完成上述操作。首先判断根节点是否为空,若为空则直接返回。然后递归地将左子树和右子树展开为链表。接着,将根节点的左子树接到根节点的右侧,并将原先的右子树接到当前链表的末尾。最后,将根节点的左子树设为空。

二叉树中的最大路径和

来源:力扣(LeetCode) 链接:leetcode.cn/problems/bi…

二叉树中的 路径 被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。

路径和 是路径中各节点值的总和。

给你一个二叉树的根节点 root ,返回其 最大路径和 。

示例 1:

图片.png

输入:root = [1,2,3]

输出:6

解释:最优路径是 2 -> 1 -> 3 ,路径和为 2 + 1 + 3 = 6

示例 2:

图片.png

输入:root = [-10,9,20,null,null,15,7]

输出:42

解释:最优路径是 15 -> 20 -> 7 ,路径和为 15 + 20 + 7 = 42

提示:

  • 树中节点数目范围是 [1, 3 * 104]
  • -1000 <= Node.val <= 1000

代码

class Solution {
    private int maxSum = Integer.MIN_VALUE;
    
    public int maxPathSum(TreeNode root) {
        maxGain(root);
        return maxSum;
    }
    
    private int maxGain(TreeNode node) {
        if (node == null) {
            return 0;
        }
        
        int leftGain = Math.max(maxGain(node.left), 0);
        int rightGain = Math.max(maxGain(node.right), 0);
        
        int newPathSum = node.val + leftGain + rightGain;
        maxSum = Math.max(maxSum, newPathSum);
        
        return node.val + Math.max(leftGain, rightGain);
    }
}

思路分析

  1. 定义一个全局变量maxSum,用于记录最大路径和的值,初始值设为最小整数值。
  2. 定义一个递归函数maxGain(TreeNode node),该函数计算以node为根节点的路径的最大和,并返回以node为起点的最大路径和。
  3. 在递归函数中,首先判断当前节点是否为空,若为空则返回0。
  4. 分别递归计算左子树和右子树的最大路径和,用leftGainrightGain表示。
  5. 计算以当前节点为根节点的路径的最大和newPathSum,即node.val + leftGain + rightGain
  6. 更新全局最大和maxSum,取maxSumnewPathSum的较大值。
  7. 返回以当前节点为起点的最大路径和,即node.val + max(leftGain, rightGain)