11.29总结

news2024/11/27 1:27:00

目录

一.连续子数组最大和

方法2动态规划

二.查找最小的k对数字

一.从先序遍历还原二叉树

二.完全二叉树

三.判断对称二叉树

四 回文

五.连续子数组最大和

六.TopK问题

思路一如果数据特别大.排序的时间复杂度会很大

思路二:用大根堆或者小根堆然后分别弹出.

思路三:前k堆

七.堆元素排序

八.对象的比较

1.equals:用来比较两个对象相不相同

2.使用compaerable接口

3.Comparator比较器比较

4.总结

5.将优先级队列变成大根堆


一.连续子数组最大和

1.暴力解法

i从第一个元素开始.j从第二个元素开始,然后j开始遍历,计算每个大小.如果第二次比上次大就换成这次的

i再从第二个元素开始,j再从第三个元素开始遍历一直反复计算算到最大值,这里的时间复杂度就是O(n2);

   public int FindGreatestSumOfSubArray (int[] array) {
        // write code here
        int len=array.length;
        int max=array[0];
        for (int i = 0; i < len; i++) {//只要到最后一个,j也进不去循环,就不会数组越界
          int  sum=array[i];
            if(sum>max){
             max=sum;
            }
            for (int j = i+1; j <len ; j++) {
                sum+=array[j];
                if(sum>max){
                    max=sum;
                }
            }
        }
        return  max;

    }
}

这里注意,如果都是负数,很有可能直接输出0所以最好让max初始为数组第一个元素,但是这种算法复杂度过大

方法2动态规划

定义一个max和sum初始值都为第一个元素,然后往后遍历,因为子数组最大要么是前面的加上本身,要么就是本身,

  public int getMax(int a,int b){
        return a>b?a:b;
    }
    public int FindGreatestSumOfSubArray (int[] array) {
        int sum= array[0];
        int max=array[0];
        for (int i = 1; i < array.length; i++) {
            sum=getMax(sum+array[i],array[i]);
            max=sum>max?sum:max;
        }
        return max;
    }
}

二.查找最小的k对数字

首先这道题我们用的是优先队列的方法

因为优先队列底层是一个小根堆,我们需要重写一个比较建立一个内部类

改变比较的方式

然后开始循环,

因为会有k的大小大于遍历的情况

所以需要范围需要在k和数组长度找个最小值,因为

i没必要都走完,就看k的大小就行.因为这是一个升序的数组.

然后建立k个大小的大堆

建立一个顺序表把元素放进里面

再放进优先队列里

放完之后再判断剩下的有没有比他第一个元素大

也就是堆顶元素.因为他是大根堆,堆顶元素一定是最大的

如果比大根堆还大.那就直接换下,找最小的,

但是如果不大.就可以直接跳出循环.因为这是一个升序数组,现在不大以后都会不大

就不用再往后遍历了

因为题目要的是

所以建立一个顺序表

接收优先队列弹出的元素

但是有可能k的值过大,还没弹到第k个,优先表就空了,所以这个时候就需要再建立一个条件,就是他不为空

class Solution {
    public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k){
        PriorityQueue<List<Integer>> priority=new PriorityQueue<>(new Comparator<List<Integer>>() {
            @Override
            public int compare(List<Integer> o1, List<Integer> o2) {
              return o2.get(0)+o2.get(1)-o1.get(0)-o1.get(1);
           }//大根堆
        });
        for (int i = 0; i <Math.min(k,nums1.length); i++) {
         //   List<Integer> list=new ArrayList<>();
            for (int j = 0;j<Math.min(k,nums2.length); j++) {
                if(priority.size()<k){
                    List<Integer> tmpList=new ArrayList<>();
                    tmpList.add(nums1[i]);
                    tmpList.add(nums2[j]);
                    priority.offer(tmpList);
                }else{
                    if(nums1[i]+nums2[j]<priority.peek().get(0)+priority.peek().get(1)){         
                    List<Integer> tmpList=new ArrayList<>();
                    tmpList.add(nums1[i]);
                    tmpList.add(nums2[j]);
                        priority.poll();
                        priority.offer(tmpList);
                    }else{
                        break;
                    }
                }

            }
         //   priority.offer(list);
        }
        List<List<Integer>> lists=new ArrayList<>();
          while(!priority.isEmpty()) {
            lists.add(priority.poll());
        }
        return lists;

    }
}

