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