Skip to content

Commit 401d499

Browse files
committed
more problems
1 parent fe1c06c commit 401d499

6 files changed

+282
-0
lines changed
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import letterCasePermutation from '../letter-case-permutation';
2+
3+
describe('Letter Case Permutation', () => {
4+
5+
test('a1b2', () => {
6+
const result = letterCasePermutation('a1b2');
7+
const expected = ['a1b2', 'a1B2', 'A1b2', 'A1B2'];
8+
expect(result).toEqual(expected);
9+
});
10+
11+
test('3z4', () => {
12+
const result = letterCasePermutation('3z4');
13+
const expected = ['3z4', '3Z4'];
14+
expect(result).toEqual(expected);
15+
});
16+
17+
test('12345', () => {
18+
const result = letterCasePermutation('12345');
19+
const expected = ['12345'];
20+
expect(result).toEqual(expected);
21+
});
22+
23+
});

__test__/word-search.test.js

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import wordSearch from '../word-search';
2+
3+
describe('Word Search', () => {
4+
5+
let board;
6+
7+
beforeEach(() => {
8+
board = [
9+
['A','B','C','E'],
10+
['S','F','C','S'],
11+
['A','D','E','E']
12+
];
13+
});
14+
15+
test('ABCCED', () => {
16+
const result = wordSearch(board, 'ABCCED');
17+
const expected = true;
18+
expect(result).toEqual(expected);
19+
});
20+
21+
test('SEE', () => {
22+
const result = wordSearch(board, 'SEE');
23+
const expected = true;
24+
expect(result).toEqual(expected);
25+
});
26+
27+
test('ABCB', () => {
28+
const result = wordSearch(board, 'ABCB');
29+
const expected = false;
30+
expect(result).toEqual(expected);
31+
});
32+
33+
});

balance-parentheses-stack.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
class Stack {
2+
constructor() {
3+
this.stack = [];
4+
}
5+
6+
push(item) {
7+
this.stack.push(item);
8+
}
9+
10+
pop() {
11+
return this.stack.pop();
12+
}
13+
14+
isEmpty() {
15+
return this.stack.length === 0;
16+
}
17+
}
18+
19+
const isBalanced = (parentheses) => {
20+
const stack = new Stack();
21+
const pairs = {
22+
'(': ')',
23+
'[': ']',
24+
'{': '}',
25+
};
26+
27+
for (const single of parentheses) {
28+
if (pairs[single] !== undefined) {
29+
stack.push(pairs[single]);
30+
} else if (stack.isEmpty()) {
31+
return false;
32+
} else if (stack.pop() !== single) {
33+
return false;
34+
}
35+
}
36+
37+
return stack.isEmpty();
38+
};
39+
40+
console.log(isBalanced('{[]}'));
41+
console.log(isBalanced('{[}}'));

letter-case-permutation.js

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Letter Case Permutation
3+
* Given a string S, we can transform every letter individually to be lowercase or uppercase to create another string. Return a list of all possible strings we could create.
4+
*
5+
* Examples:
6+
* Input: S = "a1b2"
7+
* Output: ["a1b2", "a1B2", "A1b2", "A1B2"]
8+
*
9+
* Input: S = "3z4"
10+
* Output: ["3z4", "3Z4"]
11+
*
12+
* Input: S = "12345"
13+
* Output: ["12345"]
14+
* Note:
15+
*
16+
* S will be a string with length between 1 and 12.
17+
* S will consist only of letters or digits.
18+
*
19+
*/
20+
21+
const letterCasePermutation = (str, index = 0, newStr = '', ans = []) => {
22+
if (index === str.length) {
23+
return ans.push(newStr);
24+
}
25+
26+
const char = str.charAt(index);
27+
index++;
28+
29+
if (/[a-z]/i.test(char)) {
30+
letterCasePermutation(str, index, newStr + char.toLowerCase(), ans);
31+
letterCasePermutation(str, index, newStr + char.toUpperCase(), ans);
32+
} else {
33+
letterCasePermutation(str, index, newStr + char, ans);
34+
}
35+
36+
return ans;
37+
};
38+
39+
export default letterCasePermutation;