一.从先序遍历还原二叉树

这道题我们考虑模拟递归的方式

之前层序遍历我们用的是队列:因为先进先出

而这里我们一般用的是栈来模拟递归

我们定义一个变量记录每个节点的高度

class Solution {
    public TreeNode recoverFromPreorder(String traversal) {
        char[] arr=traversal.toCharArray();
        Stack<TreeNode> stack=new Stack<>();
        int i=0;
        while(i<arr.length){
            int level=0;
             int val=0;
            while(i<arr.length&&arr[i]=='-'){
                i++;
                level++;
            }//计算多少- 并跳过
            while(i<arr.length&&Character.isDigit(arr[i])){ //防止最后一个跳出循环,数组越界
                val=val*10+(arr[i]-'0');//变成数字
                i++;
            }//到了这里数组下标指向了下一个-了
            TreeNode node=new TreeNode(val);//建立新的节点
            if(0==stack.size()){
                stack.push(node);//第一个的情况
            }else{//要么大于要么等于
                while(stack.size()!=level){
                    stack.pop();
                }//到了这里就一定相同
                TreeNode fatherNode=stack.peek();
                if(fatherNode.left==null){
                    fatherNode.left=node;
                }else{
                    fatherNode.right=node;
                }
                stack.push(node);//不要忘记放进去
            }
        }
            while(stack.size()>1){
                stack.pop();
            }
            return stack.peek();
    }
}

二.完全二叉树

思路:用层序遍历的思路分别放入节点

每放一层就判断是否为null然后弹出

并放入他的左右节点(按顺序)

再循环

每层每层的放弹出,用队列,因为队列可以保证先进先出

先放左节点可以让左节点先判断

原理就是如果不是完全二叉树,如果左右节点顺序放.有null.就会保证在检查出null的时候,后面还有节点

但是如果是完全二叉树是不可能出现这种情况

   public boolean isCompleteTree (TreeNode root) {
         Queue<TreeNode> queue=new LinkedList<>();
        if(root==null) return true;
        queue.offer(root);
        while(!queue.isEmpty()){
                TreeNode top= queue.remove();
                if(top==null){
                    break;
                }
                queue.offer(top.left);
                queue.offer(top.right);
        }
        while(!queue.isEmpty()){
             TreeNode top= queue.remove();
                if(top!=null){
                    return false;
                }
        }
        return true;
    }
}

三.判断对称二叉树

首先要结构相同,如果是一个是null一个不是就不可以

而且除了根其他的要全部对称.也就是左节点和右节点相同

所以需要写两个方法

class Solution {
    public boolean isSame(TreeNode p,TreeNode q){
        if(p==null&&q!=null) return false;
        if(p!=null&&q==null) return false;
        if(p==null&&q==null) return true;
        if(p.val!=q.val)     return false;
        return isSame(p.left,q.right)&&isSame(p.right,q.left);
    }
    public boolean isSymmetric(TreeNode root) {
        if(root==null) return true;
        return isSame(root.left,root.right);

    }
}

因为原本的方法参数只有一个,但是判断需要同时判断左边和右边,所以需要再写一个方法

四 回文

这个题目要对字符串方法非常的熟悉

首先不能对字符串本身插入,非常就改变了原来的字符串

所以我们需要新建一个对象来改变

因为插入函数只有sb有

这里注意,StringBuilder没有equlal方法需要转成字符串

这里注意,a假设有2 但是插入会多多插一个位置,所以就会少判断

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNext()) { // 注意 while 处理多个 case
            String str = in.nextLine();
            String b = in.nextLine();
            int count=0;//计数器
            for(int i=0;i<=str.length();i++){
                StringBuilder sb=new StringBuilder(str);//将str放入存储
                sb.insert(i,b);//插入方法只有SB有
                StringBuilder ss=new StringBuilder(sb);//防止逆置后 保存原来的字符串
                sb.reverse();
                if(sb.toString().equals(ss.toString())){//判断是否相同
                    count++;
                }
            }
            System.out.println(count);
        }
    }
}
写一个判断回文的方法
     public static boolean reverse(StringBuilder sb){
        int left=0;
        int right=sb.length()-1;
        char[] ch=sb.toString().toCharArray();
        while(left<right){
            if(ch[left]!=ch[right]){
                return false;
            }
            left++;right--;
        }
        return true;
    }

