38寻找二叉树的最近公共祖先39序列化和反序列化

news2024/10/6 16:18:37

38.寻找二叉树的最近公共祖先

在这里插入图片描述
这题和上一题的区别在于这不是二叉搜索树,无法根据值的大小来判断节点的位置,于是需要遍历

法1 递归写法

递归在左右子树寻找o1和o2

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param root TreeNode类 
     * @param o1 int整型 
     * @param o2 int整型 
     * @return int整型
     */
    public int lowestCommonAncestor (TreeNode root, int o1, int o2) {
        // write code here
        return helper(root,o1,o2).val;

    }
    public TreeNode helper(TreeNode root, int o1, int o2){
        if(root==null||root.val==o1||root.val==o2){
            return root;
        }
        TreeNode left = helper(root.left,o1,o2);
        如果left为空,说明这两个节点在root结点的右子树上,我们只需要返回右子树查找的结果
        TreeNode right = helper(root.right,o1,o2);
        if(left==null) return right;
        if(right==null) return left;
        如果left和right都不为空,说明这两个节点一个在root的左子树上一个在root的右子树上,
    //我们只需要返回cur结点即可。
        return root;
    }
}

时间复杂度:O(n),n是二叉树节点的个数,最坏情况下每个节点都会被访问一遍
空间复杂度:O(n),因为是递归,取决于栈的深度,最差最差情况下,二叉树退化成链表,栈的深度是n。

法2 BFS(层次遍历/队列)

思路是用层次遍历找到o1和o2,同时用MAP记录每个节点的parent节点,从o1o2出发向上寻找第一个相同的parent节点

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param root TreeNode类 
     * @param o1 int整型 
     * @param o2 int整型 
     * @return int整型
     */
    public int lowestCommonAncestor (TreeNode root, int o1, int o2) {
        // write code here
        Map<Integer,Integer> parent = new HashMap<>();
        //存每个节点对应的父节点的值
        Queue<TreeNode> q = new LinkedList<>();
        q.offer(root);
        parent.put(root.val,root.val);
        while(!q.isEmpty()||!parent.containsKey(o1)||!parent.containsKey(o2)){
            TreeNode node = q.poll();
            if(node.left!=null){
                q.offer(node.left);
                parent.put(node.left.val,node.val);
            }
            if(node.right!=null){
                q.offer(node.right);
                parent.put(node.right.val,node.val);
            }
        }
        //已经遍历到o1o2两个节点,并存好每个节点对应的parent
        HashSet<Integer> set = new HashSet<>();
        while(!set.contains(o1)){
            set.add(o1);
            o1 = parent.get(o1);//变成父节点 到root会停止
        }//将root到o1的路径上的点全部存起来
        while(!set.contains(o2)){
            set.add(o2);
            o2 = parent.get(o2);
        }//和o2路径上的判断,从下往上,第一个相同的就是结果
        return o2;

    }

}

时间复杂度:O(n),n是二叉树节点的个数,最坏情况下每个节点都会被访问一遍
空间复杂度:O(n),一个是BFS需要的队列,一个是父子节点关系的map

39. 序列化二叉树

