Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Push, Pop, Range in constant time

I was asked this in an interview:

Design a data structure that allows all these operations in constant, O(1), time:

  • Push an element
  • Pop an element
  • Range of elements : Find the smallest range of interval of the current elements.
    Eg. Range of [1, 22, 44, 56, 99, 98, 56] is 98.

I designed this using a customized stack with two variables, max and min, but this doesn't work after Pop'ing a min or max element.

What I tried :

I used a stack with two extra variable max and min:

DS 
{
 top, //Top of the Stack 
 min, //Min till now
 max  //Max till now
}

Push(DS, elem)
  Push_Stack(DS.top, elem)
  if elem < DS.min
    DS.min = elem
  if elem > DS.max
    DS.max = elem

Range(DS)
 return DS.max - DS.min

Pop(DS)
  x = Pop_Stack(DS.top)
  if (x == DS.min)
    DS.min = Find_New_Min(DS.top) //This takes linear time using this approach
  if (x == DS.max)
    DS.max = Find_New_Max(DS.top)
like image 356
mohit Avatar asked Oct 13 '13 04:10

mohit


People also ask

Do the operations Push and Pop take O 1 time?

For all the standard stack operations (push, pop, isEmpty, size), the worst-case run-time complexity can be O(1).

What is the time complexity of a stack pop operation?

Time Complexities of operations on the stack: push(), pop(), isEmpty() and peek() all take O(1) time. We do not run any loop in any of these operations.

What is time complexity for push pop and peek operation of a stack?

Popping an element from a stack will take O(1) time complexity. Popping the last element in a stack will take O(n).

What is the time complexity of push () in C++?

Time Complexity: O (1) – push () calls push_back () from std::deque, which is a constant time operation. Hence, push () is also a constant time operation. pop () – Removes the top element. pop () removes the top element from the stack, reducing its size by one.

What does push () and pop () do in C++?

push () and pop () in Stack – C++ STL The Stack is a container of elements with three principal operations: push, which adds an element to the stack. pop, which removes the most recent inserted element from the stack, if there is any.

Why are push constants written in ranges?

Push constants are written in ranges. A important reason for that, is that you can have different push constants, at different ranges, in different stages. For example, you can reserve 64 bytes (1 glm::mat4) size on the vertex shader, and then start the pixel shader push constant from offset 64.

What is the difference between push () and pop ()?

Hence, push () is also a constant time operation. pop () – Removes the top element. pop () removes the top element from the stack, reducing its size by one. If there is any second element in the stack, then it becomes the top element after the pop () is being called.


2 Answers

Implement a "Stack" that includes a range function and uses three stacks internally.


The First internal stack will represent the 'real' stack of things being pushed and popped.

The second internal stack will only be pushed to if the new element is bigger than or equal to what is on top of it.

The third internal stack will only be pushed to if the new element is smaller than or equal to what is on top of it.


Now, whenever you need to calculate the range, just peek at the top of the second and third stacks and do some simple math.

Whenever an element needs to be popped off the 'real' stack, check to see if the element is also at the top of each of the other two stacks, if it is, pop it off those stacks as well.

Since you have to pop items off the main stack in the opposite order they came in, you won't ever miss anything in the two other stacks... meaning the top of the second and third internal stacks will always be the max and min.

like image 78
Byron Lo Avatar answered Oct 05 '22 11:10

Byron Lo


This is similar to Bryon Lo answer, but before he posted I commented same

Maintain 3 stacks

  • S1 your final stacks
  • S2 and S3 temporary stacks

Rest is self explanatory

  push(T value)
  {
    if (value <= min()) 
    {
        s2.push(value);
    }

    if(value >= max())
    {
        s3.push(value);
    }
    s1.push(value);
  }

 T pop() 
 {
    T value = s1.pop();
    if (value == min()) 
    {
        s2.pop();
    }
    return value;
  }

  T min() 
  {
    if (s2.isEmpty()) 
    {
        return MAX_VALUE;
    } 
    else {
        return s2.peek();
    }
  }

   T max() 
  {
    if (s3.isEmpty()) 
    {
        return MIN_VALUE;
    } 
    else 
    {
        return s3.peek();
    }
  }
like image 36
P0W Avatar answered Oct 05 '22 11:10

P0W