双非本科准备秋招(14.1)—— 力扣刷题

今天做两个有点难度的题。

1、295. 数据流的中位数

手写堆实现:

        加入元素:

        如何维护一个中位数?我们考虑一下堆的特点,大顶堆堆顶是一个最大值,小顶堆堆顶是一个最小值,那么,如果我们可以把数据流的数据按顺序地平均地存放在两个堆中,一个大顶堆,一个小顶堆,那么大顶堆和小顶堆的堆顶不就是中位数吗?

        就像下图这样,我们依次加入数据流,最后需要形成这样的堆。

        还需要考虑一个问题,我们怎样加入元素?肯定是加一下大顶堆,再加一下小顶堆,这样依次加入元素,但是能直接就加吗?

        不可以的,因为我们的大顶堆需要存储小的那部分元素,小顶堆需要存储大的那部分元素。

        这里需要一个巧妙地操作,比如我们每次要往大顶堆添加元素,先把这个元素加到小顶堆,然后把小顶堆的堆顶加到大顶堆中。

        比如,此时来了个100,两个堆size相同,我们想加到大顶堆中

但是100很大,所以我们先加入小顶堆,然后小顶堆堆顶移到大顶堆

这样就实现了元素加入大顶堆并且大小有序。

加入代码如下:h1大顶堆,h2小顶堆。

        if(h1.size == h2.size){
            h2.offer(num);
            h1.offer(h2.poll());
        }
        else{
            h1.offer(num);
            h2.offer(h1.poll());
        }

        返回答案

          如果元素相同,返回堆头之和除以2;如果不同,那肯定是大顶堆h1多一个元素,直接返回就行。注意结果是double类型。

        if(h1.size == h2.size){
            return (h1.peek() + h2.peek())/2.0;
        }
        return 1.0*h1.peek();

这里我手写一下堆,复习一下堆的基本写法。

 h1 = new Heap(10, true);
 h2 = new Heap(10, false);

第二个参数是true代表大顶堆,是false代表小顶堆,我将大小顶堆代码合并了。

class MedianFinder {
    Heap h1 = null;
    Heap h2 = null;

    public MedianFinder() {
        h1 = new Heap(10, true);
        h2 = new Heap(10, false);
    }
    
    public void addNum(int num) {
        if(h1.size == h2.size){
            h2.offer(num);
            h1.offer(h2.poll());
        }
        else{
            h1.offer(num);
            h2.offer(h1.poll());
        }
    }
    
    public double findMedian() {
        if(h1.size == h2.size){
            return (h1.peek() + h2.peek())/2.0;
        }
        return 1.0*h1.peek();
    }
}
class Heap{
    private int[] array;
    int size;
    Boolean m;

    public Heap(int capacity, Boolean m) {
        this.array = new int[capacity];
        this.m = m;
    }

    public int peek(){
        return size==0 ? -999 : array[0];
    }

    public void offer(int offered){
        if(size == array.length) {
            resize();
        }
        up(offered);
        size++;
    }

    private void resize() {
        int capacity = size + (size>>1);
        int[] newArr = new int[capacity];
        System.arraycopy(array, 0, newArr, 0, size);
        array = newArr;
    }

    private void up(int offered) {
        int child = size;
        while(child > 0){
            int parent = (child - 1) / 2;
            if(m ? offered > array[parent] : offered < array[parent]){
                array[child] = array[parent];
            }
            else {
                break;
            }
            child = parent;
        }
        array[child] = offered;
    }

    public int poll(){
        int top = array[0];
        swap(0, size-1);
        size--;
        down(0);
        return top;
    }

    private void down(int i) {
        int lc = 2*i+1;
        int rc = lc+1;
        int now = i;
        if(lc < size && (m ? array[lc] > array[now] : array[lc] < array[now])){
            now = lc;
        }
        if(rc < size && (m ? array[rc] > array[now] : array[rc] < array[now])){
            now = rc;
        }
        if(now != i){
            swap(now, i);
            down(now);
        }
    }

    private void swap(int top, int bottom) {
        int t = array[top];
        array[top] = array[bottom];
        array[bottom] = t;
    }
}

利用优先队列:

优先队列底层就是堆嘛,所以直接用java提供的优先队列也行。( •̀ ω •́ )y

class MedianFinder {
    PriorityQueue<Integer> q1;
    PriorityQueue<Integer> q2;

    public MedianFinder() {
        q1 = new PriorityQueue<>((o1, o2)->o2-o1);
        q2 = new PriorityQueue<>();
    }
    
    public void addNum(int num) {
        if(q1.size() == q2.size()){
            q2.offer(num);
            q1.offer(q2.poll());
        }
        else{
            q1.offer(num);
            q2.offer(q1.poll());
        }
    }
    
    public double findMedian() {
        return (q1.size()==q2.size() ? 
                    1.0*(q1.peek()+q2.peek())/2 :
                        1.0*q1.peek());
    }
}

