数据结构与算法 -- 树形DP相关题型解题思路

目录

  • 一. 找出最大的平衡二叉树
  • 二. 给一个二叉树,找任意两点的最远距离
  • 给一个n叉树,每一个节点都有一个活跃度,当a来时,他的直接下属不会来,求最大的活跃度是多少

一. 找出最大的平衡二叉树

  1. 列出一棵树所有的可能是平衡二叉树的可能性
  2. 把这些信息简化 成为每一颗树都要返回的公共信息,跟左右子树没关
  3. 写出递归。
    1. 先给出递归退出条件,分析此时返回的信息是什么
    2. 然后直接拿到所有的左右子树的信息
    3. 开始依据拿到的左右子树信息开始封装自己的信息,然后向上返回。
/**
 * 1. 首先找出可能性
 * 2. 简化信息
 * 3. 改成递归
 */
public class 最大平衡二叉树 {

    public static class Node {
        Node left;
        Node right;
        int value;
        public Node(int value){
            this.value = value;
        }
    }

    public static class ReturnData{
        int size;
        Node node;
        int max;
        int min;
        public ReturnData(int size, Node node, int max, int min){
            this.size = size;
            this.node = node;
            this.max = max;
            this.min = min;
        }
    }
    public static ReturnData getMaxAVLTree(Node head){
        if (head == null){
            return new ReturnData(0, null, Integer.MIN_VALUE, Integer.MAX_VALUE);
        }
        ReturnData leftData = getMaxAVLTree(head.left);
        ReturnData rightData = getMaxAVLTree(head.right);

        int selfSize = 0;
        if (head.left == leftData.node &&
            head.right == rightData.node &&
            head.value > leftData.max &&
            head.value < rightData.min) {
            selfSize = leftData.size + rightData.size + 1;
        }

        int maxSize = 0;
        maxSize = Math.max(Math.max(leftData.size, rightData.size), selfSize);
        Node maxHead = leftData.size > rightData.size ? leftData.node : rightData.node;
        if (maxSize == selfSize){
            maxHead = head;
        }

        return new ReturnData(maxSize, maxHead, Math.max(Math.max(leftData.max, rightData.max), head.value),
                            Math.min(Math.min(leftData.min, rightData.min), head.value));
    }

    public static void main(String[] args) {
        Node root = new Node(6);
        root.right = null;
        root.left = new Node(0);
        root.left.left = new Node(5);
        root.left.left.left = new Node(4);
        root.left.left.right = new Node(7);
        ReturnData cur = getMaxAVLTree(root);
        System.out.println(cur.size);
        System.out.println(cur.max);
        System.out.println(cur.min);
    }
}

二. 给一个二叉树,找任意两点的最远距离

  1. 首先分析 给一个以x为跟节点的最大长度 可能来自:1 他的左子树 2. 他的右子树 3. 经过x节点,也就是左右子树的距离加1
  2. 信息简化: 每一个节点需要返回两个数据 1. 最大的长度 2. 深度
  3. 开始写递归
public class 二叉树任意两点最远距离 {
    public static class Node {
        Node left;
        Node right;
        int value;
        public Node(int value){
            this.value = value;
        }
    }

    public static class ReturnData{
        int distance;
        int h;
        public ReturnData(int distance, int h){
            this.distance = distance;
            this.h = h;
        }
    }

    public static ReturnData getMaxDistance(Node head){
        if (head == null) {
            return new ReturnData(0, 0);
        }
        ReturnData leftData = getMaxDistance(head.left);
        ReturnData riightData = getMaxDistance(head.right);

        int includeHeadDistance = leftData.h + riightData.h + 1;
        int p1 = leftData.distance;
        int p2 = riightData.distance;
        int resultDistance = Math.max(Math.max(p1, p2), includeHeadDistance);
        int hself = Math.max(leftData.h, riightData.h) + 1;
        return new ReturnData(resultDistance, hself);
    }
    public static void main(String[] args) {
        Node root = new Node(6);
        root.right = null;
        root.left = new Node(0);
        root.left.left = new Node(5);
        root.left.left.left = new Node(4);
        root.left.left.right = new Node(7);
        ReturnData cur = getMaxDistance(root);
        System.out.println(cur.distance);
    }


}

给一个n叉树,每一个节点都有一个活跃度,当a来时,他的直接下属不会来,求最大的活跃度是多少

1。 首先分析 给一个 跟节点x 有两种可能性 x来或者不来。来的话 活跃度就是直接下属不来的活跃度,不来的话 就是下属来于不来的最大值
2。 直接写出递归。

import java.util.ArrayList;
import java.util.List;

/**
 * 给一个n叉树,每一个节点都有一个活跃度,当a来时,他的直接下属不会来,求最大的活跃度是多少
 * 1。 首先分析 给一个 跟节点x 有两种可能性 x来或者不来。来的话 活跃度就是直接下属不来的活跃度,不来的话 就是下属来于不来的最大值
 * 2。 直接写出递归。
 */
public class 最大活跃度 {
    //多叉树的书写方式
    public static class Node {
        int huo;
        List<Node> nexts;
        public Node(int huo){
            this.huo = huo;
            nexts = new ArrayList<>();
        }
    }
    public static class ReturnData {
        int lai_huo;
        int bu_lai_huo;
        public ReturnData(int lai_huo, int bu_lai_huo) {
            this.lai_huo = lai_huo;
            this.bu_lai_huo = bu_lai_huo;
        }
    }

    public static ReturnData getMaxHuo(Node head){
        if (head == null) {
            return new ReturnData(0, 0);
        }
        int laihuo = head.huo;
        int bulaihuo = 0;
        for (int i = 0; i < head.nexts.size(); i++) {
            ReturnData data = getMaxHuo(head.nexts.get(i));
            laihuo += data.bu_lai_huo;
            bulaihuo += Math.max(data.bu_lai_huo, data.lai_huo);
        }
        return new ReturnData(laihuo, bulaihuo);
    }

}

你可能感兴趣的:(算法与数据结构)