五.连续子数组最大和

六.TopK问题

思路一如果数据特别大.排序的时间复杂度会很大

思路二:用大根堆或者小根堆然后分别弹出.

思路三:前k堆

求前k个最大元素.就把前k个元素建立成一个小根堆.如果有比堆顶大的.就换成他

因为只能根堆顶元素比.剩下两个元素可能比要比的元素小,但是都替换不了.

代码的实现

/**
 * 求数组当中前k个最小的元素
 * @param //args
 */
public static int[] topK(int[] arr,int k){
    PriorityQueue<Integer> maxHeap=new PriorityQueue<>(k, new Comparator<Integer>() {
        @Override
        public int compare(Integer o1, Integer o2) {
            return o2-o1;//创建一个大小为k的大根堆
        }
    });
    for (int i = 0; i < arr.length; i++) {
        if(maxHeap.size()<k){
            maxHeap.offer(arr[i]);//依次放前k个元素
        }else{
            //从第k+1开始根堆顶元素比较,如果小,就换上去
            if(arr[i]<maxHeap.peek()){
                //先弹出
                maxHeap.poll();
                //再放入
                maxHeap.offer(arr[i]);
            }
        }
    }
    int[] tmp=new int[k];
    for (int i = 0; i < k; i++) {
        tmp[i]=maxHeap.poll();
    }
    return tmp;

}

public static void main(String[] args) {
    int[] arr={18,21,8,10,34,12};
    int[] tmp=topK(arr,3);
    System.out.println(Arrays.toString(tmp));

}

为什么是大根堆因为一定要保证每次都跟最大的比较,然后把最大的换掉,所以最后剩下的一定是最小的

tmp是引用变量直接打印打印不出来,要用tostring方法

这道题用优先级队列做,因为优先级队列底层是小根堆,因为要找前k最小的,所以需要大根堆,比较

class Solution {
    public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k){
        PriorityQueue<List<Integer>> priority=new PriorityQueue<>(new Comparator<List<Integer>>() {
            @Override
            public int compare(List<Integer> o1, List<Integer> o2) {
              return o2.get(0)+o2.get(1)-o1.get(0)-o1.get(1);
           }//大根堆
        });
        for (int i = 0; i <Math.min(k,nums1.length); i++) {//防止k比length大,还要继续弹会造成数组越界
         //   List<Integer> list=new ArrayList<>();
            for (int j = 0; j < Math.min(k,nums2.length); j++) {
                if(priority.size()<k){
                    List<Integer> tmpList=new ArrayList<>();
                    tmpList.add(nums1[i]);
                    tmpList.add(nums2[j]);
                    priority.offer(tmpList);
                }else{
                    List<Integer> tmpList=new ArrayList<>();
                    tmpList.add(nums1[i]);
                    tmpList.add(nums2[j]);
                    if(tmpList.get(0)+tmpList.get(1)<priority.peek().get(0)+priority.peek().get(1)){
                        priority.poll();
                        priority.offer(tmpList);
                    }
                }

            }
         //   priority.offer(list);
        }
        List<List<Integer>> lists=new ArrayList<>();
        for (int i = 0; i < k&&!priority.isEmpty(); i++) {
            lists.add(priority.poll());
        }
        return lists;

    }
}

七.堆元素排序

因为要求数据从0下标到9下标从小到大.应该借助大根堆

找到最大元素再0号下标.然后再放到最后一个元素

再让总元素--(因为最后一个排序好了.不用再排序了)

代码的实现

public void heapSort(){
    int end=usedSize-1;//这样就非常巧妙
    while(end>0){
        int tmp=arr[0];
        arr[0]=arr[end];
        arr[end]=tmp;//
        shiftDown(0,end);//这里传过去的时候end就已经去掉了最后一个
        end--;
    }
}

八.对象的比较

1.equals:用来比较两个对象相不相同

如果是基本类型可以用equals

但是如果是自定义类,需要重写.

看是否是同一个类,或者另外一个是否是空的

必须成员全部相同

如果没有重写就默认用父类的

引用类型比较 要看地址比较,不是同一个对象地址不一样

2.使用compaerable接口

在类中使用Compareable接口并重写Compaeto方法

这块得自己写,如果我们想要从大王小排序就需要

这里发现.priorityQueue就自动排序了

第一次p添加一张牌

刚开始size=0

因为priorityQueue底层默认是个数组