2、239. 滑动窗口最大值

        第一想法,直接来个优先队列,但是想想不对,因为优先队列会将窗口中的数据排序,排完序之后窗口继续移动,那我就无法知道应该pop掉哪个元素了。

        我们需要一个数据结构,这个数据结构和队列很像,它能push加入队尾,pop删除队头,getMaxValue获取最大值。但是并没有这种现成的数据结构。

        实现上面需求的数据结构叫做单调队列

        单调队列中存着窗口中的元素,队列头就是当前窗口最大值,为什么能是最大值呢?因为这个队列并不是存储所有的元素,而是有选择的存,单调队列每次新加元素时,都会比较与队尾的值,如果队尾小,就一直pop,直到能添加进去,所以,如果此时新加的元素是最大值,那么它会pop掉所有队元素,成为队头。

        所以,想要在单调队列中存活,需要满足两个条件:

  • 在窗口的范围内
  • 没有被新来的元素干掉,也就是不比新来的元素小

        java中,我使用LinkedList,LinkedList实现了双端队列接口,用双端队列来模拟单调队列。

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        LinkedList<Integer> list = new LinkedList<>();
        //nums.length-k+1
        int len = nums.length;
        int[] ans = new int[len-k+1];
        int cnt = 0;
        for(int i = 0; i < len; i++){
            //弹出过时的
            while(!list.isEmpty() && list.peek() < i-k+1){
                list.poll();
            }
            //弹出末尾不够大的
            while(!list.isEmpty() && nums[list.peekLast()] < nums[i]){
                list.pollLast();
            }
            list.offer(i);
            if(i >= k-1){
                ans[cnt++] = nums[list.peek()];
            }
        }

        return ans;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

NUXTJS安装始终报错无法正常运行问题解决

近日在了解NuxtJS&#xff0c;按照官方给出方法进行安装后&#xff0c;不是报错&#xff0c;就是安装成功后运行不了。执行npm run dev后始终运行出错&#xff0c;判断肯定是对应版本问题&#xff0c;沿着这方向研究&#xff0c;最终运行成功了。 文档地址&#xff1a;安装 - …

【C++初阶】--入门基础(一)

目录 一.命名空间 1.前言引入 2.namespace关键字 (1)前言 (2)域作用限定符 :: (3)命名空间域namespace ① 细节理解 ② 命名空间的名称相同 ③命名空间的嵌套 (4)命名空间的使用 ① 加命名空间名称及作用域限定符 ②使用using将命名空间中某个成员引入 ③ 使用u…

【内置对象·js】

数学对象 document.write("圆周率为 " Math.PI "<br>");日期对象 var date new Date(); // 实例化 Date 对象var month date.getMonth() 1; // 获取月份&#xff0c;取值为 0&#xff08;一月&#xff09;到 11&#xff08;十二月&#xff09;之…

某站平台的签名算法分享

先charles抓包&#xff0c;api.xxxxxx.com域名的包 分析包 看到路径参数如下 appkey1d8b6e7d45233436&build5531000&channeldw056&mobi_appandroid&mode0&oid326052200&plat2&platformandroid&ps20&statistics%7B%22appId%22%3A1%2C%22p…

Redis核心技术与实战【学习笔记】 - 16.Redis 缓存异常:缓存和数据库不一致

概述 只要使用 Redis 缓存&#xff0c;就必须面对缓存和数据库的一致性问题。 重要的是&#xff0c;如果数据不一致&#xff0c;那么业务应用从缓存中读取的数据就不是最新数据&#xff0c;这会导致严重的问题。比如说&#xff0c;我们把电商商品的库存信息缓存在 Redis 中&am…

机器学习_13_SVM支持向量机、感知器模型

文章目录 1 感知器模型1.1 感知器的思想1.2 感知器模型构建1.3 损失函数构建、求解 2 SVM3 线性可分SVM3.1 线性可分SVM—概念3.2 线性可分SVM —SVM 模型公式表示3.3 线性可分SVM —SVM 损失函数3.4 优化函数求解3.5 线性可分SVM—算法流程3.6 线性可分SVM—案例3.7 线性可分S…

如何读论文

如何读论文 0. 目的 单篇文章从头读到尾&#xff0c;可以&#xff1b; 世界上那么多篇文章&#xff0c; 都这样读&#xff0c; 时间上划不来。 适合你的文章就那么一小撮。 paper 的八股文结构&#xff1a; titleabstractintromethodexpconclusion 1. 第一遍 海选&#…

HiveSQL题——聚合函数(sum/count/max/min/avg)

目录 一、窗口函数的知识点 1.1 窗户函数的定义 1.2 窗户函数的语法 1.3 窗口函数分类 聚合函数 排序函数 前后函数 头尾函数 1.4 聚合函数 二、实际案例 2.1 每个用户累积访问次数 0 问题描述 1 数据准备 2 数据分析 3 小结 2.2 各直播间最大的同时在线人数 …

