A stack is a collection of elements with two primary operations: push and pop. The push operation adds an element to the top of the stack, and the pop operation removes the top element. The stack follows the Last In, First Out (LIFO) principle.
Using recursion
The idea of the solution is to hold all values in the function call stack until the stack becomes empty. When the stack becomes empty, insert all held items one by one at the bottom of the stack.
- Base Case: Check if the stack is empty. If it is, there’s nothing to reverse, so return.
- Recursive Step: Pop an element from the stack and recursively call the function on the remaining stack.
- Insert at Bottom: After reaching the end of the stack (i.e., the base case), recursively insert each popped element at the bottom of the stack.This approach utilizes the Last In, First Out (LIFO) nature of the stack to efficiently to Reverse the values.
Example: In this example, we use recursion to reverse the stack. The algorithm follows a base case where it checks if the stack is empty, and if not, it pops an element from the stack, recursively calls itself on the remaining stack, and then inserts the popped element at the bottom. This process continues until the entire stack is reversed.
// JavaScript code to reverse a // stack using recursion // Create an empty stack let stack = []; // This recursive function inserts an element // at the bottom of the stack. function insertAtBottom(element) {
// If the stack is empty, push the element
if (stack.length === 0)
stack.push(element);
else {
// If the stack is not empty, pop the top element,
// call insertAtBottom recursively,
// and push the popped element back
let temp = stack.pop();
insertAtBottom(element);
stack.push(temp);
}
} // This function reverses the given stack using // the insertAtBottom() function function reverseStack() {
// If the stack is not empty, pop the top element,
// call reverseStack recursively,
// and insert the popped element at the bottom
if (stack.length > 0) {
let x = stack.pop();
reverseStack();
insertAtBottom(x);
}
} // Push elements into the stack stack.push( '100' );
stack.push( '101' );
stack.push( '102' );
stack.push( '103' );
console.log( "Original Stack:" );
console.log(stack.join( " " ));
// Reverse the stack reverseStack(); console.log( "Reversed Stack:" );
console.log(stack.join( " " ));
|
Original Stack: 100 101 102 103 Reversed Stack: 103 102 101 100
Using Memoization with Recursion
Memoization optimizes recursive functions by caching computed results. Before computing, the function checks if the result for given inputs exists in the cache it returns the cached result. Otherwise, it computes the power, stores it, and returns it. This reduces redundant computations, enhancing performance.
- Base Case: Check if the stack is empty. If it is, return an empty array.
- Memoization Check: Before processing the current stack configuration, check if its reversal has already been memoized. If so, return the memoized result.
- Recursive Step: Pop the top element from the stack and recursively call the function on the remaining stack.
- Memoize Reversed Stack: After reversing the smaller stack, add the popped element to the beginning of the reversed stack.
- Memoize Result: Memoize the reversed stack configuration.
- Return Reversed Stack: Return the reversed stack.
Example: In this approach, we use memoization to optimize performance by caching computed results. Before processing each stack configuration, the algorithm checks if its reversal has already been memoized. If not, it proceeds with the reversal process recursively, caching the result for future use.
// JavaScript code to reverse a stack //using recursion with memoization // Using memoization object to store computed results let memo = {}; // Function to reverse a stack recursively function reverseStack(stack) {
if (stack.length === 0) return [];
// Check if the result is memoized
if (!memo[stack.join()]) {
let top = stack.pop();
reverseStack(stack);
let reversedStack = memo[stack.join()] || [];
reversedStack.unshift(top);
// Use unshift to add the element
// to the beginning of the array
memo[stack.join()] = reversedStack;
}
return memo[stack.join()];
} // Original stack let st = [ '97' , '98' , '99' , '100' ];
console.log( "Original Stack:" );
console.log(st.join( " " ));
// Reverse the stack let reversedStack = reverseStack(st.slice()); // Pass a copy of the original stack console.log( "Reversed Stack:" );
console.log(reversedStack.join( " " ));
|
Original Stack: 97 98 99 100 Reversed Stack: 100 99 98 97