11.23二叉树

news2024/9/20 14:43:10

目录

一.笔试强训习题订正

1.选择题

2.编程题-组队竞赛

3.删除公共字符

解法1 哈希映射思想

解法2 暴力解法

解法3 substring解法+replaceAll()

二.二叉树相关Oj题

1.二叉树的遍历

2.二叉树分层遍历

三.二叉树的最近公共祖先

1.思路一

2.思路2

四.将二叉搜索树转化为有序链表


一.笔试强训习题订正

1.选择题

向上取整

2.编程题-组队竞赛

这道题的题眼就是水平值是第二稿水平值 也就是123 是2

并且几组就是水平置相加

这道题的思路就是先读取输入的组成的队伍

然后读取每一个元素.放入数组里

因为参加比赛的一定是3*n个选手,所以一定是数组的长度一定是

3*n

所以也好初始化数组

然后给数组排序

我们的解题思路就是每次从数组的第一个元素和最后两个取两个元素作为一组,这样就能保证每个水平最大值

要注意输入输出

先排序

假设排序后是: 1 2 3 4 5 6 7 8 9

1 和 8 9 为一组

2 和 6 7 为一组

3 和 4 5为一组

每组第二大的数字为 8 6 4

其 size=9 ;  

import java.util.*;
public  class Main{
     public static void main(String[] args){
         Scanner sc=new Scanner(System.in);
         while(sc.hasNextInt()){
             int n=sc.nextInt();
              long sum=0;
             int[] array=new int[3*n];
             for(int i=0;i<3*n;i++){
                 array[i]=sc.nextInt();
             }
         Arrays.sort(array);//数组排序
         for(int i=1;i<=n;i++){
             sum+=array[3*n-i*2];
         }
         System.out.println(sum);
         }
    }
}

这道题 刚开始我害怕可能任务这是一组队列题,其实这里看到分组就要往数组靠.

还有第二行多组输入的时候不需要处理循环,就直接用一个for循环来处理每一个来接收,

还有复习到了一个数组排序公式

Arrays.sort(数组名);

3.删除公共字符

解法1 哈希映射思想

先遍历第二个字符串,因为一个哈希数组初始都为0

就先把遍历到的字符在哈希表找到对应的位置置为1

然后遍历字符串1.每遍历一个不是1的就打印\

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        String str1=sc.nextLine();
        String str2=sc.nextLine();
        char[] hash=new char[256];
        for(int i=0;i<str2.length();i++){
            hash[str2.charAt(i)]++;
        }
        for(int i=0;i<str1.length();i++){
            if(hash[str1.charAt(i)]==0){
                System.out.print(str1.charAt(i));
            }
        }
    }
}

解法2 暴力解法

遍历字符串1,

每遍历一个元素就开始遍历字符串2有没有相同元素,如果有,就不打印.结束循环就打印.

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        String str1=sc.nextLine();
        String str2=sc.nextLine();
       for(int i =0;i<str1.length();i++){
           char ch=str1.charAt(i);
           int a=0;
           for(int j=0;j<str2.length();j++){
               if(ch==str2.charAt(j)){
                   a=1;
                   break;
               }
           }
           if(a==0){
               System.out.print(ch);
           }
       }
    }
}

解法3 substring解法+replaceAll()

这种方法要对string的各种方法熟稔于心

import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        String str1=sc.nextLine();
        String str2=sc.nextLine();
           for(int j=0;j<str2.length();j++){
              str1=str1.replaceAll(str2.substring(j,j+1),"");
           }
        System.out.println(str1);

      }
}

遍历字符串2.从第一个元素开始,如果有相同的就替换为""也就是没有

二.二叉树相关Oj题

1.二叉树的遍历

import java.util.*;
class TreeNode {
    TreeNode left;
    TreeNode right;
    char  val;
    TreeNode(char val) {
        this.val = val;
    }
}

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void inorder(TreeNode root) {
        if (root == null) return;
        inorder(root.left);
        System.out.print(root.val + " ");
        inorder(root.right);

    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextLine()) { // 注意 while 处理多个 case
            String str = in.nextLine();
            TreeNode root = creat(str);
            inorder(root);
            System.out.println();
        }
    }

        public static int i = 0;
        public static TreeNode creat(String ret) {
            TreeNode root =null;
            if (ret.charAt(i) != '#') {
               root=new TreeNode(ret.charAt(i));
                i++;
                root.left = creat(ret);
                root.right = creat(ret);
            } else {
                i++;
            }
            return root;
        }
    }

