假期无聊,不如一起刷《剑指offer》(第六天)

news2024/11/28 0:47:36

剑指 Offer 41. 数据流中的中位数

剑指 Offer 41. 数据流中的中位数
这道题是求数据流的中位数,一般情况我们可以采用排序的方式很轻松的找出中位数。如果我们采用插入排序的话,每次插入数字的时间复杂度大概是O(N),怎么能让这个时间更短呢?那么我们可以利用大小根堆的特点把单次查找的时间复杂度缩短到O(logN)。可以使用堆,具体做法如下:
我们把数据分为两部分,一部分是小于中位数的大根堆,另一部分是大于等于中位数的小根堆。我们控制两个堆的元素个数之差<=1,这样的话,如果两堆元素个数相同,就各取堆顶元素均分得到中位数,差1就取较多元素的堆顶。
具体如何插入,我们分类讨论:
在这里插入图片描述

class MedianFinder {
    private PriorityQueue<Integer> smallHeap;
    private PriorityQueue<Integer> bigHeap;
    /** initialize your data structure here. */
    public MedianFinder() {
        smallHeap=new PriorityQueue();//初始默认小根堆
        bigHeap=new PriorityQueue(new Comparator() {//转为大根堆
            @Override
            public int compare(Object o1, Object o2) {
                return (Integer)o2-(Integer)o1;
            }
        });
    }
    
    public void addNum(int num) {
        //保证size差值<=1
        if(smallHeap.size()>bigHeap.size()){//优先考虑往big插入
            if(num>smallHeap.peek()){//如果大于small的最小值,从small拿一个到big,num插入small
                int tmp=smallHeap.poll();
                bigHeap.add(tmp);
                smallHeap.add(num);
            }else{
                bigHeap.add(num);
            }
        }else if(smallHeap.size()<bigHeap.size()){//优先考虑往small插入
            if(num<=bigHeap.peek()){//如果小于等于小根堆的最小值,从big拿一个到small,num插入big
                int tmp=bigHeap.poll();
                smallHeap.add(tmp);
                bigHeap.add(num);
            }else{
                smallHeap.add(num);
            }
        }else{
            if(bigHeap.size()!=0&&smallHeap.size()!=0&&num>bigHeap.peek()){
                smallHeap.add(num);
            }else{
                bigHeap.add(num);
            }
        }
    }
    
    public double findMedian() {
        // if(smallHeap.size()!=0){
        //     System.out.println("a:"+smallHeap.peek());
        // }
        // if(bigHeap.size()!=0){
        //     System.out.println("b:"+bigHeap.peek());
        // }
        if(smallHeap.size()>bigHeap.size()){
            return 1.0*smallHeap.peek();
        }else if(smallHeap.size()<bigHeap.size()){
            return 1.0*bigHeap.peek();
        }else{
            return 1.0*(smallHeap.peek()+bigHeap.peek())/2;
        }
    }
}

/**
 * Your MedianFinder object will be instantiated and called as such:
 * MedianFinder obj = new MedianFinder();
 * obj.addNum(num);
 * double param_2 = obj.findMedian();
 */

剑指 Offer 43. 1~n 整数中 1 出现的次数

剑指 Offer 43. 1~n 整数中 1 出现的次数
我首先的想法是正常循环,挨个数字判断,但是很明显没有这么简单:时间超限了
在这里插入图片描述
既然不能循环,我觉得应该是有什么规律可循。练习了两个半小时的斯某人,决定打开题解借鉴。
以下转自:leetcode题解

得到了规律:
根据当前位 cur值的不同,分为以下三种情况:
当cur=0 时: 此位 1的出现次数只由高位 high决定,计算公式为:
high×digit
当cur=1 时: 此位 1的出现次数由高位 high和低位决定,计算公式为:
high×digit+low-1
当cur=其他数字时: 此位 1的出现次数只由高位 high决定,计算公式为:
(high+1)×digit

class Solution {
    public int countDigitOne(int n) {
        int digit = 1, res = 0;
        int high = n / 10, cur = n % 10, low = 0;
        while(high != 0 || cur != 0) {
            if(cur == 0) res += high * digit;
            else if(cur == 1) res += high * digit + low + 1;
            else res += (high + 1) * digit;
            low += cur * digit;
            cur = high % 10;
            high /= 10;
            digit *= 10;
        }
        return res;
    }
}

剑指 Offer 44. 数字序列中某一位的数字

剑指 Offer 44. 数字序列中某一位的数字
在这里插入图片描述
因为right很容易越界,我们使用long类型

