[英]Find pairs in an array such that a+b%10 = k
有一个有序列表,如
A=[7, 9, 10, 11, 12, 13, 20]
我必须找到对 a+b%10=k 其中 0<=k<=9
例如 k = 0
对:(7, 13), (9, 11), (10, 20)
如何在 O(n) 时间内找到对数?
我试图用 take mod(10) 找到转换所有列表
for (auto i : A) {
if (i <= k) {
B.push_back(i);
}
else {
B.push_back(i % 10);
}
}
之后,我尝试定义通过 unorderep_map 给出 k 的总和
unordered_map<int, int> sumList;
int j = k;
for (int i = 0; i < 10; i++) {
sumList[i] = j;
if (j==0) j=9;
j--;
}
但是我不知道如何计算 O(n) 中的对数,我现在该怎么办?
让我们从一个简单的例子开始。 假设 k = 0。这意味着我们想要找到总和为 10 的倍数的对数。这些对会是什么样子? 好吧,它们可以由
因此,假设您有一个频率表 A,其中 A[i] 是最后一位为 i 的数字的数量。 那么末位分别为 i 和 j 的数字对的数量由下式给出
基于此,如果您想计算总和为 k mod 10 的对数,您可以
最后一步需要时间 O(1),因为只有 10 个存储桶,并且迭代您需要的对,因此最多需要恒定的工作量。
我将把细节的rest留给你。
希望这可以帮助!
您可以为此修改计数排序。 以下是未经测试、未经优化且仅用于说明的版本:
int mods[10];
void count_mods(int nums[], int n) {
for (int i = 0; i < n; i++)
mods[nums[i]%10]++;
}
int count_pairs(int k) {
// TODO: there's definitely a better way to do this, but it's O(1) anyway..
int count = 0;
for (int i = 0; i < 10; i++)
for (int j = i+1; j < n; j++)
if ((i + j) % 10 == k) {
int pairs = mods[i] > mods[j] ? mods[j] : mods[i];
if (i == j)
pairs /= 2;
count += pairs;
}
return count;
}
编辑:使用较小的常数。
int mods[10];
void count_mods(int nums[], int n) {
for (int i = 0; i < n; i++)
mods[nums[i]%10]++;
}
int count_pairs(int k) {
int count = 0;
for (int i = 0; i < 10; i++) {
int j = k - i;
if (j < 0)
j += 10;
count += min(mods[i], mods[j]);
// When k = 2*i we count half (rounded down) the items to make the pairs.
// Thus, we substract the extra elements by rounding up the half.
if (i == j)
count -= (mods[i]+1) / 2;
}
// We counted everything twice.
return count / 2;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.