Arrays 有多少个具有最大n个唯一编号的连续子阵列
我在网上发现了一个编程难题,想知道是否有更有效的解决方案 问题: 系统将为您提供一个n个数字的列表,以及一个数字X,该数字X表示可以包含在连续子数组中的不同数字的最大数量。我们需要计算所有满足X条件的连续子数组 输入 第一行是两个数字n和x;子阵列中数字的数量和唯一数字的最大数量 例如:Arrays 有多少个具有最大n个唯一编号的连续子阵列,arrays,algorithm,sub-array,Arrays,Algorithm,Sub Array,我在网上发现了一个编程难题,想知道是否有更有效的解决方案 问题: 系统将为您提供一个n个数字的列表,以及一个数字X,该数字X表示可以包含在连续子数组中的不同数字的最大数量。我们需要计算所有满足X条件的连续子数组 输入 第一行是两个数字n和x;子阵列中数字的数量和唯一数字的最大数量 例如: 5 2 1 2 3 1 1 ans = 10 explanation: ([1],[2],[3],[1],[1],[1,2],[2,3],[3,1],[1,1],[3,1,1]) 我的方法 使用两个循环遍历列
5 2
1 2 3 1 1
ans = 10
explanation: ([1],[2],[3],[1],[1],[1,2],[2,3],[3,1],[1,1],[3,1,1])
我的方法
使用两个循环遍历列表的所有子数组,并计算相关子数组中唯一数字的数量(使用集合)。当然,一定有更有效的方法来计算这个?对不起,如果这个问题不属于这里,请随意编辑
编辑:nellex的更正代码,有时给出错误的答案
int main() {
int n, x;
cin >> n >> x;
vector<int> a;
for (int i = 1; i <= n; i++) {
int b;
cin >> b;
a.push_back(b);
}
int ans = 0, end = 1;
set<int> uniq;
map<int, int> freq;
for (int start = 0; start < n; start++) {
cout << start << " and end=" << end << endl;
while (uniq.size() <= x && end < n) {
if (uniq.size() == x && freq[a[end]] == 0) {
break;
}
uniq.insert(a[end]);
freq[a[end]]++;
end++;
}
cout << "added " << end << " - " << start << " to ans" << endl;
ans += end - start;
freq[a[start]]--;
if (freq[a[start]] == 0) {
uniq.erase(a[start]);
}
}
cout << ans;
}
最大的限制是:
1≤k≤n≤100
1≤xi≤10
1≤k≤n≤5⋅10^5
1≤xi≤10^9
滑动窗口方法适合作为该问题的更好解决方案,这将使我们能够使用集合和映射在O(n*log(n))中解决该问题:
intmain(){
int n,x;
cin>>n>>x;
向量a(n);
对于(inti=0;i>a[i];
int end=0;
长ans=0;
设置uniq;
地图频率;
对于(int start=0;start while(uniq.size()我们可以在O(n)
时间中解决这个问题,方法是保留两个指针,p\u l
和p\u r
,这两个指针都向上推进数组,同时更新频率计数,h[e]
,用于我们遇到的每个元素以及当前唯一项的数量,k
例如:
5 2
1 2 3 1 1
让我们看看每个迭代
k = 0
h = {}
total = 0
p_r = -1
p_l = -1
1: p_r = 0
h = {1:1}
k = 1
total = 1
2: p_r = 1
h = {1:1, 2:1}
k = 2
total = 1 + 2 = 3
3: p_r = 2
h = {1:1, 2:1, 3:1}
k = 3
=> move p_l until k equals X:
p_l = 0
h = {1:1-1=0, 2:1, 3:1}
k = 3 - 1 = 2
total = 3 + 2 = 5
1: p_r = 3
h = {1:1, 2:1, 3:1}
k = 3
=> move p_l until k equals X:
p_l = 1
h = {1:1, 2:1-1=0, 3:1}
k = 3 - 1 = 2
total = 5 + 2 = 7
1: p_r = 4
h = {1:2, 2:0, 3:1}
k = 2
total = 7 + 3 = 10
我很困惑。问题是什么?当有三个数字时为什么x 2是?如果我们想要唯一的数字,为什么答案包含三次[1]
,…在示例中,问题是列表[1,2,3,1,1]的子数组有多少包含最大2个唯一的数字。如果我不清楚,抱歉。为什么你认为这是低效的?你说的是,我删除了C++标签,因为这不是C++中的任何问题。@ UlrichEckhardt,因为有大的测试用例(例如10 ^ 5)。我的代码超出了时间限制。@Quiti我发现您对代码的修改有点不正确。如果您正在将数组索引为0,请在初始化过程中设置int end=0
。同样,对于给定的约束,您需要使用long
作为答案。我仍然想知道,如何声明int a[n+1]?Visual Studio说“表达式必须具有常量值"。否则,谢谢。我想它是与C++11标准一起引入的,但不太确定。另外,我意识到我的代码中有一个bug,我现在已经修复了。你可能想再看一次。我的道歉=/仍然得到超出范围的错误,你确定已经修复了吗?我似乎真的不知道它是从哪里来的为什么从1开始呢?我喜欢这个主意,但是代码似乎有点不完整。@Quiti你能分享一下程序失败的测试用例吗?
k = 0
h = {}
total = 0
p_r = -1
p_l = -1
1: p_r = 0
h = {1:1}
k = 1
total = 1
2: p_r = 1
h = {1:1, 2:1}
k = 2
total = 1 + 2 = 3
3: p_r = 2
h = {1:1, 2:1, 3:1}
k = 3
=> move p_l until k equals X:
p_l = 0
h = {1:1-1=0, 2:1, 3:1}
k = 3 - 1 = 2
total = 3 + 2 = 5
1: p_r = 3
h = {1:1, 2:1, 3:1}
k = 3
=> move p_l until k equals X:
p_l = 1
h = {1:1, 2:1-1=0, 3:1}
k = 3 - 1 = 2
total = 5 + 2 = 7
1: p_r = 4
h = {1:2, 2:0, 3:1}
k = 2
total = 7 + 3 = 10