力扣543.二叉树的直径(java)(迭代法 and 左右根后序遍历迭代法)

题目来源

543. 二叉树的直径 - 力扣(LeetCode)

代码1(递归法)

java 复制代码
/**
 * 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 int maxDiameter = 0;

    public int diameterOfBinaryTree(TreeNode root) {
        getDepth(root);
        return maxDiameter;
    }
    //返回当前结点最大深度(左右子树最大深度+1)以及求左右子树最大深度之和(该结点最大直径)
    private int getDepth(TreeNode node) {
        if(node == null) return 0;

        int leftDepth = getDepth(node.left);
        int rightDepth = getDepth(node.right);

        maxDiameter = Math.max(maxDiameter,leftDepth + rightDepth);
        
        return Math.max(leftDepth, rightDepth)+1;
    }
}

代码分析

直径:一个结点的,左子树最大深度 + 右子树最大深度

最大直径: 所有结点中,的最大的那个。

在求一个结点的深度时(max(left,right) + 1) ,顺便求出来该结点的直径

代码2(dfs迭代法,左右根后序遍历)

java 复制代码
/**
 * 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 {
    public int diameterOfBinaryTree(TreeNode root) {
        if(root == null) return 0;

        int maxDiameter = 0;
        Stack<Object[]> stack = new Stack<>(); // 存储:[节点, 是否访问过]
        Map<TreeNode, Integer> depth = new HashMap<>();

        stack.push(new Object[]{root,false});
        while(!stack.isEmpty()) {
            Object[] entry = stack.pop();
            TreeNode node = (TreeNode) entry[0];
            boolean isVisited = (boolean)entry[1];

            if(!isVisited) {
                // 首次弹出处理: 其实就是遍历顺序以及回退顺序处理
                // 根放里边,然后是右,然后是左。
                // 其实就是后续遍历,用于二次弹出回退计算处理
                stack.push(new Object[]{node,true});

                if(node.right!=null) stack.push(new Object[]{node.right,false});
                if(node.left!=null) stack.push(new Object[]{node.left,false});
            } else {
                int leftDepth = depth.getOrDefault(node.left, 0);
                int rightDepth = depth.getOrDefault(node.right, 0);
                maxDiameter = Math.max(maxDiameter, leftDepth+rightDepth);

                depth.put(node, Math.max(leftDepth,rightDepth)+1);
            }
        }
        return maxDiameter;
    }
}

代码分析

二次弹出,模拟的是 : 左右根后序遍历,核心是先处理左右子树的计算,再处理根结点

哈希表存储结点深度,是为了获取左右子树结点的深度,用于计算。

栈的存储的是 : Object[] 用于放 结点 + 结点访问情况(是否访问过)

当然也可以用哈希表来存储。 Map<TreeNode, boolean>

相关推荐
2401_831920741 天前
C++代码国际化支持
开发语言·c++·算法
m0_672703311 天前
上机练习第51天
数据结构·c++·算法
ArturiaZ1 天前
【day60】
算法·深度优先·图论
2401_851272991 天前
自定义内存检测工具
开发语言·c++·算法
☆5661 天前
C++中的命令模式
开发语言·c++·算法
仰泳的熊猫1 天前
题目2577:蓝桥杯2020年第十一届省赛真题-走方格
数据结构·c++·算法·蓝桥杯
CoovallyAIHub1 天前
Pipecat:构建实时语音 AI Agent 的开源编排框架,500ms 级端到端延迟
深度学习·算法·计算机视觉
灰色小旋风1 天前
力扣13 罗马数字转整数
数据结构·c++·算法·leetcode
2301_810160951 天前
C++与物联网开发
开发语言·c++·算法
cm6543201 天前
基于C++的操作系统开发
开发语言·c++·算法