Java 在一堆整数中交换对?

Java 在一堆整数中交换对?,java,integer,stack,Java,Integer,Stack,我们被指派了这个任务 编写一个方法switchPairs,该方法将整数堆栈作为参数,并从堆栈底部开始切换连续的数字对 例: [1,2,3,4,5,6]变为[2,1,4,3,6,5] 但我们也被告知,我们只能使用一个队列作为辅助存储…我不明白这怎么可能?我们是否至少需要2个,因为我们要交换成对的数字,而您不能选择要弹出的堆栈索引?1)将堆栈中的所有值弹出到队列中 2) 对于队列中的每一对值,按相反顺序将该对推回堆栈 使用下面的注释,我们注意到将所有元素推到队列上并返回列表将颠倒顺序 然后,我们可以

我们被指派了这个任务

编写一个方法switchPairs,该方法将整数堆栈作为参数,并从堆栈底部开始切换连续的数字对

例: [1,2,3,4,5,6]变为[2,1,4,3,6,5]

但我们也被告知,我们只能使用一个队列作为辅助存储…我不明白这怎么可能?我们是否至少需要2个,因为我们要交换成对的数字,而您不能选择要弹出的堆栈索引?

1)将堆栈中的所有值弹出到队列中

2) 对于队列中的每一对值,按相反顺序将该对推回堆栈

使用下面的注释,我们注意到将所有元素推到队列上并返回列表将颠倒顺序

然后,我们可以再次将这些值推送到列表上,注意列表现在的顺序是正确的,并应用2

Stack bottom 1,2,3,4,5,6 top
Queue front 6,5,4,3,2,1 end
Stack bottom 6,5,4,3,2,1 top
Queue front 1,2,3,4,5,6 end
现在应用2)


好吧,你不需要一个以上的队列。您只需小心将元素插入队列的位置

下面是一个快速的演练:

  • 开始弹出堆栈中的元素
  • 弹出的第二个元素,要插入到先前弹出的元素前面
  • 完成后,按相反顺序迭代队列(使用Deque或按相反顺序对队列排序),将所有元素推入堆栈
下面是一段代码片段

public <T> Deque<T> switchPairs(final Deque<T> stack) {
    final Deque<T> result = new ArrayDeque<>();
    if(stack.size() % 2 != 0) {
        throw new IllegalArgumentException("I don't know how to handle odd sized lists.");
    }
    List<T> buffer = new LinkedList<>();
    int lastIndex = 0;
    while(!stack.isEmpty()) {
        buffer.add(stack.pop());
        buffer.add(lastIndex, stack.pop());
        lastIndex += 2;
    }
    for(final ListIterator<T> listIterator = buffer.listIterator(buffer.size()); listIterator.hasPrevious();) {
        result.push(listIterator.previous());
    }

    return result;
}
public-Deque开关对(最终Deque堆栈){
最终设计结果=新的ArrayDeque();
if(stack.size()%2!=0){
抛出新的IllegalArgumentException(“我不知道如何处理奇数大小的列表”);
}
列表缓冲区=新的LinkedList();
int lastIndex=0;
而(!stack.isEmpty()){
add(stack.pop());
add(lastIndex,stack.pop());
lastIndex+=2;
}
for(final ListIterator ListIterator=buffer.ListIterator(buffer.size());ListIterator.hasPrevious();){
push(listIterator.previous());
}
返回结果;
}
支持两端的操作。所以好好利用这一点

将项目从堆栈中弹出,然后交替地
addFirst
addLast
将它们添加到队列中。所以一堆
[1,2,3,4,5,6]
变成
[2,4,6,5,3,1]

现在,颠倒这个过程,从队列中移除元素并将它们推回到堆栈上。我们做的最后一个操作是
addLast
;因此,如果我们从
removeFirst
开始,它将有效地交换每对的顺序。(这一切都假定堆栈中的元素数为偶数)

可视化:

stack           deque
[1,2,3,4,5,6]   []
[1,2,3,4,5]     >[6]
[1,2,3,4]       [6,5]<
[1,2,3]         >[4,6,5]
[1,2]           [4,6,5,3]<
[1]             >[2,4,6,5,3]
[]              [2,4,6,5,3,1]<

[2]             <[4,6,5,3,1]
[2,1]           [4,6,5,3]>
[2,1,4]         <[6,5,3]
[2,1,4,3]       [6,5]>
[2,1,4,3,6]     <[5]
[2,1,4,3,6,5]   []>
stack-deque
[1,2,3,4,5,6]   []
[1,2,3,4,5]     >[6]
[1,2,3,4]       [6,5]<
[1,2,3]         >[4,6,5]
[1,2]           [4,6,5,3]<
[1]             >[2,4,6,5,3]
[]              [2,4,6,5,3,1]<
[2]             
[2,1,4]         
[2,1,4,3,6]     

