【发布时间】:2018-12-30 23:36:24
【问题描述】:
说实话,我有点困惑。我正在解决经典算法问题之一。给定一个整数集合,找出是否有 2 个元素的和等于给定数字。
所以我实施了 2 个解决方案。
bool find1(std::vector<int>& V, int sum)
{
std::unordered_set<int> hashTable;
for (int i = 0; i < V.size(); ++i)
{
if (hashTable.find(V[i]) != hashTable.end())
{
return true;
}
hashTable.insert(sum - V[i]);
}
return false;
}
bool find2(std::vector<int>& V, int sum)
{
for (int i = 0; i < V.size() ; ++i)
{
if (std::binary_search(V.begin(), V.end(), sum - V[i]))
{
return true;
}
}
return false;
}
Find1 预计是一个线性算法(取决于桶的负载和散列函数的效率)。
Find2 预计为 NlogN,我们循环并为每次迭代进行二进制搜索。
实现这个功能后,我尝试在一个比较大的集合上测试这些算法的运行时间,结果让我很困惑..
int main()
{
std::vector<int> V(10000,0);
std::chrono::system_clock::time_point now1 = std::chrono::system_clock::now();
for (int i = 0; i < 100; ++i)
{
bool b = find1(V, 1000);
}
std::chrono::system_clock::time_point then1 = std::chrono::system_clock::now();
std::cout <<"Linear with hashing = "<< std::chrono::duration_cast<std::chrono::microseconds>(then1 - now1).count()<<std::endl;
std::chrono::system_clock::time_point now2 = std::chrono::system_clock::now();
std::sort(V.begin(), V.end());
for (int i = 0; i < 100; ++i)
{
bool b = find2(V, 1000);
}
std::chrono::system_clock::time_point then2 = std::chrono::system_clock::now();
std::cout <<"NlogN with binary_search = " <<std::chrono::duration_cast<std::chrono::microseconds>(then2 - now2).count() << std::endl;
system("pause");
}
在这里,我用 0 初始化 vector,以确保两个算法都运行最坏的情况。
程序的输出是:
Linear with hashing = 6759245
NlogN with binary_search = 4508025
这怎么可能?谁能给我解释一下?
【问题讨论】:
-
您不仅在
Find1中搜索元素,还插入了一个元素。此外,您还执行 IO 操作,这可能是一种开销。您是否尝试过在没有这些操作的情况下运行它? -
为什么在一个全为 0 的数组中搜索 1000 是二进制搜索的最坏情况?我希望它在发现数组中的最大值小于 1000 时立即终止。
-
@BluesSolo IO 操作不在计时范围内,因此它们不参与计算。
-
@NathanOliver 他之前的方法中有一个
std::cout << V[i] << std::endl;。显然它在一秒钟前被删除了。 -
V已经排序,所以std::sort(V.begin(), V.end());可能是O(N)。
标签: c++ algorithm sorting search time-complexity