• 【二叉树-最长路径系列(任意路径)】直径、最长同值路径、 最大路径和(DFS、树形DP)


    总述

    • 这类题目都是求一个最长路径,这个路径可以不经过根节点。
    • 使用dfs(即递归地遍历树)的方法。维护一个全局最长路径max作为最终结果,而递归方法dfs返回的是含根节点的最长路径。(若不使用全局变量,也可将返回类型构造自定义类,如题目124的代码2)
    • 注意题目是求路径(两点之间一条线)与节点数的区别,
      • 决定+1之类的细节
      • 决定dfs的递归终止是null节点还是叶子结点(若是叶子结点,当到叶子结点,要控制不进入null结点)。
    • 另外,求不经过根节点的最长路径一定是全部节点都要遍历,不存在剪枝情况,所以dfs不要放到if语句中。
    • 另附树形DP的思想:满足"依次求出每一个节点为根节点的二叉树的子树上的最大距离,那么最终答案一定在其中",所以可以使用树形dp。
      详细分析步骤按树形dp步骤来即可,简单。

    题目 543. 二叉树的直径

    给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过根结点。

    代码

    class Solution {
        private int maxLen=0;
        public int diameterOfBinaryTree(TreeNode root) {
            if(root==null){return 0;}
            getTreeHeight(root);
            return maxLen;
        }
    
        private int getTreeHeight(TreeNode root){
            if(root.left==null&&root.right==null){
                return 0;
            }
    
            int leftHeight=root.left==null?0:getTreeHeight(root.left)+1;
            int rightHeight=root.right==null?0:getTreeHeight(root.right)+1;
            maxLen=Math.max(maxLen,leftHeight+rightHeight);
            return Math.max(leftHeight,rightHeight);
        }
    }
    

    题目 687. 最长同值路径

    给定一个二叉树,找到最长的路径,这个路径中的每个节点具有相同值。 这条路径可以经过也可以不经过根节点。

    注意:两个节点之间的路径长度由它们之间的边数表示。

    题解

    增加判断,若左孩子与当前节点值不同,则清左边最大同值路径长度=0;右孩子同理。

    代码

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
    class Solution {
        private int maxLen=0;
        public int longestUnivaluePath(TreeNode root) {
            if(root==null){return 0;}
            dfs(root);
            return maxLen;
        }
    
        private int dfs(TreeNode root){
            if(root.left==null&&root.right==null){
                return 0;
            }
    
            int leftMaxLen=root.left==null?0:dfs(root.left)+1;//因为所有路径都要遍历到,所以不能有剪枝操作,所以dfs不能放到if里面去。
            if(root.left!=null&&root.left.val!=root.val){
                leftMaxLen=0;
            }
            int rightMaxLen=root.right==null?0:dfs(root.right)+1;
            if(root.right!=null&&root.right.val!=root.val){
                rightMaxLen=0;
            }
    
            maxLen=Math.max(maxLen,leftMaxLen+rightMaxLen);
            return Math.max(leftMaxLen,rightMaxLen);
        }
    }
    

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

    给定一个非空二叉树,返回其最大路径和。

    本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。

    题解

    与上两题不同,这题是求节点和,所以当和为负,要更新为0;

    代码

    class Solution {
    	private int max = Integer.MIN_VALUE;
    
    	public int maxPathSum(TreeNode root) {
    		maxRootPathSum(root);
    		return max;
    	}
    
        private int maxRootPathSum(TreeNode root){
            if(root==null){return 0;}
    
            int leftMaxVal=Math.max(0,maxRootPathSum(root.left));
            int rightMaxVal=Math.max(0,maxRootPathSum(root.right));
            max=Math.max(max,leftMaxVal+rightMaxVal+root.val);
            return Math.max(leftMaxVal,rightMaxVal)+root.val;
        }
    }
    

    代码2 返回类型使用构造类,代替类变量

    class Type{
    	int maxDis;
    	int treeHeight;
    	
    	public Type(int maxDis,int treeHeight) {
    		this.maxDis=maxDis;
    		this.treeHeight=treeHeight;
    	}
    }
    
    public class Main {	
    	public static void main(String args[]) {
    		//test
    		Node n1=new Node(1);
    		Node n2=new Node(2);
    		Node n3=new Node(3);
    		Node n4=new Node(4);
    		Node n5=new Node(5);
    		n1.left=n2;
    		n1.right=n3;
    		n3.left=n4;
    		n3.right=n5;
    		
    		int maxDis=maxDistance(n1).maxDis;
    		System.out.println(maxDis);
    	}
    	
    	public static Type maxDistance(Node root) {
    		if(root==null) {
    			return new Type(0,0);
    		}
    		Type lMes=maxDistance(root.left);
    		Type rMes=maxDistance(root.right);
    		int disTemp=lMes.treeHeight+rMes.treeHeight+1;
    		int maxDis=Math.max(Math.max(lMes.maxDis, rMes.maxDis), disTemp);
    		int height=Math.max(lMes.treeHeight, rMes.treeHeight)+1;
    		return new Type(maxDis,height);
    	}
    }
    
  • 相关阅读:
    「日常训练」More Cowbell(Codeforces Round #334 Div.2 B)
    「日常训练」Battle Over Cities
    「日常训练」湫湫系列故事——设计风景线(HDU-4514)
    「日常训练」Caterpillar(POJ-3310)
    python压缩解压文件
    python图像处理
    python删除文件或者目录
    python循环执行程序的装饰器
    python中logging模块的使用
    python中yield迭代器
  • 原文地址:https://www.cnblogs.com/coding-gaga/p/11318622.html
Copyright © 2020-2023  润新知