在这里插入图片描述

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
import java.util.*;
public class Solution {
    String Serialize(TreeNode root) {
        ArrayList<String> list = new ArrayList<>();
        Queue<TreeNode> q = new LinkedList<>();
        if(root==null) return "";
        list.add(Integer.toString(root.val));
        q.offer(root);
        while(!q.isEmpty()){
            TreeNode node = q.poll();
            if(node.left!=null){
                q.offer(node.left);
                list.add(Integer.toString(node.left.val));
            }else list.add("#");
            if(node.right!=null){
                q.offer(node.right);
                list.add(Integer.toString(node.right.val));
            }else list.add("#");
        }
        int flag=0;//去掉最后面的#
        for(int i=list.size()-1; i>=0;i--){
            if(list.get(i)!="#") flag=1;
            if(flag==0&&list.get(i)=="#")
                list.remove(i);
            
        }
        //System.out.println(String.join(",", list));
        return String.join(",", list);//用,来标记,否则不知道具体数值的划分
        
    }
    TreeNode Deserialize(String str) {
        if(str.length()==0) return null;
        Queue<TreeNode> q = new LinkedList<>();
        System.out.println(str);
        System.out.println(str.length());
        int num = 0;
        int i=0;
        while(i < str.length()&&str.charAt(i)!=','){
            num = num*10+str.charAt(i)-'0';
            i++;
        }
        i++;//跳过,
        TreeNode root = new TreeNode(num);
        System.out.println(num);
        q.offer(root);
        while(i < str.length()){
            num = 0;      
            TreeNode node = q.poll();

            if(i < str.length()&&str.charAt(i)=='#'){
                i +=2;    //跳过#和,        
            }
            else if(i < str.length()){
                while(i < str.length()&&str.charAt(i)!=','){
                    num = num*10+str.charAt(i)-'0';
                    i++;
                }
                node.left = new TreeNode(num);
                System.out.println(num);
                q.offer(node.left); 
                i++;
            }
            num=0;
            if(i < str.length()&&str.charAt(i)=='#'){
                i +=2;    //跳过#和,        
            }
            else if(i < str.length()){
                while(i < str.length()&&str.charAt(i)!=','){
                    num = num*10+str.charAt(i)-'0';
                    i++;
                }
                node.right = new TreeNode(num);
                System.out.println(num);
                q.offer(node.right); 
                i++;
            }
        }
        return root;
       
    }
}

用层次遍历,时间和空间复杂度都是O(n). 感觉这题考的完全是数组的操作,写的时候百度了很久,看了题解发现有更合适的操作,有可边长数组stringBuilder,反序列的时候可以直接用str.split来划分。

split和**Integer.parseInt()**可以将反序列的代码简化为