class Solution {
    public int findNthDigit(int n) {
        //先把范围缩小到0-9 或者10-99 或者100-999等等
        long k=1;
        long level=1;//1代表0-9  每+1,代表范围扩大 例如2代表10-99
        long chars=0;//目前已占用的字符数
        long right=10;//每个范围所占字符数
        while(n>right){
            level++;//范围增大
            chars=(int)right;
            right=right+(level*90*k);
            k*=10;
        }
        n-=chars;
        //保存除数的结果
        long div=n/level;
        //保存取模的结果
        long mod=n%level;
        //将除数加上所在范围的基数u,比如443 得到84要+100
        if(k!=1)
        div+=k;
        return Long.toString(div).charAt((int)mod)-'0';
    }
}

共勉
请添加图片描述

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

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

相关文章

shell原理及Linux权限

shell及Linux权限 目录shell及Linux权限一、指令1.tar指令&#xff08;重要&#xff09;2.热键3.bc命令4.uname –r指令&#xff1a;5.关机6.以下命令作为扩展:二.shell命令以及运行原理三.权限1.权限的概念&#xff1a;2.Linux下有两种用户&#xff1a;超级用户&#xff08;ro…

一图读懂mybatis 查询接口的源码流程

图比较大&#xff1a;如果看着比较糊的话&#xff0c;可以下载高清图&#xff1a;https://download.csdn.net/download/langwuzhe/87376216 第一步&#xff1a;创建 StatementHandler、ParameterHandler、ResultSetHandler-----------(三剑客的新生) 创建 StatementHandler 对…

WPS怎么转换PDF?保证你一学就会

相信大家在处理文件的时候肯定会使用到WPS文件&#xff0c;WPS文件包括Word、Excel、PPT文件&#xff0c;是我们经常使用的几种文件&#xff0c;有这几种文件我们可以更好的完成工作&#xff0c;但是在有些情况下&#xff0c;我们需要将WPS转换成PDF文件&#xff0c;这样就会更…

AS弹性伸缩简单介绍

AS 介绍 弹性伸缩(AutoScaling)是一种服务&#xff0c;可以自动调整弹性计算资源&#xff08;ECS)&#xff0c;以满足业务需求的变化。 弹性伸缩仅支持ECS实例或ECI实例数量的增加和减少&#xff0c;但不支持单个ECS实例或ECI实例的配置变更。 应用场景&#xff1a;弹性扩张、…

Windows安装使用Docker,方便你的开发和部署(DockerDesktop篇)

前言 首先声明&#xff0c;此篇不是完全的Docker技术文章&#xff0c;而是单纯的教你使用Docker&#xff0c;不包含Docker的一些命令、如何打包Docker镜像等等。 为什么要用Docker&#xff1f; 大家好&#xff0c;我是小简&#xff0c;今天带来一篇Windosw环境下使用Docker的…

女生学软件测试有什么优势么

在IT技术行业&#xff0c;女生学习软件测试还是有很大优势的。女生相较于男生更有耐心&#xff0c;包容性强&#xff0c;心思细腻&#xff0c;对细节把控更好&#xff0c;同时还能帮助团队男女平衡&#xff0c;活跃气氛。 软件测试是一个只要你肯学习就会有回报的职业&#xf…

判断用户输入的数字是奇数还是偶数

判断用户输入的数字是奇数还是偶数代码关键知识点 条件运算符&#xff0c; 相等运算符&#xff0c;为了让两个不同的数据类型&#xff08;如number和string&#xff09;的值可以作比较&#xff0c;必须要把一种类型转换为另一种类型&#xff08;转换成相同的类型&#xff09;&…

Ae 效果详解:CC Ball Action

Ae菜单&#xff1a;效果/模拟/CC Ball ActionEffect/Simulation/CC Ball ActionCC Ball Action &#xff08;滚珠操作效果&#xff09;可以将所有的像素变成小球模样&#xff0c;并且能够打破图层成球形网格。可通过摄像机观察其所具有的 3D 效果。◆ ◆ ◆效果控件属性说明S…

【数据结构与算法——C语言版】6. 排序算法(4)——快速排序

前言 本文介绍排序算法中的快速排序&#xff0c;快速排序是比较常用的一种排序算法&#xff0c;也是面试中经常会问到的一种排序算法&#xff0c;简称快排&#xff0c;是我们要介绍的第一种时间复杂度为O(nlogn)的排序算法。 核心思想 快速排序(Quick Sort)使用分治法策略&a…

Vue--》详解状态管理工具——Vuex

