【发布时间】:2014-11-27 10:37:13
【问题描述】:
编辑:问题实际上是算法问题(感谢 molbdnilo 下面的回答)失败的情况是 O(N2) --> 二次的。下面的人实际上是在试图找到一个真正的最坏情况 O( N Log(N) ) 时间复杂度算法。
我接受了这个月的代码挑战。我花了大约一个小时才得到 100% 正确的 O(N Log(N)) 时间复杂度算法。
但正如您在下面看到的那样,我的性能提高了 75%,因为其中一项测试需要 10 倍的时间才能运行。我不明白为什么! 你能指出我的错误吗?
第 2 点包含我的解决方案的完整问题描述和完整报告(测试用例和时间安排)。
粗略地说,我一个接一个地添加每根绳索,并从添加的节点位置更新到根(祖先)的路径,并使用可以添加到每个祖先“下方/下方”的新最大权重。
代码如下:
// you can use includes, for example:
#include <algorithm>
#include <vector>
#include <map>
#include <iostream>
using namespace std;
// you can write to stdout for debugging purposes, e.g.
// cout << "this is a debug message" << endl;
struct node
{
int max_to_add;
int id;
node* mummy;
};
std::map< int, node* > nodes;
bool insertRope( int durability, int pos, int Id, int weight )
{
node* n = new node;
n->id = Id;
nodes[Id] = n;
if( pos == -1 )
{
n->max_to_add = durability - weight;
n->mummy = NULL;
if( n->max_to_add < 0 ) return false;
}
else
{
std::map< int, node* >::iterator it = nodes.find(pos);
if( it != nodes.end() )
{
node* parent = (*it).second;
n->mummy = parent;
n->max_to_add = std::min( ( parent->max_to_add - weight), (durability - weight) ) ;
if( n->max_to_add < 0 ) return false;
node* current = n;
while ( (current = current->mummy) != NULL )
{
current->max_to_add = current->max_to_add - weight;
if( current->max_to_add < 0 )
{
return false;
}
}
}
}
return true;
}
int solution(vector<int> &A, vector<int> &B, vector<int> &C) {
// write your code in C++11
for(int i = 0; i < A.size() ; ++i)
{
if( insertRope( A[i], C[i],i,B[i] ) == false ) {return i;}
}
return A.size();
}
int main()
{
/*static const int arrA[] = {4, 3, 1};
vector<int> vecA (arrA, arrA + sizeof(arrA) / sizeof(arrA[0]) );
static const int arrB[] = {2, 2, 1};
vector<int> vecB (arrB, arrB + sizeof(arrB) / sizeof(arrB[0]) );
static const int arrC[] = {-1, 0, 1};
vector<int> vecC (arrC, arrC + sizeof(arrC) / sizeof(arrC[0]) );
*/
static const int arrA[] = {5, 3, 6, 3, 3};
vector<int> vecA (arrA, arrA + sizeof(arrA) / sizeof(arrA[0]) );
static const int arrB[] = {2, 3, 1, 1, 2};
vector<int> vecB (arrB, arrB + sizeof(arrB) / sizeof(arrB[0]) );
static const int arrC[] = {-1, 0, -1, 0, 3};
vector<int> vecC (arrC, arrC + sizeof(arrC) / sizeof(arrC[0]) );
int sol = solution(vecA,vecB,vecC);
system("PAUSE");
return 0;
}
编辑 1: 根据 Rafid 的建议,我使用了 new[],效果更好,但我仍然遇到性能问题: https://codility.com/cert/view/certRT5YDP-W65HGPF28B5RN5AY/details
【问题讨论】:
-
你在什么平台上?我建议使用 callgrind 来查看您的瓶颈在哪里。在相当大的输入数据集(100k)上,这也会失败(性能方面),因此请尝试自己使用具有代表性的输入数据集。
-
我在 Windows 7 64 位上使用 VS2010。我不知道他们在什么平台上测试。 callgrind 在 Windows 上不可用?也许很困......
-
callgrind 在 Windows afaik 上不可用。 VerySleepy 将为您提供可能有用的信息。
-
我会在家里测试它,除非我可以绕过缺少的管理员权限并在此处安装它。 :)
-
我认为您在构建长线(没有分支)时会超时,因为为了调整
max_to_add,您每次插入时都会遍历所有节点(二次时间,IIRC) .
标签: c++ performance algorithm