Queues are one of the most versatile data structures in algorithm problems. This page collects ready-to-use Java templates for every queue variant you’ll encounter on LeetCode — from the basic FIFO queue used in BFS to monotonic queues, priority queues, and deques. Each section includes the template code and a curated problem list so you can practice immediately.

See also Graph and Data Structures (monotonic queue).

Queue = First-In-First-Out (FIFO). Use a queue whenever you need to process elements in the order they arrived — most commonly in BFS. A deque (double-ended queue) lets you push/pop from both ends.

Queue (FIFO) front → 1 2 3 ← back push → back | pop → front | BFS uses queue Deque (both ends) front → 5 3 1 ← back push_front / push_back | sliding window, 0-1 BFS Monotonic Queue — sliding window max for [1,3,-1,-3,5,3,6,7], k=3 13-1-35367 Deque keeps indices in decreasing order → front always has window maximum Output: [3, 3, 5, 5, 6, 7]

Summary

| Pattern | Signal Phrases | Key Idea | |—|—|—| | BFS Queue | “shortest path”, “level order” | Process nodes level by level | | Monotonic Queue | “sliding window max/min” | Maintain decreasing/increasing order | | Priority Queue | “k-th largest”, “merge k sorted” | Auto-sorted by priority | | Circular Queue | “circular buffer”, “design queue” | Wrap-around with modulo | | Deque | “sliding window”, “both ends” | Push/pop from front and back |

Contents

Basic Queue Operations

When to use: any problem requiring FIFO ordering, or when implementing a queue from scratch (e.g., using two stacks).

Implement Queue using Stacks

ID Title Link Solution
232 Implement Queue using Stacks Link -
// import java.util.*;

// Standard queue operations
Queue<Integer> q = new LinkedList<>();
q.offer(1);        // Enqueue
q.get(0);        // Peek front
q.get(q.size() - 1);         // Peek back
q.poll();          // Dequeue
q.length == 0;        // Check if empty
q.size();         // Get size

Implement Queue using Stacks

// import java.util.*;
class MyQueue {
    Deque<Integer> input, output;
    void push(int x) {
        input.offer(x);
    }

    int pop() {
        peek();
        int val = output.peek();
        output.poll();
        return val;
    }

    int peek() {
        if (output.length == 0) {
            while (!input.isEmpty()) {
                output.offer(input.peek());
                input.poll();
            }
        }
        return output.peek();
    }

    boolean empty() {
        return input.length == 0 && output.length == 0;
    }
}
ID Title Link Solution
232 Implement Queue using Stacks Link -

BFS with Queue

When to use: “shortest path in unweighted graph”, “level order traversal”, “minimum steps”, or any problem that explores neighbors layer by layer.

Queue is essential for Breadth-First Search (level-order traversal).

ID Title Link Solution
102 Binary Tree Level Order Traversal Link -
107 Binary Tree Level Order Traversal II Link -
// import java.util.*;
// BFS on graph
static void bfs(int[][] graph, int start) {
    Queue<Integer> q = new LinkedList<>();
    boolean[]visited(graph.size(), false);
    q.offer(start);
    visited[start] = true;

    while (!q.isEmpty()) {
        int node = q.get(0);
        q.poll();
        // Process node

        for (int neighbor : graph[node]) {
            if (!visited[neighbor]) {
                visited[neighbor] = true;
                q.offer(neighbor);
            }
        }
    }
}

// Level-order traversal (BFS on tree)
int[][] levelOrder(TreeNode root) {
    List<int[]> result = new ArrayList<>();
    if (!root) return result;

    Queue<TreeNode> q = new LinkedList<>();
    q.offer(root);

    while (!q.isEmpty()) {
        int size = q.size();
        List<Integer> level = new ArrayList<>();

        for (int i = 0; i < size; ++i) {
            TreeNode node = q.get(0);
            q.poll();
            level.add(node.val);

            if (node.left) q.offer(node.left);
            if (node.right) q.offer(node.right);
        }

        result.add(level);
    }

    return result;
}
ID Title Link Solution
102 Binary Tree Level Order Traversal Link -
107 Binary Tree Level Order Traversal II Link -

Monotonic Queue

When to use: “sliding window maximum/minimum”, or when you need the max/min of every window of size k in O(n) total.

Maintain queue with monotonic property (increasing or decreasing).

