Queue using two stacks, by Apple

Today's Daily Coding Problem:

This problem was asked by Apple.
Implement a queue using two stacks. Recall that a queue is a FIFO (first-in, first-out) data structure with the following methods: enqueue, which inserts an element into the queue, and dequeue, which removes it.

This is a very common technical interview question, including its variations, such as:

  • Implement a stack using two queues
  • Optimize for enqueue/push operation (O(1)-time)
  • Optimize for dequeue/pop operation (O(1)-time)
My implementation below optimizes it for the enqueue operation (in O(1)-time), while the dequeue will suffer a little bit on time (O(n)-time).
The idea is as follows:
  • On the enqueue operation, push to stack 1
  • On the dequeue, pop from stack 1 pushing to stack 2. Save the last element, which you'll return later. Then push all the elements back to stack 1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
namespace DailyCodingProblem
{
 class DailyCodingProblem11062018
 {
 private Stack[] stack = null;
 public DailyCodingProblem11062018()
 {
 stack = new Stack[2];
 stack[0] = new Stack();
 stack[1] = new Stack();
 }
 public void Enqueue(string item)
 {
 stack[0].Push(item);
 }
 public string Dequeue()
 {
 if (stack[0].Count == 0) return null;
 //Get, swap, remove
 string retVal = SwapStacksReturnLast(stack[0], stack[1], true);
 //Swap back, don't remove, ignore the result
 SwapStacksReturnLast(stack[1], stack[0], false);
 return retVal;
 }
 private string SwapStacksReturnLast(Stack from, Stack to, bool remove)
 {
 string retVal = "";
 while (from.Count> 0)
 {
 retVal = (string)from.Pop();
 if (!remove || from.Count> 0)
 to.Push(retVal);
 }
 return retVal;
 }
 }
}

Comments

  1. LeetCode also has a variant of this problem https://leetcode.com/problems/implement-queue-using-stacks

    The second invocation of SwapStacksReturnLast is not really necessary:

    class MyQueue {
    private:
    stack head;
    stack tail;

    void rebalance() {
    if (tail.empty()) {
    while (!head.empty()) {
    tail.push(head.top());
    head.pop();
    }
    }
    }
    public:

    /** Push element x to the back of queue. */
    void push(int x) {
    head.push(x);
    }

    /** Removes the element from in front of queue and returns that element. */
    int pop() {
    rebalance();
    int value = tail.top();
    tail.pop();
    return value;
    }

    /** Get the front element. */
    int peek() {
    rebalance();
    return tail.top();
    }

    /** Returns whether the queue is empty. */
    bool empty() {
    return head.empty() && tail.empty();
    }
    };

    We need to maintain an invariant that second stack always contains elements that can be popped in the "queue" order. To do this, we always push into the first stack, but when we pop, we check if second stack is not empty and if so pop the element out of it. In order to maintain the invariant, we just need to push all the elements from the first stack into the second stack when second stack becomes empty, since this transfer reverses the order of pushes and makes it "queue"-like.

    Cheers,
    Taras

    Reply Delete

Post a Comment

[フレーム]

Popular posts from this blog

Quasi FSM (Finite State Machine) problem + Vibe

Not really an FSM problem since the state isn't changing, it is just defined by the current input. Simply following the instructions should do it. Using VSCode IDE you can also engage the help of Cline or Copilot for a combo of coding and vibe coding, see below screenshot. Cheers, ACC. Process String with Special Operations I - LeetCode You are given a string  s  consisting of lowercase English letters and the special characters:  * ,  # , and  % . Build a new string  result  by processing  s  according to the following rules from left to right: If the letter is a  lowercase  English letter append it to  result . A  '*'   removes  the last character from  result , if it exists. A  '#'   duplicates  the current  result  and  appends  it to itself. A  '%'   reverses  the current  result . Return the final string  result  after processing all char...

Shortest Bridge – A BFS Story (with a Twist)

Here's another one from the Google 30 Days challenge on LeetCode — 934. Shortest Bridge . The goal? Given a 2D binary grid where two islands (groups of 1s) are separated by water (0s), flip the fewest number of 0s to 1s to connect them. Easy to describe. Sneaky to implement well. 🧭 My Approach My solution follows a two-phase Breadth-First Search (BFS) strategy: Find and mark one island : I start by scanning the grid until I find the first 1 , then use BFS to mark all connected land cells as 2 . I store their positions for later use. Bridge-building BFS : For each cell in the marked island, I run a BFS looking for the second island. Each BFS stops as soon as it hits a cell with value 1 . The minimum distance across all these searches gives the shortest bridge. πŸ” Code Snippet Here's the core logic simplified: public int ShortestBridge(int[][] grid) { // 1. Mark one island as '2' and gather its coordinates List<int> island = FindAndMark...

Classic Dynamic Programming IX

A bit of vibe code together with OpenAI O3. I asked O3 to just generate the sieve due to laziness. Sieve is used to calculate the first M primes (when I was using Miller-Rabin, was giving me TLE). The DP follows from that in a straightforward way: calculate the numbers from i..n-1, then n follows by calculating the min over all M primes. Notice that I made use of Goldbach's Conjecture as a way to optimize the code too. Goldbach's Conjecture estates that any even number greater than 2 is the sum of 2 primes. The conjecture is applied in the highlighted line. Cheers, ACC. PS: the prompt for the sieve was the following, again using Open AI O3 Advanced Reasoning: " give me a sieve to find the first M prime numbers in C#. The code should produce a List<int> with the first M primes " Minimum Number of Primes to Sum to Target - LeetCode You are given two integers  n  and  m . You have to select a multiset of  prime numbers  from the  first   m  pri...