给定一个长度为 n 的整数数组 a1,a2,…,an ,数组中的每个元素都是一个 1∼n 之间的整数。 我们规定,数组中出现次数最多的元素为数组的核心元素,例如数组 [1,1,1,2,3] 的核心元素为 1 。 此外,如果数组中出现次数最多的元素不唯一,则出现次数最多的元素中数值最小的那个元素为数组的核心元素,例如数组 [1,2,2,3,3] 的核心元素为 2 。 对于 1≤i≤n 的每个整数 i ,请你计算有多少个给定数组的非空连续子数组的核心元素为 i 。c++代码
时间: 2024-02-13 20:00:28 浏览: 116
以下是对应的 C++ 代码实现:
```c++
#include <iostream>
#include <vector>
#include <map>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> nums(n);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
map<int, int> freq;
int max_freq = 0;
int core = -1;
for (int i = 0; i < n; i++) {
freq[nums[i]]++;
if (freq[nums[i]] > max_freq || (freq[nums[i]] == max_freq && nums[i] < core)) {
max_freq = freq[nums[i]];
core = nums[i];
}
}
vector<int> count(n + 1);
int l = 0, r = 0;
int ans = 0;
while (r < n) {
count[nums[r]]++;
while (count[core] * 2 <= r - l + 1 && l <= r) {
count[nums[l]]--;
l++;
}
ans += count[core];
r++;
}
for (int i = 1; i <= n; i++) {
cout << ans << " ";
if (nums[i - 1] == core) {
ans--;
}
}
return 0;
}
```
算法思路:
首先,我们需要遍历整个数组,记录出现次数最多的元素以及其出现次数。具体来说,我们可以使用哈希表(C++ 中的 `map`)来存储每个元素出现的次数,然后遍历哈希表,找到出现次数最多的元素。
接下来,我们需要统计以每个元素为核心的子数组个数。假设当前核心元素为 i,我们使用两个指针 l 和 r,初始时均指向数组的第一个位置。然后我们不断向右移动指针 r,并记录当前所遍历的子数组中各个元素出现的次数。当以 i 为核心的子数组长度小于等于 2*count[i] 时,我们需要向右移动指针 l,并更新各个元素出现的次数,直到以 i 为核心的子数组长度大于 2*count[i] 为止。
最后,我们记录以 i 为核心的子数组个数,然后继续移动指针 r,直到遍历完整个数组。
时间复杂度:
遍历整个数组需要 O(n) 的时间复杂度,统计以每个元素为核心的子数组个数也需要 O(n) 的时间复杂度。因此,总时间复杂度为 O(n)。
空间复杂度:
我们需要使用一个哈希表和一个数组来存储各个元素出现的次数,因此空间复杂度为 O(n)。
阅读全文