算法笔记(十三)—— 树形DP及Morris遍历

news2024/9/27 5:59:42

树形DP:

 

Question1: 

 以X为头结点的树,最大距离:

1. X不参与,在左子树上的最大距离

2. X不参与,在右子树上的最大距离

3. X参与,左树上最远的结点通过X到右树最远的结点

最后的结果一定是三种情况的最大值

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Info{
    public:
        int maxdistace;
        int high;
        Info(int val1 , int val2){
            maxdistace = val1;
            high = val2;
        }
};

class Solution {
public:
    Info dp(TreeNode* node){
        if(node==nullptr){
            return Info(0,0);
        }
        Info l = dp(node->left);
        Info r= dp(node->right);
        return Info(max(l.high+r.high+1 , max(l.maxdistace , r.maxdistace)) , max(l.high,r.high)+1);
    }

    int diameterOfBinaryTree(TreeNode* root) {
        Info res = dp(root);
        return res.maxdistace-1;
    }
};

Question2: 

 根据某树头结点来或不来进行分类即可

#include <iostream>
#include<bits/stdc++.h>
using namespace std;

class TreeNode{
public:
	int num;
	int happy;
	vector<TreeNode*> nexts;
	TreeNode(int number , int val){
		num = number;
		happy = val;
	}
};

class Info{
public:
	int inval;
	int outval;
	Info(int val1 , int val2){
		inval = val1;
		outval = val2;
	}
};

vector<TreeNode*> Happy;

Info dp(int cur){
	if(Happy[cur]->nexts.empty())return Info(Happy[cur]->happy , 0);
	int inv = Happy[cur]->happy;
	int outv = 0;
	for(auto &it:Happy[cur]->nexts){
		Info temp = dp(it->num);
		inv += temp.outval;
		outv += max(temp.inval , temp.outval);
	}
	return Info(inv , outv);
}

int main() {
	int n , root;
	cin>>n>>root;
	Happy.resize(n);
	for(int i = 1 ; i<=n ; i++){
		int val;
		cin>>val;
		Happy[i-1] = new TreeNode(i-1 , val);
	}
	for(int i = 0 ; i<n-1 ; i++){
		int up , low;
		cin>>up>>low;
		Happy[up-1]->nexts.push_back(Happy[low-1]);
	}
	Info res = dp(root-1);
	cout<<max(res.inval , res.outval);
	return 0;
}

Morris遍历(时间复杂度O(N) 空间复杂度O(1))

前序:第一次到达一个节点的时候就打印

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res;
        if(root==nullptr)return res;
        while(root!=nullptr){
            TreeNode* temp = root->left;
            if(temp!=nullptr){
                while(temp->right!=nullptr&&temp->right!=root){
                    temp = temp->right;
                }
                if(temp->right==nullptr){
                    temp->right = root;
                    res.push_back(root->val);
                    root = root->left;
                    continue;
                }
                else{
                    temp->right = nullptr;
                }
            }
            else{
                res.push_back(root->val);
            }
            root = root->right;
        }
        return res;
    }
};

中序:只能到达一次的节点直接打印,能到达两次的第二次打印

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        if(root==nullptr)return res;
        while(root!=nullptr){
            TreeNode* temp = root->left;
            if(temp!=nullptr){
                while(temp->right!=nullptr&&temp->right!=root){
                    temp = temp->right;
                }
                if(temp->right==nullptr){
                    temp->right = root;
                    root = root->left;
                    continue;
                }
                else{
                    temp->right = nullptr;
                }
            }
            res.push_back(root->val);
            root = root->right;
        }
        return res;
    }
};

后序:第二次回到一个节点时,逆序打印该节点左子树,右边界,最后单独逆序打印整棵树右边界