rat-in-maze-backtracking.js

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
const maze = [
2+
[ 1, 0, 0, 0 ],
3+
[ 1, 1, 0, 1 ],
4+
[ 1, 0, 0, 0 ],
5+
[ 1, 1, 1, 1 ],
6+
];
7+
8+
class MazeBacktrack {
9+
constructor(maze) {
10+
if (!Array.isArray(maze) || maze.length === 0) {
11+
throw new Error('Maze should be an array with more than one row');
12+
}
13+
14+
this.maze = maze;
15+
this.numberOfRows = maze.length;
16+
this.numberOfColumns = maze[0].length;
17+
this.exitRow = this.numberOfRows - 1;
18+
this.exitColumn = this.numberOfColumns - 1;
19+
this.directions = [
20+
[ 0, 1 ], // FORWARD
21+
[ 1, 0 ], // DOWN
22+
];
23+
this.clearSolution();
24+
}
25+
26+
clearSolution() {
27+
this.solution = new Array(this.numberOfRows)
28+
.fill(null)
29+
.map(() => new Array(this.numberOfColumns).fill(0));
30+
}
31+
32+
isValid(i, j) {
33+
return (
34+
i >= 0 &&
35+
i < this.numberOfRows &&
36+
j >= 0 &&
37+
j < this.numberOfColumns &&
38+
this.maze[i][j] === 1
39+
);
40+
}
41+
42+
/**
43+
*
44+
* @param {number} i
45+
* @param {number} j
46+
* @time complexity: O(2^(N^2))
47+
* @space complexity: O(N^2)
48+
*/
49+
dfs(i = 0, j = 0) {
50+
if (!this.isValid(i, j)) {
51+
return false;
52+
}
53+
54+
// MARK CURRENT BLOCK AS PART OF THE SOLUTION
55+
this.solution[i][j] = 1;
56+
57+
// READ THE DESINTATION
58+
if (i === this.exitRow && j === this.exitColumn) {
59+
return this.solution;
60+
}
61+
62+
for (const [x, y] of this.directions) {
63+
if (this.dfs(i + x, j + y)) {
64+
return this.solution;
65+
}
66+
}
67+
68+
// UNMARK CURRENT BLOCK
69+
this.solution[i][j] = 0;
70+
71+
return false;
72+
}
73+
}
74+
75+
const solve = new MazeBacktrack(maze);
76+
77+
console.log(solve.dfs());

word-search.js

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/**
2+
* Word Search
3+
* Given a 2D board and a word, find if the word exists in the grid.
4+
*
5+
* The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.
6+
*
7+
* Example:
8+
*
9+
* board =
10+
* [
11+
* ['A','B','C','E'],
12+
* ['S','F','C','S'],
13+
* ['A','D','E','E']
14+
* ]
15+
*
16+
* Given word = "ABCCED", return true.
17+
* Given word = "SEE", return true.
18+
* Given word = "ABCB", return false.
19+
*/
20+
21+
const wordSearch = (board, word) => {
22+
const rows = board.length,
23+
cols = board[0].length,
24+
directions = [
25+
[ -1, 0 ], // Up
26+
[ 0, 1 ], // Right
27+
[ 1, 0 ], // Down
28+
[ 0, -1 ], // Left
29+
];
30+
31+
const bfs = (i, j, index) => {
32+
if (i < 0 || i >= rows || j < 0 || j >= cols || // OUT OF RANGE
33+
board[i][j] !== word.charAt(index)) { // NOT SAME CHARACTER
34+
return false;
35+
}
36+
37+
index++;
38+
39+
// END OF WORD
40+
// MATCH IS FOUND
41+
if (index === word.length) {
42+
return true;
43+
}
44+
45+
const temp = board[i][j];
46+
board[i][j] = null;
47+
48+
for (const [x, y] of directions) {
49+
if (bfs(i + x, j + y, index)) {
50+
return true;
51+
}
52+
}
53+
54+
board[i][j] = temp;
55+
return false;
56+
};
57+
58+
for (let i = 0; i < rows; i++) {
59+
for (let j = 0; j < cols; j++) {
60+
if (bfs(i, j, 0)) {
61+
return true;
62+
}
63+
}
64+
}
65+
66+
return false;
67+
};
68+
69+
export default wordSearch;

0 commit comments

Comments
 (0)