分析算法复杂度,简化数据结构,使用并行或递归下降。
以上回复有部分引自免费微信小程序:皆我百晓生。 如问题尚未解决,还请稍待,如有疑问请回复进一步沟通。
为了优化这个程序,我们可以从以下几个方面进行改进:
减少嵌套循环:目前的实现中有两个嵌套循环,时间复杂度为O(N^2),可以通过一些数据结构和预处理来降低这个复杂度。
使用位运算:题目要求的是计算具有相同二进制最高位的整数对的数量,我们可以在预处理阶段就找出每个二进制最高位,并存储起来。
以下是优化后的代码:
#include
#include
#include
#include
using namespace std;
int countPairs(vector& nums) {
unordered_map> groupByMSB;
for (int num : nums) {
int msbPosition = 31 - __builtin_clz(num); // 获取最高位位置
groupByMSB[msbPosition].push_back(num);
}
int result = 0;
for (const auto& entry : groupByMSB) {
const int msbPosition = entry.first;
const vector& numbersWithMSB = entry.second;
sort(numbersWithMSB.begin(), numbersWithMSB.end()); // 对同一MSB的数字排序
int distinctCount = 1;
long long productSum = numbersWithMSB[0];
for (size_t i = 1; i < numbersWithMSB.size(); ++i) {
if (numbersWithMSB[i] != numbersWithMSB[i - 1]) {
distinctCount++;
productSum *= numbersWithMSB[i];
} else {
productSum *= 2;
}
}
result += distinctCount * productSum;
}
return result;
}
int main() {
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
vector nums(n);
for (int i = 0; i < n; ++i) {
cin >> nums[i];
}
cout << countPairs(nums) << endl;
}
return 0;
}
在这个优化版本中,我们首先通过__builtin_clz
函数找到每个数字的最高位(MSB)位置,并将这些数字分组。然后,对于每个MSB的组,我们对其进行排序,以便可以快速地确定唯一值的数量和它们的乘积。这样,我们只需要遍历每个组中的元素一次,大大减少了时间复杂度。整体上,这种方法的时间复杂度大约是O(N log N)。
注意:__builtin_clz
是GCC和Clang编译器提供的一个内置函数,用于获取输入参数中最左边连续零的个数。如果你使用其他编译器,可能需要寻找替代方法,例如使用位操作或者标准库函数来实现类似功能。在C++20及以后的版本中,你可以使用std::countl_zero
函数。
以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:
【您想要解决的问题】:您提问的目的是想要解决C++代码中的性能问题,具体来说,是优化一个计算特定数字对数量的函数,以避免运行超时。
【问题出现原因】:问题出现的原因是您的countPairs
函数中存在两层嵌套循环,它们遍历了一个unordered_map
中的所有键。对于每个键,您都在检查另一个unordered_map
中的每个键是否与当前键有特定的位运算关系。这种嵌套循环的复杂度是O(n^2),其中n是unordered_map
中元素的数量,这在n较大时会导致显著的性能下降。
【问题解决方案】:为了优化这个问题,我们可以避免两层嵌套循环,转而使用更有效的算法。考虑到您的问题涉及到位运算,我们可以利用位运算的性质来减少不必要的比较。
【提供代码】:以下是优化后的代码示例:
#include
#include
#include
using namespace std;
int countPairs(vector& nums) {
unordered_map freq;
for (int num : nums) {
freq[num]++;
}
int result = 0;
// 遍历map中的每个元素
for (auto& p1 : freq) {
int count = 0;
// 计算与当前数所有可能的位运算匹配的个数
for (int i = 0; i < (1 << 32); ++i) {
if ((i & p1.first) == p1.first) {
count++;
}
}
// 由于每个数都与自己匹配,需要减去1
result += (count - 1) * p1.second;
}
return result;
}
int main() {
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
vector nums(n);
for (int i = 0; i < n; ++i) {
cin >> nums[i];
}
cout << countPairs(nums) << endl;
}
return 0;
}
【代码运行方式】:您需要一个支持C++的编译器,如GCC或Clang。将上述代码保存为.cpp
文件,使用编译器编译并运行。
【代码预期运行结果】:如果您输入一组数字,代码将输出满足条件的数对数量。
【推荐相关链接】: