Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solving Algorithm Problems with Stack #1077

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ a set of rules that precisely define a sequence of operations.
* **Linked Lists**
* `B` [Straight Traversal](src/algorithms/linked-list/traversal)
* `B` [Reverse Traversal](src/algorithms/linked-list/reverse-traversal)
* **Stack**
* `B` [Valid Parentheses](src/algorithms/stack/valid-parentheses) - check if a string has valid parentheses in the correct order
* **Trees**
* `B` [Depth-First Search](src/algorithms/tree/depth-first-search) (DFS)
* `B` [Breadth-First Search](src/algorithms/tree/breadth-first-search) (BFS)
Expand Down
44 changes: 44 additions & 0 deletions src/algorithms/stack/valid-parentheses/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Valid Parentheses Problem

Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.

An input string is valid if:

Open brackets must be closed by the same type of brackets.
Open brackets must be closed in the correct order.
Every close bracket has a corresponding open bracket of the same type.


Example 1:

`Input: s = "()"`

Output: true

Example 2:

`Input: s = "()[]{}"`

Output: true

Example 3:

`Input: s = "(]"`

Output: false

This is actually a very common interview question and a very good example of how to use a stack data structure to solve problems.

## Solution
The problem can be solved in two ways

### Bruteforce Approach
We can iterate through the string and then for each character in the string, we check for it's last closing character in the the string. Once we find the last closing character in the string, we remove both characters and then repeat the iteration, if we don't find a closing character for an opening character, then the string is invalid. The time complexity of this would be O(n^2) which is not so efficient.

### Using a Stack
We can use a hashtable to store all opening characters and the value would be the respective closing character. We can then iterate through the string and if we encounter an opening parantheses, we push it's closing character to the stack. If we ecounter a closing paraentheses, then we pop the stack and confirm that the popped element is equal to the current closing parentheses character. If it is not then the string is invalid. At the end of the iteration, we also need to check that the stack is empty. If it is not then the string is invalid. If it is, then the string is valid. This is a more efficient approach with a Time complexity and Space complexity of O(n).


## References

- [Leetcode](https://leetcode.com/problems/valid-parentheses/)
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import isValid from '../validParentheses';

describe('validParentheses', () => {
it('should return false when string is empty', () => {
expect(isValid('')).toBe(false);
});

it('should return true when string contains valid parentheses in correct order', () => {
expect(isValid('()')).toBe(true);
expect(isValid('()[]{}')).toBe(true);
expect(isValid('((({[]})))')).toBe(true);
});

it('should return false when string contains invalid parentheses', () => {
expect(isValid('(]')).toBe(false);
expect(isValid('()[]{} }')).toBe(false);
expect(isValid('((({[(]})))')).toBe(false);
});

it('should return false when string contains valid parentheses in wrong order', () => {
expect(isValid('({)}')).toBe(false);
});
});
42 changes: 42 additions & 0 deletions src/algorithms/stack/valid-parentheses/validParentheses.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import Stack from '../../../data-structures/stack/Stack';
import HashTable from '../../../data-structures/hash-table/HashTable';

// Declare hashtable containg opening parentheses as key and it's closing parentheses as value.
const hashTable = new HashTable(3);
hashTable.set('{', '}');
hashTable.set('(', ')');
hashTable.set('[', ']');

/**
* Check if string has valid parentheses.
*
* @param {string} parenthesesString
* @return {boolean}
*/
export default function isValid(parenthesesString) {
// If string is empty return false
if (parenthesesString.length === 0) {
return false;
}
// Create stack
const stack = new Stack();

// Loop through each character of string
for (let i = 0; i < parenthesesString.length; i += 1) {
const currentCharacter = parenthesesString[i];
// If character is opening parentheses push it's closing parentheses to stack
if (hashTable.has(currentCharacter)) {
stack.push(hashTable.get(currentCharacter));
} else {
/* If character is a closing parentheses then,:
check If stack is empty, if it is return false.
if stack is not empty, pop from stack and compare it with current character.
If they are not same return false. */
if (stack.isEmpty() || stack.pop() !== currentCharacter) {
return false;
}
}
}
// If stack is empty return true else return false
return stack.isEmpty();
}