计算视图里的projection和aggregation节点区别

Projection 和 Aggregation到底有什么区别&#xff1f; 看名字就能看出来的。 那么在什么场景下用呢&#xff1f; 1. Projection就是投影&#xff0c;也就是说你本来的源里有什么&#xff0c;就直接给你拿出来。 除了这个&#xff0c;它使用的场景就是&#xff1a; 只映射需…

Framework - ActivityThread 应用启动UI渲染流程

一、概念 ActivityThread拥有 main(String[] agrs) 方法&#xff0c;作为程序的入口&#xff0c;是应用程序的初始化类。&#xff08;ActivityThread不是主线程&#xff0c;它在 main() 方法中实例化&#xff0c;是运行在主线程中。&#xff09;ApplicationThread是 ActivityT…

解析Excel文件内容,按每列首行元素名打印出某个字符串的统计占比(超详细)

目录 1.示例&#xff1a; 1.1 实现代码1&#xff1a;列数为常量 运行结果&#xff1a; 1.2 实现代码2&#xff1a;列数为变量 运行结果&#xff1a; 1.示例&#xff1a; 开发需求&#xff1a;读取Excel文件&#xff0c;统计第3列到第5列中每列的"False"字段占…

STM32SPI通信协议--(2)W25Q64简介

一、W25Q64简介 1、W25Qxx中的xx是不同的数字&#xff0c;表示了这个芯片不同的存储容量&#xff1b; 2、存储器分为易失性与非易失性&#xff0c;主要区别是存储的数据是否是掉电不丢失&#xff1a; 易失性存储器&#xff1a;SRAM、DRAM&#xff1b; 非易失性存储器&#xff…

django+flask+python高校教材管理系统47nia

本.4论文结构 绪论&#xff1a;剖析项目可行性&#xff0c;表明研究方向。 开发技术&#xff1a;系统关键运用了Python技术性、Django框架、B/S架构和myspl数据库查询&#xff0c;并进行了详细介绍[6]。 系统分析&#xff1a;包含系统的总体构造&#xff0c;用例图和结构图。 系…

使用机器学习算法预测在线订餐需求

咱们国内的美团和国外的 Swiggy 和 Zomato 引入市场后&#xff0c;在线订餐的需求量很大。食品配送公司利用客户的购买习惯来加快配送过程。食品订单预测系统是这些公司可以用来加快整个交付过程的有用技术之一。 这些公司对客户的主要目标是在正确的时间交付食物。为了更快地…

二叉树的层序遍历 II

给你二叉树的根节点 root &#xff0c;返回其节点值 自底向上的层序遍历 。 &#xff08;即按从叶子节点所在层到根节点所在的层&#xff0c;逐层从左向右遍历&#xff09; 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[15,7],[9,20],…

【数据开发】pyspark入门与RDD编程

【数据开发】pyspark入门与RDD编程 文章目录 1、pyspark介绍2、RDD与基础概念3、RDD编程3.1 Transformation/Action3.2 数据开发流程与环节 1、pyspark介绍 pyspark的用途 机器学习专有的数据分析。数据科学使用Python和支持性库的大数据。 spark与pyspark的关系 spark是一…

[BUUCTF]-PWN:roarctf_2019_easy_pwn解析

先看保护 64位&#xff0c;got表不可写 看ida 大致就是alloc创建堆块&#xff0c;fill填充堆块&#xff0c;free释放堆块&#xff0c;show输出堆块内容 这里要注意的点有以下 alloc创建堆块&#xff1a;这里采用的是calloc而不是malloc&#xff0c;calloc在创建堆块时会初始…

小白水平理解面试经典题目_二维数组类LeetCode 2966 Divide Array【排序算法实现】

2966 将数组划分为具有最大差值的数组 小白渣翻译&#xff1a; 给定一个大小为 n 的整数数组 nums 和一个正整数 k 。 将数组分成一个或多个大小为 3 的数组&#xff0c;满足以下条件&#xff1a; nums 的每个元素都应该位于一个数组中。一个数组中任意两个元素之间的差异小…

python打造光斑处理系统6:高斯拟合

文章目录 构建拟合函数数据获取打印信息 光斑处理&#xff1a;python处理高斯光束的图像 光斑处理系统&#xff1a; 程序框架&#x1f31f;打开图像&#x1f31f;参数对话框/伪彩映射&#x1f31f;裁切ROI光强分布 构建拟合函数 scipy中提供了非线性最小二乘回归算法&#x…

创建型模式-单例模式:定义、实现及应用

目录 一、模式定义二、针对问题1.解决的问题2.解决方案3.举个例子4.设计模式适合场景5.实现方式6.优缺点7.与其他模式的关系 三、代码实现 一、模式定义 单例模式&#xff08;Singleton Pattern&#xff09;是一种创建型模式&#xff0c;用于限制某个类只能创建一个对象。它提…