LeetCode --- 二叉树操作

Posted lalala

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode --- 二叉树操作相关的知识,希望对你有一定的参考价值。

543. 二叉树的直径

乍看是 根节点的 左子树最大高度 + 右子树最大高度 + 1

但其实不能这样,因为路径可能并不经过根节点,如图二

因此要用一个 max 来保存最后的最大路径和

在求二叉树高度的递归中,在每个根节点(在递归函数中),比较 max 与 以这个当前根节点的  左子树最大高度 + 右子树最大高度 + 1 

 

/**
 * Definition for a binary tree node.
 * public class TreeNode 
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() 
 *     TreeNode(int val)  this.val = val; 
 *     TreeNode(int val, TreeNode left, TreeNode right) 
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     
 * 
 */
class Solution 

    private static int maxDiameter = 0;

    public Solution() 
        maxDiameter = 0;
    

    public int diameterOfBinaryTree(TreeNode root) 
        dfs(root);
        // 在递归求树高的过程中求出来的 maxDiameter
        return maxDiameter;
    

    private int dfs(TreeNode nowRoot) 
        if (nowRoot == null) 
            return 0;
        
        int leftHeight = dfs(nowRoot.left);
        int rightHeight = dfs(nowRoot.right);

        // 路径长度最大值为左子树 + 右子树高度,与之前的最大值比较
        maxDiameter = Math.max(leftHeight + rightHeight, maxDiameter);

        // 因为要通过递归求树高度,所以最后仍要返回高度:左右子树中较高的那个(而不是路径和)
        return Math.max(leftHeight, rightHeight) + 1;
    

 

124. 二叉树中的最大路径和

最大路径怎么求?

最后的最大路径,任一节点 都有可能作为这个最大路径的根节点

所以有一个全局的最大路径 maxPathSum, 每次递归的时候(在每个根节点)都要与之比较

如果当前节点作为 最后最大路径的根节点,那么 只当前根节点/当前根节点+左子树/当前根节点+右子树/当前根节点+左子树+右子树 这四种情况都行

所以,要取这四种情况中最大的来与 maxPathSum 比较,这四种一定会包含当前根节点,所以四种中最大的求法就是:初始值为当前根节点的值,左子树>0 就加左子树,右子树>0 就加右子树

递归的返回值应该是什么?

之前比较路径的时候,由于当前节点可能作为最后最长路径的根,所以要把四种情况都算上

但是返回的时候,当前节点的情况是作为之后的一些结果的子集,这时候当前节点一定不能为最长路径的根节点

所以要么选择左分支 root.val + leftSum,要么选择右分支 root.val + rightSum

/**
 * Definition for a binary tree node.
 * public class TreeNode 
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() 
 *     TreeNode(int val)  this.val = val; 
 *     TreeNode(int val, TreeNode left, TreeNode right) 
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     
 * 
 */
class Solution 

    private static int maxPathSum = Integer.MIN_VALUE;

    public Solution() 
        maxPathSum = Integer.MIN_VALUE;
    

    public int maxPathSum(TreeNode root) 
        dfs(root);
        return maxPathSum;
    

    private int dfs(TreeNode root) 
        int thisRootSum = 0;
        if (root == null) 
            return thisRootSum;
        

        int leftSum = dfs(root.left);
        int rightSum = dfs(root.right);
        
        // 最长路径可能以任一结点为根。只当前根节点/根节点+左子树/根节点+右子树/根节点+左子树+右子树 这四种情况都行,选出这四种情况下最大的
        int thisRootMax = root.val;
        if (leftSum > 0) 
            thisRootMax += leftSum;
        
        if (rightSum > 0) 
            thisRootMax += rightSum;
        
        // 最长路径可能以任一结点为根,所以每个节点的最大与之前的最大比较一下
        maxPathSum = Math.max(maxPathSum, thisRootMax);
        
        // 之前比较路径的时候,由于当前节点可能作为最后最长路径的根,所以要把四种情况都算上
        // 但是返回的时候,是作为之后的一些结果的子集,这时候当前节点一定不能为最长路径的根节点
        // 所以要么选择左分支 root.val + leftSum,要么选择右分支 root.val + rightSum
        int chooseLeftOrRightMax = Math.max(root.val + leftSum, root.val + rightSum);
        // 收益小于0,直接舍弃
        if (chooseLeftOrRightMax < 0) 
            chooseLeftOrRightMax = 0;
        
        return chooseLeftOrRightMax;
    

 

