Skip to content

Commit 555e35d

Browse files
authored
Merge pull request #1151 from aakhtar3/subset
refactor: js-subset
2 parents c8ae072 + 29c2ca8 commit 555e35d

9 files changed

+381
-274
lines changed
Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,39 @@
1-
function partition(s) {
2-
let res = [];
3-
let part = [];
4-
5-
function dfs(i) {
6-
if (i >= s.length) {
7-
res.push(part.slice());
8-
return;
9-
}
10-
11-
for (let j = i; j < s.length; j++) {
12-
if (isPali(s, i, j)) {
13-
part.push(s.slice(i, j + 1));
14-
dfs(j + 1);
15-
part.pop();
16-
}
17-
}
18-
}
19-
20-
dfs(0);
21-
return res;
22-
23-
function isPali(s, l, r) {
24-
while (l < r) {
25-
if (s[l] != s[r]) {
26-
return false;
27-
}
28-
l = l + 1;
29-
r = r - 1;
30-
}
31-
return true;
32-
}
33-
}
1+
/**
2+
* https://leetcode.com/problems/palindrome-partitioning/
3+
* Time O(N * 2^N) | Space O(N^2)
4+
* @param {string} s
5+
* @return {string[][]}
6+
*/
7+
function partition(s, left = 0, _partition = [], partitions = []) {
8+
const isBaseCase = s.length <= left
9+
if (isBaseCase) {
10+
if (_partition.length) partitions.push(_partition.slice());
11+
12+
return partitions
13+
}
14+
15+
for (let right = left; right < s.length; right++) {
16+
if (!isPalindrome(s, left, right)) continue;
17+
18+
backTrack(s, left, right, _partition, partitions)
19+
}
20+
21+
return partitions
22+
}
23+
24+
const backTrack = (s, left, right, _partition, partitions) => {
25+
_partition.push(s.slice(left, (right + 1)));
26+
partition(s, (right + 1), _partition, partitions);
27+
_partition.pop();
28+
}
29+
30+
const isPalindrome = (str, left, right) => {
31+
while (left < right) {
32+
const isSame = str[left] === str[right];
33+
if (!isSame) return false;
34+
35+
left++; right--;
36+
}
37+
38+
return true;
39+
}
Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,39 @@
1-
function letterCombinations(digits) {
2-
let res = [];
3-
4-
const digitToChar = {
5-
2: 'abc',
6-
3: 'def',
7-
4: 'ghi',
8-
5: 'jkl',
9-
6: 'mno',
10-
7: 'qprs',
11-
8: 'tuv',
12-
9: 'wxyz',
13-
};
14-
15-
function backtrack(i, curStr) {
16-
if (curStr.length === digits.length) {
17-
res.push(curStr);
18-
return;
19-
}
20-
21-
for (const c of digitToChar[digits[i]]) {
22-
backtrack(i + 1, curStr + c);
23-
}
24-
}
25-
26-
if (digits) {
27-
backtrack(0, '');
28-
}
29-
30-
return res;
31-
}
1+
/**
2+
* https://leetcode.com/problems/letter-combinations-of-a-phone-number/
3+
* Time O(N * 4^N) | Space O(N)
4+
* @param {string} digits
5+
* @return {string[]}
6+
*/
7+
var letterCombinations = function(digits, combination = [], combinations = []) {
8+
const isBaseCase = !digits
9+
if (isBaseCase) {
10+
if (combination.length) combinations.push(combination.join(''))
11+
12+
return combinations;
13+
}
14+
15+
const letters = phoneButtons[ digits[0] ];
16+
17+
for (const char of letters) {
18+
backTrack(digits, char, combination, combinations);
19+
}
20+
21+
return combinations;
22+
};
23+
24+
const backTrack = (digits, char, combination, combinations) => {
25+
combination.push(char)
26+
letterCombinations(digits.slice(1), combination, combinations)
27+
combination.pop()
28+
}
29+
30+
const phoneButtons = ({
31+
2: ['a', 'b', 'c'],
32+
3: ['d', 'e', 'f'],
33+
4: ['g', 'h', 'i'],
34+
5: ['j', 'k', 'l'],
35+
6: ['m', 'n', 'o'],
36+
7: ['p', 'q', 'r', 's'],
37+
8: ['t', 'u', 'v'],
38+
9: ['w', 'x', 'y', 'z'],
39+
})

