栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

LeetCode 题解随笔:二叉树(2)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

LeetCode 题解随笔:二叉树(2)

目录

 一、遍历思维模式

 543. 二叉树的直径

二、分解问题思维模式

114. 二叉树展开为链表


一旦发现题目和子树有关,大概率要给函数设置合理的定义和返回值,在后序位置写代码了。

二叉树解题的思维模式分两类(来源:labuladong):

1、是否可以通过遍历一遍二叉树得到答案?如果可以,用一个 traverse 函数配合外部变量来实现,这叫「遍历」的思维模式。

2、是否可以定义一个递归函数,通过子问题(子树)的答案推导出原问题的答案?如果可以,写出这个递归函数的定义,并充分利用这个函数的返回值,这叫「分解问题」的思维模式。

无论使用哪种思维模式,你都需要思考:

如果单独抽出一个二叉树节点,它需要做什么事情?需要在什么时候(前/中/后序位置)做?其他的节点不用你操心,递归函数会帮你在所有节点上执行相同的操作。

 一、遍历思维模式

 543. 二叉树的直径
int max_diameter;
    int diameterOfBinaryTree(TreeNode* root) {
        MaxDepth(root);
        return max_diameter;
    }
    // 最大直径是左右结点深度和
    int MaxDepth(TreeNode* node) {
        if (!node)   return 0;
        int left_max = MaxDepth(node->left);
        int right_max = MaxDepth(node->right);
        // 遍历最大深度的同时,由于是后序遍历,顺便可以得到但前结点处的最大直径
        int cur_diameter = left_max + right_max;
        max_diameter = max(max_diameter, cur_diameter);
        return 1 + max(left_max, right_max);
    }

每一条二叉树的「直径」长度,就是一个节点的左右子树的最大深度之和。借助后序遍历求最大深度的方法,利用全局变量记录最大元素,一次遍历即可获得结果。

二、分解问题思维模式

114. 二叉树展开为链表
// 分治思想,把子树展开为链表
    void flatten(TreeNode* root) {
        if (!root)   return;
        // 后序遍历
        flatten(root->left);
        flatten(root->right);
        // 当存在左子树时,把右子树接到左子树的右侧叶节点上
        if (root->left) {
            TreeNode* cur = root->left;
            while (cur->right)   cur = cur->right;
            cur->right = root->right;
            root->right = root->left;
            root->left = nullptr;
        }
        return;
    }

注意本题的返回值为void类型,说明题目希望在原地完成拉直操作,分解思想可以解决本问题。

如下图所示(来源:labuladong),对于一个节点 x,可以执行以下流程:

1、先利用 flatten(x.left) 和 flatten(x.right) 将 x 的左右子树拉平。

2、将 x 的右子树接到左子树下方,然后将整个左子树作为右子树。

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1014821.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号