2023-03-16 Likou daily question

Link:

https://leetcode.cn/problems/count-subarrays-with-median-k/

Title meaning:

Given an array, find the number of non-empty sub-arrays with median k after sorting , the length of the array is n, and it contains 1 to n non-repeating integers

When the length of the subarray is even, k should be on the left side

untie:

Treat those greater than k as 1, and those less than k as -1. The prefix sz[i+1] can represent the [0,i]offset value of k from the median of this subarray (k is not necessarily in it)

For any required sub-array, it must first be satisfied that k is contained in it

It can be seen that when k is the median and k is in the segment, the number of numbers greater than k and the number of numbers less than k in the segment are equal, and the offset value is 0;

Similarly, when k is left of the median and k is in this segment, the offset value needs to be 1, and the number of numbers greater than k in this segment is one more than the number of numbers smaller than k.

So when the offset value of this segment is 0 or 1, and k is in this segment, it must be the required subarray

Traverse the array, store the ones less than k into the map, initialize map[0]=1, because my sz[i] represents the offset value of the prefix array including i, and sz[0] contains the offset of nums[0] For shifting, consider the case where the starting point is before element 0 (two mistakes), and the offset value equal to k does not need to be stored, because the starting point of the sub-array must be before k (one mistake).

Each offset value greater than or equal to k is the value sz[i+1]provided for the answermap[ sz[i+1] ]+map[ sz[i+1]-1 ]

[L, R] offset value sz[R+1]-sz[L], because the sz array is stored for subscript +1, so the code is too ugly

Actual code:

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
const int N=1E5+3;
int sz[N],mao;
int solve(vector<int>& nums, int k)
{
    map<int,int>pd;//配对组 
    int lg=nums.size(),ans=0;
    //前缀+绝对处理 
    for(int i=0;i<lg;i++)
    {
        if(nums[i]<k) sz[i+1]=sz[i]-1;
        if(nums[i]==k)
        {
            sz[i+1]=sz[i];
            mao=i;
        }
        if(nums[i]>k) sz[i+1]=sz[i]+1;
        //cout<<sz[i+1]<<endl;
    }
    pd[0]=1;//最左端为起点 
    for(int i=0;i<lg;i++)
    {
        if(i<mao) pd[ sz[i+1] ]++;//累计 起点 
        else
        {
            ans=ans+pd[ sz[i+1] ]+pd[ sz[i+1]-1 ];
        }
        //cout<<"temp_ans:"<<ans<<endl;
    }
    //返回答案 
    return ans;
}
int main()
{
    int n,k;cin>>n;
    vector<int> nums;
    for(int i=1;i<=n;i++)
    {
        int temp;cin>>temp;
        nums.push_back(temp);
    }
    cin>>k;
    
    int ans=solve(nums,k);
    cout<<"ans="<<ans<<endl;
}

limit:

  • n == nums.length
  • 1 <= n <= 105
  • 1 <= nums[i], k <= n
  • numsThe integers in are different from each other

Guess you like

Origin blog.csdn.net/Fei_WuYan/article/details/129600732