我们知道一个关键事实:将堆栈中的所有元素移动到队列中,然后再移回到堆栈中,只需颠倒原始堆栈中元素的顺序即可。例如,[1,2,3,4]将产生[4,3,2,1]

我们有一种方法可以做到这一点:

1)弹出堆栈的所有元素并将其排入队列。

2)一次从队列中删除两个元素,并将其推送到堆栈中。根据我们的关键事实,我们知道这两个要素现在的顺序颠倒了。将这两个值添加回队列。

3)重复步骤2,直到所有对都循环通过。

4)删除队列中的所有元素并将其推送到堆栈中。我们几乎完成了——从我们的关键事实来看,我们知道这是我们想要的相反输出。

5)弹出堆栈中的所有元素并将其排队。移除所有元素并将其推回堆栈。这会使一切颠倒过来,我们得到了所需的输出。

这里是一个例子。假设我们从一个堆栈开始[1,2,3,4,5,6],其中1是堆栈的顶部

(Step 0) [1, 2, 3, 4, 5, 6] (Stack)

(Step 1) [6, 5, 4, 3, 2, 1] (Queue) (1 is beginning of queue)

(Step 2) [6, 5, 4, 3] (Queue) [2, 1] (Stack)

(Step 2) [1, 2, 6, 5, 4, 3] (Queue)

(Step 3) [1, 2, 6, 5] (Queue) [4, 3] (Stack)

(Step 3) [3, 4, 1, 2, 6, 5] (Queue)

(Step 3) [3, 4, 1, 2] (Queue) [6, 5] (Stack)

(Step 3) [5, 6, 3, 4, 1, 2] (Queue)

(Step 4) [5, 6, 3, 4, 1, 2] (Stack)

(Step 5) [2, 1, 4, 3, 6, 5] (Queue)

(Step 5) [2, 1, 4, 3, 6, 5] (Stack)

当然,这是假设我们只有基本的FIFO队列和后进先出堆栈可用(无法访问DEQUE或其他链接列表)。

我不理解你的最后一句话。你不能选择弹出的顺序,那又怎样?你只需要按正确的顺序将它们推回到堆栈上,这很容易做到,因为辅助存储是不受限制的。你能澄清一下你所说的不受限制是什么意思吗?我想我只能在我把它们从队列前面移走的时候推它们?我们这里说的是什么类型的“队列”?我假设对于一个赋值,这个队列是最基本的一个——FIFO,两端的操作,等等。如果它有比这个更多的特性(比如Deques),那么它会非常简单。不……它比那个稍微复杂一些。这样做会颠倒整个堆栈的顺序。例如,[1,2,3,4]将返回[3,4,1,2]@Makoto它必须是Java
队列
还是可以是Java
列表
?很抱歉--[1,2,3,4]不返回[3,4,1,2]。它应该返回[4,3,2,1],除非您在其中添加一些更聪明的步骤(将堆栈中的所有元素弹出到队列中,移除队列中的所有元素并将其放回堆栈只会反转这些元素)。这个过程已经解释过了——除了我已经详细阐述的要点之外,实际上没有太多需要解释的内容。此外,如果他们将其逐字复制到他们的程序中,他们将在奇数列表中受到伤害,并且这是一个很容易搜索的事实。至少根据我的代码,我的结果是不正确的……而且如果堆栈大于10,我得到的队列将停止在10?Java的
队列
(Step 0) [1, 2, 3, 4, 5, 6] (Stack)

(Step 1) [6, 5, 4, 3, 2, 1] (Queue) (1 is beginning of queue)

(Step 2) [6, 5, 4, 3] (Queue) [2, 1] (Stack)

(Step 2) [1, 2, 6, 5, 4, 3] (Queue)

(Step 3) [1, 2, 6, 5] (Queue) [4, 3] (Stack)

(Step 3) [3, 4, 1, 2, 6, 5] (Queue)

(Step 3) [3, 4, 1, 2] (Queue) [6, 5] (Stack)

(Step 3) [5, 6, 3, 4, 1, 2] (Queue)

(Step 4) [5, 6, 3, 4, 1, 2] (Stack)

(Step 5) [2, 1, 4, 3, 6, 5] (Queue)

(Step 5) [2, 1, 4, 3, 6, 5] (Stack)