【14】二叉树的Morris等

目录

一.树形dp套路 

二.派对的最大快乐值

三.Morris遍历

morris先序遍历

morris中序遍历

moris后序遍历

判断是不是搜索二叉树

四.额外习题


一.树形dp套路 

 

情况1:最大距离,节点X不参与。 => 左树最大距离 or 右树最大距离

情况2:最大距离,节点X参与。 => 最大距离 = 左树高度+1+右树高度

常见的分类,是头节点参不参与来罗列可能性。

可以设计:
节点的信息 => 最大距离maxDistance 、树高height

节点cur时的最大距离 = max{left的maxDistance, right的maxDistance,left的height+right的height+1}

	public static class Node { // 树节点public int value; // 节点值public Node left; // 左子树public Node right; // 右子树public Node(int data) { // 构造this.value = data;}}// 返回最大距离public static int maxDistance(Node head) { return process(head).maxDistance;}// 一个节点的返回信息public static class ReturnType{public int maxDistance; // 最大距离public int h; // 高度public ReturnType(int m, int h) { // 构造this.maxDistance = m;; this.h = h;}}// 给出当前节点的返回信息(最大距离,高度)public static ReturnType process(Node head) {if(head == null) {return new ReturnType(0,0);}ReturnType leftReturnType = process(head.left); // 左树返回信息ReturnType rightReturnType = process(head.right); // 右数返回信息int includeHeadDistance = leftReturnType.h + 1 + rightReturnType.h; // 计算包含根节点的最大距离int p1 = leftReturnType.maxDistance; // 左子树最大距离int p2 = rightReturnType.maxDistance; // 右子树最大举例int resultDistance = Math.max(Math.max(p1, p2), includeHeadDistance); // 到当前位置可以获得的最大距离int hitself  = Math.max(leftReturnType.h, leftReturnType.h) + 1; // 高度return new ReturnType(resultDistance, hitself); // 将信息放回给上一级}

二.派对的最大快乐值

情况1:节点X参与

X参与的最大快乐 = X乐 + a不来的最大快乐 + b不来的最大快乐 + c不来的最大快乐

情况2:节点X不参与

X不参与的最大快乐 = 0 + max(a来的最大快乐,a不来的最大快乐) + max(b来的最大快乐,b不来的最大快乐) + max(c来的最大快乐,c不来的最大快乐) 

	public static class Employee{public int happy;public List<Employee> nexts;}public static class ReturnType{public int no_maxhappy;public int yes_maxhappy;public ReturnType(int no, int yes) {no_maxhappy=no;yes_maxhappy=yes;}}public static ReturnType process(Employee head) {if(head.nexts.isEmpty()) { // 基层员工 return new ReturnType(0, head.happy);}int no_maxhappy=0; // head不来的最大快乐int yes_maxhappy=head.happy; // head来的最大快乐for(Employee next:head.nexts) {ReturnType node=process(next);yes_maxhappy+=node.no_maxhappy;no_maxhappy+=Math.max(node.no_maxhappy, node.yes_maxhappy);}return new ReturnType(no_maxhappy, yes_maxhappy);}

三.Morris遍历

笔试不要用Morris遍历,面试阶段用。(学术名词:线索二叉树)

【如果不用栈,如何回到上级节点,用底层节点大量的空闲指针】

标准1:如果没有左树 => 当前节点cur向右树走。

标准2

如果有左树,找到左树中最右节点 => 最右节点右指针为空 => 右指针指向当前节点cur => 当前节点cur向左树走。

标准3

如果有左树,找到左树中最右节点 => 最右节点右指针不为空 =>  当前节点cur向右树走。

	public static class Node {public int value;Node left;Node right;public Node(int data) {this.value = data;}}public static void morris(Node head) {if (head == null) {return;}Node cur1 = head;Node cur2 = null;while (cur1 != null) { //  过流程cur2 = cur1.left; // cur2是cur左孩子if (cur2 != null) {while (cur2.right != null && cur2.right != cur1) {cur2 = cur2.right;}// cur2变成cur左子树上,最后的节点if (cur2.right == null) { // 这是第一次来到curcur2.right = cur1;cur1 = cur1.left;continue;} else { // cur2.right == nullcur2.right = null;}}cur1 = cur1.right;}}

单独遍历左子树有边界这件事,每个节点至多被遍历1次,总代价至多是O(n),并不会多严重。

morris先序遍历

  • 只一次来到的节点 => 直接打印
  • 来到两次的节点 => 第一次打印
	public static void morrisPre(Node head) {if (head == null) {return;}Node cur1 = head;Node cur2 = null;while (cur1 != null) {cur2 = cur1.left;if (cur2 != null) {while (cur2.right != null && cur2.right != cur1) {cur2 = cur2.right;}if (cur2.right == null) {cur2.right = cur1;System.out.print(cur1.value + " ");cur1 = cur1.left;continue;} else {cur2.right = null;}} else {System.out.print(cur1.value + " ");}cur1 = cur1.right;}System.out.println();}

morris中序遍历

  • 只一次来到的节点 => 直接打印
  • 来到两次的节点 => 第二次打印
	public static void morrisIn(Node head) {if (head == null) {return;}Node cur1 = head;Node cur2 = null;while (cur1 != null) { //  过流程cur2 = cur1.left; // cur2是cur左孩子if (cur2 != null) {while (cur2.right != null && cur2.right != cur1) {cur2 = cur2.right;}// cur2变成cur左子树上,最后的节点if (cur2.right == null) { // 这是第一次来到curcur2.right = cur1;cur1 = cur1.left;continue;} else { // cur2.right == nullcur2.right = null;}}System.out.print(cur1.value + " ");cur1 = cur1.right;}System.out.println();}

moris后序遍历

	public static void morrisPos(Node head) {if (head == null) {return;}Node cur1 = head;Node cur2 = null;while (cur1 != null) {cur2 = cur1.left;if (cur2 != null) {while (cur2.right != null && cur2.right != cur1) {cur2 = cur2.right;}if (cur2.right == null) {cur2.right = cur1;cur1 = cur1.left;continue;} else {cur2.right = null;printEdge(cur1.left);}}cur1 = cur1.right;}printEdge(head);System.out.println();}public static void printEdge(Node head) {Node tail = reverseEdge(head);Node cur = tail;while (cur != null) {System.out.print(cur.value + " ");cur = cur.right;}reverseEdge(tail);}public static Node reverseEdge(Node from) {Node pre = null;Node next = null;while (from != null) {next = from.right;from.right = pre;pre = from;from = next;}return pre;}

判断是不是搜索二叉树

在中序遍历的位置判断,是否preValue是一直在递增的。

	public static boolean isBST(Node head) {if (head == null) {return true;}Node cur1 = head;Node cur2 = null;int preValue=Integer.MIN_VALUE;while (cur1 != null) { //  过流程cur2 = cur1.left; // cur2是cur左孩子if (cur2 != null) {while (cur2.right != null && cur2.right != cur1) {cur2 = cur2.right;}// cur2变成cur左子树上,最后的节点if (cur2.right == null) { // 这是第一次来到curcur2.right = cur1;cur1 = cur1.left;continue;} else { // cur2.right == nullcur2.right = null;}}if(cur1.value <= preValue) {return false;}preValue = cur1.value;cur1 = cur1.right;}return true;}

如果方法必须要节点第3次遍历的强整合

    => 递归套路是最优解(非叶子节点到3次,叶子节点到1次)

如果方法没必要节点第3次遍历的强整合

    => morris遍历(非叶子节点可以到2次,叶子到1次)

四.额外习题

原问题:

使用位图,2^32个数需要2^32bit的空间 = 512MB

进阶问题:

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

html编写贪吃蛇页面小游戏(可以玩)

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>贪吃蛇小游戏</title><style>body {…

【软件逆向】第2课,软件逆向安全工程师之区分应用32位和64位,每天5分钟学习逆向吧!

目标学习使用StudyPE区分应用 在软件逆向中区分应用类型是关键性的一部分 &#xff0c;只有区分类型后才能选择对应工具进行后续处理。 1.打开StudyPE工具。 2.将我们需要逆向的软件&#xff0c;拖拽到StudyPE中&#xff0c;查看应用信息。 以上用一款视觉AI软件举例&#…

Java设计模式-原型模式-一次性理解透

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1. 前言2. 原型模式的主要角色2.1 原型接口或抽象类2.2 具体原型类2.3 客户端2.4 克隆方法 3. 原型模式使用场景3.1 创建对象是昂贵的3.2 对象的变化3.3 动态配置3.…

【STM32】DMA数据转运(存储器到存储器)

本篇博客重点在于标准库函数的理解与使用&#xff0c;搭建一个框架便于快速开发 目录 DMA简介 DMA时钟使能 DMA初始化 转运起始和终止的地址 转运方向 数据宽度 传输次数 转运触发方式 转运模式 通道优先级 DMA初始化框架 选择开启DMA通道 更改转运次数 DMA应用…

【第二节】80x86汇编-寄存器和标志位

目录 前言 一、汇编相关概念 1.1 数据表示与类型 1.2 汇编语言的构成 1.3 存储器及指令、数据 1.4 存储单元 1.5 CPU对存储器的读写操作 1.6 CPU读写内存单元的过程 1.7 intel CPU发展 1.8 8086 内部结构 二、寄存器 2.1 寄存器概览 2.2 32位寄存器 2.3 16位寄存器…

三维建模软件:地理信息与遥感领域的智慧构建者

在地理信息与遥感技术的广阔舞台中&#xff0c;建模软件如同一位卓越的建筑师&#xff0c;以数据为砖瓦&#xff0c;智慧为水泥&#xff0c;构建出一个又一个又一个逼真、动态的虚拟世界。本文将深入探究其技术核心、应用实例、未来趋势&#xff0c;揭示建模软件如何在地理信息…

《爱情,到此为止》票房大卖 贾斯汀巴尔多尼与布莱克莱弗利的矛盾升级 是真的还是炒作

布蕾克莱弗利&#xff0c;贾斯汀巴尔多尼 布莱克莱弗利凭借电影《我们的末日》在周末取得了票房成功&#xff0c;首映票房收入达 5000 万美元。在电影院困难时期&#xff0c;这是一个了不起的成就&#xff0c;但没有人谈论这一胜利——粉丝们对她与导演兼联合主演贾斯汀巴尔多…

排序(基数,堆,归并)

基数排序 定义0-9十个桶&#xff0c;先排序个数&#xff0c;在排序十位&#xff0c;依次向下&#xff08;桶就是二维数组&#xff09; 按照个位先排一次 个位已经有序了&#xff0c;桶内遵循先进先出 没有十位放到0里 取出 百位 这样排序就完成了。放进取出几次&#xff0c;取…

Flink Checkpoint expired before completing解决方法

在Flink消费Kafka日志的时候出现了这样的一则报错&#xff0c; JobManager报错如下&#xff1a; 2024-03-07 15:21:12,500 [Checkpoint Timer] WARN org.apache.flink.runtime.checkpoint.CheckpointFailureManager [] - Failed to trigger or complete checkpoint 181 for …

Python酷库之旅-第三方库Pandas(082)

目录 一、用法精讲 341、pandas.Series.str.startswith方法 341-1、语法 341-2、参数 341-3、功能 341-4、返回值 341-5、说明 341-6、用法 341-6-1、数据准备 341-6-2、代码示例 341-6-3、结果输出 342、pandas.Series.str.strip方法 342-1、语法 342-2、参数 …

bug的常见排查和分析思路以及相关的原因分类

作为开发人员&#xff0c;经常会收到来自用户和QA&#xff0c;领导反馈的各种问题。 为了快速问题&#xff0c;我们有时需要站在更高的角度&#xff0c;更全面的看待问题。才能更快锁定问题。 具体的bug还需要结合企业实际业务情况&#xff0c;相关的框架&#xff0c;依赖库&…

PHP项目任务系统小程序源码

&#x1f680;解锁高效新境界&#xff01;我的项目任务系统大揭秘&#x1f50d; &#x1f31f; 段落一&#xff1a;引言 - 为什么需要项目任务系统&#xff1f; Hey小伙伴们&#xff01;你是否曾为了杂乱的待办事项焦头烂额&#xff1f;&#x1f92f; 或是项目截止日逼近&…

QT、C++简单界面设计

#include "mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent) {---------------------窗口设置----------------------this->setWindowTitle("南城贤子摄影工作室");//设置窗口标题this->setWindowIcon(QIcon("d:\\Pictures\\C…

PUMA论文阅读

PUMA: Efficient Continual Graph Learning with Graph Condensation PUMA&#xff1a;通过图压缩进行高效的连续图学习 ABSTRACT 在处理流图时&#xff0c;现有的图表示学习模型会遇到灾难性的遗忘问题&#xff0c;当使用新传入的图进行学习时&#xff0c;先前学习的这些模…

c语言中比较特殊的输入格式

目录 一.%[ ] 格式说明符 1.基本用法 (1)读取字母字符: (2)读取数字字符: (3)读取所有字符直到遇到空格: (4)读取直到换行符: 2.使用范围和组合: 3.^ 取反操作 4.注意事项 (1). 字符范围的正确表示 (2). 避免字符集中的特殊字符冲突 (3).避免空字符集 (4). 输入长…

构建高效外贸电商系统的技术探索与源码开发

在当今全球化的经济浪潮中&#xff0c;外贸电商作为连接国内外市场的桥梁&#xff0c;其重要性日益凸显。一个高效、稳定、功能全面的外贸电商系统&#xff0c;不仅能够助力企业突破地域限制&#xff0c;拓宽销售渠道&#xff0c;还能提升客户体验&#xff0c;增强品牌竞争力。…

Wireshark过滤规则

一、按IP地址过滤 1、查看源IP为 xx 的包 ip.srcIP地址 例如&#xff1a;ip.src172.18.10.56 2、查看目标IP为 xx 的包 ip.dstIP地址 例如&#xff1a;ip.dst172.16.76.251 3、查看源或目标IP为 xx 的包 ip.addrIP地址 例如&#xff1a;ip.addr172.18.10.56 二、按MAC地…

数学建模--浅谈多波束测线问题

目录 1.问题说明 2.问题分析 3.代码分析 1.问题说明 这个是国赛的真题&#xff0c;我们这个里面只是浅谈&#xff0c;就是对于这个里面运用的过程仿真的思路进行说明&#xff0c;这个探测的波束问题实际上也是一个简单的过程仿真问题&#xff0c;也是需要去进行作图的&#…

【中等】 猿人学web第一届 第5题 js混淆-乱码增强

文章目录 请求流程请求参数cookie信息 加密参数定位Hook CookieAST 还原混淆代码解密函数还原字符串还原数组引用还原浏览器内置对象 / 变量值引用还原逗号表达式还原 unicode, 16进制数值字符串相加AST 解混淆完整代码 加密参数还原cookie m字段m字段坑点 cookie RM4hZBv0dDon…

什么是云原生?(二)

1. 云原生的定义 云原生指构建和运行应用以充分利用通过云技术交付模式交付的分布式计算。云原生应用旨在充分利用云技术平台特有的可扩展性、弹性和灵活性优势。 根据云原生计算基金会 (CNCF) 的定义&#xff0c;云原生技术可帮助企业在公有云、私有云和混合云环境中构建和…