Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 39 additions & 33 deletions javascript/131-Palindrome-Partitioning.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,39 @@
function partition(s) {
let res = [];
let part = [];

function dfs(i) {
if (i >= s.length) {
res.push(part.slice());
return;
}

for (let j = i; j < s.length; j++) {
if (isPali(s, i, j)) {
part.push(s.slice(i, j + 1));
dfs(j + 1);
part.pop();
}
}
}

dfs(0);
return res;

function isPali(s, l, r) {
while (l < r) {
if (s[l] != s[r]) {
return false;
}
l = l + 1;
r = r - 1;
}
return true;
}
}
/**
* https://leetcode.com/problems/palindrome-partitioning/
* Time O(N * 2^N) | Space O(N^2)
* @param {string} s
* @return {string[][]}
*/
function partition(s, left = 0, _partition = [], partitions = []) {
const isBaseCase = s.length <= left
if (isBaseCase) {
if (_partition.length) partitions.push(_partition.slice());

return partitions
}

for (let right = left; right < s.length; right++) {
if (!isPalindrome(s, left, right)) continue;

backTrack(s, left, right, _partition, partitions)
}

return partitions
}

const backTrack = (s, left, right, _partition, partitions) => {
_partition.push(s.slice(left, (right + 1)));
partition(s, (right + 1), _partition, partitions);
_partition.pop();
}

const isPalindrome = (str, left, right) => {
while (left < right) {
const isSame = str[left] === str[right];
if (!isSame) return false;

left++; right--;
}

return true;
}
70 changes: 39 additions & 31 deletions javascript/17-Letter-Combinations-of-a-Phone-Number.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,39 @@
function letterCombinations(digits) {
let res = [];

const digitToChar = {
2: 'abc',
3: 'def',
4: 'ghi',
5: 'jkl',
6: 'mno',
7: 'qprs',
8: 'tuv',
9: 'wxyz',
};

function backtrack(i, curStr) {
if (curStr.length === digits.length) {
res.push(curStr);
return;
}

for (const c of digitToChar[digits[i]]) {
backtrack(i + 1, curStr + c);
}
}

if (digits) {
backtrack(0, '');
}

return res;
}
/**
* https://leetcode.com/problems/letter-combinations-of-a-phone-number/
* Time O(N * 4^N) | Space O(N)
* @param {string} digits
* @return {string[]}
*/
var letterCombinations = function(digits, combination = [], combinations = []) {
const isBaseCase = !digits
if (isBaseCase) {
if (combination.length) combinations.push(combination.join(''))

return combinations;
}

const letters = phoneButtons[ digits[0] ];

for (const char of letters) {
backTrack(digits, char, combination, combinations);
}

return combinations;
};

const backTrack = (digits, char, combination, combinations) => {
combination.push(char)
letterCombinations(digits.slice(1), combination, combinations)
combination.pop()
}

const phoneButtons = ({
2: ['a', 'b', 'c'],
3: ['d', 'e', 'f'],
4: ['g', 'h', 'i'],
5: ['j', 'k', 'l'],
6: ['m', 'n', 'o'],
7: ['p', 'q', 'r', 's'],
8: ['t', 'u', 'v'],
9: ['w', 'x', 'y', 'z'],
})
52 changes: 17 additions & 35 deletions javascript/39-Combination-Sum.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,26 @@
//////////////////////////////////////////////////////////////////////////////
// Backtracking
// Time: Theta(log(n)^(target/min)) O(n^(target/min))
// Space: Theta(log(n)*(target/min)^2) O(n*(target/min)^2)
//////////////////////////////////////////////////////////////////////////////

