【发布时间】:2019-09-01 06:25:13
【问题描述】:
假设有 n 个囚犯围成一圈站着。第一个犯人有一把刀,他用刀杀死了第二个犯人,然后把刀传给了第三个人,第三个人杀死了第四个犯人,然后把刀传给了第五个犯人。
重复这个循环,直到只剩下一个囚犯。请注意,囚犯们站成一圈,因此第一个囚犯在第 n 个囚犯旁边。返回最后一个囚犯的索引。
我尝试使用循环链表来实现该解决方案。这是我的代码
循环链表的结构是:-
struct Node
{
int Data;
Node *Next;
};
Node *Head = NULL;
这是我的 deleteByAddress() 和 main() 函数:-
inline void deleteByAddress(Node *delNode)
{
Node *n = Head;
if(Head == delNode)
{
while(n -> Next != Head)
{
n = n -> Next;
}
n -> Next = Head -> Next;
free(Head);
Head = n -> Next;
return ;
}
while(n -> Next != delNode)
{
n = n -> Next;
}
n -> Next = delNode -> Next;
delete delNode;
}
int main(void)
{
for(int i = 1 ; i <= 100 ; i++)
insertAtEnd(i);
Node *n = Head;
while(Head -> Next != Head)
{
deleteByAddress(n -> Next);
n = n -> Next;
}
cout << Head -> Data;
return 0;
}
上面的代码完美运行,并在 n = 100 时产生所需的输出,即 73。
有什么方法可以降低时间复杂度或使用更高效的数据结构来实现相同的问题。
【问题讨论】:
-
应用一致的缩进方案会帮助你自己和那些试图帮助你的人。 (我认为它实际上可能是一致的,但非常令人困惑的不寻常。请为每个
{缩进并为每个}取消缩进,而不仅仅是那些内部函数。) -
双链表?
-
Head在您显示的代码中似乎未定义。请升级到minimal reproducible example。 -
减少时间复杂度的方法是,在大多数情况下,挑战因超时原因而失败,而不是模拟和使用数学。幸运的是,它变成了单行。考虑索引并尝试确定如何找到那些在第一轮中幸存下来的索引。然后考虑第二轮。刀是怎么来的?这取决于什么?例如,对于 2 的幂,最后一个常设囚犯将始终是索引为 0 的那个。
-
感谢您展示
Head的声明、定义和初始化。但是请一路制作minimal reproducible example。
标签: c++ algorithm linked-list