这里我出现了一些问题

在创建二叉树这一步,我先入为主直接初始化根,先不说没有考虑到第一个节点就是空的,也就是这棵树就是空树.也没有考虑到假如树的分节点是空的,进入递归,直接创建了一个内容是#的树而不是返回空.逻辑出错

最好的方法就是初始化先是null.判断是否为#.是就初始化,并i++.进入left.或者就是null并i+=

往后遍历

2.二叉树分层遍历

这里我们考虑到用队列.先进先出,底层用顺序表也就是数组存放每一层

遍历树.判断是否为空,不是就是放入他的左子树和右子树.并打印他,

如果是空,就不打印

这样从左向右打印

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> lists=new ArrayList<>();
         if(root==null) return lists;
        Queue<TreeNode> queue=new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()){
            List<Integer> list=new ArrayList<>();
            int size=queue.size();//求队列长度没有length公式只有大小的
            while(size!=0){
               TreeNode cur=queue.poll();
               list.add(cur.val);
               if(cur.left!=null){
               queue.offer(cur.left);
              } 
              if(cur.right!=null){
               queue.offer(cur.right);
              }
            size--;
            }
            lists.add(list);
        }
        return lists;
    }
}

注意队列的长度公式.只有里面有多少元素 的公式也就是 queue.size()

这道题怎么样分层

就是求每一次循环得到的队列长度,然后循环放入

并且每次放入顺序表里,都会弹出.这样保证上一层的空了

这种情况,遇到最后一组,会显示还有元素,就继续进入循环,但是因为是空的,所以不放元素,但是还是一组表,就会显示多一层

所以还是得分开进行判断放元素

这道题还有很多问法

1.求二叉树的左视图,其实就是链表的每组数组的第一个元素

2.求二叉树的宽度,其实就是数组最长的,

三.二叉树的最近公共祖先

1.思路一

如果给定的树是一颗二叉搜索树

根节点的左子树都比根小

根节点的右子树都比根大

根据中序遍历 : 左子树-根-右子树

我们可以思考

就按根节点来想.如果

1.p是root或者q是root

2.如果p的值和q的值都小于root.那么就说明公共祖先都在root的左树

那就说明公共祖先是在root的左树中

3.如果p的值和q的值都大于root.那么就说明公共祖先都在root的右树

那就说明公共祖先是root的右树

4.如果一个大于根节点另外一个小于根节点,就说明一个在左子树,一个在右子树

那么公共祖先就是root

那么我们可以往后递归,再对root,left和root.right进行判断递归

直到找到满足条件

那么我们再发散一下,如果他只是一颗普通的树呢

那就分别在左子树和右子树找到p或者q,如果能在左子树或者右子树找到那就返回找到的节点

但是如果左子树和右子树都找到了.那就返回根节点

如果都没有就返回null

然后再发散一下

递归根节点,传递的p和q不变

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null) return null;
        if(p==root||q==root) return root;

        TreeNode curLeft=lowestCommonAncestor( root.left, p, q);
        TreeNode curright=lowestCommonAncestor( root.right, p, q);

        if(curLeft!=null&&curright==null){
            return curLeft;
        }
        if(curLeft==null&&curright!=null){
            return curright;
        }
        if(curLeft!=null&&curright!=null){
            return root;
        }
        return null;
        
    }
}

先判断是否是空的,再判断是否找到,如果找不到就开始往下递归.,如果一边有一边没有,就返回一边的.如果两边都有,就说明在两边就直接返回这个节点,如果两边都没有,就返回null

递归回来,

递归的思想我觉得就是先大问题,然后通过小问题判断细节,就搞定.

2.思路2

假设这颗二叉树是孩子双亲表示法表示的

因为都知道上一颗连接他的是谁,回溯过去,就跟链表求交点的题目一样的做法

先存储节点的对应的父节点回溯过去存储在相应链表里

但是这道题是孩子表示法表示,并没有双亲节点

因为栈可以依次存储,并先进后出,依次从后往前吐出来

第一步.我们可以用两个栈存储路径

第二步.求栈的大小

第三步,让栈中多的元素出差值个元素

第四步开始出栈,直到栈顶元素相同,此时就是公共祖先,

框架搭好了

但是还是有疑惑.我们如何找根节点到指定节点的路径呢

所以这里我们需要建立一个路径的方法.

