Count Subarrays With Median K

Count Subarrays With Median K

You are given an array nums of size n consisting of distinct integers from 1 to n and a positive integer k.

Return the number of non-empty subarrays in nums that have a median equal to k.

Note:

  • The median of an array is the middle element after sorting the array in ascending order. If the array is of even length, the median is the left middle element.
    • For example, the median of [2,3,1,4] is 2, and the median of [8,4,3,5,1] is 4.
  • A subarray is a contiguous part of an array.

Example 1:

Input: nums = [3,2,1,4,5], k = 4
Output: 3
Explanation: The subarrays that have a median equal to 4 are: [4], [4,5] and [1,4,5].

Example 2:

Input: nums = [2,3,1], k = 3
Output: 1
Explanation: [3] is the only subarray that has a median equal to 3.

Constraints:

  • n==nums.length
  • 1n105
  • 1nums[i],kn
  • The integers in nums are distinct.

 

解题思路

  没做出来,菜。

  关键是要想到下面这个性质,如果一个长度为n的数组排序后的中位数是k,如果n是奇数,那么大于k的数的个数应该恰好为n2,小于k的数的个数也恰好为n2;如果n是偶数,那么大于k的数的个数应该恰好为n2, 小于k的数的个数应该恰好为n21

  接着我们可以构造一个数组a,如果nums[i]>k,那么a[i]=1;如果nums[i]<k,那么a[i]=1;如果nums[i]=k,那么a[i]=0。任然后对数组a求前缀和,得到前缀和数组s。如果某个区间[i,j]排序后的中位数为k,问题就变成了,如果区间长度为奇数那么s[i]s[j1]=0;如果区间长度为偶数那么s[i]s[j1]=1

  因此我们可以枚举区间右端点i,根据i的奇偶性看看有多少个j (1ji)满足上面的条件,因此可以开个哈希表,每次枚举完i后根据i的奇偶性来统计s[i](代码是枚举i之前统计s[i1])。

  这里有个坑要注意的是由于区间的中位数必须要包含k这个数,假设k在原数组中的下标为x,因此在用哈希表统计的时候应该统计必定包含ks[i],也就是说当i>x的时候就不能再用哈希表记录s[i]了。

  AC代码如下:

复制代码
 1 class Solution {
 2 public:
 3     int countSubarrays(vector<int>& nums, int k) {
 4         int n = nums.size();
 5         vector<int> s(n + 1);
 6         int x;
 7         for (int i = 1; i <= n; i++) {
 8             if (nums[i - 1] == k) x = i;
 9             int t = 0;
10             if (nums[i - 1] > k) t = 1;
11             else if (nums[i - 1] < k) t = -1;
12             s[i] = s[i - 1] + t;
13         }
14         unordered_map<int, int> mp[2];
15         int ret = 0;
16         for (int i = 1; i <= n; i++) {
17             if (i - 1 < x) mp[i - 1 & 1][s[i - 1]]++;   // 当j - 1 >= x,区间[i, j]就不包含k了
18             ret += mp[i & 1][s[i] - 1] + mp[i - 1 & 1][s[i]]; // 区间长度为偶数的情况加上区间长度为奇数的情况
19         }
20         return ret;
21     }
22 };
复制代码
posted @   onlyblues  阅读(72)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示