统计中位数为 K 的子数组

2023-10-27

给你一个长度为n的数组nums ,该数组由从1n的不同整数组成。另给你一个正整数k

统计并返回nums中的 中位数等于k的非空子数组的数目。

注意:

数组的中位数是按递增顺序排列后位于中间的那个元素,如果数组长度为偶数,则中位数是位于中间靠的那个元素。

例如,[2,3,1,4] 的中位数是 2 ,[8,4,3,5,1] 的中位数是 4 。
子数组是数组中的一个连续部分

示例 :

输入:nums = [3,2,1,4,5], k = 4
输出:3
解释:中位数等于 4 的子数组有:[4]、[4,5] 和 [1,4,5] 。

思路:

首先,看到中位数我们应该敏感的想到,如果一个数组的中位数是k,那么其一定具有以下性质之一

  • 数组中比k大的数的个数 等于 数组中比k小的数的个数
  • 数组中比k大的数的个数数组中比k小的数的个数1 个。

如果当前我们已知合法的子数组的终点位置,如何快速知道以当前终点位置为终点的合法子数组的个数呢?用前缀和 + 哈希表就可以解决。

为了计算每个子数组中的大于k的元素个数与小于k的元素个数之差,需要将原始数组做转换,将大于k的元素转换成1,小于的元素转换成−1,等于 k 的元素转换成 0。转换后的数组中,每个子数组的元素和为对应的原始子数组中的大于 k 的元素个数与小于 k 的元素个数之差。

为了在转换后的数组中寻找符合要求的子数组,可以计算转换后的数组的前缀和,根据前缀和寻找符合要求的子数组即子数组的和为0或者1的情况)。

规定空前缀的前缀和是0且对应下标-1

k在原始数组中所在位置的下标为idx_k,如果存在一个中位数为k的子数组[left,right],那么肯定有0 <= left <= idx_x <= right < n且下标right处的前缀和与下标left - 1处的前缀和的差为0或者1

具体算法:

pre(前缀和)为0,设idx_kk在原数组中的位置,map[0] = 1,对应选择的子数组为左端点时的情况
从左到右遍历数组,对于 0 <= i < n ,如果nums[i] < kpre减一;如果nums[i] > kpre加一 。对于当前位置i来说,如果:

  • i < idx_k,说明位置i只能被作为某个(或某几个)合法子数组的左端点,此时可以将哈希表中map[pre]的值加一,将其记录下来。
  • i >= idx_k,说明位置i只能被作为某个(或某几个)合法子数组的右端点,此时可以在哈希表中查找,如果表中存在keypre(对应子数组的和为0的情况)或者pre - 1(对应子数组的和为1的情况)的键值对,那么说明这个右端点可以和之前的map[pre] + map[pre - 1]个左端点构成合法子数组,即将答案加上map[pre] + map[pre - 1]

遍历结束之后,即可得到中位数等于 k 的非空子数组的数目。

代码:

class Solution {
public:
    int countSubarrays(vector<int>& nums, int k) {
        unordered_map<int, int> mp;
        int n = nums.size();
        int pre = 0, ans = 0, idx = n;
        for(int i = 0; i < nums.size(); ++ i) {
            if(nums[i] == k) {
                idx = i;
                break;
            }
        }
        mp[0] = 1;
        for(int i = 0; i < n; ++ i) {
            if(nums[i] < k) pre--;
            else if(nums[i] > k) pre ++;
            if(i < idx) {  //不能等的原因和前缀和做差有关
            	//此时能作为左端点
                mp[pre] ++;   
            } 
            else {
             	//此时能作为右端点
                ans += mp[pre] + mp[pre - 1];  
                //这里不用判 键为pre和pre-1的键值对 是否存在的原因是如果不存在,值为0,不影响答案。
            }
        }
        return ans;
    }
};

类似的题目:

2588. 统计美丽子数组数目
待更新……

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

统计中位数为 K 的子数组 的相关文章

