当前位置: 首页 > article >正文

3134. 找出唯一性数组的中位数(24.8.27)

前言

本次通过学习 灵茶山艾府 的代码进行解题研究

题目

题目描述

给你一个整数数组 nums 。数组 nums 的唯一性数组是一个按元素从小到大排序的数组,包含了 nums 的所有非空子数组中不同元素的个数。

换句话说,这是由所有 0 <= i <= j < nums.Lengthdistinct(nums[i..j]) 组成的递增数组。其中,distinct(nums[..j]) 表示从下标 i 到下标 j 的子数组中不同元素的数量。

返回 nums 唯一性数组的中位数。

注意,数组的中位数定义为有序数组的中间元素。如果有两个中间元素,则取值较小的那个。

示例 1

输入:nums=[1,2,3]

输出:1

解释:

nums 的唯一性数组为 [distinct(nums[(0..0)], distinct(nums[1..1]), distinct(nums [2.2]), distinct(nums[0..1]), distinct(nums[1..2]), distinct(nums[0..2])],即 [1,1,1,2,2,3] 。唯一性数组的中位数为 1 ,因此答案是 1


示例 2

输入:nums=[3,4,3,4,5]

输出:2

解释:

nums 的唯一性数组为 [1,1,1,1,1,2,2,2,2,2,2,2,3,3,3] 。唯一性数组的中位数为 2 ,因此答案是 2

示例 3

输入:nums=[4,3,5,4]

输出:2

解释:

nums 的唯一性数组为 [1,1,1,1,2,2,2,3,3,3] 。唯一性数组的中位数为 2 ,因此答案是 2

提示

  • 1<=nums.Length<=105

  • 1<=nums[i]<=105

解题思路

见代码

代码

/*
子数组 是数组中连续的 非空 元素序列
子集的个数 :
            子集中数的个数: 1 2   3   4    ... n
            这个子集的个数: n n-1 n-2 n-3  ... 1
            数总和(由等差数列求和得):(n+1)*n/2

中位数:数组的 中位数 定义为有序数组的中间元素。如果有两个中间元素,则取值较小的那个
       假设一个数组有 3 个数,则中位数是 1
       假设一个数组有 4 个数,则中位数是 1
       假设一个数组有 2k+1 个数,则中位数是 k+1【((2k+1)+1)/2】
       假设一个数组有 2k 个数,则中位数是 k-1 【(2k+1)/2】
       -->假设一个数组有 n 个数,则中位数是 (n+1)/2


*/
class Solution {
public:
    int medianOfUniquenessArray(vector<int>& nums) {
        int n=nums.size();
        long long k=((long long)n*(n+1)/2+1)/2;//数组的个数
        /*
        设子数组的个数为 cnt,如果 cnt<k 
        说明二分的 m 小了,更新二分左边界 left,否则更新二分右边界 right
        */
        auto solve=[&](int m){
            long long cnt=0;
            int left=0;
            unordered_map<int, int> h;//记录次数
            //滑动窗口的模板
            //先固定左端,移动右端
            for(int left=0,right=0;right<n;right++){
                h[nums[right]]++;
                //当大于 m 即大于了的子数组个数
                //窗户口元素过多了
                while(h.size()>m){
                    h[nums[left]]--;//减去多余的统计个数
                    if(h[nums[left]]==0){
                        h.erase(nums[left]);//删除多余的窗口统计
                    }
                    left++;//将左边界向右移动一位
                }
                cnt+=right-left+1; // 右端点固定为 r 时,有 r-l+1 个合法左端点
                if(cnt>=k) return true;
            }
            return false;
        };
        int l=0,r=n;
        /*
        二分的内容是 distinct的数组中的内容
        比如实例1:
        nums = [1,2,3],distinct=[1, 1, 1, 2, 2, 3], ans=1
        l=0,r=3,mid=1,k=3
        进入solve当中,
        进行第一轮操作后,left=0,right=0,h.size()=1,cnt=1<k
        进行第二轮操作后,left=0,right=1,h.size()=2>m,窗口滑动一次,left++,cnt=2<k
        进行第三轮操作后,left=1,right=2,h.size()=2>m,窗口滑动一次,left++,cnt=3=k,即此刻说明我所组成的子数组数已经达到我所求的k的位置
        */
        while(l+1<r){
            int mid=(l+r)/2;
            if(solve(mid)) r=mid;
            else l=mid;
        }
        return r;
    }
};

http://www.kler.cn/a/287802.html

相关文章:

  • Vue3 provide 和 inject的使用
  • 深入List集合:ArrayList与LinkedList的底层逻辑与区别
  • GitLab 降级安装出现 500 错误,如何解决?
  • 《C语言程序设计现代方法》note-5 数组
  • 工化企业内部能源能耗过大 落实能源管理
  • 深度学习中的Pixel Shuffle和Pixel Unshuffle:图像超分辨率的秘密武器
  • 基于 OpenCV 的数字图像处理实验平台设计
  • MyBatis 源码解析:Configuration 对象的生成与初始化
  • 三台机器,第一台机器可以ssh到第二台机器,第二台机器可以ssh到第三台机器,请问第一台机器上怎么通过ssh 直接从第三台机器scp文件到第一台机器?
  • 树数据结构(Tree Data Structures)的全面指南:深度解析、算法实战与应用案例
  • 【WPF】WPF学习之【一】基础知识
  • 62.一个机器人位于一个 m x n 网格的左上角 。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角。实现一个算法计算路径的数量
  • 计算机毕业设计python停车场车位推荐管理系统y4uzk
  • “JavaScript里的多线程“WebWorker
  • scikit-learn:一个强大的机器学习Python库
  • APO选择ClickHouse存储Trace的考量
  • 代理IP的API接口:轻松实现自动化代理切换
  • 《软件工程导论》(第6版)第3章 需求分析 复习笔记
  • 同样128个内核,AMD霄龙9755性能翻倍:Zen 5架构下的性能飞跃
  • 【嵌入式学习笔记】STM32中断配置及相关知识
  • Go语言学习(一)
  • SpringBoot链路追踪②:如何集成?
  • Fabric.js中fabric.Text的深入解析
  • linux下部署数据库总结
  • Kubernetes中三种探针的作用你真的知道吗?
  • C语言操作符的介绍