Skip to content

Commit d43d397

Browse files
authored
Merge branch 'master' into tranlsation/hebrew
2 parents ff01159 + 49e0814 commit d43d397

File tree

4 files changed

+122
-11
lines changed

4 files changed

+122
-11
lines changed

README.md

+13-11
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ _Read this in other languages:_
3131
[_Português_](README.pt-BR.md),
3232
[_Русский_](README.ru-RU.md),
3333
[_Türkçe_](README.tr-TR.md),
34-
[_Italiana_](README.it-IT.md),
34+
[_Italiano_](README.it-IT.md),
3535
[_Bahasa Indonesia_](README.id-ID.md),
3636
[_Українська_](README.uk-UA.md),
3737
[_Arabic_](README.ar-AR.md),
@@ -144,6 +144,8 @@ a set of rules that precisely define a sequence of operations.
144144
* **Linked Lists**
145145
* `B` [Straight Traversal](src/algorithms/linked-list/traversal)
146146
* `B` [Reverse Traversal](src/algorithms/linked-list/reverse-traversal)
147+
* **Stack**
148+
* `B` [Valid Parentheses](src/algorithms/stack/valid-parentheses) - check if a string has valid parentheses in the correct order
147149
* **Trees**
148150
* `B` [Depth-First Search](src/algorithms/tree/depth-first-search) (DFS)
149151
* `B` [Breadth-First Search](src/algorithms/tree/breadth-first-search) (BFS)
@@ -198,7 +200,7 @@ algorithm is an abstraction higher than a computer program.
198200
* **Brute Force** - look at all the possibilities and selects the best solution
199201
* `B` [Linear Search](src/algorithms/search/linear-search)
200202
* `B` [Rain Terraces](src/algorithms/uncategorized/rain-terraces) - trapping rain water problem
201-
* `B` [Recursive Staircase](src/algorithms/uncategorized/recursive-staircase) - count the number of ways to reach to the top
203+
* `B` [Recursive Staircase](src/algorithms/uncategorized/recursive-staircase) - count the number of ways to reach the top
202204
* `A` [Maximum Subarray](src/algorithms/sets/maximum-subarray)
203205
* `A` [Travelling Salesman Problem](src/algorithms/graph/travelling-salesman) - shortest possible route that visits each city and returns to the origin city
204206
* `A` [Discrete Fourier Transform](src/algorithms/math/fourier-transform) - decompose a function of time (a signal) into the frequencies that make it up
@@ -229,7 +231,7 @@ algorithm is an abstraction higher than a computer program.
229231
* `B` [Jump Game](src/algorithms/uncategorized/jump-game)
230232
* `B` [Unique Paths](src/algorithms/uncategorized/unique-paths)
231233
* `B` [Rain Terraces](src/algorithms/uncategorized/rain-terraces) - trapping rain water problem
232-
* `B` [Recursive Staircase](src/algorithms/uncategorized/recursive-staircase) - count the number of ways to reach to the top
234+
* `B` [Recursive Staircase](src/algorithms/uncategorized/recursive-staircase) - count the number of ways to reach the top
233235
* `B` [Seam Carving](src/algorithms/image-processing/seam-carving) - content-aware image resizing algorithm
234236
* `A` [Levenshtein Distance](src/algorithms/string/levenshtein-distance) - minimum edit distance between two sequences
235237
* `A` [Longest Common Subsequence](src/algorithms/sets/longest-common-subsequence) (LCS)
@@ -242,9 +244,9 @@ algorithm is an abstraction higher than a computer program.
242244
* `A` [Bellman-Ford Algorithm](src/algorithms/graph/bellman-ford) - finding the shortest path to all graph vertices
243245
* `A` [Floyd-Warshall Algorithm](src/algorithms/graph/floyd-warshall) - find the shortest paths between all pairs of vertices
244246
* `A` [Regular Expression Matching](src/algorithms/string/regular-expression-matching)
245-
* **Backtracking** - similarly to brute force, try to generate all possible solutions, but each time you generate next solution you test
246-
if it satisfies all conditions, and only then continue generating subsequent solutions. Otherwise, backtrack, and go on a
247-
different path of finding a solution. Normally the DFS traversal of state-space is being used.
247+
* **Backtracking** - similarly to brute force, try to generate all possible solutions, but each time you generate the next solution, you test
248+
if it satisfies all conditions and only then continue generating subsequent solutions. Otherwise, backtrack and go on a
249+
different path to finding a solution. Normally the DFS traversal of state-space is being used.
248250
* `B` [Jump Game](src/algorithms/uncategorized/jump-game)
249251
* `B` [Unique Paths](src/algorithms/uncategorized/unique-paths)
250252
* `B` [Power Set](src/algorithms/sets/power-set) - all subsets of a set
@@ -254,8 +256,8 @@ different path of finding a solution. Normally the DFS traversal of state-space
254256
* `A` [Combination Sum](src/algorithms/sets/combination-sum) - find all combinations that form specific sum
255257
* **Branch & Bound** - remember the lowest-cost solution found at each stage of the backtracking
256258
search, and use the cost of the lowest-cost solution found so far as a lower bound on the cost of
257-
a least-cost solution to the problem, in order to discard partial solutions with costs larger than the
258-
lowest-cost solution found so far. Normally BFS traversal in combination with DFS traversal of state-space
259+
a least-cost solution to the problem in order to discard partial solutions with costs larger than the
260+
lowest-cost solution found so far. Normally, BFS traversal in combination with DFS traversal of state-space
259261
tree is being used.
260262