这里我的思路就是先判断是否为空,返回假

然后直接把root压入栈内,

然后判断是否为相同,就直接返回真

如果都不相同.就开始找子树或者右树

如果在一个节点的右树找到,那么在他的左树所有压进去的节点都会弹出来.

并会返回false.就开始向上递归.

因为左边没有相同的额节点的时候,就会弹出,每回溯一次都会弹出一次,直到回到那个节点,

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null) return null;
        Stack<TreeNode> s1=new Stack<>();
        Stack<TreeNode> s2=new Stack<>();
        path(root,p,s1);
        path(root,q,s2);

        int size1=s1.size();
        int size2=s2.size();
        int size=0;
        if(size1>size2){
            size=size1-size2;
            while(size!=0){
                s1.pop();
                size--;
            }
        }else{
             size=size2-size1;
            while(size!=0){
                s2.pop();
                size--;
        }
    }
      while(!s1.isEmpty()){
            if(s1.peek()==s2.peek()){
                return s1.peek();
            }
            s1.pop();s2.pop();
        }
       return null;
    }
    boolean path(TreeNode root,TreeNode p,Stack<TreeNode> s){
        if(root==null||p==null) return false;
         s.push(root);
        if(root==p) return true;
        boolean flg=path(root.left,p,s);
        if(flg) return true;
        flg=path(root.right,p,s);
        if(flg) return true;
        s.pop();
        return false;

    }

四.将二叉搜索树转化为有序链表

我的思路就是一边排序一边修改指向

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

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

相关文章

力扣(LeetCode)795. 区间子数组个数(C++)

模拟 有一种构想&#xff0c;只考虑上边界&#xff0c;在小边界和大边界之间的连续子数组个数 小于等于大边界的连续子数组个数 −-− 小于小边界的连续子数组个数。 连续子数组个数计算公式 sumn(n1)2sum \dfrac{n\times (n1)}{2}sum2n(n1)​ 长度为 nnn 的小于某上界的区间…

UML建模

UML定义了行为图&#xff08;动态&#xff09;和状态图&#xff08;静态&#xff09;两大类。&#xff08;分类依据&#xff1a;对象是否根据时间变化&#xff09; 下面简介一下用例图、类图、时序图和状态图的概念。 “41”视图模型 逻辑视图&#xff1a;逻辑试图主要是用来…

CV攻城狮入门VIT(vision transformer)之旅——近年超火的Transformer你再不了解就晚了!

&#x1f34a;作者简介&#xff1a;秃头小苏&#xff0c;致力于用最通俗的语言描述问题 &#x1f34a;专栏推荐&#xff1a;深度学习网络原理与实战 &#x1f34a;近期目标&#xff1a;写好专栏的每一篇文章 &#x1f34a;支持小苏&#xff1a;点赞&#x1f44d;&#x1f3fc;、…

PowerJob 定时从SFTP下载文件踩的坑

一. 业务需求 SFTP上有多个目录, 每小时要下载一次文件, 每个目录的下载任务都是一个独立的工作流任务. 二.问题描述 手动执行每个任务可以正常执行, 但是当所有任务都开启定定时任务执行时(每小时执行一次),任务实例就会报错. 三.问题分析 查看服务端和worker端的日志, …

【ML特征工程】第 2 章 :简单数字的花式技巧

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

PDF怎么转换成Word?给大家分享三种简单的转换方法

我们怎么把拿到手的PDF文件转换成Word文档格式呢&#xff1f;众所周知&#xff0c;PDF文件虽然没有办法能够直接在文件上进行编辑&#xff0c;但是我们可以借助一些编辑软件来实现这一操作&#xff0c;尽管这样还是会有很多小伙伴习惯在Word中来编辑文件内容&#xff0c;因此怎…

EasyRecovery2023重新找回丢失的文件数据恢复软件

Ontrack EasyRecovery2023易恢复一款数据文件恢复软件&#xff0c;号称最好的数据恢复软件&#xff01;可以全面恢复删除丢失数据&#xff0c;能对电脑误删文件恢复&#xff0c;格式化硬盘数据恢复&#xff0c;手机U盘数据恢复等等&#xff0c;威力非常的强大&#xff01;支持恢…

运动耳机怎么选,盘点目前适合运动的几款耳机