javascript/39-Combination-Sum.js

Lines changed: 17 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,26 @@
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-
71
/**
2+
* https://leetcode.com/problems/combination-sum/
3+
* Time O(N * ((Target/MIN) + 1)) | Space O(N * (Target/Min))
84
* @param {number[]} candidates
95
* @param {number} target
106
* @return {number[][]}
117
*/
12-
function combinationSum(candidates, target) {
13-
candidates.sort((a, b) => a - b);
14-
const combos = [];
15-
const combo = [];
16-
const set = new Set(candidates);
17-
buildCombos(target);
18-
return combos;
8+
var combinationSum = function (candidates, target, index = 0, combination = [], combinations = []) {
9+
const isBaseCase = target < 0;
10+
if (isBaseCase) return combinations;
1911

20-
/**
21-
* @param {number} target
22-
* @param {number=} start = `0`
23-
* @return {void}
24-
*/
25-
function buildCombos(target, start = 0) {
26-
if (set.has(target)) {
27-
combo.push(target);
28-
combos.push(combo.slice());
29-
combo.pop();
30-
}
12+
const isTarget = target === 0;
13+
if (isTarget) return combinations.push(combination.slice());
3114

32-
const mid = Math.floor(target / 2);
33-
for (
34-
let i = start;
35-
i < candidates.length && candidates[i] <= mid;
36-
++i
37-
) {
38-
const candidate = candidates[i];
39-
combo.push(candidate);
40-
buildCombos(target - candidate, i);
41-
combo.pop();
42-
}
15+
for (let i = index; i < candidates.length; i++) {
16+
backTrack(candidates, target, i, combination, combinations);
4317
}
18+
19+
return combinations;
4420
}
21+
22+
const backTrack = (candidates, target, i, combination, combinations) => {
23+
combination.push(candidates[i]);
24+
combinationSum(candidates, (target - candidates[i]), i, combination, combinations);
25+
combination.pop();
26+
}

javascript/40-Combination-Sum-II.js

Lines changed: 28 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,39 @@
1-
//////////////////////////////////////////////////////////////////////////////
2-
// Backtracking
3-
// Time: Theta(2^log(n)) O(2^n)
4-
// Space: Theta(2^log(n)) O(2^n)
5-
//////////////////////////////////////////////////////////////////////////////
6-
71
/**
2+
* https://leetcode.com/problems/combination-sum-ii/
3+
* Time O(2^N) | Space O(N)
84
* @param {number[]} candidates
95
* @param {number} target
106
* @return {number[][]}
117
*/
12-
function combinationSum2(candidates, target) {
13-
candidates.sort((a, b) => a - b);
8+
var combinationSum2 = function(candidates, target) {
9+
candidates.sort((a, b) => a - b)
10+
11+
return dfs(candidates, target)
12+
};
1413

15-
const combos = [];
16-
const combo = [];
17-
const map = Object.create(null);
14+
const dfs = (candidates, target, index = 0, combination = [], combinations = []) => {
15+
const isBaseCase = target < 0;
16+
if (isBaseCase) return combinations;
1817

19-
for (let i = 0; i < candidates.length; ++i) {
20-
map[candidates[i]] = i;
18+
const isTarget = target === 0;
19+
if (isTarget) {
20+
if (combination.length) combinations.push(combination.slice());
21+
22+
return combinations
2123
}
2224

23-
getCombos(target);
24-
return combos;
25-
26-
/**
27-
* @param {number} target
28-
* @param {number=} start = `0`
29-
* @return {void}
30-
*/
31-
function getCombos(target, start = 0) {
32-
if (target in map && start <= map[target]) {
33-
combo.push(target);
34-
combos.push(combo.slice());
35-
combo.pop();
36-
}
37-
38-
const mid = Math.floor(target / 2);
39-
for (
40-
let i = start;
41-
i < candidates.length && candidates[i] <= mid;
42-
++i
43-
) {
44-
if (i !== start && candidates[i] === candidates[i - 1]) {
45-
continue;
46-
}
47-
combo.push(candidates[i]);
48-
getCombos(target - candidates[i], i + 1);
49-
combo.pop();
50-
}
25+
for (let i = index; i < candidates.length; i++) {
26+
const isDuplicate = (index < i) && (candidates[i - 1] === candidates[i]);
27+
if (isDuplicate) continue;
28+
29+
backTrack(candidates, target, i, combination, combinations);
5130
}
31+
32+
return combinations;
33+
}
34+
35+
const backTrack = (candidates, target, i, combination, combinations) => {
36+
combination.push(candidates[i])
37+
dfs(candidates, (target - candidates[i]), (i + 1), combination, combinations)
38+
combination.pop()
5239
}

javascript/46-Permutations.js

Lines changed: 66 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,66 @@
1-
function permute(nums) {
2-
const res = [];
3-
4-
if (nums.length === 1) {
5-
return [nums.slice()];
6-
}
7-
8-
for (const i of nums) {
9-
let n = nums.shift();
10-
11-
let perms = permute(nums);
12-
13-
for (const perm of perms) {
14-
perm.push(n);
15-
}
16-
17-
perms.forEach((perm) => {
18-
res.push(perm);
19-
});
20-
21-
nums.push(n);
22-
}
23-
24-
return res;
25-
}
1+
/**
2+
* https://leetcode.com/problems/permutations/solution/
3+
* Time O(N!) | Space(N!)
4+
* @param {number[]} nums
5+
* @return {number[][]}
6+
*/
7+
var permute = function(nums) {
8+
return dfs(nums)
9+
}
10+
11+
var dfs = function(nums, permutation = [], permutations = []) {
12+
const isBaseCase = nums.length === permutation.length
13+
if (isBaseCase) return permutations.push(permutation.slice())
14+
15+
for (let i = 0; i < nums.length; i++) {
16+
if (permutation.includes(nums[i])) continue;
17+
18+
backTrack(nums, i, permutation, permutations);
19+
}
20+
21+
return permutations;
22+
}
23+
24+
const backTrack = (nums, i, permutation, permutations) => {
25+
permutation.push(nums[i])
26+
dfs(nums, permutation, permutations)
27+
permutation.pop()
28+
}
29+
30+
/**
31+
* https://leetcode.com/problems/permutations/solution/
32+
* Time O(N!) | Space(N!)
33+
* @param {number[]} nums
34+
* @return {number[][]}
35+
*/
36+
var permute = function(nums) {
37+
return bfs(nums)
38+
}
39+
40+
const bfs = (nums, levels = [[]], permutations = []) => {
41+
for (const num of nums) {
42+
for (let i = (levels.length - 1); 0 <= i; i--) {
43+
const previousLevel = levels.shift()
44+
45+
for (let index = 0; index < (previousLevel.length + 1); index++) {
46+
const level = reArrangeSet(previousLevel, num, index)
47+
48+
const isBaseCase = level.length === nums.length;
49+
if (isBaseCase) {
50+
permutations.push(level);
51+
continue
52+
}
53+
54+
levels.push(level)
55+
}
56+
}
57+
}
58+
59+
return permutations
60+
}
61+
62+
const reArrangeSet = (previousLevel, num, index) => {
63+
const [ before, after ] = [ previousLevel.slice(0, index), previousLevel.slice(index) ]
64+
65+
return [...before, num, ...after]
66+
}

0 commit comments

Comments
 (0)