/*
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
import java.util.*;
public class Solution {
    String Serialize(TreeNode root) {
        ArrayList<String> list = new ArrayList<>();
        Queue<TreeNode> q = new LinkedList<>();
        if(root==null) return "";
        list.add(Integer.toString(root.val));
        q.offer(root);
        while(!q.isEmpty()){
            TreeNode node = q.poll();
            if(node.left!=null){
                q.offer(node.left);
                list.add(Integer.toString(node.left.val));
            }else list.add("#");
            if(node.right!=null){
                q.offer(node.right);
                list.add(Integer.toString(node.right.val));
            }else list.add("#");
        }
        int flag=0;
        for(int i=list.size()-1; i>=0;i--){
            if(list.get(i)!="#") flag=1;
            if(flag==0&&list.get(i)=="#")
                list.remove(i);
            
        }
        System.out.println(list);
        return String.join(",", list);
        
    }
    TreeNode Deserialize(String str) {
        if(str.length()==0) return null;
        Queue<TreeNode> q = new LinkedList<>();
        String[] ss = str.split(",");
        TreeNode root = new TreeNode(Integer.parseInt(ss[0]));
        q.offer(root);
        for(int i = 1; i < ss.length;){    
            TreeNode node = q.poll();
            if(!ss[i].equals("#")){
                node.left = new TreeNode(Integer.parseInt(ss[i]));
                q.offer(node.left); 
                i++;        
            }else i++;
            
            if(i < ss.length&&!ss[i].equals("#")){
                node.right = new TreeNode(Integer.parseInt(ss[i]));
                q.offer(node.right); 
                i++;
            }else i++;
        }
        return root;
       
    }
}

!!!注意这里判断两个字符串是否相同要用**equals()方法,不能直接用==!!!因为包装类用==只是判断两个对象是否一致,用equals()**才是判断值是否相同。

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

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

相关文章

12月编程语言排行榜公布啦~

2022年迎来了最后一个月&#xff0c;我们可以看到&#xff0c;在这一年中编程语言起起伏伏&#xff0c;有的语言始终炙手可热&#xff0c;而有的语言却逐渐“没落”...... 日前&#xff0c;全球知名TIOBE编程语言社区发布了12月编程语言排行榜&#xff0c;有哪些新变化&#x…

Test Squence测试过程中如何按照特定条件暂停或者停止仿真

在Simulink模型做Test Squence测试时&#xff0c;工程师有时候希望测试用例能按照自己期望的条件来停止或暂停仿真&#xff0c;这个期望的特定条件&#xff0c;可以是时间达到&#xff0c;也可以是任何能达到的特定状态。 具体实现方法如下&#xff1a; 1、在Test Harness测试…

公司 CTO:高性能开发,你不会 Netty,怎么好意思拿 20K?

主管&#xff1a;这个版块用 Netty 框架就可以了呀&#xff0c;不会吗&#xff1f; &#xff08;此时&#xff0c;公司 CTO 路过&#xff09; 某程序员&#xff1a;这个我真不会... 主管&#xff1a;好了好了&#xff0c;那这一块我交给别人去做&#xff0c;这个也不难啊&am…

代码随想录刷题记录day36 整数拆分+不同的二叉搜索树

代码随想录刷题记录day36 整数拆分不同的二叉搜索树 参考&#xff1a;代码随想录 343. 整数拆分 思想 一个数可以被拆分成2个数或者3个及以上的数。 dp[i]表示拆分i以后&#xff0c;得到的最大的乘积 拆分成两个数 j和i-j,拆分成三个数及以上 j 和dp[i-j]&#xff0c;dp[i…

面试10分钟就完事了,问的实在是太...

干了两年外包&#xff0c;本来想出来正儿八经找个互联网公司上班&#xff0c;没想到算法死在另一家厂子。 自从加入这家外包公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以也就忍了。没想到11月一纸通知&#xff0c;所有人不许加班&#xff0c;薪资…

【矩阵乘法】C++实现外部矩阵乘法

问题描述 ​ 使用文件和内存模拟系统缓存&#xff0c;并利用矩阵乘法验证实际和理论情况。 算法思想 设计一个Matrix类&#xff0c;其中Matrix是存在磁盘中的一个二进制文件&#xff0c;类通过保存的矩阵属性来读取磁盘。前八个字节为两个int32&#xff0c;保存矩阵的行列数…

Linux||报错:vboxuser is not in the sudoers file. This incident will be reported.

一、问题描述 打算在Ubuntu虚拟机上部署SonarQube时&#xff0c;为避免各种不必要的奇怪问题&#xff0c;预先使用sudo命令修改系统参数。 命令如下&#xff1a;sudo sysctl -w vm.max_map_count262144 报错如下&#xff1a;vboxuser is not in the sudoers file. This inciden…

制造业企业库存管理的现状与解决措施

在竞争激烈的现代经济时代&#xff0c;制造行业面临着巨大的挑战和压力&#xff0c;必须与时俱进&#xff0c;适应市场的各种变化才能生存并保持活力。随着经营模式的变化与产品数量的增加&#xff0c;对产品库存管理也提出更大的挑战。库存管理是指与库存相关的计划和控制活动…

数据库设计 Relational Language

除了最为常用的SQL语句之外&#xff0c;还存在着几种不常用的数据库语言&#xff0c;这里简单介绍&#xff0c;了解即可。 Relational Algebra(RA) 一种程序性语言&#xff0c;可以与SQL对应着转换&#xff0c;语法即转换规则如下&#xff1a; σ&#xff1a;与WHERE对应&am…

一篇文章让你搞懂各种压缩,gzip压缩,nginx的gzip压缩,Minification压缩

前言 同学们可能听过这些压缩&#xff0c;但是可能不是了解&#xff0c;这篇文章让你弄清他们 webpack的gzip压缩和nginx的gzip压缩有什么区别&#xff1f;怎样开启gzip压缩&#xff1f;Minfication压缩又是什么鬼&#xff1f;怎样使项目优化的更好&#xff1f;本篇文章讲的是…

DBCO点击试剂1629057-08-4,DBCO-C3-Maleimide,DBCO-C3-Mal

一、基础产品数据&#xff08;Basic Product Data&#xff09;&#xff1a; CAS号&#xff1a;1629057-08-4 中文名&#xff1a;二苯基环辛炔-C3-马来酰亚胺、二苯并环辛炔-C3-马来酰亚胺 英文名&#xff1a;DBCO-C3-Maleimide&#xff0c;DBCO-C3-Mal 结构式&#xff08;Struc…

MAC 通过IDEA启动tomcat,显示80端口被占用解决办法

mac系统下使用IntelliJ IDEA中的Tomcat报错问题&#xff1a;Address localhost:80 is already in use 一、状况描述 本人在跑一个tomcat的项目时&#xff0c;由于项目限制了用域名访问&#xff0c;为了方便本地开发调试&#xff0c;需在tomcat在IDEA中将端口设置为80&#xff…

three.js问题记录---MeshLambertMaterial材质颜色失效

初学three.js&#xff0c;跟着教程走都比较顺利&#xff0c;自己尝试写个demo的时候发现创建一个物体&#xff0c;在给材质颜色的时候出现了一个问题。 在three.js官网文档&#xff08;https://www.techbrood.com/threejs/docs/&#xff09;中&#xff0c;我们可以看到材料&am…

论文解读-Early Detection of Cybersecurity Threats Using Collaborative Cognition

1 概述与介绍 作者描述了一种新颖的协作框架&#xff0c;该框架通过利用语义丰富的知识表示和与不同机器学习技术集成的推理功能来协助安全分析人员。文中介绍的认知网络安全系统从各种文本源中提取信息&#xff0c;并使用一种扩展的UCO安全本体的将其存储在知识图谱中。该系统…

[附源码]Python计算机毕业设计SSM家庭安防系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

一个ubuntu系统搭建redis集群

下载redis(如果要搭建redis集群不建议使用命令下载&#xff0c;因为后面启动集群时redis5.0一下的会有问题&#xff0c;依赖ruby) 更新apt sudo apt update使用apt下载 sudo apt install redis-server打开redis配置文件 sudo vim /etc/redis/redis.conf设置远程连接&#x…

2023年tiktok自动化运营软件新排名看这里!

【导读】2022年即将结束啦&#xff0c;你的tiktok运营效果怎么样呢&#xff1f;这里我们小编告诉您&#xff0c;用tiktok自动化运营软件可以取得事半功倍的效果哦&#xff01;这里就带大家看看2023年tiktok自动化运营软件排名哦&#xff01; 2023年tiktok自动化运营软件新排名看…

FPGA学习笔记(九)SPI学习总结及stm32的HAL库下SPI配置

系列文章目录 一、FPGA学习笔记&#xff08;一&#xff09;入门背景、软件及时钟约束 二、FPGA学习笔记&#xff08;二&#xff09;Verilog语法初步学习(语法篇1) 三、FPGA学习笔记&#xff08;三&#xff09; 流水灯入门FPGA设计流程 四、FPGA学习笔记&#xff08;四&…

上海亚商投顾:沪指继续震荡向上 零售等消费股表现活跃

上海亚商投顾前言&#xff1a;无惧大盘大跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 市场情绪三大指数今日低开高走&#xff0c;深成指盘中涨超1%&#xff0c;创业板指一度涨逾1.5%&#xff0c;随后均上演冲高回…

【C++进阶】引用 函数提高

文章目录一 、引用1.1 引用的基本使用1.2 引用的注意事项1.3 引用做函数参数1.4 引用的本质 &#xff1a;指针的常量1.5 常量引用二、函数提高1 函数默认参数2 函数占位参数3 函数重载一 、引用 1.1 引用的基本使用 作用&#xff1a;给变量起别名 语法&#xff1a;数据类型 &a…