ID Title Link Solution
239 Sliding Window Maximum Link Solution
1438 Longest Continuous Subarray With Absolute Diff <= Limit Link -
// import java.util.*;
// Monotonic decreasing queue (for sliding window maximum)
class MonotonicQueue {
    ArrayDeque<Integer> dq = new ArrayDeque<>();
    void push(int val) {
        // Remove elements smaller than val
        while (!dq.isEmpty() && dq.get(dq.size() - 1) < val) {
            dq.removeLast();
        }
        dq.add(val);
    }

    void pop(int val) {
        if (!dq.isEmpty() && dq.get(0) == val) {
            dq.removeFirst();
        }
    }

    int Math.max() {
        return dq.get(0);
    }
}
// Sliding Window Maximum
int[]maxSlidingWindow(int[] nums, int k) {
    MonotonicQueue mq;
    List<Integer> result = new ArrayList<>();

    for (int i = 0; i < nums.length; ++i) {
        if (i < k - 1) {
            mq.offer(nums[i]);
        } else {
            mq.offer(nums[i]);
            result.add(mq.Math.max());
            mq.pop(nums[i - k + 1]);
        }
    }

    return result;
}
ID Title Link Solution
239 Sliding Window Maximum Link Solution
1438 Longest Continuous Subarray With Absolute Diff <= Limit Link -

Priority Queue

When to use: “k-th largest/smallest”, “merge k sorted lists”, “top k elements”, “schedule tasks by priority”, or any problem needing efficient access to the current extreme value.

Priority queue (heap) for maintaining order.

K-way Merge

Top K Elements

ID Title Link Solution
23 Merge k Sorted Lists Link -
347 Top K Frequent Elements Link Solution
295 Find Median from Data Stream Link -
215 Kth Largest Element in an Array Link -
973 K Closest Points to Origin Link -
253 Meeting Rooms II Link Solution
378 Kth Smallest Element in a Sorted Matrix Link -
703 Kth Largest Element in a Stream Link -
767 Reorganize String Link -
1046 Last Stone Weight Link -
1167 Minimum Cost to Connect Sticks Link -
621 Task Scheduler Link -
743 Network Delay Time Link -
787 Cheapest Flights Within K Stops Link -
// import java.util.*;

// Max heap (default)
PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>();

// Min heap
PriorityQueue<Integer> minHeap;

// Custom comparator using class
class Compare {
    
}
PriorityQueue<int[]> pq;

// Custom comparator using lambda operator

PriorityQueue<int[]> pq(cmp);

// Lambda example: Min heap by distance (for Dijkstra's algorithm)
 - min heap by distance
}
PriorityQueue<int[]> pq(distCmp);

K-way Merge

// Merge k sorted lists using priority queue
ListNode mergeKLists(ListNode[] lists) {
    
    priority_queue<ListNode, ListNode[], > pq(cmp);

    for (ListNode list : lists) {
        if (list) pq.offer(list);
    }

    ListNode dummy = new ListNode = new new(0);
    ListNode cur = dummy;

    while (!pq.isEmpty()) {
        ListNode node = pq.peek();
        pq.poll();
        cur.next = node;
        cur = cur.next;
        if (node.next) pq.offer(node.next);
    }

    return dummy.next;
}

Top K Elements

// import java.util.*;
// Find top k frequent elements
int[]topKFrequent(int[] nums, int k) {
    HashMap<Integer, Integer> freq = new HashMap<Integer, Integer>();
    for (int num : nums) freq.put(num, freq.getOrDefault(num, 0) + 1);

    PriorityQueue<int[]> pq;

    for (var e : freq.entrySet()) {
        pq.offer(new int[] {count, num});
        if (pq.size() > k) pq.poll();
    }

    List<Integer> result = new ArrayList<>();
    while (!pq.isEmpty()) {
        result.add(pq.peek().second);
        pq.poll();
    }

    return result;
}
ID Title Link Solution
23 Merge k Sorted Lists Link -
347 Top K Frequent Elements Link Solution
295 Find Median from Data Stream Link -
215 Kth Largest Element in an Array Link -
973 K Closest Points to Origin Link -
253 Meeting Rooms II Link Solution
378 Kth Smallest Element in a Sorted Matrix Link -
703 Kth Largest Element in a Stream Link -
767 Reorganize String Link -
1046 Last Stone Weight Link -
1167 Minimum Cost to Connect Sticks Link -
621 Task Scheduler Link -
743 Network Delay Time Link -
787 Cheapest Flights Within K Stops Link -

