在堆栈中间找到元素

时间:2011-09-18 11:31:28

标签: c algorithm data-structures recursion

我在一次采访中被问到这个问题。问题是我会得到一个堆栈,并且必须在堆栈的中间位置找到元素。“top”索引不可用(这样你就不会弹出()top / 2次并返回答案)。假设当pop()返回-1时你将到达堆栈的底部。不要使用任何其他数据结构。

例如:

stack   index
----- 
 2    nth element
 3
 99
 .
 1    n/2 th element
 .
 -1   bottom of the stack(0th index)

答案:1(我的意思不是中位数。找到中间位置的元素)

递归是唯一的方法吗?

谢谢,

PSY

6 个答案:

答案 0 :(得分:13)

遍历堆栈,计算深度,并在返回途中返回相应的元素。

int middle(stack* s, int n, int* depth) {
  if (stack_empty(s)) {
    *depth = n;
    return 0; //return something, doesn't matter..
  }
  int val = stack_pop(s);
  int res = middle(s, n+1, depth);
  stack_push(s, val);
  if (n == *depth/2)
    return val;
  return res;
}

int depth;
middle(&stack, 0, &depth);

注意:是的,递归是唯一的方法。不知道堆栈的深度意味着你必须将这些值存储在某个地方。

答案 1 :(得分:6)

递归绝不是唯一的方法;)

但是,递归为您提供了隐含的附加堆栈(即函数参数和局部变量),并且看起来您需要一些额外的存储来存储遍历的元素,在这种情况下,看起来递归可能是给定的唯一方法那个约束。

答案 2 :(得分:0)

这是一个解决方案:取两个指针,一次推进其中一个步骤(快速),另一个一次只推进一步(慢速)。如果快速到达底部,则返回指向中间索引的慢速指针。不需要递归。

int * slow = stack;
int * fast = stack;
while(1) {
    if(STACK_BOTTOM(fast)) return slow;
    fast--;
    if(STACK_BOTTOM(fast)) return slow;
    slow--;
    fast--;
}

答案 3 :(得分:0)

递归似乎是唯一的方法。如果在弹出过程中尝试使用快速和慢速指针概念,则需要将值存储在某处并且违反不需要其他数据结构的要求。

答案 4 :(得分:0)

此问题标有c,因此对于c编程语言,我同意递归是唯一的方法。但是,如果支持第一类匿名函数,则可以在不递归的情况下解决它。一些伪代码(使用Haskell的lambda语法):

n = 0
f = \x -> 0        # constant function that always returns 0

while (not stack_empty) do
    x = pop
    n = n+1
    f = \a -> if (a == n) then x else f(a)

middle = f(n/2)    # middle of stack

# stack is empty, rebuilt it up to middle if required 
for x in (n .. n/2) do push(f(x))

请注意:在while循环期间,f没有(递归)调用。 else分支中的f(a)仅用于构造一个新的(!)函数,该函数再次被称为f

假设堆栈有3个元素10,20,30(从下到上)这基本上构造了lambda

(\a -> if a==1
       then 30
       else (\b -> if b==2
                   then 20
                   else (\c -> if c==3
                                  then 10
                                  else (\d -> 0)(c)
                        )
                        (b)
            )
            (a)
)

或更具可读性

f(x) = if x==1 then 30 else (if x==2 then 20 else (if x==3 then 10 else 0)) 

答案 5 :(得分:0)

“......不要使用任何其他数据结构。”

然后该任务无法解决,因为您需要一些存储弹出数据的位置。你需要另一个用于递归的堆栈,它也是一个数据结构。禁止任何数据结构并允许递归是没有意义的。