将列表的第一个元素移到末尾

10

有没有一种聪明的方法来做到这一点?我最好的方法是:

object next = list.get(0) ;
list.remove(0) ;
list.add(next) ;

如果不行的话,是否有任何类型的集合可以使这更容易?我不喜欢需要临时对象来存储我想要移动的元素...

编辑:我已经用我的代码测试了下面列出的建议:

    long starttime = System.nanoTime() ;
    for (int i = 0; i < ntours; i++){
        profit += retrieveGroupsWillPlay(groups, ngroups, limit) ;
    }
    long endtime = System.nanoTime() ;
    System.out.println("Timing: " + (endtime - starttime)) ;
    System.out.println("Profit: " + profit) ;

这是结果:(利润:15,确保结果对我的代码正确)
代码:

private static int retrieveGroupsWillPlay(ArrayList<Integer> queue,int ngroups, int limit) { 
    int peopleWillPlay = 0 ;
    for (int i = 0; i < ngroups; i++){
        int nextGroup = queue.get(0) ;
        if(limit >= peopleWillPlay + nextGroup) {
            peopleWillPlay += nextGroup ;
            queue.add(nextGroup) ;
            queue.remove(0) ;
        }
        else break ;
    }
    return peopleWillPlay ;
}

结果:

Timing: 23326
Profit: 15
Timing: 22171
Profit: 15
Timing: 22156
Profit: 15
Timing: 22944
Profit: 15
Timing: 22240
Profit: 15
Timing: 21769
Profit: 15
Timing: 21866
Profit: 15
Timing: 22341
Profit: 15
Timing: 24049
Profit: 15
Timing: 22420
Profit: 15

代码:

private static int retrieveGroupsWillPlay(ArrayList<Integer> queue,int ngroups, int limit) { 
    int peopleWillPlay = 0 ;
    for (int i = 0; i < ngroups; i++){
        int nextGroup = queue.get(0) ;
        if(limit >= peopleWillPlay + nextGroup) {
            peopleWillPlay += nextGroup ;
            Collections.rotate(queue, -1) ;
        }
        else break ;
    }
    return peopleWillPlay ;
}

结果:

Timing: 92101
Profit: 15
Timing: 87137
Profit: 15
Timing: 84531
Profit: 15
Timing: 105919
Profit: 15
Timing: 77019
Profit: 15
Timing: 84805
Profit: 15
Timing: 93393
Profit: 15
Timing: 77079
Profit: 15
Timing: 84315
Profit: 15
Timing: 107002
Profit: 15

代码:

private static int retrieveGroupsWillPlay(ArrayList<Integer> queue,int ngroups, int limit) { 
    int peopleWillPlay = 0 ;
    for (int i = 0; i < ngroups; i++){
        int nextGroup = queue.get(0) ;
        if(limit >= peopleWillPlay + nextGroup) {
            peopleWillPlay += nextGroup ;
            queue.add(queue.remove(0)) ;
        }
        else break ;
    }
    return peopleWillPlay ;
}

结果:

Timing: 28079
Profit: 15
Timing: 28994
Profit: 15
Timing: 29525
Profit: 15
Timing: 22240
Profit: 15
Timing: 38326
Profit: 15
Timing: 33742
Profit: 15
Timing: 21500
Profit: 15
Timing: 22714
Profit: 15
Timing: 20939
Profit: 15
Timing: 30157
Profit: 15

代码:

private static int retrieveGroupsWillPlay(LinkedList<Integer> queue,int ngroups, int limit) { 
    int peopleWillPlay = 0 ;
    for (int i = 0; i < ngroups; i++){
        int nextGroup = queue.get(0) ;
        if(limit >= peopleWillPlay + nextGroup) {
            peopleWillPlay += nextGroup ;
            queue.addLast(queue.removeFirst()) ;
        }
        else break ;
    }
    return peopleWillPlay ;
}

结果:

Timing: 31104
Profit: 15
Timing: 42332
Profit: 15
Timing: 36443
Profit: 15
Timing: 31840
Profit: 15
Timing: 31387
Profit: 15
Timing: 32102
Profit: 15
Timing: 31347
Profit: 15
Timing: 30666
Profit: 15
Timing: 32781
Profit: 15
Timing: 32464
Profit: 15

代码:

private static int retrieveGroupsWillPlay(LinkedList<Integer> queue,int ngroups, int limit) { 
    int peopleWillPlay = 0 ;
    for (int i = 0; i < ngroups; i++){
        int nextGroup = queue.get(0) ;
        if(limit >= peopleWillPlay + nextGroup) {
            peopleWillPlay += nextGroup ;
            queue.offer(queue.poll()) ;
        }
        else break ;
    }
    return peopleWillPlay ;
}

结果:

Timing: 35389
Profit: 15
Timing: 34849
Profit: 15
Timing: 43606
Profit: 15
Timing: 41796
Profit: 15
Timing: 51122
Profit: 15
Timing: 59302
Profit: 15
Timing: 32340
Profit: 15
Timing: 35654
Profit: 15
Timing: 34586
Profit: 15
Timing: 35479
Profit: 15 

3
更好的结构用于做什么?你想要达成什么目标?另外,是哪种类型的列表?ArrayList还是LinkedList?性能可能会有所不同... - pcalcao
6个回答

25

您可以使用Collections.rotate来实现:

Collections.rotate(list, -1);

13

我不太确定你想做什么,但是我来试试:

如果你正在使用类似于 ArrayList 的东西,可以这样做:

list.add(list.remove(0));

请记住,从ArrayList中remove的时间复杂度为线性时间,即O(N),因此极其低效。

如果您可以选择列表类型,您可能想要一个实现了Dequeue接口的LinkedList,这样它将允许您执行以下操作:

list.offer(list.poll());

“offer”和“poll”均在常数时间内完成操作。

如果您想使用Collections类中的内置功能,您可以按照@dasblinkenlight的建议使用Collections.rotate(list, -1);(这里为了完整性而添加)。


5
您不需要一个临时变量,只需写入以下内容:

list.add(list.remove(0));

1
明显的答案是:

list.add(list.remove(0))

我认为最优雅的方法是:
你还可以使用以下方式:
但这将改变另一个元素的位置(即最后一个元素)。你也可以使用Collections.rotate(list,-1),但旋转列表可能意味着移动其所有元素(我猜这取决于List的实现),这可能不太高效。

我不确定,但是Collections.rotate的行为可能会因列表类型而异,如果它是一个链接列表,那么它只会将第一个元素链接到末尾。 - elaich

1

0

你也可以使用 LinkedList#addLast() 方法。

list.add(next) ;     
list.addLast(list.removeFirst());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接