Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6d8a9bb

Browse files
authored
Merge branch 'neetcode-gh:main' into main
2 parents 67dabb9 + db1b275 commit 6d8a9bb

9 files changed

+852
-0
lines changed

javascript/286-Walls-And-Gates.js

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
//////////////////////////////////////////////////////////////////////////////
2+
// Depth First Search (DFS)
3+
// Time: Theta(mn) O(mnk) Space: Theta(mn) O(mn)
4+
// Theoretically the BFS implementation should be faster as it calculates the
5+
// distance from the gate for each cell exactly once, but in practice the DFS
6+
// solution outperforms it. I'm guessing the implementation of the queue,
7+
// specifically `queue.shift()`, costs more than the few extra DFS
8+
// calculations that occur.
9+
//////////////////////////////////////////////////////////////////////////////
10+
11+
const INF = 2 ** 31 - 1;
12+
13+
/**
14+
* @param {number[][]} rooms
15+
* @return {void} Do not return anything, modify rooms in-place instead.
16+
*/
17+
function wallsAndGates(rooms) {
18+
for (let i = 0; i < rooms.length; ++i) {
19+
for (let j = 0; j < rooms[0].length; ++j) {
20+
if (rooms[i][j] === 0) {
21+
fillRooms(rooms, i - 1, j);
22+
fillRooms(rooms, i + 1, j);
23+
fillRooms(rooms, i, j - 1);
24+
fillRooms(rooms, i, j + 1);
25+
}
26+
}
27+
}
28+
}
29+
30+
/**
31+
* @param {number[][]} rooms
32+
* @param {number} i
33+
* @param {number} j
34+
* @param {number=} count = `0`
35+
* @return {void}
36+
*/
37+
function fillRooms(rooms, i, j, count = 0) {
38+
39+
if (!inBounds(rooms, i, j) || rooms[i][j] < 1) {
40+
return;
41+
}
42+
43+
++count;
44+
45+
if (rooms[i][j] !== INF && rooms[i][j] <= count) {
46+
return;
47+
}
48+
49+
rooms[i][j] = count;
50+
51+
fillRooms(rooms, i - 1, j, count);
52+
fillRooms(rooms, i + 1, j, count);
53+
fillRooms(rooms, i, j - 1, count);
54+
fillRooms(rooms, i, j + 1, count);
55+
}
56+
57+
/**
58+
* @param {number[][]} rooms
59+
* @param {number} i
60+
* @param {number} j
61+
* @return {boolean}
62+
*/
63+
function inBounds(rooms, i, j) {
64+
return i >= 0 && j >= 0 && i < rooms.length && j < rooms[0].length;
65+
}
66+
67+
//////////////////////////////////////////////////////////////////////////////
68+
// Breadth First Search (BFS)
69+
// Time: Theta(mn) O(mn) Space: Theta(mn) O(mn)
70+
// Theoretically the BFS implementation should be faster as it calculates the
71+
// distance from the gate for each cell exactly once, but in practice the DFS
72+
// solution outperforms it. I'm guessing the implementation of the queue,
73+
// specifically `queue.shift()`, costs more than the few extra DFS
74+
// calculations that occur.
75+
//////////////////////////////////////////////////////////////////////////////
76+
77+
const INF = 2 ** 31 - 1;
78+
const DIRECTIONS = [
79+
[ -1, 0 ],
80+
[ 1, 0 ],
81+
[ 0, -1 ],
82+
[ 0, 1 ],
83+
];
84+
85+
/**
86+
* @param {number[][]} rooms
87+
* @return {void}
88+
*/
89+
function wallsAndGates(rooms) {
90+
91+
const queue = [];
92+
93+
for (let i = 0; i < rooms.length; ++i) {
94+
for (let j = 0; j < rooms[0].length; ++j) {
95+
if (rooms[i][j] === 0) {
96+
queue.push([ i, j ]);
97+
}
98+
}
99+
}
100+
101+
let count = 1;
102+
103+
while (queue.length) {
104+
105+
let length = queue.length;
106+
107+
while (length--) {
108+
109+
[ i, j ] = queue.shift();
110+
111+
for ([ k, l ] of DIRECTIONS) {
112+
k += i;
113+
l += j;
114+
if (inBounds(rooms, k, l) && rooms[k][l] === INF) {
115+
rooms[k][l] = count;
116+
queue.push([ k, l ]);
117+
}
118+
}
119+
}
120+
121+
++count;
122+
}
123+
}
124+
125+
/**
126+
* @param {number[][]} rooms
127+
* @param {number} i
128+
* @param {number} j
129+
* @return {boolean}
130+
*/
131+
function inBounds(rooms, i, j) {
132+
return i >= 0 && j >= 0 && i < rooms.length && j < rooms[0].length;
133+
}