随机推荐

  • Ubuntu18.04更换源及类似问题解决方案

    Ubuntu18 04更换源及类似问题解决方案 文章目录 Ubuntu18 04更换源及类似问题解决方案 1 前言 2 Ubuntu18 04 LTS 更换国内源 3 最后 1 前言 目前部分开发板使用的Ubuntu操作系统 使用Qt RO
  • WSL重启方法

    WSL Ubuntu18 04 LTS 重启方法 以管理员权限运行cmd gt gt net stop LxssManager 停止 gt gt net start LxssManager 启动
  • 抓取一闪而过的提示消息文本

    前端业务操作出现一闪而过的message提示信息 它们有一个特点就是显示1 2s后会自动消失 例如下图1 图1 这些消息不像 alert 警告框 confirm 确认框 和prompt 提示框 那样 需要用户手动点击确定或取消按钮后才消失
  • 华为od机考真题-HJ32密码截取(中等)

    求最大回文子串 while 1 try str1 input if len str1 1 print 1
  • 渗透测试学习目录

    网络攻击防范 课程介绍 1 HTML 01 HTML标签和文本属性 02 form表单 input 标签 属性 03 a标签 img标签 table标签 04 无序列表和有序列表 05 frameset frame 框架的使用 2 div
  • VS离线安装NuGet包

    VS离线安装NuGet包 以VS 2017为例 一 下载NuGet包 官方NuGet包下载网址 https www nuget org 1 搜索需要下载的包名称 点击进入包详情页面 2 点击Download package 下载离线包 3
  • [NOI2011]阿狸的打字机【AC自动机fail树+树状数组】

    题目链接 P2414 题目给出N个字符串 我们现在想知道的是第x个字符串在第y个字符串中出现的次数是多少次 求每个字符在其余字符中出现次数 想到从AC自动机上走 其实可以看作是求它的后缀的前缀中有多少个是满足的 换言之 我们可以去fail树
  • 日前日内多阶段多时间尺度源荷储协调调度(matlab代码)

    多阶段多时间尺度的源荷储协调调度的优势是考虑新能源出力的波动性与随机性 减少需求响应负荷的不确定性会对电网制定的日前调度计划准确性的影响 也就是能够更加精准的进行调度和分析 优化结果的可用性更强 在这方面论文里面 金力的 考虑特性分布的储能
  • 如何利用excel中的数据源制作数据地图

    关于这个问题 制作数据地图的方法已不新奇 总体来说有这么几类方案 一类方案 直接在excel里制作 优势 个人小数据量应用较为方便简单 缺点 需要熟悉VBA 且更强大的功能对VBA水平要求较高 1 绘制地图图形 VBA宏语言 思路 用插入图
  • MOS管相关知识

    MOS管 MOS管的英文全称叫MOSFET Metal Oxide Semiconductor Field Effect Transistor 即金属氧化物半导体型场效应管 属于场效应晶体管中的绝缘栅型 MOS管是场效应管的一种 在一般电子
  • 版本号自动生成方法

    只需把 AssemblyInfo cs文件中的 assembly AssemblyVersion 1 0 0 0 改成 assembly AssemblyVersion 1 0 另外还需要把 assembly AssemblyFileVer
  • 什么是负载均衡,看完文章秒懂

    一 负载均衡简介 1 1 大型网站面临的挑战 大型网站都要面对庞大的用户量 高并发 海量数据等挑战 为了提升系统整体的性能 可以采用垂直扩展和水平扩展两种方式 垂直扩展 在网站发展早期 可以从单机的角度通过增加硬件处理能力 比如 CPU 处
  • 运行时报错“version `GLIBCXX_3.4.29‘ not found”底层原理分析

    文章目录 1 报错的现象 2 为什么程序有的报找不到某个版本的动态库 有的报找不到动态库文件 2 1 找不到动态库 2 2 找不到某个版本的动态库 2 2 1 报错的原因 2 2 2 动态库的版本是如何指定的 程序又是如何记录依赖的动态库版
  • DecimalField的使用

    DecimalField 类 DecimalField max digits 无 decimal places 无 选项 固定精度的十进制数 在Python中表示一个 十进制的实例 有两个必需的参数 DecimalField max dig
  • 浏览器插件下载“Download failed. Please check your connection.”解决方法

    第一步 查看错误原因 Download failed Please check your connection 下载失败 请检查您的连接 第二步 根据问题根源查看connects相关设置 第三步 分析原因 我是开启了Manual proxy
  • NeRF必读:Instant-NGP----RTX3090单卡就能玩转NeRF

    前言 NeRF从2020年发展至今 仅仅三年时间 而Follow的工作已呈井喷之势 相信在不久的将来 NeRF会一举重塑三维重建这个业界 甚至重建我们的四维世界 开头先吹一波 NeRF的发展时间虽短 有几篇工作却在我研究的领域开始呈现万精油
  • C语言---双向链表(详解)---数据结构

    双向链表所需要头文件 首先重定义类型名 意义我前几篇讲过几次了 这里就不在赘述了 顺序表 单链表的开头都有说明 然后我们需要一个结构体 结构体包含 存储数据的 a 指向一个节点的指针 next 指向上一个节点的指针 prve 双向链表实现的
  • pgadmin4更改数据类型和主键

    在 pgAdmin 4 中更改数据类型和主键需要以下步骤 打开 pgAdmin 4 连接到您想要修改的数据库 找到并打开您想要修改的表 单击该表后单击 设计 按钮 找到要修改的列 单击该列后单击 编辑 删除 按钮 在弹出的窗口中 更改 数据
  • hai子兄弟表示法(C语言实现)——树的存储结构

    孩子兄弟表示法实际就是创建一棵二叉树 include
  • 统计中位数为 K 的子数组

    给你一个长度为n的数组nums 该数组由从1 到n的不同整数组成 另给你一个正整数k 统计并返回nums中的 中位数等于k的非空子数组的数目 注意 数组的中位数是按递增顺序排列后位于中间的那个元素 如果数组长度为偶数 则中位数是位于中间靠左