Loading problems...
TL;DR: The optimal solution for the given constraints uses a dynamic array (vector/list) to directly access the -th element, remove it, and append it to the end of the list in time.
The "Design Most Recently Used Queue" problem asks us to implement a specialized queue data structure initialized with integers from 1 to n. The key requirement is the fetch(k) operation, which retrieves the k-th element (1-indexed) from the current sequence, removes it from its current position, and moves it to the very end of the queue. We must return the value of the fetched element.
This is a LeetCode 1756 Solution that focuses on clean class design and efficient simulation of the required behavior.
A brute force approach often attempts to strictly adhere to the definition of a "Queue" (FIFO) without leveraging random access.
std::queue or LinkedList).k-1 elements and store them in a temporary buffer (or rotate them to the back).k-th element (the target).k-1 elements at the front (if using a buffer) or accept the rotation.Pseudo-code:
textfunction fetch(k): temp_list = [] for i from 1 to k-1: temp_list.add(queue.dequeue()) target = queue.dequeue() // Restore elements to front (difficult with standard Queue) // Or reconstruct entire queue new_queue = new Queue() for item in temp_list: new_queue.enqueue(item) while queue is not empty: new_queue.enqueue(queue.dequeue()) new_queue.enqueue(target) queue = new_queue return target
Complexity Analysis:
Why it is suboptimal: While technically , the constant factors are high due to repeated memory allocation and object movement. Furthermore, using a pure Queue abstraction makes accessing the -th element cumbersome compared to random-access data structures. This approach struggles with code complexity and efficiency compared to using a dynamic array.
The core insight for LeetCode 1756 lies in analyzing the constraints and the nature of the operations.
std::vector in C++, ArrayList in Java, or list in Python) supports:
i is .i is because subsequent elements must shift left.Given the constraints, an operation per fetch results in a total complexity of roughly operations, which is well within the typical execution time limit (usually allowing operations per second). Therefore, the most pragmatic design is a direct simulation using a dynamic array.
Visual Description:
Imagine the queue as a contiguous block of memory. When fetch(k) is called, we locate the slot at index . We extract the value, causing a "gap." The block of memory to the right of the gap shifts left to fill it. Finally, the extracted value is placed in the newly available slot at the far right end of the block.

Let's trace n = 4 (Queue: [1, 2, 3, 4]) and fetch(3).
[1, 2, 3, 4].3 - 1 = 2.3.3. The list shifts: [1, 2, 4].3 to the end. The list becomes: [1, 2, 4, 3].3.[1, 2, 4, 3].2 - 1 = 1.2.2. List shifts: [1, 4, 3].2 to end. List becomes: [1, 4, 3, 2].2.The algorithm is correct by simulation.
[1, ..., n], satisfying the initial condition.k to k-1, we correctly access the -th element in a 0-indexed array.remove operation in dynamic arrays preserves the relative order of all remaining elements. The append operation places the element at the logical end. This strictly follows the problem's definition of the MRU move.cpp#include <vector> #include <numeric> class MRUQueue { private: std::vector<int> queue; public: MRUQueue(int n) { // Reserve memory to avoid reallocations queue.reserve(n); for (int i = 1; i <= n; ++i) { queue.push_back(i); } } int fetch(int k) { // Convert 1-based index to 0-based int index = k - 1; // Retrieve the element int val = queue[index]; // Remove the element at the specific index // erase shifts elements after 'index' to the left -> O(N) queue.erase(queue.begin() + index); // Add the element to the end -> O(1) queue.push_back(val); return val; } };
javaimport java.util.ArrayList; import java.util.List; class MRUQueue { private List<Integer> queue; public MRUQueue(int n) { queue = new ArrayList<>(n); for (int i = 1; i <= n; i++) { queue.add(i); } } public int fetch(int k) { // ArrayList.remove(int index) removes the element and returns it. // It also shifts subsequent elements to the left. // k is 1-based, so we access k-1. int val = queue.remove(k - 1); // Add the element to the end of the list queue.add(val); return val; } }
pythonclass MRUQueue: def __init__(self, n: int): # Initialize list with 1 to n self.queue = list(range(1, n + 1)) def fetch(self, k: int) -> int: # pop(index) removes the element at the index and returns it. # Elements shift automatically. k is 1-based, so use k-1. val = self.queue.pop(k - 1) # Append the value to the end of the list self.queue.append(val) return val
Time Complexity:
Space Complexity:
The Design pattern and the concept of moving elements based on access frequency appear in several other popular interview questions:
Why does my solution fail with "Time Limit Exceeded" on larger constraints?
Why is my output incorrect by one position?
queue[k] instead of queue[k-1] retrieves the wrong element.Why is using a Linked List effectively the same complexity here?