javascript/36-Valid-Sudoku.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**
2+
* @param {character[][]} board
3+
* @return {boolean}
4+
*/
5+
function isValidSudoku(board) {
6+
const rows = {};
7+
const cols = {};
8+
const squares = {};
9+
10+
for (let r = 0; r < 9; r++) {
11+
for (let c = 0; c < 9; c++) {
12+
const num = board[r][c];
13+
14+
if (num === '.') {
15+
continue;
16+
}
17+
18+
const grid = `${Math.floor(r / 3)}${Math.floor(c / 3)}`;
19+
20+
if (!cols[c]) {
21+
cols[c] = new Set();
22+
}
23+
if (!rows[r]) {
24+
rows[r] = new Set();
25+
}
26+
if (!squares[grid]) {
27+
squares[grid] = new Set();
28+
}
29+
30+
if (rows[r].has(num) || cols[c].has(num) || squares[grid].has(num)) {
31+
return false;
32+
}
33+
34+
cols[c].add(num)
35+
rows[r].add(num)
36+
squares[grid].add(num)
37+
}
38+
}
39+
40+
return true;
41+
}

javascript/39-Combination-Sum.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//////////////////////////////////////////////////////////////////////////////
2+
// Backtracking
3+
// Time: Theta(log(n)^(target/min)) O(n^(target/min))
4+
// Space: Theta(log(n)*(target/min)^2) O(n*(target/min)^2)
5+
//////////////////////////////////////////////////////////////////////////////
6+
7+
/**
8+
* @param {number[]} candidates
9+
* @param {number} target
10+
* @return {number[][]}
11+
*/
12+
function combinationSum(candidates, target) {
13+
14+
candidates.sort((a, b) => a - b);
15+
16+
const combos = [];
17+
const combo = [];
18+
const set = new Set();
19+
20+
for (const candidate of candidates) {
21+
set.add(candidate);
22+
}
23+
24+
buildCombos(target);
25+
return combos;
26+
27+
/**
28+
* @param {number} target
29+
* @param {number=} start = `0`
30+
* @return {void}
31+
*/
32+
function buildCombos(target, start = 0) {
33+
34+
if (set.has(target)) {
35+
combo.push(target);
36+
combos.push(combo.slice());
37+
combo.pop();
38+
}
39+
40+
const mid = Math.floor(target / 2);
41+
for (let i = start; i < candidates.length && candidates[i] <= mid; ++i) {
42+
const candidate = candidates[i];
43+
combo.push(candidate);
44+
buildCombos(target - candidate, i);
45+
combo.pop();
46+
}
47+
}
48+
}

javascript/40-Combination-Sum-II.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//////////////////////////////////////////////////////////////////////////////
2+
// Backtracking
3+
// Time: Theta(2^log(n)) O(2^n)
4+
// Space: Theta(2^log(n)) O(2^n)
5+
//////////////////////////////////////////////////////////////////////////////
6+
7+
/**
8+
* @param {number[]} candidates
9+
* @param {number} target
10+
* @return {number[][]}
11+
*/
12+
function combinationSum2(candidates, target) {
13+
14+
candidates.sort((a, b) => a - b);
15+
16+
const combos = [];
17+
const combo = [];
18+
const map = Object.create(null);
19+
20+
for (let i = 0; i < candidates.length; ++i) {
21+
map[candidates[i]] = i;
22+
}
23+
24+
getCombos(target);
25+
return combos;
26+
27+
/**
28+
* @param {number} target
29+
* @param {number=} start = `0`
30+
* @return {void}
31+
*/
32+
function getCombos(target, start = 0) {
33+
34+
if (target in map && start <= map[target]) {
35+
combo.push(target);
36+
combos.push(combo.slice());
37+
combo.pop();
38+
}
39+
40+
const mid = Math.floor(target / 2);
41+
for (let i = start; i < candidates.length && candidates[i] <= mid; ++i) {
42+
if (i !== start && candidates[i] === candidates[i - 1]) {
43+
continue;
44+
}
45+
combo.push(candidates[i]);
46+
getCombos(target - candidates[i], i + 1);
47+
combo.pop();
48+
}
49+
}
50+
}

0 commit comments

Comments
 (0)