【LeetCode 每日一题】2488. 统计中位数为 K 的子数组(hard)

2488. 统计中位数为 K 的子数组

前缀和+哈希表。分别统计每个位置大于k和小于k的数字个数的差值,并以此找符合条件的子数组。


对于一个子数组,我们设 k k k 的位置为 i n d e x index index ,大于 k k k 的数字的数量为 r i g h t _ n u m right\_num right_num ,小于 k k k 的数字的数量为 l e f t _ n u m left\_num left_num,二者的差值 d i s = l e f t _ n u m − r i g h t _ n u m dis=left\_num-right\_num dis=left_numright_num 。则对于任何两个位置 i i i j j j ,如果满足 i < i n d e x < = j i<index<=j i<index<=j d i s [ i ] = d i s [ j ]    或    d i s [ i ] = d i s [ j ] + 1 dis[i]=dis[j]\;或\;dis[i]=dis[j]+1 dis[i]=dis[j]dis[i]=dis[j]+1则该子数组一定是满足条件的子数组。

  • 对于 d i s [ i ] = d i s [ j ] dis[i]=dis[j] dis[i]=dis[j],表示 [ i , j ] [i,j] [i,j] 之间的 l e f t _ n u m = r i g h t _ n u m left\_num=right\_num left_num=right_num ,满足中位数的第一个情况
  • 对于 d i s [ i ] = d i s [ j ] + 1 dis[i]=dis[j]+1 dis[i]=dis[j]+1,由于表示 d i s = l e f t _ n u m − r i g h t _ n u m dis=left\_num-right\_num dis=left_numright_num,意味着 [ i , j ] [i,j] [i,j] 之间的 l e f t _ n u m − r i g h t _ n u m = − 1 left\_num-right\_num=-1 left_numright_num=1 ,符合中位数的第二种情况。

那具体应该怎么做呢,我们只遍历一次数组,维护两个前缀和 l e f t _ n u m left\_num left_num r i g h t _ n u m right\_num right_num。由于这个子数组一定要包含 k k k ,所以在遇到 k k k 之前,我们用哈希表 m p mp mp 记录每一个 d i s dis dis 出现的次数;当遇到 k k k 之后,我们就开始计算子数组的数量,对于 k k k 之后的每一个位置,子数组数量为 m p [ d i s ] + m p [ d i s + 1 ] mp[dis]+mp[dis+1] mp[dis]+mp[dis+1]

class Solution {
    
    
public:
    int countSubarrays(vector<int>& nums, int k) {
    
    
        int n=nums.size();
        int res=0;
        int left_num=0;
        int right_num=0;
        unordered_map<int,int> mp;
        mp[0]++;
        int flag=false;
        for(int i=0;i<n;i++){
    
    
            if(nums[i]<k)left_num++;
            if(nums[i]==k) flag=true;
            if(nums[i]>k) right_num++;
            int dis=left_num-right_num;
            if(!flag){
    
    
                mp[dis]++;
            }
            else{
    
    
                res+=mp[dis];
                res+=mp[dis+1];
                // cout<<dis<<" "<<mp[dis]<<" "<<mp[dis+1]<<endl;
            }
        }
        return res;
    }
};

之前也有遇到一个前缀和求子集的题目,可以看这里感受一下。






菩萨蛮 【清·纳兰性德】

萧萧几叶风兼雨,离人偏识长更苦。欹枕数秋天,蟾蜍下早弦。
夜寒惊被薄,泪与灯花落。无处不伤心,轻尘在玉琴。

  1. 长更:长夜。
  2. 蟾蜍:代指月亮。

猜你喜欢

转载自blog.csdn.net/qq_44623371/article/details/129583977
今日推荐