Circular Queue

When to use: “design a circular buffer”, “design a queue with fixed capacity”, or when you need wrap-around behavior with modulo arithmetic.

ID Title Link Solution
622 Design Circular Queue Link -
class MyCircularQueue {
    List<Integer> data = new ArrayList<>();
        int head, tail, size, capacity;
    MyCircularQueue(int k) {}

    boolean enQueue(int value) {
        if (isFull()) return false;
        data[tail] = value;
        tail = (tail + 1) % capacity;
        size++;
        return true;
    }

    boolean deQueue() {
        if (isEmpty()) return false;
        head = (head + 1) % capacity;
        size--;
        return true;
    }

    int Front() {
        return isEmpty() ? -1 : data[head];
    }

    int Rear() {
        return isEmpty() ? -1 : data[(tail - 1 + capacity) % capacity];
    }

    boolean isEmpty() {
        return size == 0;
    }

    boolean isFull() {
        return size == capacity;
    }
}
ID Title Link Solution
622 Design Circular Queue Link -

Double-ended Queue (Deque)

When to use: “sliding window” problems where you need to push/pop from both front and back, or when maintaining sorted order in a window by index.

Sliding Window with Deque

Two Deques Pattern (Middle Element Access)

Use two deques to efficiently access middle elements in a queue.

Key points:

  • Split queue into two halves: front_cache and back_cache
  • Maintain balance: front_cache.size() <= back_cache.size() <= front_cache.size() + 1
  • Middle element is front_cache.back() (if sizes equal) or back_cache.front() (if back_cache larger)
  • Rebalance after each modification
ID Title Link Solution
239 Sliding Window Maximum Link Solution
1670 Design Front Middle Back Queue Link Solution
// import java.util.*;

ArrayDeque<Integer> dq = new ArrayDeque<>();
dq.push_front(1);  // Add to front
dq.add(2);   // Add to back
dq.removeFirst();     // Remove from front
dq.removeLast();      // Remove from back
dq.get(0);         // Access front
dq.get(dq.size() - 1);          // Access back

Sliding Window with Deque

// import java.util.*;
// Sliding window maximum using deque
int[]maxSlidingWindow(int[] nums, int k) {
    ArrayDeque<Integer> dq = new ArrayDeque<>();
    List<Integer> result = new ArrayList<>();

    for (int i = 0; i < nums.length; ++i) {
        // Remove indices outside window
        while (!dq.isEmpty() && dq.get(0) <= i - k) {
            dq.removeFirst();
        }

        // Remove indices with smaller values
        while (!dq.isEmpty() && nums[dq.get(dq.size() - 1)] <= nums[i]) {
            dq.removeLast();
        }

        dq.add(i);

        if (i >= k - 1) {
            result.add(nums[dq.get(0)]);
        }
    }

    return result;
}

Two Deques Pattern (Middle Element Access)

Use two deques to efficiently access middle elements in a queue.

// import java.util.*;
// Front Middle Back Queue: Two deques with rebalancing
class FrontMiddleBackQueue {
    ArrayDeque<Integer> front_cache, back_cache;

    void rebalance() {
        // Maintain: front_cache.size() <= back_cache.size() <= front_cache.size() + 1
        while(front_cache.size() > back_cache.size()) {
            back_cache.push_front(front_cache.get(front_cache.size() - 1));
            front_cache.removeLast();
        }
        while(back_cache.size() > front_cache.size() + 1) {
            front_cache.add(back_cache.get(0));
            back_cache.removeFirst();
        }
    }
    void pushMiddle(int val) {
        front_cache.add(val);
        rebalance();
    }

    int popMiddle() {
        if(front_cache.length == 0 && back_cache.length == 0) return -1;
        if(front_cache.size() == back_cache.size()) {
            int val = front_cache.get(front_cache.size() - 1);
            front_cache.removeLast();
            return val;
        } else {
            int val = back_cache.get(0);
            back_cache.removeFirst();
            return val;
        }
    }
}

Key points:

  • Split queue into two halves: front_cache and back_cache
  • Maintain balance: front_cache.size() <= back_cache.size() <= front_cache.size() + 1
  • Middle element is front_cache.back() (if sizes equal) or back_cache.front() (if back_cache larger)
  • Rebalance after each modification
ID Title Link Solution
239 Sliding Window Maximum Link Solution
1670 Design Front Middle Back Queue Link Solution

More templates