Sheldon, Leonard, Penny, Rajesh and Howard are in the queue for a "Double Cola" drink vending machine; there are no other people in the queue. The first one in the queue (Sheldon) buys a can, drinks it and doubles! The resulting two Sheldons go to the end of the queue. Then the next in the queue (Leonard) buys a can, drinks it and gets to the end of the queue as two Leonards, and so on.javascript
For example, Penny drinks the third can of cola and the queue will look like this:java
Rajesh, Howard, Sheldon, Sheldon, Leonard, Leonard, Penny, Penny
数组Write a program that will return the name of a man who will drink the n-th cola.this
Note that in the very beginning the queue looks like that:code
Sheldon, Leonard, Penny, Rajesh, Howard
队列
题目: 有一个队列Sheldon, Leonard, Penny, Rajesh, Howard
,排到的人,再次排到队尾,并将本身变成双倍。若给了一个队列names,排到的第r我的是谁?(题目比较绕,不知道该怎么描述?)ip
// 初始队列, 第一轮 ["Sheldon", "Leonard", "Penny", "Rajesh", "Howard"] // Sheldon排过队以后,从新到队尾,并将本身复制了一份 ["Leonard", "Penny", "Rajesh", "Howard", "Sheldon", "Sheldon"] // ... // 第二轮,队列以下 ["Sheldon", "Sheldon", "Leonard", "Leonard", "Penny", "Penny", "Rajesh", "Rajesh", "Howard", "Howard"] // 第三轮,队列以下 ["Sheldon", "Sheldon", "Sheldon", "Sheldon", "Leonard", "Leonard", "Leonard", "Leonard", "Penny", "Penny", "Penny", "Penny", "Rajesh", "Rajesh", "Rajesh", "Rajesh", "Howard", "Howard", "Howard", "Howard"]
队列每轮事后,队列中的人数将变为原来的二倍。若初始队列的长度为len,第r人位于第m轮get
第一轮:n=1,sum = len
第二轮:n=2,sum = len + len * 2
第三轮:n=4,sum = len + len * 2 + len * 4
...
第m轮:n=2^m, sum = len + len * 2 + …… + len * n
it
则,第r我的在第m轮的排名为:x = r + len * n - sum
io
则,第r我的的名字在初始队列中排名为t(数组下标为t-1),则:(t-1) * n < x <= t * n
因此,t = Math.ceil( x / n )
最后,代码整理以下:
function whoIsNext(names, r){ var len = names.length; var sum = names.length; var n = 1; while(sum < r) { n *= 2; sum += len * n; } return names[Math.ceil((r + len * n - sum) / n) - 1] }
function whoIsNext(names, r) { var l = names.length; while (r >= l) { r -= l; l *= 2; } return names[Math.ceil(names.length * r / l)-1]; }
两个方法一个用加法,一个用减法,得出最后一轮的人数。我的也以为 减法 更 clever 一点 ?