给定一个长度为 n 的整数数组 a1,a2,…,an ,数组中的每个元素都是一个 1∼n 之间的整数。 我们规定,数组中出现次数最多的元素为数组的核心元素,例如数组 [1,1,1,2,3] 的核心元素为 1 。 此外,如果数组中出现次数最多的元素不唯一,则出现次数最多的元素中数值最小的那个元素为数组的核心元素,例如数组 [1,2,2,3,3] 的核心元素为 2 。 对于 1≤i≤n 的每个整数 i ,请你计算有多少个给定数组的非空连续子数组的核心元素为 i 。 输入格式 第一行包含整数 n 。 第二行包含 n 个整数 a1,a2,…,an 。 输出格式 共一行,输出 n 个整数,其中第 i 个整数表示给定数组中核心元素为 i 的非空连续子数组的数量。 数据范围 前 3 个测试点满足 1≤n≤10 。 所有测试点满足 1≤n≤5000 ,1≤ai≤n 。用c++写代码
时间: 2024-01-16 10:04:39 浏览: 176
以下是基于哈希表的 C++ 代码实现:
```
#include <iostream>
#include <unordered_map>
using namespace std;
int main()
{
int n;
cin >> n;
int a[n];
for (int i = 0; i < n; i++)
cin >> a[i];
unordered_map<int, int> freq; // 哈希表记录每个元素的出现次数
int left = 0, right = 0; // 滑动窗口的左右边界
int res[n + 1]; // 记录每个元素为核心元素的连续子数组数量
fill(res, res + n + 1, 0);
while (right < n)
{
freq[a[right]]++; // 统计当前窗口内每个元素的出现次数
right++;
int max_freq = 0; // 当前窗口内出现次数最多的元素的出现次数
int max_num = 0; // 当前窗口内出现次数最多的元素的数值
// 从当前窗口内统计出现次数最多的元素
for (auto& [num, f] : freq)
{
if (f > max_freq)
{
max_freq = f;
max_num = num;
}
}
// 如果当前窗口内出现次数最多的元素在左右边界之间,则可以作为核心元素
if (max_freq <= (right - left) / 2 && max_num != 0)
res[max_num]++;
// 如果当前窗口的长度大于等于出现次数最多的元素的出现次数,则左边界右移
while ((right - left) >= 2 * max_freq)
{
freq[a[left]]--;
left++;
}
}
// 累加每个元素为核心元素的连续子数组数量
for (int i = n - 1; i >= 1; i--)
res[i] += res[i + 1];
// 输出结果
for (int i = 1; i <= n; i++)
cout << res[i] << " ";
return 0;
}
```
时间复杂度:O(n)
阅读全文