算法设计与分析 树形dp
树形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相关推荐
- 算法设计与分析:贪心算法 - 排课问题(DP与贪心的区别与应用)
文章目录 前言 贪心算法概念 排课问题 问题描述与分析 动态规划求解 简化问题应用贪心算法 总结 本文参考UCAS卜东波老师算法设计与分析课程撰写 前言 前面两大章节的内容分治思想与动态规划暂时告一段 ...
- 算法设计与分析实验指导(完整版)
算法设计与分析实验指导 文章目录 算法设计与分析实验指导 1. 快速排序及第k小数 1.1 快速排序 1.1.1 Implementation 1 1.1.2 算法特性分析 1.1.3 Improve ...
- 算法设计与分析课程的时间空间复杂度
算法设计与分析课程的时间空间复杂度: 总结 算法 时间复杂度 空间复杂度 说明 Hanoi $ O(2^n) $ $ O(n) $ 递归使用 会场安排问题 \(O(nlogn)\) \(O(n)\) ...
- 哈工大威海算法设计与分析_计算机算法设计与分析第一章 算法概述
晓强Deep Learning的读书分享会,先从这里开始,从大学开始.大家好,我是晓强,计算机科学与技术专业研究生在读.我会不定时的更新我的文章,内容可能包括深度学习入门知识,具体包括CV,NLP方向 ...
- 【算法设计与分析】经典常考三十三道例题AC代码
❥小虾目前大三,我校在大一下开设<数据结构>这门课,大二上开了<算法设计与分析>这门课,很庆幸这两门课的上机考试总成绩一门100,一门99,最后总分也都90+.下文会给出机试的 ...
- Python 算法设计与分析 投资问题
Python 算法设计与分析 投资问题 投资问题 题目:设有m元钱,n项投资,函数fi(x)表示将x元投入第i项项目所产生的效益,i=1,2,3,-,n.问:如何分配这m元钱,使得投资的总效益最高? ...
- 算法设计与分析-----动态规划
算法设计与分析-----动态规划(c语言) 一.动态规划 1.定义 2.动态规划问题的解法 3.动态规划求解的基本步骤 4.动态规划与其他方法的比较 5.求解整数拆分问题 6.求解最大连续子序列和问题 ...
- CUMT2022算法设计与分析A考试
CUMT2022算法设计与分析A考试 综合题 40 矩阵连乘 10 流水作业调度变形 10 最短路径 10 最小生成树 10 算法分析 时间复杂度 15 01背包变形 15 算法设计 称重 15 积木 ...
- C/C++ 算法设计与分析实验报告
算法设计与分析实验报告 算法实验整体框架的构建 菜单代码块 选择函数代码块 主函数代码块 实验模块Ⅰ:算法分析基础--Fibonacci序列问题 实验解析 Fibonacci序列问题代码块 实验模块Ⅱ ...
最新文章
- js 正则之检测素数
- hello是c语言中的变量吗,C语言hello world详解
- Java方法中的参数太多,第4部分:重载
- python画害羞的表情_用Python把你的朋友变成表情包
- iOS 自定义UIButton
- Bootstrap-分页插件Paginator
- 黑苹果alc269声卡仿冒id_AppleALC仿冒声卡驱动alc269优化版(Lenovo Z580亲测)
- java实现微信企业号API服务端调用封装
- 概率论排列公式和组合公式实质 压强 : 压力=ps=压强*面积; 万有引力公式:
- 【微信小程序】快进来弹钢琴啦~钢琴小程序源码分享
- 记录Notepad软件保护眼睛的颜色怎么设置
- 计算机毕业设计php的校园电影网站系统
- 重积分定理与计算总结
- 修改植物大战僵尸游戏存档——跳关并快速实现财富自由
- mysql 磁盘读取原理_mysql 底层原理
- mysql查询IN索引无效的问题【已解决】
- forward_list
- WPF之布局属性HorizontalAlignment、HorizontalContentAlignment、VertialAlignment、VerticalContentAlignment
- 几种常见的RAID工作模式讨论
- 一键百度 一键翻译 云脉CC慧眼百度搜索版
热门文章
- python image库安装_Python如何安装Image库呢?
- 某银行系统ACS认证之TACACS+认证方案
- Expression 拼接组合表达式(附--封装代码)
- 高效准确地过滤Outlook垃圾邮件
- Andriod Studio 2021.1.1 Patch1 中文汉化方法
- js中 slice 用法用法全解析
- Apple发布新电脑
- ajax文件插件上传,7 款基于 JavaScript/AJAX 的文件上传插件
- 工程专题|idea一个对话打开多个工程
- 高精度秒表StopWatch的使用方法及示例程序