LeetCode951-翻转等价二叉树

问题:翻转等价二叉树

我们可以为二叉树 T 定义一个翻转操作,如下所示:选择任意节点,然后交换它的左子树和右子树。

只要经过一定次数的翻转操作后,能使 X 等于 Y,我们就称二叉树 X 翻转等价于二叉树 Y。

编写一个判断两个二叉树是否是翻转等价的函数。这些树由根节点 root1 和 root2 给出。

 

示例:

输入:root1 = [1,2,3,4,5,6,null,null,null,7,8], root2 = [1,3,2,null,6,4,5,null,null,null,null,8,7]
输出:true
解释:We flipped at nodes with values 1, 3, and 5.

技术分享图片

 

提示:

  1. 每棵树最多有 100 个节点。
  2. 每棵树中的每个值都是唯一的、在 [0, 99] 范围内的整数。

 

链接:https://leetcode-cn.com/contest/weekly-contest-113/problems/flip-equivalent-binary-trees/

分析:

1.两个空指针相同

2.一个空一个非空,不相同

3.如果两个非空,值不等,不相同

4.两个非空且值相等,设为r1,r2,那么r1.left=r2.left 且r1.right=r2.right,或者r1.left=r2.right 且r1.right=r2.left,则相等,否则不等,递归即可。

 

AC Code:

 

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     bool flipEquiv(TreeNode* root1, TreeNode* root2) {
13         bool ret = false;
14         ret = check(root1, root2);
15         return ret;
16     }
17     bool check(TreeNode* root1, TreeNode* root2)
18     {
19         if (root1 == nullptr && root2 == nullptr)
20         {
21             return true;
22         }
23         if (root1 != nullptr && root2 != nullptr)
24         {
25             if (root1->val != root2->val)
26             {
27                 return false;
28             }
29             else
30             {
31                 
32                 return (check(root1->left, root2->left) && check(root1->right, root2->right))|| check(root1->left, root2->right) && check(root1->right, root2->left);
33 
34             }
35         }
36         else
37         {
38             return false;
39         }
40 
41         
42     }
43 };

 

其他:

1.第一code:

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     bool flipEquiv(TreeNode* root1, TreeNode* root2) {
13         if (root1 == nullptr && root2 == nullptr)
14             return true;
15 
16         if (root1 == nullptr || root2 == nullptr)
17             return false;
18 
19         if (root1->val != root2->val)
20             return false;
21 
22         if (flipEquiv(root1->left, root2->left))
23             return flipEquiv(root1->right, root2->right);
24 
25         return flipEquiv(root1->left, root2->right) && flipEquiv(root1->right, root2->left);
26     }
27 };

2.虽然AC一次过了,不过测试的时候例子错了,所有的值使用前先判断是否为空,之前在这个上面栽过跟头,不过还是没记住,近期貌似也就周末参加个周赛了,手生了。

以上是关于LeetCode --- 二叉树操作的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode951-翻转等价二叉树

Leetcode刷题100天—701. 二叉搜索树中的插入操作( 二叉树)—day34

Leetcode刷题100天—701. 二叉搜索树中的插入操作( 二叉树)—day34

⭐算法入门⭐《二叉树 - 二叉搜索树》中等03 —— LeetCode 701. 二叉搜索树中的插入操作

二叉树镜像问题——Offer. 27&28

[LeetCode]257. 二叉树的所有路径