方法1
首先扭转整个队列(不考虑21,22等),然后反转每个块(即, 21,22等)使用堆栈。这可以迭代完成。
这与句子问题(着名访谈问题)中的反向词类似。
(见摸索出以下示例与伪代码)
方法2)
如果你想绝对做递归,那么我会建议你使用一个队列作为辅助存储器,而不是叠加。
您将一个块插入辅助队列,递归地反转列表的其余部分,然后将这些元素排入主队列。
该代码将是这样的(handwavy伪)
StrangeReverse(Queue <T> q) {
Queue<T> aux;
// this removes first block from q, and places them in aux
while (elem_of_first_block(q)) {
aux.Enque(elem);
}
// Recursively reverse the rest of the q.
StrangeReverse(q);
// place the first block back in q, at the end.
// in the order they appeared originally.
while (aux.HasElements()) {
q.Enque(aux.Deque());
}
}
递归版本可以转换为迭代的,由具有队列的堆叠!您可以从每个块中创建一个队列,并将其堆叠起来。然后弹出堆栈,使用队列。
甲制定了示例方法的1
[11, 12, 21, 22, 43, 44]
颠倒该(使用堆栈或通过递归方法)
[44, 43, 22, 21, 12, 11]
立即反转每个块:
push 44, the 43.
Stack = [44, 43]. Queue = [22, 21, 12, 11]
现在Enque从堆栈中弹出
Stack = [], Queue = [22, 21, 12, 11, 43, 44]
push 22, 21
Stack = [22, 21], Queue = [12, 11, 43, 44]
Enque通过弹出堆栈。
Stack = [], Queue = [12, 11, 43, 44, 21, 22]
最终我们得到
[43, 44, 21, 22, 11, 12]
注:确定块,你可能需要在队列偷看方法。
伪方法的代码1
void StrangeReverse(Queue<T> q) {
Stack<T> s;
int count = q.Count();
if (count < 2) return;
for (i = 0; i < count; i++) {
T elem = q.Deque();
s.Push(elem);
}
while (s.HasElements()) {
T elem = s.Pop();
q.Enque(elem);
}
// Now the queue has been reversed,
// in the normal fashion.
ReverseBlocks(q);
}
void ReverseBlocks(Queue<T> q) {
int reversed = 0;
int count = q.Count();
while (reversed < count) {
reversed += ReverseSingleBlock(q);
}
}
int ReverseSingleBlock(Queue <T> q) {
Stack <T> s;
T prevElem = q.Deque();
s.Push(prevElem);
T curElem = q.Peek();
while(curElem == prevElem) {
s.Push(curElem);
q.Deque();
prevElem = curElem;
curElem = q.Peek();
}
int count = 0;
while(s.HasElements()) {
T elem = s.Pop();
q.Enque(elem);
count++;
}
return count;
}
22和23是不是不同的元素? – 2013-03-22 04:25:29
它必须是一个错字。 – 2013-03-22 04:27:11
@JavaNewb不,它们没有什么不同,因为比较器只查看本例中的第一个数字。 – Enzo 2013-03-22 04:27:29