Skip to content

Crack SDE

Most of the content are generated by AI, with human being reviewed, edited, and revised

Menu
  • Home
  • Daily English Story
  • Tech Interviews
  • Cloud Native
  • DevOps
  • Artificial Intelligence
Menu

LC#622 Design Circular Queue

Posted on 05/10/2025 by user


Design your implementation of the circular queue. The circular queue is a linear data structure in which the operations are performed based on FIFO (First In First Out) principle, and the last position is connected back to the first position to make a circle. It is also called “Ring Buffer”.

One of the benefits of the circular queue is that we can make use of the spaces in front of the queue. In a normal queue, once the queue becomes full, we cannot insert the next element even if there is a space in front of the queue. But using the circular queue, we can use the space to store new values.

Implement the MyCircularQueue class:

MyCircularQueue(k) Initializes the object with the size of the queue to be k.
int Front() Gets the front item from the queue. If the queue is empty, return -1.
int Rear() Gets the last item from the queue. If the queue is empty, return -1.
boolean enQueue(int value) Inserts an element into the circular queue. Return true if the operation is successful.
boolean deQueue() Deletes an element from the circular queue. Return true if the operation is successful.
boolean isEmpty() Checks whether the circular queue is empty or not.
boolean isFull() Checks whether the circular queue is full or not.
You must solve the problem without using the built-in queue data structure in your programming language.

package main

import "fmt"

// MyCircularQueue implements a fixed-size circular queue.
// It supports constant-time enqueue, dequeue, and access operations.
type MyCircularQueue struct {
	data       []int
	head       int // Index of the front element
	tail       int // Index where the next element will be inserted
	size       int // Current number of elements
	capacity   int // Maximum number of elements
}

// Constructor622 initializes a new circular queue with capacity k.
func Constructor622(k int) MyCircularQueue {
	if k <= 0 {
		panic("Queue capacity must be greater than zero")
	}
	return MyCircularQueue{
		data:     make([]int, k),
		capacity: k,
	}
}

// IsEmpty returns true if the queue is empty.
func (q *MyCircularQueue) IsEmpty() bool {
	return q.size == 0
}

// IsFull returns true if the queue has reached its capacity.
func (q *MyCircularQueue) IsFull() bool {
	return q.size == q.capacity
}

// EnQueue inserts an element at the rear of the queue.
// Returns false if the queue is full.
func (q *MyCircularQueue) EnQueue(value int) bool {
	if q.IsFull() {
		return false
	}
	q.data[q.tail] = value
	q.tail = (q.tail + 1) % q.capacity
	q.size++
	return true
}

// DeQueue removes the element at the front of the queue.
// Returns false if the queue is empty.
func (q *MyCircularQueue) DeQueue() bool {
	if q.IsEmpty() {
		return false
	}
	q.head = (q.head + 1) % q.capacity
	q.size--
	return true
}

// Front returns the front element of the queue.
// Returns -1 if the queue is empty.
func (q *MyCircularQueue) Front() int {
	if q.IsEmpty() {
		return -1
	}
	return q.data[q.head]
}

// Rear returns the last inserted element in the queue.
// Returns -1 if the queue is empty.
func (q *MyCircularQueue) Rear() int {
	if q.IsEmpty() {
		return -1
	}
	lastIndex := (q.tail - 1 + q.capacity) % q.capacity
	return q.data[lastIndex]
}

// For demonstration
func main() {
	q := Constructor622(3)
	fmt.Println(q.EnQueue(1)) // true
	fmt.Println(q.EnQueue(2)) // true
	fmt.Println(q.EnQueue(3)) // true
	fmt.Println(q.EnQueue(4)) // false, full
	fmt.Println(q.Rear())     // 3
	fmt.Println(q.IsFull())   // true
	fmt.Println(q.DeQueue())  // true
	fmt.Println(q.EnQueue(4)) // true
	fmt.Println(q.Rear())     // 4
}

Below is the enhanced MyCircularQueue implementation with concurrency safety using sync.Mutex, and a simple performance benchmark using Go’s testing framework.

  • Clean method structure with Lock/Unlock
  • Added sync.Mutex to protect shared state (head, tail, size)
  • *MyCircularQueue used instead of value receiver for performance and thread safety
  • Includes a benchmark simulating high-concurrency operations
package main

import (
	"fmt"
	"sync"
)

// MyCircularQueue implements a fixed-size circular queue with concurrency safety.
type MyCircularQueue struct {
	data     []int
	head     int
	tail     int
	size     int
	capacity int
	mu       sync.Mutex
}

// Constructor622 initializes a new circular queue with capacity k.
func Constructor622(k int) *MyCircularQueue {
	if k <= 0 {
		panic("Queue capacity must be greater than zero")
	}
	return &MyCircularQueue{
		data:     make([]int, k),
		capacity: k,
	}
}

// IsEmpty returns true if the queue is empty.
func (q *MyCircularQueue) IsEmpty() bool {
	q.mu.Lock()
	defer q.mu.Unlock()
	return q.size == 0
}

// IsFull returns true if the queue is full.
func (q *MyCircularQueue) IsFull() bool {
	q.mu.Lock()
	defer q.mu.Unlock()
	return q.size == q.capacity
}

// EnQueue inserts an element at the rear of the queue.
func (q *MyCircularQueue) EnQueue(value int) bool {
	q.mu.Lock()
	defer q.mu.Unlock()
	if q.size == q.capacity {
		return false
	}
	q.data[q.tail] = value
	q.tail = (q.tail + 1) % q.capacity
	q.size++
	return true
}

// DeQueue removes the element from the front of the queue.
func (q *MyCircularQueue) DeQueue() bool {
	q.mu.Lock()
	defer q.mu.Unlock()
	if q.size == 0 {
		return false
	}
	q.head = (q.head + 1) % q.capacity
	q.size--
	return true
}

// Front returns the front item from the queue.
func (q *MyCircularQueue) Front() int {
	q.mu.Lock()
	defer q.mu.Unlock()
	if q.size == 0 {
		return -1
	}
	return q.data[q.head]
}

// Rear returns the last inserted item from the queue.
func (q *MyCircularQueue) Rear() int {
	q.mu.Lock()
	defer q.mu.Unlock()
	if q.size == 0 {
		return -1
	}
	lastIndex := (q.tail - 1 + q.capacity) % q.capacity
	return q.data[lastIndex]
}

Share this:

  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on X (Opens in new window) X

Related

Leave a Reply Cancel reply

You must be logged in to post a comment.

Recent Posts

  • LC#622 Design Circular Queue
  • Started with OpenTelemetry in Go
  • How Prometheus scrap works, and how to find the target node and get the metrics files
  • How to collect metrics of container, pods, node and cluster in k8s?
  • LC#200 island problem

Recent Comments

  1. another user on A Journey of Resilience

Archives

  • May 2025
  • April 2025
  • February 2025
  • July 2024
  • April 2024
  • January 2024
  • December 2023
  • November 2023
  • October 2023
  • September 2023
  • August 2023
  • June 2023
  • May 2023

Categories

  • Artificial Intelligence
  • Cloud Computing
  • Cloud Native
  • Daily English Story
  • Database
  • DevOps
  • Golang
  • Java
  • Leetcode
  • Startups
  • Tech Interviews
©2025 Crack SDE | Design: Newspaperly WordPress Theme
Manage Cookie Consent
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
Functional Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes. The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.
Manage options Manage services Manage {vendor_count} vendors Read more about these purposes
View preferences
{title} {title} {title}