A stack is an abstract data type that adheres to the Last-In-First-Out (LIFO) principle in the context of data structures and algorithms (DSA). It’s a linear data structure with operations like push (adding an element to the top) and pop (removing the topmost element).
Note: A stack can be visualized as a stack of plates where you can only access the topmost plate. The last plate you put on the stack is the first one to be removed.
The following are some common operations implemented on the stack:
Operation | Time Complexity (N- no. o elements in the stack) | Space Complexity |
---|---|---|
push() | O(1) | O(1) |
pop() | O(1) | O(1) |
isEmpty() | O(1) | O(1) |
isFull() | O(1) | O(1) |
peek() | O(1) | O(1) |
count() | O(1) | O(1) |
change() | O(1) | O(1) |
display() | O(N) | O(N) |
Stacks are commonly used in various algorithms and programming tasks due to their simple and efficient structure. Some applications of stacks include:
A stack can be implemented in two ways:
push(int element)
: This function adds an element to the top of the stack. It has a time complexity of O(1) since adding an element to an array at a specific index takes constant time.pop()
: This function removes and returns the topmost element from the stack. It also has a time complexity of O(1) since accessing and removing an element from a specific index in an array takes constant time.isEmpty()
: This function checks if the stack is empty. It has a time complexity of O(1) since it only requires checking the value of the top
variable, which is constant time.isFull()
: This function checks if the stack is full. It has a time complexity of O(1) since it only requires comparing the top
variable with the capacity, which is constant time.peek()
: This function returns the topmost element of the stack without removing it. It has a time complexity of O(1) as it directly accesses the element at the top
index of the array.size()
: This function returns the number of elements in the stack. It has a time complexity of O(1) as it simply returns the value of the top
variable, which represents the number of elements in the stack.display()
: This function displays all the elements in the stack. It has a time complexity of O(N) where N is the number of elements in the stack since it requires iterating over each element in the array and printing it.public class Stack {
private int capacity;
private int top;
private int[] stackArray;
public Stack(int capacity) {
this.capacity = capacity;
this.top = -1;
this.stackArray = new int[capacity];
}
public void push(int element) {
if (top < capacity - 1) {
stackArray[++top] = element;
} else {
System.out.println("Stack Overflow");
}
}
public int pop() {
if (top >= 0) {
return stackArray[top--];
} else {
System.out.println("Stack Underflow");
return -1; // Or throw an exception
}
}
public boolean isEmpty() {
return (top == -1);
}
public boolean isFull() {
return (top == capacity - 1);
}
public int peek() {
if (top >= 0) {
return stackArray[top];
} else {
System.out.println("Stack is empty");
return -1; // Or throw an exception
}
}
public int size() {
return top + 1;
}
public void display() {
System.out.print("Stack: ");
for (int i = 0; i <= top; i++) {
System.out.print(stackArray[i] + " ");
}
System.out.println();
}
}
push(int element)
: This function adds an element to the top of the stack by creating a new node and updating the top
reference. It has a time complexity of O(1) since it involves creating a new node and updating a reference.pop()
: This function removes and returns the topmost element from the stack by updating the top
reference. It also has a time complexity of O(1) as it only involves updating a reference.isEmpty()
: This function checks if the stack is empty. It has a time complexity of O(1) as it only requires checking the value of the top
reference, which is constant time.peek()
: This function returns the topmost element of the stack without removing it. It has a time complexity of O(1) as it directly accesses the element referenced by the top
reference.display()
: This function displays all the elements in the stack by iterating over the linked list. It has a time complexity of O(N) where N is the number of elements in the stack since it requires visiting each node in the linked list.class Node {
int data;
Node next;
public Node(int data) {
this.data = data;
this.next = null;
}
}
public class Stack {
private Node top;
public Stack() {
this.top = null;
}
public void push(int element) {
Node newNode = new Node(element);
newNode.next = top;
top = newNode;
}
public int pop() {
if (top != null) {
int poppedValue = top.data;
top = top.next;
return poppedValue;
} else {
System.out.println("Stack Underflow");
return -1; // Or throw an exception
}
}
public boolean isEmpty() {
return (top == null);
}
public int peek() {
if (top != null) {
return top.data;
} else {
System.out.println("Stack is empty");
return -1; // Or throw an exception
}
}
public void display() {
System.out.print("Stack: ");
Node current = top;
while (current != null) {
System.out.print(current.data + " ");
current = current.next;
}
System.out.println();
}
}
Array Implementation | Linked List Implementation | |
---|---|---|
Memory Allocation | Requires a fixed-size array | Dynamic allocation of nodes |
Insertion (Push) | Direct access at top index (O(1)) | Creation of new node and reference update (O(1)) |
Deletion (Pop) | Direct access at top index (O(1)) | Reference update and node deallocation (O(1)) |
Memory Efficiency | More memory efficient (no overhead) | Slightly less memory efficient (overhead of nodes and references) |
Resizing | Resizing the array can be expensive | No resizing required |
Advantages | – Constant-time access and updates – More memory efficient | – Dynamic size handling |
Disadvantages | – Limited capacity – Costly resizing if capacity is exceeded | – No predefined maximum capacity – Slightly less memory efficient |
You are given N elements and your task is to Implement a Stack in which you can get a minimum element in O(1) time.
Example:
Input: push(2) push(3) pop() getMin() push(1) getMin() Output: 2 1 Explanation: In the first test case for query push(2) Insert 2 into the stack. The stack will be {2} push(3) Insert 3 into the stack. The stack will be {2 3} pop() Remove top element from stack Poped element will be 3 the stack will be {2} getMin() Return the minimum element min element will be 2 push(1) Insert 1 into the stack. The stack will be {2 1} getMin() Return the minimum element min element will be 1
Your Task:
You are required to complete the three methods push() which takes one argument an integer ‘x’ to be pushed into the stack, pop() which returns an integer popped out from the stack, and getMin() which returns the min element from the stack. (-1 will be returned if for pop() and getMin() the stack is empty.)
Expected Time Complexity: O(1) for all the 3 methods.
Expected Auxiliary Space: O(1) for all the 3 methods.
Solution:
import java.util.Stack;
class MinStack {
private Stack<Integer> stack;
private Stack<Integer> minStack;
public MinStack() {
stack = new Stack<>();
minStack = new Stack<>();
}
public void push(int x) {
stack.push(x);
if (minStack.isEmpty() || x <= minStack.peek()) {
minStack.push(x);
}
}
public int pop() {
if (stack.isEmpty()) {
return -1;
}
int popped = stack.pop();
if (popped == minStack.peek()) {
minStack.pop();
}
return popped;
}
public int getMin() {
if (minStack.isEmpty()) {
return -1;
}
return minStack.peek();
}
}
Explanation:
MinStack
class has two stacks: stack
to store the actual elements minStack
to store the minimum values.stack
. Then, if the minStack
is empty or the new element is less than or equal to the top element of minStack
, we push the new element onto minStack
as well.stack
is empty. If it is, we return -1 indicating an empty stack. Otherwise, we pop the element from the stack
and check if it is the same as the top element of minStack
. If it is, we also pop the top element from minStack
.minStack
. If minStack
is empty, we return -1 indicating an empty stack.Given an expression string x. Examine whether the pairs and the orders of {,},(,),[,] are correct in exp.
For example, the function should return ‘true’ for exp = [()]{}{[()()]()} and ‘false’ for exp = [(]).
Note: The drive code prints “balanced” if function return true, otherwise it prints “not balanced”.
Example:
Input: {([])} Output: true Explanation: { ( [ ] ) }. Same colored brackets can form balanced pairs, with 0 number of unbalanced bracket.
Expected Time Complexity: O(|x|)
Expected Auixilliary Space: O(|x|)
Solution:
Stack<Character> stack = new Stack<>();
for (char c : exp.toCharArray()) {
if (c == '(' || c == '[' || c == '{') {
stack.push(c);
} else {
if (stack.isEmpty()) {
return false;
}
char top = stack.pop();
if ((c == ')' && top != '(') || (c == ']' && top != '[') || (c == '}' && top != '{')) {
return false;
}
}
}
return stack.isEmpty();
Explanation:
ispar
function takes a string exp
as input and returns a boolean value indicating whether the brackets are balanced or not.(
, [
, or {
), we push it onto the stack.)
, ]
, or }
), we check if the stack is empty. If it is, there is no corresponding opening bracket, so the brackets are not balanced, and we return false.( )
, [ ]
, { }
), we return false.Given a binary tree, find its preorder traversal.
Example 1:
Input: 1 / 4 / \ 4 2 Output: 1 4 4 2
Example 2:
Input: 6 / \ 3 2 \ / 1 2 Output: 6 3 1 2 2
Your Task:
You just have to complete the function preorder() which takes the root node of the tree as input and returns an array containing the preorder traversal of the tree.
Expected Time Complexity: O(N).
Expected Auxiliary Space: O(N).
Solution:
// class Node{
// int data;
// Node left,right;
// Node(int d){
// data=d;
// left=right=null;
// }
// }
class BinaryTree
{
//Function to return a list containing the preorder traversal of the tree.
static ArrayList<Integer> preorder(Node root)
{ ArrayList<Integer> result = new ArrayList<>();
if (root == null) {
return result;
}
Stack<Node> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
Node node = stack.pop();
result.add(node.data);
if (node.right != null) {
stack.push(node.right);
}
if (node.left != null) {
stack.push(node.left);
}
}
return result;
// Code here
}
}
Explanation:
BinaryTree
class represents a binary tree.preorder
function takes the root node of the binary tree as input and returns an ArrayList<Integer>
containing the preorder traversal of the tree.ArrayList<Integer>
called result
to store the preorder traversal elements.result
list.result
list.result
list containing the preorder traversal elements.Given a stack, the task is to sort it such that the top of the stack has the greatest element.
Example:
Input: Stack: 11 2 32 3 41 Output: 41 32 11 3 2
Your Task:
You don’t have to read input or print anything. Your task is to complete the function sort() which sorts the elements present in the given stack. (The sorted stack is printed by the driver’s code by popping the elements of the stack.)
Expected Time Complexity: O(N*N)
Expected Auxilliary Space: O(N) recursive.
Solution:
import java.util.Stack;
class SortStack {
public static void sort(Stack<Integer> stack) {
if (stack.isEmpty()) {
return;
}
int temp = stack.pop();
sort(stack);
insertSorted(stack, temp);
}
private static void insertSorted(Stack<Integer> stack, int element) {
if (stack.isEmpty() || element > stack.peek()) {
stack.push(element);
} else {
int temp = stack.pop();
insertSorted(stack, element);
stack.push(temp);
}
}
}
Explanation:
sort
function takes a stack of integers as input and sorts its elements in descending order.temp
.temp
element back into the stack in the correct position using the insertSorted
helper function.insertSorted
function is a recursive helper function that inserts an element into the stack at the correct position.insertSorted
with the remaining stack elements until we find the correct position to insert the element.Note: also read about Pointers in DSA
If you like my post please follow me to read my latest post on programming and technology.
https://www.instagram.com/coderz.py/
https://www.facebook.com/coderz.py
Staying up to the mark is what defines me. Hi all! I’m Rabecca Fatima a keen learner, great enthusiast, ready to take new challenges as stepping stones towards flying colors.
Problem Statement: Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. Example…
Given an integer A. Compute and return the square root of A. If A is…
Given a zero-based permutation nums (0-indexed), build an array ans of the same length where…
A heap is a specialized tree-based data structure that satisfies the heap property. It is…
What is the Lowest Common Ancestor? In a tree, the lowest common ancestor (LCA) of…