在数组中查找对,使得 a+b%10 = k
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 倍的对数。这些对会是什么样子?好吧,它们可以通过以下方式形成
- 将最后一个数字为 1 的数字与最后一个数字为 9 的数字相加,
- 将最后一个数字为 2 的数字与最后一个数字为 8 的数字相加,
- 将最后一个数字为 3 的数字与最后一个数字为 7 的数字相加,
- 将最后一个数字为 4 的数字与最后一个数字为 6 的数字相加,或
- 将最后一个数字为 5 的两个数字相加,或
- 将最后一个数字为 0 的两个数字相加。
因此,假设您有一个频率表 A,其中 A[i] 是最后一个数字 i 的数字数。那么最后几位分别为 i 和 j 的数字对数由下式给出
- A[i] * A[j] 如果 i ≠ j,并且
- A[i] * A[i-1]/2 如果 i = j。
基于此,如果您想计算总和为 k mod 10 的对数,您可以
- 填写 A 数组,然后
- 遍历所有可能的总和为 k 的对,使用上面的公式计算对的数量,而不明确列出所有对。
最后一步需要时间 O(1(,因为只有十个存储桶,因此迭代您需要的对最多需要恒定的工作量。
其余的细节交给你。
希望这有帮助!
您可以为此修改计数排序。 下面是一个未经测试、未优化且仅供说明的版本:
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;
}
相关文章:
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- 为什么我不能在 FOR LOOP 中使用 i/10,C++?
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- Windows 10-使用gtkmm-3.0库和g++[包括再现]的分段故障
- clang整洁10忽略了我的NOLINT命令
- 如何解决错误:SCIP C++中的 SCIP 阶段无效 <10>
- 标准 N3337 5.2.10 第 7 条中的C++"类型"是什么意思?
- 是否可以用C++/WinRT将windows 10.0.14393作为目标
- 为什么 -mmacosx-version-min=10.10 不阻止使用标记为从 10.11 开始的函数?
- 如何使用 llvm-10 库在C++定义 LLVM 全局值变量?
- 整数溢出,最大值为 pow(10,19)
- 如果 x < 10,则添加前导 0 并将其存储为 int
- <filesystem> 在 clang 6 和 10 上 #include 错误
- 在 Windows 8/10 技术中完全实时的屏幕捕获,没有延迟
- Vulkan SDK 版本 1.1.85.0 在 Kubuntu 18.10 上链接
- 为什么我只能在C++中使用可变长度数组分配小于 10 mb 的内存?
- 16 位到 10 位转换代码说明
- 奇怪的代码抛出编译错误模板< J,int aSize=10> C2143:语法错误:在"<"之前缺少";"
- 在数组中查找对,使得 a+b%10 = k