树形dp

  • 概述
  • 题目一:二叉树节点间的最大距离问题
  • 题目二:排队最大快乐值(多叉树问题)
  • 题目三:判断是否为满二叉树
  • 题目四:判断是否为平衡二叉树
  • 题目五:判断是否为二叉排序树

概述

  • 使用前提:如果题目求解的目标是S规则,则求解的流程可以定成以每一个节点为头节点的子树在S规则下的每一个答案,并且最终答案一定在其中
  • 套路步骤:
    (1)以某一个节点X为头节点的子树中,分析答案有哪些可能性(难点),并且这种分析是以X的左子树,X的右子树和X的整个树的角度来考虑可能性的
    (2)根据(1)的可能性分析,列出所有需要的信息
    (3)合并(2)的信息,对左右树提出同样的要求,并写出信息结构
    (4)设计递归函数,递归函数是处理以X为头节点的情况下的答案,包括设计递归的basecase,默认直接得到左右树的所有信息(黑盒的构造),以及把可能性做整合,并且要返回第三步的信息结构(黑盒的拆解)(在以下题目中,递归函数设计部分对黑盒的使用用更为详细的说明)

题目一:二叉树节点间的最大距离问题



如图:a到b的距离为2,d到c的距离为4,d到k的距离为6

  • 枚举(暴力)思路:任意两个节点直接均可以求出直接的距离,所有可以求出任意两节点距离后找最大值,但是时间复杂度过高
  • 树形dp思路:
    1 可能性分析:两大类,X是否参与最大值
    (1)X参与,X左树的最低端到X右树的最低端,左树的高度 + 1 + 右树的高度
    (2)X不参与,左右树内部解决,左树的最大距离,右树的最大距离
    (3)X的最大长度就在:左树的最大距离;右树的最大距离;左树的高度 + 1 + 右树的高度,三者中的最大值
    2 信息要求
    (1)情况一:左树的高度,右树的高度
    (2)情况二:左树的最大距离,右树的最大距离
    (3)综上所述:子树需要给父节点返回的信息结构:最大距离,高度
    3 递归函数设计
    (1)basecase:节点为空时返回信息(0,0)
    (2)黑盒的构造:假设直接得到了左右子树想要的信息结构
    (3)拆解黑盒:给出具体一个节点在得到左右子树信息后,如何整合出该节点的信息结构
    public static class Node{//树结点public int value;public Node left;public Node right;public Node(int date){//初始化this.value = date;}}public static class Info{//信息返回类型public int maxDistance;public int height;public Info(int maxDistance, int height){this.maxDistance = maxDistance;this.height = height;}}public static int maxDistance(Node head){//最大距离函数return process(head).maxDistance;}public static Info process(Node x){//求以X为头的整棵树的Info信息if (x == null){//basecasereturn new Info(0, 0);}//黑盒的构造:递归调用得到左右子树的Info信息Info leftInfo = process(x.left);Info rightInfo = process(x.right);//信息的整合//不含X时左右树提供的最大距离int leftDistance = leftInfo.maxDistance;int rightDistance = rightInfo.maxDistance;//含X时的最大距离int xDistance = leftInfo.height + 1 + rightInfo.height;//拆解黑盒:给出该节点信息的解决方法int maxDistance = Math.max(xDistance, Math.max(leftDistance, rightDistance));int height = Math.max(leftInfo.height, rightInfo.height) + 1;return new Info(maxDistance, height);}

题目二:排队最大快乐值(多叉树问题)


  • 树形dp思路:
    1 可能性分析:两大类,X是否参与最大值
    (1)X参与,最大值:X的值 + X子树的顶点不参与的情况下,提供的最大值
    (2)X不参与,最大值:0 + max(子树顶点参与,子树顶点不参与)
    (3)最大值:X参与,X不参与的最大值
    2 信息要求
    (1)情况一:头节点参与的最大值
    (2)情况二:头节点不参与的最大值
    (3)综上所述:子树需要给父节点返回的信息结构:(子树顶点参与,子树顶点不参与)
    3 递归函数设计
    (1)basecase:节点为叶子节点时,返回(该节点的值,0)
    (2)黑盒的构造:假设直接得到了所有子树想要的信息结构
    (3)拆解黑盒:给出具体一个节点在得到所有子树信息后,如何整合出该节点的信息结构
    public static class Employee{//员工信息类public int happy; //快乐值要求达到最大public List<Employee> nexts; //子节点public Employee(int date){//初始化this.happy = date;}}public static class Info{//信息返回类型public int xMaxHappy; //x节点参与public int maxHappy; //x不参与public Info(int xMaxHappy, int maxHappy){this.xMaxHappy = xMaxHappy;this.maxHappy = maxHappy;}}public static int maxHappy(Employee boss){//最大快乐值Info headInfo = process(boss);return Math.min(headInfo.xMaxHappy, headInfo.maxHappy);}public static Info process(Employee x){//返回x的Info信息if (x.nexts.isEmpty()){//basecasereturn new Info(x.happy, 0);}int xMaxHappy = x.happy;int maxHappy = 0;for (Employee next : x.nexts){//遍历x的子树//黑盒的构造Info nextInfo = process(next);//拆黑盒xMaxHappy += nextInfo.maxHappy;maxHappy += Math.max(nextInfo.xMaxHappy, nextInfo.maxHappy);}return new Info(xMaxHappy, maxHappy);}

题目三:判断是否为满二叉树

  • 树形dp思路:
    1 可能性分析:深度H,节点数为N
    (1)是满二叉树:N == 2 ^ H - 1
    (2)不是满二叉树:N != 2 ^H - 1
    2 信息要求
    (1)父节点的H = 左右子树中H的较大值 + 1
    (2)父节点的N = 左N + 右N
    (3)子树需要给父节点返回的信息结构:深度,节点树
    3 递归函数设计
    (1)basecase:节点为空,返回(0,0)
    (2)黑盒的构造:假设直接得到了左右子树想要的信息结构
    (3)拆解黑盒:给出具体一个节点在得到所有子树信息后,如何整合出该节点的信息结构
     public static class Node{int value;Node left;Node right;public Node(int date){this.value = date;}}public static class Info{public int height; //树的高度public int num; //节点数public Info(int height, int num){//初始化this.height = height;this.num = num;}}public static boolean isFull(Node head){//判断是否为满二叉树Info headInfo = process(head);//1 << x, 2的x次方return headInfo.num == (1 << headInfo.height - 1);}public static Info process(Node x){//返回x的Info信息if (x == null){//basecasereturn new Info(0, 0);}//黑盒子的构建Info left = process(x.left);Info right= process(x.right);//拆解黑盒int height = Math.max(left.height, right.height) + 1;int num = left.num + right.num + 1;return new Info(height, num);}

题目四:判断是否为平衡二叉树

  • 树形dp思路:
    1 可能性分析:
    (1)X平衡:左右均为平衡二叉树,且|左高度 - 右高度| <= 1
    (2)X不平衡,不满足平衡的一条就行
    2 信息要求
    (1)左右子树是否平衡
    (2)左右树的高度
    (3)子树需要给父节点返回的信息结构:是否平衡,高度
    3 递归函数设计
    (1)basecase:节点为空,返回(true,0)
    (2)黑盒的构造:假设直接得到了左右子树想要的信息结构
    (3)拆解黑盒:给出具体一个节点在得到所有子树信息后,如何整合出该节点的信息结构
    public static class Node{int value;Node left;Node right;public Node(int date){this.value = date;}}public static class Info {//Infopublic boolean isBalanced; //树是否平衡public int height; public Info(boolean isBalanced, int height){//构造函数this.isBalanced = isBalanced;this.height = height;}}public static boolean isBalancedTree(Node head){return process(head).isBalanced;}public static Info process(Node x){//返回x的Info信息if (x == null){//basecasereturn new Info(true, 0);}//黑盒构造Info leftTree = process(x.left); Info rightTree= process(x.right);//拆解黑盒int height = Math.max(leftTree.height, rightTree.height) + 1;boolean isBalanced = leftTree.isBalanced && rightTree.isBalanced&& Math.abs(leftTree.height - rightTree.height) < 2;return new Info(isBalanced, height);}

题目五:判断是否为二叉排序树

  • 树形dp思路:
    1 可能性分析:
    (1)X是:左max < head.value < 右min,左右均为二叉排序树
    (2)X不是,不满足条件
    2 信息要求
    (1)左右子树是否为二叉排序树
    (2)左的max,min;右的min,max
    (1)子树需要给父节点返回的信息结构:是否为二叉排序树,左右的max,min
    3 递归函数设计
    (1)basecase:节点为空,因为max,min不好设置,直接返回null
    (2)黑盒的构造:假设直接得到了左右子树想要的信息结构
    (3)拆解黑盒:给出具体一个节点在得到所有子树信息后,如何整合出该节点的信息结构
    public static class Node{int value;Node left;Node right;public Node(int date){this.value = date;}}public static class Info {//infopublic boolean isBST; //树是否为搜索树public int min; //树的最小值public int max; //树的最大值public Info(boolean isBST, int min, int max){//构造函数this.isBST = isBST;this.min = min;this.max = max;}}public static boolean isBSTree(Node head){return process(head).isBST;}public static Info process(Node x){//返回x的Infoif (x == null){//空树的min,max不好设置,直接设置为nullreturn null;}//黑盒构造Info leftTree = process(x.left); //递归调用Info rightTree= process(x.right);//拆解黑盒int min = x.value; //min,max的设置int max = x.value;if (leftTree != null){//左子树为空min = Math.min(min, leftTree.min);max = Math.max(max, leftTree.max);}if (rightTree != null){//右子树为空min = Math.min(min, rightTree.min);max = Math.max(max, rightTree.max);}boolean isBST = true; //isBST设置if (leftTree != null && (leftTree.isBST || leftTree.max > x.value)){//左不为空的条件下:左子树不是搜索二叉树或左的max > head,value//不满足搜索二叉树isBST = false;}if (rightTree != null && (rightTree.isBST || rightTree.min < x.value)){isBST = false;}return new Info(isBST, min, max);}

算法设计与分析 树形dp相关推荐

  1. 算法设计与分析:贪心算法 - 排课问题(DP与贪心的区别与应用)

    文章目录 前言 贪心算法概念 排课问题 问题描述与分析 动态规划求解 简化问题应用贪心算法 总结 本文参考UCAS卜东波老师算法设计与分析课程撰写 前言 前面两大章节的内容分治思想与动态规划暂时告一段 ...

  2. 算法设计与分析实验指导(完整版)

    算法设计与分析实验指导 文章目录 算法设计与分析实验指导 1. 快速排序及第k小数 1.1 快速排序 1.1.1 Implementation 1 1.1.2 算法特性分析 1.1.3 Improve ...

  3. 算法设计与分析课程的时间空间复杂度

    算法设计与分析课程的时间空间复杂度: 总结 算法 时间复杂度 空间复杂度 说明 Hanoi $ O(2^n) $ $ O(n) $ 递归使用 会场安排问题 \(O(nlogn)\) \(O(n)\) ...

  4. 哈工大威海算法设计与分析_计算机算法设计与分析第一章 算法概述

    晓强Deep Learning的读书分享会,先从这里开始,从大学开始.大家好,我是晓强,计算机科学与技术专业研究生在读.我会不定时的更新我的文章,内容可能包括深度学习入门知识,具体包括CV,NLP方向 ...

  5. 【算法设计与分析】经典常考三十三道例题AC代码

    ❥小虾目前大三,我校在大一下开设<数据结构>这门课,大二上开了<算法设计与分析>这门课,很庆幸这两门课的上机考试总成绩一门100,一门99,最后总分也都90+.下文会给出机试的 ...

  6. Python 算法设计与分析 投资问题

    Python 算法设计与分析 投资问题 投资问题 题目:设有m元钱,n项投资,函数fi(x)表示将x元投入第i项项目所产生的效益,i=1,2,3,-,n.问:如何分配这m元钱,使得投资的总效益最高? ...

  7. 算法设计与分析-----动态规划

    算法设计与分析-----动态规划(c语言) 一.动态规划 1.定义 2.动态规划问题的解法 3.动态规划求解的基本步骤 4.动态规划与其他方法的比较 5.求解整数拆分问题 6.求解最大连续子序列和问题 ...

  8. CUMT2022算法设计与分析A考试

    CUMT2022算法设计与分析A考试 综合题 40 矩阵连乘 10 流水作业调度变形 10 最短路径 10 最小生成树 10 算法分析 时间复杂度 15 01背包变形 15 算法设计 称重 15 积木 ...

  9. C/C++ 算法设计与分析实验报告

    算法设计与分析实验报告 算法实验整体框架的构建 菜单代码块 选择函数代码块 主函数代码块 实验模块Ⅰ:算法分析基础--Fibonacci序列问题 实验解析 Fibonacci序列问题代码块 实验模块Ⅱ ...

最新文章

  1. js 正则之检测素数
  2. hello是c语言中的变量吗,C语言hello world详解
  3. Java方法中的参数太多,第4部分:重载
  4. python画害羞的表情_用Python把你的朋友变成表情包
  5. iOS 自定义UIButton
  6. Bootstrap-分页插件Paginator
  7. 黑苹果alc269声卡仿冒id_AppleALC仿冒声卡驱动alc269优化版(Lenovo Z580亲测)
  8. java实现微信企业号API服务端调用封装
  9. 概率论排列公式和组合公式实质 压强 : 压力=ps=压强*面积; 万有引力公式:
  10. 【微信小程序】快进来弹钢琴啦~钢琴小程序源码分享
  11. 记录Notepad软件保护眼睛的颜色怎么设置
  12. 计算机毕业设计php的校园电影网站系统
  13. 重积分定理与计算总结
  14. 修改植物大战僵尸游戏存档——跳关并快速实现财富自由
  15. mysql 磁盘读取原理_mysql 底层原理
  16. mysql查询IN索引无效的问题【已解决】
  17. forward_list
  18. WPF之布局属性HorizontalAlignment、HorizontalContentAlignment、VertialAlignment、VerticalContentAlignment
  19. 几种常见的RAID工作模式讨论
  20. 一键百度 一键翻译 云脉CC慧眼百度搜索版

热门文章

  1. python image库安装_Python如何安装Image库呢?
  2. 某银行系统ACS认证之TACACS+认证方案
  3. Expression 拼接组合表达式(附--封装代码)
  4. 高效准确地过滤Outlook垃圾邮件
  5. Andriod Studio 2021.1.1 Patch1 中文汉化方法
  6. js中 slice 用法用法全解析
  7. Apple发布新电脑
  8. ajax文件插件上传,7 款基于 JavaScript/AJAX 的文件上传插件
  9. 工程专题|idea一个对话打开多个工程
  10. 高精度秒表StopWatch的使用方法及示例程序