class Solution {
public:
    TreeNode* reverse(TreeNode* root){
        TreeNode* pre = nullptr;
        TreeNode* next = nullptr;
        while(root!=nullptr){
            next = root->right;
            root->right = pre;
            pre = root;
            root = next;
        }
        return pre;
    }

    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
        TreeNode* head = root;
        if(root==nullptr)return res;
        while(root!=nullptr){
            TreeNode* temp = root->left;
            if(temp!=nullptr){
                while(temp->right!=nullptr&&temp->right!=root){
                    temp = temp->right;
                }
                if(temp->right==nullptr){
                    temp->right = root;
                    root = root->left;
                    continue;
                }
                else{
                    temp->right = nullptr;
                    TreeNode* cur = reverse(root->left);
                    TreeNode* temp = cur;
                    while(temp!=nullptr){
                        res.push_back(temp->val);
                        temp = temp->right;
                    }
                    root->left = reverse(cur);
                }
            }
            root = root->right;
        }
        TreeNode* cur = reverse(head);
        TreeNode* temp = cur;
        while(temp!=nullptr){
            res.push_back(temp->val);
            temp = temp->right;
        }
        root = reverse(cur);
        return res;
    }
};

如果一个方法需要第三次信息的强整合(向左树要信息,向右树要信息再处理),必须用递归;如果不需要,则morris遍历是最优解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/367082.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【微信小程序】-- 常用视图容器类组件介绍(六)

&#x1f48c; 所属专栏&#xff1a;【微信小程序开发教程】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#…

Spring Boot与Vue:实现图片的上传

文章目录1. 项目场景2. 问题描述3. 实现方案3.1 方案一&#xff1a;上传图片&#xff0c;转换成 Base64 编码并返回3.1.1 前端页面组件3.1.2 前端 JS 函数3.1.3 后端 Controller3.2 方案二&#xff1a;上传图片&#xff0c;并返回图片路径3.2.1 前端页面组件3.2.1 前端 JS 函数…

shell的函数

一、shell函数 有些脚本段间互相重复&#xff0c;如果能只写一次代码块而在任何地方都能引用那就提高了代码的可重用性。 shell 允许将一组命令集或语句形成一个可用块&#xff0c;这些块称为 shell 函数。 二、shell函数的格式 2.1.第一种格式 函数名&#xff08…

selenium自动化测试用例需要关注的几点

自动化测试设计简介注&#xff1a;参看文章地址 我们在本章提供的信息&#xff0c;对自动化测试领域的新人和经验丰富的老手都是有用的。本篇中描述最常见的自动化测试类型&#xff0c; 还描述了可以增强您的自动化测试套件可维护性和扩展性的“设计模式”。还没有使用这些技术…

Clion安装Platformio支持

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、系统配置二、什么是platformio三、安装配置1.安装Clion2.安装platformio插件3.安装platformio&#xff08;CLI&#xff09;4. 配置Clion环境5. 创建示例Demo…

低功耗设计:rush current

在power gating的设计中有一个rush current的概念&#xff0c;它的产生原因是switch cell上电过程相当于电容充电过程&#xff0c;会产生一个短期的大电流&#xff0c;称之为rush current。 1.rush current的危害 1&#xff09;rush current产生的压降可能会造成大的短路电流…

Python学习笔记——NumPy

一、向量数据 ①概念 向量数据是指存储一系列同类数据的有序数据结构。 ②分类 python中的列表和元组可以用来存储向量数据。 分为 一维列表&#xff0c;二维列表&#xff0c;三(多)维列表。 ③向量数据结构的理解 二、产生原因 大量的向量数据计算时&#xff0c;使用pyt…

蓝桥杯的比赛流程和必考点

蓝桥杯的比赛流程和必考点 距省赛仅1个多月&#xff01;蓝桥杯的比赛流程和必考点&#xff0c;你还不清楚&#xff1f; “巷子里的猫很自由&#xff0c;却没有归宿&#xff1b;围墙里的狗有归宿&#xff0c;终身都得低头。人生这道选择题&#xff0c;怎么选都会有遗憾。” 但不…

弹性负载均衡器类型

Hello大家好&#xff0c;在本课时&#xff0c;我们将讨论AWS不同类型的弹性负载均衡器,也就是ELB。 对于认证考试您需要了解针对不同的场景使用哪种类型的负载均衡器。 负载均衡器类型 应用程序负载均衡器 第一个是应用程序负载均衡器&#xff0c;也就是ALB&#xff0c;ALB在…

ArcGIS手动分割矢量面要素从而划分为多个面部分的方式:Cut Polygons Tool