261263
## How to use this repository
@@ -295,14 +297,14 @@ rm -rf ./node_modules
295297
npm i
296298
```
297299

298-
Also make sure that you're using a correct Node version (`>=16`). If you're using [nvm](https://github.com/nvm-sh/nvm) for Node version management you may run `nvm use` from the root folder of the project and the correct version will be picked up.
300+
Also, make sure that you're using the correct Node version (`>=16`). If you're using [nvm](https://github.com/nvm-sh/nvm) for Node version management you may run `nvm use` from the root folder of the project and the correct version will be picked up.
299301

300302
**Playground**
301303

302304
You may play with data-structures and algorithms in `./src/playground/playground.js` file and write
303305
tests for it in `./src/playground/__test__/playground.test.js`.
304306

305-
Then just simply run the following command to test if your playground code works as expected:
307+
Then just, simply run the following command to test if your playground code works as expected:
306308

307309
```
308310
npm test -- 'playground'
@@ -318,7 +320,7 @@ npm test -- 'playground'
318320
### Big O Notation
319321

320322
*Big O notation* is used to classify algorithms according to how their running time or space requirements grow as the input size grows.
321-
On the chart below you may find most common orders of growth of algorithms specified in Big O notation.
323+
On the chart below, you may find the most common orders of growth of algorithms specified in Big O notation.
322324

323325
![Big O graphs](./assets/big-o-graph.png)
324326

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Valid Parentheses Problem
2+
3+
Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.
4+
5+
An input string is valid if:
6+
7+
Open brackets must be closed by the same type of brackets.
8+
Open brackets must be closed in the correct order.
9+
Every close bracket has a corresponding open bracket of the same type.
10+
11+
12+
Example 1:
13+
14+
`Input: s = "()"`
15+
16+
Output: true
17+
18+
Example 2:
19+
20+
`Input: s = "()[]{}"`
21+
22+
Output: true
23+
24+
Example 3:
25+
26+
`Input: s = "(]"`
27+
28+
Output: false
29+
30+
This is actually a very common interview question and a very good example of how to use a stack data structure to solve problems.
31+
32+
## Solution
33+
The problem can be solved in two ways
34+
35+
### Bruteforce Approach
36+
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.
37+
38+
### Using a Stack
39+
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).
40+
41+
42+
## References
43+
44+
- [Leetcode](https://leetcode.com/problems/valid-parentheses/)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import isValid from '../validParentheses';
2+
3+
describe('validParentheses', () => {
4+
it('should return false when string is empty', () => {
5+
expect(isValid('')).toBe(false);
6+
});
7+
8+
it('should return true when string contains valid parentheses in correct order', () => {
9+
expect(isValid('()')).toBe(true);
10+
expect(isValid('()[]{}')).toBe(true);
11+
expect(isValid('((({[]})))')).toBe(true);
12+
});
13+
14+
it('should return false when string contains invalid parentheses', () => {
15+
expect(isValid('(]')).toBe(false);
16+
expect(isValid('()[]{} }')).toBe(false);
17+
expect(isValid('((({[(]})))')).toBe(false);
18+
});
19+
20+
it('should return false when string contains valid parentheses in wrong order', () => {
21+
expect(isValid('({)}')).toBe(false);
22+
});
23+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import Stack from '../../../data-structures/stack/Stack';
2+
import HashTable from '../../../data-structures/hash-table/HashTable';
3+
4+
// Declare hashtable containg opening parentheses as key and it's closing parentheses as value.
5+
const hashTable = new HashTable(3);
6+
hashTable.set('{', '}');
7+
hashTable.set('(', ')');
8+
hashTable.set('[', ']');
9+
10+
/**
11+
* Check if string has valid parentheses.
12+
*
13+
* @param {string} parenthesesString
14+
* @return {boolean}
15+
*/
16+
export default function isValid(parenthesesString) {
17+
// If string is empty return false
18+
if (parenthesesString.length === 0) {
19+
return false;
20+
}
21+
// Create stack
22+
const stack = new Stack();
23+
24+
// Loop through each character of string
25+
for (let i = 0; i < parenthesesString.length; i += 1) {
26+
const currentCharacter = parenthesesString[i];
27+
// If character is opening parentheses push it's closing parentheses to stack
28+
if (hashTable.has(currentCharacter)) {
29+
stack.push(hashTable.get(currentCharacter));
30+
} else {
31+
/* If character is a closing parentheses then,:
32+
check If stack is empty, if it is return false.
33+
if stack is not empty, pop from stack and compare it with current character.
34+
If they are not same return false. */
35+
if (stack.isEmpty() || stack.pop() !== currentCharacter) {
36+
return false;
37+
}
38+
}
39+
}
40+
// If stack is empty return true else return false
41+
return stack.isEmpty();
42+
}

0 commit comments

Comments
 (0)