​相对于传统耳机而言&#xff0c;现如今越来越多的人喜欢使用骨传导耳机&#xff0c;毕竟无需入耳不管是在运动还是日常&#xff0c;防丢能力会更加好&#xff0c;耳挂式的佩戴更加不用担心在剧烈运动的情况下脱落&#xff0c;但在骨传导耳机中已经有了很多个品牌入驻&#xf…

先聊聊「堆栈」,再聊聊「逃逸分析」。Let’s Go!

要搞清楚GO的逃逸分析一定要先搞清楚内存分配和堆栈&#xff1a; 内存分配既可以分配到堆中&#xff0c;也可以分配到栈中。 什么样的数据会被分配到栈中&#xff0c;什么样的数据又会被分配到堆中呢&#xff1f; GO语言是如何进行内存分配的呢&#xff1f;其设计初衷和实现原…

云原生丨5大Datadog集成,快速提高团队效率!

Datadog是DevOps、开发人员和 SRE 团队的必备好物&#xff0c;它适用于各种规模的云应用程序。 然而&#xff0c;尽管 Datadog 功能十分强大&#xff0c;但大多数企业并没有充分发挥 Datadog 全部价值。 什么是 Datadog Datadog 是一个可观察性平台&#xff0c;提供监控、安…

3.1、数据链路层概述

3.1、数据链路层概述 3.1.1、数据链路层在网络体系结构中所处的地位 如下所示&#xff0c;主机 H1 给主机 H2 发送数据&#xff0c;中间要经过三个路由器和电话网、局域网以及广域网等多种网络 从五层协议原理体系结构的角度来看&#xff1a; 主机应具有体系结构中的各个层…

使用HTML制作静态网站:传统文化戏剧锡剧带psd设计图(2个页面)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

【项目_01】搭建项目基本框架、底部tabbar、头部banner | 旅途拾景 | 基于Vue3全家桶

&#x1f4ad;&#x1f4ad; ✨&#xff1a;搭建项目基本框架、底部tabbar、头部banner| 路途拾景 | 基于Vue3全家桶   &#x1f49f;&#xff1a;东非不开森的主页   &#x1f49c;: 因为很多东西来不及去做去看可是时间很快总是赶不上&#xff0c;所以要去成长呀&#x1f4…

作业-11.23

1、广播 接收端 #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <stdlib.h> #include <netinet/in.h> #include <netinet/ip.h> #include <arpa/inet.h> #include <unistd.h> #include <str…

Diffusion Autoencoders: Toward a Meaningful and Decodable Representation

​ Diffusion Autoencoders: Toward a Meaningful and Decodable Representation 扩散自编码器:面向有意义和可解码的表示 code&#xff1a;https://github.com/phizaz/diffae A CVPR 2022 (ORAL) paper (paper, site, 5-min video) Diffusion probabilistic models (DPMs) hav…

算法设计与分析 SCAU17089 最大m子段和

17089 最大m子段和 时间限制:1000MS 代码长度限制:10KB 提交次数:0 通过次数:0 题型: 编程题 语言: G;GCC;VC;JAVA Description “最大m子段和”问题&#xff1a;给定由n个整数&#xff08;可能为负&#xff09;组成的序列a1、a2、a3、…、an&#xff0c;以及一个正整数m&a…

【Java】初识IO流【附导航】

文章目录01 什么是IO02 数据源03 什么是流04 IO流原理⇩➩ 导航01 什么是IO 对于任何程序设计语言而言&#xff0c;输入输出&#xff08;Input / Output&#xff09;系统都是非常核心的功能。程序运行需要数据&#xff0c;数据的获取往往需要跟系统外部进行通信&#xff0c;外部…

论文复现|Panoptic Deeplab(全景分割PyTorch)

摘要&#xff1a;这是发表于CVPR 2020的一篇论文的复现模型。本文分享自华为云社区《Panoptic Deeplab(全景分割PyTorch)》&#xff0c;作者&#xff1a;HWCloudAI 。 这是发表于CVPR 2020的一篇论文的复现模型&#xff0c;B. Cheng et al, “Panoptic-DeepLab: A Simple, Str…

63. 不同路径 II

题目 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那么从左上角到…

MySQL主/从-主/主集群安装部署

MySQL集群架构的介绍 我们在使用到MySQL数据库的时候&#xff0c;只是一个单机的数据库服务。在实际的生产环境中&#xff0c;数据量可能会非常庞大&#xff0c;这样单机服务的MySQL在使用的时候&#xff0c;性能会受到影响影响。并且单机服务的MySQL的数据安全性也会受到影响…