本文介绍在ArcGIS下属ArcMap软件中&#xff0c;通过“Cut Polygons Tool”工具&#xff0c;对一个面要素矢量图层加以手动分割&#xff0c;从而将其划分为指定形状的多个部分的方法。 对于一个面要素矢量文件&#xff0c;有时我们需要对其加以划分&#xff0c;通过手动勾勒新的…

Python杂题-- 内附蓝桥题:裁纸刀

杂题 ~~不定时更新&#x1f383;&#xff0c;上次更新&#xff1a;2023/02/23 蓝桥例题1-裁纸刀&#x1f52a; 问题描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 小蓝有一个裁纸刀&#xff0c;每次可以将一张纸沿…

高阶数据结构之LRU Cache

文章目录什么是LRU Cache&#xff1f;LRU Cache的实现JDK中自带的数据结构模拟实现LRU Cache&#xff08;双向链表哈希表&#xff09;什么是LRU Cache&#xff1f; LRU的全称是“Least Recently Used”的缩写&#xff0c;表示最近最少的使用&#xff0c;是一种Cache替换算法&am…

机器学习和深度学习综述

机器学习和深度学习综述 1. 人工智能、机器学习、深度学习的关系 近些年人工智能、机器学习和深度学习的概念十分火热&#xff0c;但很多从业者却很难说清它们之间的关系&#xff0c;外行人更是雾里看花。在研究深度学习之前&#xff0c;先从三个概念的正本清源开始。概括来说…

2022-2-23作业

一、通过操作Cortex-A7核&#xff0c;串口输入相应的命令&#xff0c;控制LED灯进行工作 1.例如在串口输入led1on,开饭led1灯点亮 2.例如在串口输入led1off,开饭led1灯熄灭 3.例如在串口输入led2on,开饭led2灯点亮 4.例如在串口输入led2off,开饭led2灯熄灭 5.例如在串口输…

关于性能测试,你不可不知的内容

目录 1、性能测试概述 2、常见的性能测试指标 2.1、并发 2.2、响应时间 2.3、事务 2.3.1、事务响应时间 2.3.2、每秒事务通过数&#xff08;TPS&#xff09; 2.4、点击率 2.5、吞吐量 2.6、资源利用率 3、性能测试分类 3.1、一般性能测试 3.2、负载测试 3.3、压力…

虹科Dimetix激光测距仪在锯切系统中的应用

HK-Dimetix激光测距仪——锯切系统应用 许多生产设施&#xff0c;例如金属服务中心&#xff0c;使用切割锯将每个客户的订单切割成一定长度。定长切割过程通常涉及卷尺和慢跑锯的传送带。但更简单的替代方法是使用虹科Dimetix非接触式激光距离传感器。 为了切断大长度的棒材&…

Day898.Join语句执行流程 -MySQL实战

Join语句执行流程 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于Join语句执行流程的内容。 在实际生产中&#xff0c;关于 join 语句使用的问题&#xff0c;一般会集中在以下两类&#xff1a; 不让使用 join&#xff0c;使用 join 有什么问题呢&#xff1f;如果有…

1+1>2 ?多数据源关联分析系列…

数据表连接的 join 操作&#xff0c;相信大家都不陌生吧&#xff1f;在数据分析时&#xff0c;经常需要对多个不同的数据源进行关联操作&#xff0c;因此各类数据库的 SQL 语言都包含了丰富的 join 语句&#xff0c;以支持批计算关联。而在金融的业务场景中&#xff0c;流数据实…

系统崩溃如何恢复数据?4步,教您快速抢救丢失的数据

电脑保存着很多个人文件和数据&#xff0c;如果碰到电脑系统崩溃&#xff0c;可能会导致文件无法访问&#xff0c;甚至我们的数据会发生丢失的情况。系统崩溃如何恢复数据&#xff1f;我们先来了解下Windows操作系统发生崩溃的常见原因&#xff1a;一次性打开太多软件&#xff…

AG9300方案替代|替代AG9300设计Type-C转VGA方案|CS5260设计原理图

AG9300方案替代|替代AG9300设计Type-C转VGA方案|CS5260设计原理图 安格 AG9300是一款实现USB TYPE-C到VGA数据的单片机解决方案转换器。ALGOLTEK AG9300支持USB Type-C显示端口交替模式&#xff0c;AG9300可以将视频和音频流从USB Type-C接口传输到VGA端口。在AG9300&#xff0…