Python 在虚拟无限列表中查找元素

Python 在虚拟无限列表中查找元素,python,algorithm,math,implementation,Python,Algorithm,Math,Implementation,我试图解决这个问题: 列表初始化为[“Sheldon”、“Leonard”、“Penny”、“Rajesh”、“Howard”],然后进行一系列操作。在每个操作中,列表的第一个元素被移动到列表的末尾并复制。例如,在第一个操作中,列表变成[“Leonard”、“Penny”、“Rajesh”、“Howard”、“Sheldon”、“Sheldon”](移动和复制“Sheldon”);在第二个操作中,它变成[“Penny”、“Rajesh”、“Howard”、“Sheldon”、“Sheldon”、

我试图解决这个问题:

列表初始化为
[“Sheldon”、“Leonard”、“Penny”、“Rajesh”、“Howard”]
,然后进行一系列操作。在每个操作中,列表的第一个元素被移动到列表的末尾并复制。例如,在第一个操作中,列表变成
[“Leonard”、“Penny”、“Rajesh”、“Howard”、“Sheldon”、“Sheldon”]
(移动和复制
“Sheldon”
);在第二个操作中,它变成
[“Penny”、“Rajesh”、“Howard”、“Sheldon”、“Sheldon”、“Leonard”、“Leonard”]
(移动并复制“Leonard”);等。给定正整数n,查找在第n次操作中移动和复制的字符串。[摘自]

我已经写了一个有效的解决方案,但是当n很大时,它太慢了:


我如何才能更快地完成此操作?

您将无法避免计算列表,但也许您可以让它变得更简单:

每个周期(谢尔顿再次成为第一个)列表的长度都会翻倍,因此看起来如下:

1次循环后:SSLLPPRRHH

2次循环后:SSSSLLPPRRRRHHHH

他们喝可乐的次数是5*((2**n)-1),其中n是循环次数

因此,您可以计算最接近结束周期的列表状态。 例如。 可乐50号:

5*((2**3))=40意味着在40杯可乐之后,谢尔顿是下一位

然后,您可以使用任务中描述的算法,并获取行中的最后一个算法


希望这有帮助。

这里有一个解决方案,它在
O(log(input/len(l))
中运行,而不进行任何实际计算(无列表操作):


说明:每次向后推整个列表时,列表长度将精确地增加
len(l)x2^i
。但你必须先弄清楚这种情况发生了多少次。这就是while正在做的事情(这就是
n=n-len(l)*(2**i)
正在做的事情)。当它意识到将发生附加双重列表的
i
次时,while停止。最后,在计算出
i
之后,您必须计算索引。但是,在出现的第个列表中,每个元素都被复制了
2^i
次,因此您必须通过
2**i
来划分数字。一个小细节是,对于索引,您必须减去
1
,因为Python中的列表是0索引的,而您的输入是1索引的。

正如@khelwood所说,您可以推断出需要将列表加倍多少次

要理解这一点,请注意,如果您从5个人的列表开始,并执行迭代的5个步骤,那么您将按照与之前相同的顺序对每个人执行两次

我不是100%确定你对第n个位置的意思,因为它一直在移动,但是如果你指的是在n次迭代后在前面的那个人,求出满足条件的最大整数I

5*2^i<n 

5*2^i您可以在不实际生成列表的情况下找出答案。将每个名称加倍一次将使列表的长度加倍。您可以计算出需要将列表加倍多少次,然后推断出此时列表的结构。@khelwood您能详细说明一下吗。@Aman您是在找人帮您解决这个问题吗?凯尔伍德给了你一个巨大的提示,如果你想自己解决它的话,这个提示应该会对你有所帮助。@Code徒弟,从那时起,我一直在遵循凯尔伍德的提示,并试图解决。。我只是一个初学者,这就是为什么花时间学习的原因me@Aman即使不是初学者,解决问题也需要时间。我建议你阅读《如何回答问题》。请注意,您的建议避免了计算整个列表。你可以运用一些数学知识来尽可能多地提前完成周期。我建议你欣赏一个比你的更有效的解决方案。我知道它并没有写出来,但老实说,读了你的问题几乎让我大吃一惊,所以不要谈论写作
l = ['Sheldon','Leonard','Penny','Rajesh','Howard']
n = int(input()) # taking input from user to print the name of the person
                 # standing at that position

i = 0
while n>(len(l)*2**i):
    n = n - len(l)* (2**i)
    i = i + 1

index = int((n-1)/(2**i ))

print(l[index])
5*2^i<n