/**
* https://leetcode.com/problems/combination-sum/
* Time O(N * ((Target/MIN) + 1)) | Space O(N * (Target/Min))
* @param {number[]} candidates
* @param {number} target
* @return {number[][]}
*/
function combinationSum(candidates, target) {
candidates.sort((a, b) => a - b);
const combos = [];
const combo = [];
const set = new Set(candidates);
buildCombos(target);
return combos;
var combinationSum = function (candidates, target, index = 0, combination = [], combinations = []) {
const isBaseCase = target < 0;
if (isBaseCase) return combinations;

/**
* @param {number} target
* @param {number=} start = `0`
* @return {void}
*/
function buildCombos(target, start = 0) {
if (set.has(target)) {
combo.push(target);
combos.push(combo.slice());
combo.pop();
}
const isTarget = target === 0;
if (isTarget) return combinations.push(combination.slice());

const mid = Math.floor(target / 2);
for (
let i = start;
i < candidates.length && candidates[i] <= mid;
++i
) {
const candidate = candidates[i];
combo.push(candidate);
buildCombos(target - candidate, i);
combo.pop();
}
for (let i = index; i < candidates.length; i++) {
backTrack(candidates, target, i, combination, combinations);
}

return combinations;
}

const backTrack = (candidates, target, i, combination, combinations) => {
combination.push(candidates[i]);
combinationSum(candidates, (target - candidates[i]), i, combination, combinations);
combination.pop();
}
69 changes: 28 additions & 41 deletions javascript/40-Combination-Sum-II.js
Original file line number Diff line number Diff line change
@@ -1,52 +1,39 @@
//////////////////////////////////////////////////////////////////////////////
// Backtracking
// Time: Theta(2^log(n)) O(2^n)
// Space: Theta(2^log(n)) O(2^n)
//////////////////////////////////////////////////////////////////////////////

/**
* https://leetcode.com/problems/combination-sum-ii/
* Time O(2^N) | Space O(N)
* @param {number[]} candidates
* @param {number} target
* @return {number[][]}
*/
function combinationSum2(candidates, target) {
candidates.sort((a, b) => a - b);
var combinationSum2 = function(candidates, target) {
candidates.sort((a, b) => a - b)

return dfs(candidates, target)
};

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

for (let i = 0; i < candidates.length; ++i) {
map[candidates[i]] = i;
const isTarget = target === 0;
if (isTarget) {
if (combination.length) combinations.push(combination.slice());

return combinations
}

getCombos(target);
return combos;

/**
* @param {number} target
* @param {number=} start = `0`
* @return {void}
*/
function getCombos(target, start = 0) {
if (target in map && start <= map[target]) {
combo.push(target);
combos.push(combo.slice());
combo.pop();
}

const mid = Math.floor(target / 2);
for (
let i = start;
i < candidates.length && candidates[i] <= mid;
++i
) {
if (i !== start && candidates[i] === candidates[i - 1]) {
continue;
}
combo.push(candidates[i]);
getCombos(target - candidates[i], i + 1);
combo.pop();
}
for (let i = index; i < candidates.length; i++) {
const isDuplicate = (index < i) && (candidates[i - 1] === candidates[i]);
if (isDuplicate) continue;

backTrack(candidates, target, i, combination, combinations);
}

return combinations;
}

const backTrack = (candidates, target, i, combination, combinations) => {
combination.push(candidates[i])
dfs(candidates, (target - candidates[i]), (i + 1), combination, combinations)
combination.pop()
}
91 changes: 66 additions & 25 deletions javascript/46-Permutations.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,66 @@
function permute(nums) {
const res = [];

if (nums.length === 1) {
return [nums.slice()];
}

for (const i of nums) {
let n = nums.shift();

let perms = permute(nums);

for (const perm of perms) {
perm.push(n);
}

perms.forEach((perm) => {
res.push(perm);
});

nums.push(n);
}

return res;
}
/**
* https://leetcode.com/problems/permutations/solution/
* Time O(N!) | Space(N!)
* @param {number[]} nums
* @return {number[][]}
*/
var permute = function(nums) {
return dfs(nums)
}

var dfs = function(nums, permutation = [], permutations = []) {
const isBaseCase = nums.length === permutation.length
if (isBaseCase) return permutations.push(permutation.slice())

for (let i = 0; i < nums.length; i++) {
if (permutation.includes(nums[i])) continue;

backTrack(nums, i, permutation, permutations);
}

return permutations;
}

const backTrack = (nums, i, permutation, permutations) => {
permutation.push(nums[i])
dfs(nums, permutation, permutations)
permutation.pop()
}

/**
* https://leetcode.com/problems/permutations/solution/
* Time O(N!) | Space(N!)
* @param {number[]} nums
* @return {number[][]}
*/
var permute = function(nums) {
return bfs(nums)
}

const bfs = (nums, levels = [[]], permutations = []) => {
for (const num of nums) {
for (let i = (levels.length - 1); 0 <= i; i--) {
const previousLevel = levels.shift()

for (let index = 0; index < (previousLevel.length + 1); index++) {
const level = reArrangeSet(previousLevel, num, index)

const isBaseCase = level.length === nums.length;
if (isBaseCase) {
permutations.push(level);
continue
}

levels.push(level)
}
}
}

return permutations
}

const reArrangeSet = (previousLevel, num, index) => {
const [ before, after ] = [ previousLevel.slice(0, index), previousLevel.slice(index) ]

return [...before, num, ...after]
}
Loading