- read

Deep Dive into Stacks + LeetCode Practice

Hayk Simonyan 39

Deep Dive into Stacks + LeetCode Practice

Hayk Simonyan
Level Up Coding
Published in
4 min read16 hours ago

--

Today, let’s delve into Stacks coupled with a LeetCode challenge. This post seeks not just to impart knowledge, but also to offer a hands-on challenge to consolidate your learning. So let’s dive in!

A Brief Introduction to Stacks

Picture a pile of dishes. Each new dish is placed on top and also removed from the top when needed.

This mirrors the Last In, First Out (LIFO) principle that stacks operate on. The last element added is always the first to be removed. This principle is simple but incredibly versatile in computer systems, forming the backbone of numerous algorithms and functionalities.

let myStack = []; // Creating a stack

myStack.push(10); // Adding an item
myStack.push(20); // Adding another

let top = myStack.pop(); // Removing the last item (20)

In JavaScript, even without a built-in stack data structure, we can leverage arrays and their methods like push() and pop() to emulate a stack.

The Multifaceted Applications of Stacks

Stacks are omnipresent across various computer systems ensuring the accurate order of operations. Some familiar instances include the “back” functionality of web browsers, undo features in numerous software applications, and notably, managing function calls in recursion, like the call stack in JavaScript.

Unveiling the Efficiency of Stack Operations

Stacks predominantly support three types of operations, each boasting its own functionality and use case:

  • Push: Introduces a new item to the top.
  • Pop: Eliminates the item at the top.
  • Peek/Top: A sneak peek at the top item without altering it.

A key allure of stacks lies in the efficiency with which these operations are executed, all boasting a time complexity of O(1). Whether you’re adding an item, removing the top one, or merely sneaking a peek, stacks ensure consistently brisk performance.

let myStack = [1, 2, 3, 4, 5, 6];

myStack.push(100); // Pushing: O(1)
myStack.at(-1); // Peeking: O(1)
myStack.pop(); // Popping: O(1)

However, a Bit of a Roadblock…

Not every operation is a breezy ride. Searching within a stack is characterized by an O(n) time complexity, potentially necessitating a traversal through the entire stack.

let target = 100;
let found = myStack.includes(target); // O(n) exploration

Remember, stacks were not conceived for search operations. Their prowess is entrenched in the aforementioned primary operations, which are notably O(1).

LeetCode Challenge!

With our newfound knowledge of stacks, let’s pit it against a real-world scenario with the LeetCode 155 — Min Stack problem.

The challenge is to construct a conventional stack but with a twist. Incorporate a method (getMin) capable of efficiently fetching the minimum element. Before peeking at the solution, immerse yourself in the problem and wrestle with it a bit. Stay tuned for the upcoming blog post that will unravel an efficient solution to this challenge!

Wrapping Up: Quick Recap and Forward Path

Quick Recap: Stacks embody the LIFO data structures, with primary operations being Push, Pop, and Peek, all performing at an impressive O(1) time complexity. Even though searching within a stack might nudge us into O(n) time territory, it’s important to recognize that searches are not the inherent forte of stacks.

Up Next: If you’re intrigued by the concept of estimating Big O complexities of stacks and other data structures, check out my full Big O Notation Guide.

Stay Tuned: In the next article, we’ll dissect and explore the solution to the Min Stack LeetCode problem!

🚀 Happy Coding!