目录 vuex 搭建vuex环境 vuex的使用 vuex开发者工具使用 getters mapState和mapGetters mapMutations和mapActions 多组件共享数据 vuex实现模块化 vuex 专门在Vue中实现集中式状态(数据)管理的一个Vue插件&#xff0c;对vue应用中多个组件的共享状态进行集中式的管…

c语言进阶(4)——字符函数的详细解析

文章目录1.strlen函数2.strcpy函数3.strcat函数4.strcmp函数5.strncpy函数6.strncat函数7.strncmp函数8.strstr函数9.strtok函数10. strerror函数11. 相关字符转换函数12.字符转换函数1.strlen函数 size_t strlen( const char *string ); 用途&#xff1a;用来计算字符串长度的…

【云原生进阶之容器】第二章Controller Manager原理2.8节--Resync机制

8 Resync机制 8.1 DeltaFIFO队列为什么需要Resync 为什么需要 Resync 机制呢?因为在处理 SharedInformer 事件回调时,可能存在处理失败的情况,定时的 Resync 让这些处理失败的事件有了重新 onUpdate 处理的机会。 主要的目的是为了不丢数据,处理 resync 机制还有边缘触发与…

公务员考试催生一家上市公司,公务员真的是一条好的出路吗

公务员考试能催生一家公司吗&#xff1f;还真的可以&#xff0c;而且在2023.01.09日也就是今天上市。公务员真的是一条好的出路吗&#xff0c;现在考公务员还行不行&#xff1f;这需要结合我们当下的环境来综合分析。我们都经历了疫情&#xff0c;期间各个大厂频频将裁员大棒挥…

《Spring揭秘》读书笔记 1:IoC和AOP

1 Spring框架的由来 Spring框架的本质&#xff1a;提供各种服务&#xff0c;以帮助我们简化基于POJO的Java应用程序开发。 各种服务实现被划分到了多个相互独立却又相互依赖的模块当中&#xff1a; Core核心模块&#xff1a;IoC容器、Framework工具类。 AOP模块&#xff1a;S…

如何抓住风口,利用互联网赚钱?(內含三大商业模式推荐)建议收藏

大家好&#xff0c;我是你们熟悉而又陌生的好朋友梦龙&#xff0c;一个创业期的年轻人 今天跟你做个分享&#xff0c;众所周知互联网是一块非常大的蛋糕&#xff0c;几位互联网巨头也做不到完全吃透&#xff0c;同时也是一个门槛较低的创业之路&#xff0c;非常的适合年轻人&a…

8、Javaweb_ServlethttpRequst

Servlet&#xff1a; 1. 概念 2. 步骤 3. 执行原理 4. 生命周期 5. Servlet3.0 注解配置 6. Servlet的体系结构 Servlet -- 接口 | GenericServlet -- 抽象类 | HttpServlet -- 抽象类 * GenericServlet&#xff1a;将Servlet接口中其他的方…

C语言-指针进阶-常见笔试面试题详解(9.4)

目录 思维导图&#xff1a; 指针和数组笔试题 指针笔试题 写在最后&#xff1a; 思维导图&#xff1a; 指针和数组笔试题 只有多刷题&#xff0c;才能巩固提高所学的知识。 例1&#xff1a; #include <stdio.h>int main() {//一维数组int a[] { 1,2,3,4 };//求出…

「精研科技」× 企企通,全球MIM龙头借助采购供应商数字化向多领域突破

近日&#xff0c;金属粉末注射成型&#xff08;MIM&#xff09;龙头企业江苏精研科技股份有限公司&#xff08;以下简称“精研科技”&#xff09;与企企通达成合作。双方将共同构建完整的采购管理和供应商协同平台&#xff0c;加强供应商管理&#xff0c;提高采购效率&#xff…

Netty源码性能分析 - ThreadLocal PK FastThreadLocal

序 既然jdk已经有ThreadLocal&#xff0c;为何netty还要自己造个FastThreadLocal&#xff1f;FastThreadLocal快在哪里&#xff1f;这需要从jdk ThreadLocal的本身说起。在java线程中&#xff0c;每个线程都有一个ThreadLocalMap实例变量&#xff08;如果不使用ThreadLocal&…

使用Alexnet实现CIFAR100数据集的训练

如果对你有用的话&#xff0c;希望能够点赞支持一下&#xff0c;这样我就能有更多的动力更新更多的学习笔记了。&#x1f604;&#x1f604; 使用Alexnet进行CIFAR-10数据集进行测试&#xff0c;这里使用的是将CIFAR-10数据集的分辨率扩大到224X224&#xff0c;因为在测试…