我需要选择正确的数据结构以进行锻炼的帮助。
对于输入,我得到了应该执行的操作数( t ),并且在该索引的自然数序列后以空格分隔。因此,例如:
3 1 2 3
这意味着将在序列{1,2,3}上执行3个操作。
还定义了一个指针,用于显示当前位置。我应按该顺序执行的操作是:
R- >删除索引 PTR + 1 上的元素 c 并将 PTR 向前移动 c 次 __
X- >在元素 c 之后插入,该元素位于索引 PTR上 (因此在 PTR + 1 上插入),元素 c的 值为 c-1, 并且当然将 PTR 向前移动 c 次。
我的工作是找到执行操作后结束序列 [R 和 X 牛逼 倍,这样,如果它的元素 甚至 然后执行 [R ,否则做 X 。在开始时, PTR 显示第一个元素(如果存在),并且应该全部处于循环中。
对于发布后开始的给定示例, 输出 应为:
0 0 3 1
我知道这听起来可能令人困惑,所以让我向您展示如何逐步进行。
t = 1 开始顺序:1 2 3 实际位置: PTR- > 1 运算: X , c = 1 结束顺序:1 0 2 3 结束位置:PTR-> 0 t = 2 开始顺序:1 0 2 3 实际位置: PTR- > 0 运算: R , c = 2 结束顺序:1 0 3 结束位置:PTR-> 1 t = 3 开始顺序:1 0 3 实际位置: PTR- > 1 运算: X , c = 1 结束顺序:1 0 0 3 结束位置:PTR-> 0
t = 1
开始顺序:1 2 3 实际位置: PTR- > 1 运算: X , c = 1 结束顺序:1 0 2 3 结束位置:PTR-> 0
开始顺序:1 2 3
实际位置: PTR- > 1
运算: X , c = 1
结束顺序:1 0 2 3
结束位置:PTR-> 0
t = 2
开始顺序:1 0 2 3 实际位置: PTR- > 0 运算: R , c = 2 结束顺序:1 0 3 结束位置:PTR-> 1
开始顺序:1 0 2 3
实际位置: PTR- > 0
运算: R , c = 2
结束顺序:1 0 3
结束位置:PTR-> 1
t = 3
开始顺序:1 0 3 实际位置: PTR- > 1 运算: X , c = 1 结束顺序:1 0 0 3 结束位置:PTR-> 0
开始顺序:1 0 3
结束顺序:1 0 0 3
解决方案是从 PTR 正确的方向开始。因此输出应为:0 0 3 1
至于限制:
C序列的起始长度最大为10 ^ 7
t 操作次数,最多10 ^ 7
将 PTR 右移最多10 ^ 9次
我创建了基于循环链表的算法。可行,但是对于某些测试来说太慢了。如果有人可以帮助我找到最佳的数据结构,我将不胜感激。
我的老师也暗示我应该使用 二进制列表 ,但是老实说,我在互联网上找不到任何关于此结构的信息!也许有人也知道这件事,然后告诉我在哪里可以找到有关它的信息?我会很感激的。
使用圆形双向链表。它具有O(1)插入和删除。(也许这就是您的讲师所指的“二进制列表”。)
有趣的事实:您可以使用带有XOR技巧的代码来减少双链表的内存使用率。由于更好的缓存行为,较低的内存利用率将意味着较大列表的速度更快。在XOR链接列表上还有一个SOQ&A,详细列出了它的一些缺点。