数组长度默认是11

如果长度不够就要扩容

如果i是0 就放在第一个下标

如果放第二个元素

就要向上调整

可以发现,调用构造方法的时候,comparator是null

那么向上调整的时候就直接jinelse语句

这里就会发现.e会被强转为Comparable类型

所以如果card不实现COMPARABLE接口就会强转不过来会报错

这里就调用Card的compaeto方法所以就算实现接口不重写也不可以

如果第二个就是比第一个大,就不需要交换(因为底层就是个小堆)

但是如果比他小,就需要往下走,交换,进行循环

那如果怎么样实现大堆呢

就改变CARD类本身的comparto方法,让前面的大于后面的大于0

3.Comparator比较器比较

实现一个ccomparator比较器

用户自定义比较器类,实现Comparator接口

但是我们要用PriorityQueue

来进行比较,除了之前的比较方法

还有第一种,第一种如何实现

打开源码可以发现

构造方法默认是null,所以我们得穿一个比较器

先构造一个比较器,然后再构建队列的时候,放进去

4.总结

5.将优先级队列变成大根堆

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

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

相关文章

CANoe-vTESTstudio之State Diagram编辑器(功能介绍)

1. 阶段 State Diagram从测试设计到测试执行,分为4个阶段: Test Design 在测试设计期间,测试设计人员使用图形元素和分配的测试代码来对要测试的SUT的状态和转换进行建模。这个阶段的结果是生成状态图 Evaluation 在评估期间,将验证各个元素及其关系并创建路径。评估产…

SpringBoot中如何实现业务校验,这种方式才叫优雅!

大家好&#xff0c;在日常的接口开发中&#xff0c;为了保证接口的稳定安全&#xff0c;我们一般需要在接口逻辑中处理两种校验&#xff1a; 参数校验 业务规则校验 首先我们先看看参数校验。 参数校验 参数校验很好理解&#xff0c;比如登录的时候需要校验用户名密码是否为…

Opencv边缘检测、轮廓发现、绘制轮廓

Opencv边缘检测、轮廓发现、绘制轮廓 提取图像轮廓的2个步骤 1、 findContours函数找轮廓&#xff0c; 2、 drawContours函数画轮廓 轮廓的查找——cv::findContours() 函数cv::findContour是从二值图像中来计算轮廓的&#xff0c;它可以使用cv::Canny()函数处理的图像&am…

【华为上机真题 2022】字符串分隔

&#x1f388; 作者&#xff1a;Linux猿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我&#xff0c;关注我&#xff0c;有问题私聊&#xff01; &…

Java---线程详解(并发并行,Thread类,Runnable接口,同步机制,线程死锁......)

目录 一、概念 1、进程 2、线程 &#xff08;1&#xff09;单线程 &#xff08;2&#xff09;多线程 &#xff08;3&#xff09;并发 &#xff08;4&#xff09;并行 二、线程基本使用 1、创建线程的两种方式 &#xff08;1&#xff09;继承Thread类 &#xff08;2&am…

esp8266用arduino连上阿里云(图文操作,100%成功)

最近学习了esp8266/esp32单片机。第一次使用arduino这个IDE&#xff0c;搞多了Keil5&#xff0c;这个实在是有点不习惯。进步都是困难的&#xff0c;现在回想起来&#xff0c;发现也没多难&#xff0c;回到正题。 准备软件&#xff1b;Arduino IDE 准备硬件&#xff1a;esp82…

面试:插件化相关---activity

我们先来看下Android常规Activity的启动流程 如何评价360的Android插件化框架RePlugin&#xff1f; - 知乎 1、调用Context.startActivity -> ActivityManagerProxy -> AMS, AMS通过Intent从PMS拿到ActivityInfo并创建ActivityRecord和token放入前台ActivityStack&…

macOS端React的项目WebPack热更新(HMR)失效问题分析及解决,原因竟是Windows文件系统不区分大小写导致

项目场景&#xff1a; 最近做的项目是一个使用UmiJS搭建的React的前端老项目&#xff0c;项目是上一个开发团队遗留下来的老项目&#xff0c;我们接着在原来的基础上开发。团队成员中有的是Windows电脑&#xff0c;有的是Mac电脑&#xff0c;所以存在规范不统一的情况。 问题描…

[附源码]计算机毕业设计springboot基于web的建设科技项目申报管理系统

项目运行 环境配置&#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…

微服务框架 SpringCloud微服务架构 5 Nacos 5.6 环境隔离

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构5 Nacos5.6 环境隔离5.6.1 环境隔离 - namespace5.6.2 使用 namespace5.6.…

Python的PyQt框架的使用-创建主窗体篇

Python的PyQt框架的使用-构建环境篇一、前言二 、创建主窗体一、前言 个人主页: ζ小菜鸡大家好我是ζ小菜鸡&#xff0c;小伙伴们&#xff0c;让我们一起来学习Python的PyQt框架的使用。如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连) 二 、创建主窗体 &#xff08;1&am…

【Linux】高频指令及简单的vim使用(0基础带你快速入门)

目录 一、目录操作指令 1.1、ls 1.2、pwd 1.3、cd 1.4、touch 1.5、cat 1.6、echo 1.7、mkdir 1.8、rm 1.9、mv 1.10、cp 二、Linux中如何手动安装插件 三、vim 3.1、打开文件 3.2、编辑文件 3.3、保存退出 一、目录操作指令 1.1、ls 语法&#xff1a; 第一种&#…

高维多元时序数据之间的相似性度量

1. 简介 时间序列作为一种按时间顺序排列的特殊数据&#xff0c;是数据挖掘的重要研究内容&#xff0c;其中包括数据准备、数据选择、数据预处理、数据缩减、数据挖掘目标确定、挖掘算法确定、数据挖掘、模式解释及知识评价&#xff19;个处理步骤&#xff37;。数据挖掘方面的…

@SentinelResource注解的使用

SentinelResource注解的使用 1、按资源名称限流后续处理 前置条件&#xff1a; 启动Nacos启动Sentinel 1.1、修改cloudalibaba-sentinel-service8401 引入自己的API通用包 <!--自己的公共包,可以使用Payment支持Entuty--> <dependency><groupId>com.zcl.s…

word目录怎么自动生成?用这个方法,快速自动生成

当我们在写论文或者是编写文档的时候&#xff0c;都需要生成导航目录。很多人写完文档之后想要将其自动生成目录&#xff0c;但是不知道该怎么操作&#xff1f;word目录怎么自动生成&#xff1f;下面我就为大家分享三个步骤&#xff0c;快速自动设置文档的目录。 操作环境&…

SpringBoot配置文件

文章目录配置文件的作用配置文件的格式.properties 配置文件说明.properties 基本语法.properies 读取配置信息.yml 配置说明.yml 基本语法.yml 进阶使用.yml 读取配置信息.properties VS .yml配置文件的作用 整个项目中所有重要的数据都是在配置⽂件中配置的&#xff0c;比如…

社区系统项目复盘-6

文章目录什么是Elasticsearch&#xff1f;Spring是怎么整合Elasticsearch的&#xff1f;开发社区搜索功能Elasticsearch实现全文搜索功能什么是Elasticsearch&#xff1f; Elasticsearch简介 一个分布式的、Restful风格的搜索引擎支持对各种类型的数据的检索搜索速度快&#xf…

FSR-Unity-URP 1.0 的性能和兼容性问题

1&#xff09;FSR-Unity-URP 1.0 的性能和兼容性问题 ​2&#xff09;计算大文件MD5耗时问题 3&#xff09;如何监听Unity即将Reload Script 4&#xff09;如何对Unity游戏的Android崩溃和ANR问题进行符号化解析 这是第315篇UWA技术知识分享的推送。今天我们继续为大家精选了若…

2022年GPS广播星历精密星历如何下载

注意&#xff1a;&#xff01;&#xff01;网上现有很多教程的星历下载地址 ftp://cddis.gsfc.nasa.gov/已经访问不了了&#xff0c;最新的方法见下文&#xff0c;亲测有效~ 1、星历下载网址&#xff08;需要注册一下&#xff09;Earthdata Loginhttps://cddis.nasa.gov/archiv…

我的居家生活--爱摸鱼的美工(二)

-----------作者&#xff1a;天涯小Y 这失败的拉花叫”海上升明月” 呜一 做自己&#xff0c;不太好也没关系 我给自己居家的时间不多了 11月30日我决定”解封” 从身心开始&#xff0c;愿脚步跟上 突如其来的“银丝” 让我沮丧 黑芝麻的疗法因快递又安排不上 算了.幼笑吧 白发…