Skip to content

Commit fd0c359

Browse files
committedJan 22, 2019
Merge branch 'book' into gitbook
2 parents d80d5eb + a2cc598 commit fd0c359

File tree

8 files changed

+612
-3
lines changed

8 files changed

+612
-3
lines changed
 

‎.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@ node_modules
33
coverage/
44
**/dist/
55
_book/
6+
<<<<<<< HEAD
7+
=======
8+
.DS_Store
9+
>>>>>>> book
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/* eslint-disable */
2+
3+
/**
4+
* binary search O(log n)
5+
* @param {number[]} nums
6+
* @param {number} target
7+
* @return {number}
8+
*/
9+
var searchInsert = function(nums, target, start = 0) {
10+
if (!nums.length) return start;
11+
const i = parseInt(nums.length / 2, 10);
12+
13+
if (nums[i] === target) {
14+
return start + i;
15+
} else if (target > nums[i]) {
16+
const newArray = nums.slice(i + 1);
17+
if (!newArray.length) return start + i + 1;
18+
return searchInsert(newArray, target, start + i + 1);
19+
} else {
20+
return searchInsert(nums.slice(0, i), target, start);
21+
}
22+
};
23+
24+
// ---
25+
26+
const assert = require('assert');
27+
function test() {
28+
assert.equal(searchInsert([], 0), 0);
29+
assert.equal(searchInsert([], 1), 0);
30+
31+
assert.equal(searchInsert([1], 0), 0);
32+
assert.equal(searchInsert([1], 2), 1);
33+
34+
assert.equal(searchInsert([1,3,5,6], 5), 2);
35+
assert.equal(searchInsert([1,3,5,6], 2), 1);
36+
assert.equal(searchInsert([1,3,5,6], 7), 4);
37+
assert.equal(searchInsert([1,3,5,6], 0), 0);
38+
39+
assert.equal(searchInsert([1,3,5], 5), 2);
40+
41+
}
42+
test();
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/* eslint-disable */
2+
3+
/**
4+
* https://leetcode.com/articles/regular-expression-matching/
5+
* Pattern:
6+
* '.' Matches any single character.
7+
* '*' Matches zero or more of the preceding element.
8+
*
9+
* @param {string} s
10+
* @param {string} p
11+
* @return {boolean}
12+
*/
13+
var isMatch = function(s, p) {
14+
let si = s.length - 1;
15+
16+
for(let pi = p.length - 1; pi > 0; pi--) {
17+
switch(p[pi]) {
18+
case '.':
19+
if (si > 0) { si--; }
20+
else { return false; }
21+
break;
22+
case '*':
23+
const char = p[--pi];
24+
while(si > 0 && (char === '.' || char === s[si])) {
25+
si--;
26+
}
27+
break;
28+
default:
29+
if (si > 0 && p[pi] === s[si]) {
30+
si--;
31+
} else {
32+
return false;
33+
}
34+
}
35+
}
36+
37+
return si <= 0;
38+
};
39+
40+
const assert = require('assert');
41+
function test() {
42+
assert.equal(isMatch('aa', 'aa'), true);
43+
assert.equal(isMatch('aa', 'a'), false);
44+
45+
assert.equal(isMatch('aa', 'a.'), true);
46+
assert.equal(isMatch('aaa', 'a.'), false);
47+
assert.equal(isMatch('aaa', 'a..'), true);
48+
49+
assert.equal(isMatch('', 'a*'), true);
50+
assert.equal(isMatch('a', 'a*'), true);
51+
assert.equal(isMatch('aa', 'a*'), true);
52+
assert.equal(isMatch('aab', 'a*'), false);
53+
assert.equal(isMatch('aab', 'a*b'), true);
54+
55+
assert.equal(isMatch('aab', 'c*a*b'), true);
56+
assert.equal(isMatch('caab', 'c*a*b'), true);
57+
58+
assert.equal(isMatch('abc', '.*'), true);
59+
60+
assert.equal(isMatch('mississippi', 'mis*is*p*.'), false);
61+
assert.equal(isMatch('mississippi', 'mis*is*ip*.'), true);
62+
63+
assert.equal(isMatch('ab', '.*..'), true);
64+
assert.equal(isMatch('abcz', '.*z'), true);
65+
assert.equal(isMatch('abcz', '.*x'), false);
66+
assert.equal(isMatch('zabc', 'z.*'), true);
67+
assert.equal(isMatch('zabc', 'x.*'), false);
68+
assert.equal(isMatch('zabcz', 'z.*z'), true);
69+
assert.equal(isMatch('zabcx', 'z.*z'), false);
70+
}
71+
test();
72+
73+
74+
75+
/////
76+
77+
var isMatch3 = function(s, p) {
78+
let pi = 0;
79+
80+
for(let si = 0; si < s.length; si++) {
81+
switch(p[pi]) {
82+
case '.':
83+
if (pi < p.length) { pi++; }
84+
else { return false; }
85+
break;
86+
case '*':
87+
const last = p[pi - 1];
88+
if(last === s[si]) {
89+
break; // break switch
90+
}
91+
pi++; // continue to the default case
92+
default:
93+
if (pi < p.length && p[pi] === s[si]) {
94+
pi++;
95+
continue;
96+
} else {
97+
return false;
98+
}
99+
}
100+
}
101+
102+
return true;
103+
};
104+
105+
var isMatch2 = function(s, p) {
106+
let pi = p.length - 1;
107+
108+
for(let si = s.length - 1; si > 0; si--) {
109+
switch(p[pi]) {
110+
case '.':
111+
if (pi > 0) { pi--; }
112+
else { return false; }
113+
break;
114+
case '*':
115+
const last = p[--pi];
116+
while(si > 0 && last === s[si]) {
117+
si--;
118+
}
119+
break;
120+
default:
121+
if (pi > 0 && p[pi] === s[si]) {
122+
pi--;
123+
continue;
124+
} else {
125+
return false;
126+
}
127+
}
128+
}
129+
130+
return true;
131+
};
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/* eslint-disable */
2+
3+
/**
4+
* Runtime O(10^n)
5+
* https://leetcode.com/problems/next-permutation/
6+
* @param {number[]} nums
7+
* @return {void} Do not return anything, modify nums in-place instead.
8+
*/
9+
var nextPermutation2 = function(nums) {
10+
const current = parseInt(nums.join(''), 10);
11+
const max = Math.pow(10, nums.length);
12+
13+
for(let next = current + 1; next < max; next++) {
14+
if(isPermutation(nums, next)) {
15+
setNumbersInArray(nums, next);
16+
return;
17+
}
18+
}
19+
};
20+
21+
function isPermutation(array, number) {
22+
return array.sort().join('') === numberToArray(number, array.length).sort().join('');
23+
}
24+
25+
function numberToArray(num, pad = 0) {
26+
return num.toString().padStart(pad, "0").split('').map(s => +s)
27+
}
28+
29+
function setNumbersInArray(to, number) {
30+
const from = numberToArray(number, to.length);
31+
32+
for(let i = 0; i < to.length; i++) {
33+
to[i] = from[i];
34+
}
35+
}
36+
37+
38+
/*
39+
// swap last with previous and check if is bigger
40+
// if not, swap last with previous - 1 recursively and check if bigger
41+
// sort in asc order the rest and check if bigger
42+
43+
123
44+
132
45+
213
46+
231
47+
312
48+
321
49+
---
50+
123
51+
*/
52+
53+
// generate all numbers - discard no matching: O(10^n)
54+
//
55+
56+
57+
// starting from last find a bigger number than current
58+
59+
60+
function nextPermutation(nums) {
61+
62+
// try to find next
63+
for(let i = nums.length - 2; i >= 0; i--) {
64+
let smallestBigger;
65+
66+
for(let j = i + 1; j < nums.length; j++) {
67+
if (nums[j] > nums[i]) {
68+
smallestBigger = Math.min(nums[j], smallestBigger || nums[j]);
69+
}
70+
}
71+
72+
if (smallestBigger) {
73+
const k = nums.lastIndexOf(smallestBigger);
74+
[nums[i], nums[k]] = [nums[k], nums[i]]; // swap
75+
// sort asc starting from i
76+
sort(nums, i + 1);
77+
return;
78+
}
79+
}
80+
81+
sort(nums);
82+
}
83+
84+
/**
85+
* Sort in-place from start on
86+
* @param {*} array
87+
* @param {*} start
88+
*/
89+
function sort(array, start = 0) {
90+
for(let i = start; i < array.length; i++) {
91+
for (let j = i + 1; j < array.length; j++) {
92+
if (array[i] > array[j]) {
93+
[array[i], array[j]] = [array[j], array[i]];
94+
}
95+
}
96+
}
97+
}
98+
99+
// -----
100+
const assert = require('assert');
101+
function test() {
102+
let a;
103+
104+
a = [100, 4,3,2];
105+
sort(a, 1);
106+
assert.deepEqual(a, [100, 2, 3, 4]);
107+
108+
a = [1, 2, 3];
109+
nextPermutation(a);
110+
assert.deepStrictEqual(a, [1, 3, 2]);
111+
112+
a = [2, 3, 1];
113+
nextPermutation(a);
114+
assert.deepStrictEqual(a, [3, 1, 2]);
115+
116+
a = [3, 2, 1];
117+
nextPermutation(a);
118+
assert.deepEqual(a, [1, 2, 3]);
119+
120+
a = [0,0,4,2,1,0];
121+
nextPermutation(a);
122+
assert.deepStrictEqual(a, [0,1,0,0,2,4]);
123+
124+
// Time Limit Exceeded on leetcode for O(n^10) algorithm
125+
a = [2,2,7,5,4,3,2,2,1];
126+
nextPermutation(a);
127+
assert.deepStrictEqual(a, [2,3,1,2,2,2,4,5,7]);
128+
129+
a = [5,4,7,5,3,2];
130+
nextPermutation(a);
131+
assert.deepEqual(a, [5,5,2,3,4,7]);
132+
}
133+
test();

‎lab/exercises/medium/permute.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/* eslint-disable */
2+
3+
/**
4+
* https://www.youtube.com/watch?v=AfxHGNRtFac
5+
* https://www.geeksforgeeks.org/write-a-c-program-to-print-all-permutations-of-a-given-string/
6+
* https://leetcode.com/articles/permutations/
7+
* @param {number[]} nums
8+
* @return {number[][]}
9+
*/
10+
var permute = function (nums) {
11+
var result = [];
12+
backtrack(nums, result);
13+
return result;
14+
};
15+
16+
function backtrack(nums, result, first = 0) {
17+
// console.log(Array(first).fill(" ").join(""), JSON.stringify({nums, first}));
18+
if (first === nums.length - 1) {
19+
// console.log(nums);
20+
result.push(nums.slice());
21+
} else {
22+
for (let i = first; i < nums.length; i++) {
23+
swap(nums, first, i);
24+
backtrack(nums, result, first + 1);
25+
swap(nums, first, i);
26+
}
27+
}
28+
};
29+
30+
function swap(array, i, j) {
31+
[array[i], array[j]] = [array[j], array[i]]
32+
}
33+
34+
// ---
35+
36+
const assert = require('assert');
37+
38+
function test() {
39+
// assert.deepEqual(permute([1]), [
40+
// [1]
41+
// ]);
42+
// assert.deepEqual(permute([1, 2]), [
43+
// [1, 2],
44+
// [2, 1]
45+
// ]);
46+
assert.deepEqual(permute([1, 2, 3]), [
47+
[1, 2, 3],
48+
[1, 3, 2],
49+
[2, 1, 3],
50+
[2, 3, 1],
51+
[3, 2, 1],
52+
[3, 1, 2]
53+
]);
54+
}
55+
test();
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/* eslint-disable */
2+
3+
/**
4+
* @param {number[]} nums
5+
* @param {number} k
6+
* @return {number[]}
7+
*/
8+
var topKFrequent = function(nums, k) {
9+
const count = getCount(nums); // O(n)
10+
const frequenciesToNumbers = invertMapKeyValues(count); // O(n)
11+
12+
// print the last k most frequent
13+
const descendingFrequencies = Array.from(frequenciesToNumbers.keys()).sort((a, b) => b - a);
14+
const valuesByFrequencencies = descendingFrequencies.reduce((array, key) => {
15+
return array.concat(frequenciesToNumbers.get(key));
16+
},[]);
17+
18+
// console.log(JSON.stringify({freqToNum: Array.from(freqToNum), f, v}));
19+
20+
return valuesByFrequencencies.slice(0, k);
21+
};
22+
23+
/**
24+
* Get repeated number count
25+
* Runtime: O(n)
26+
* @param {array} nums
27+
* @returns {Map} counts
28+
*/
29+
function getCount(nums) {
30+
const counts = new Map();
31+
32+
for(let n of nums) {
33+
if(counts.has(n)) {
34+
counts.set(n, 1 + counts.get(n));
35+
} else {
36+
counts.set(n, 1);
37+
}
38+
}
39+
40+
return counts;
41+
}
42+
43+
/**
44+
* Invert key and values in a Map.
45+
* Similar to _.invert (https://lodash.com/docs/4.17.11#invert)
46+
* @param {*} map
47+
*/
48+
function invertMapKeyValues(map) {
49+
const inverted = new Map();
50+
51+
for(let [key, value] of map.entries()) {
52+
if (inverted.has(value)) {
53+
inverted.set(value, inverted.get(value).concat(key));
54+
} else {
55+
inverted.set(value, [key]);
56+
}
57+
}
58+
59+
return inverted;
60+
}
61+
62+
/*
63+
< O(n log n) - linear or log
64+
65+
*/
66+
67+
// hashmap
68+
69+
// ---
70+
71+
const assert = require('assert');
72+
function test() {
73+
assert.deepEqual(topKFrequent([1], 1), [1]);
74+
assert.deepEqual(topKFrequent([1,1,1,2,2,3], 2), [1, 2]);
75+
assert.deepEqual(topKFrequent([3, 1, 4, 4, 5, 2, 6, 1], 2), [1, 4]);
76+
assert.deepEqual(topKFrequent([7, 10, 11, 5, 2, 5, 5, 7, 11, 8, 9], 4).sort(), [5, 11, 7, 10].sort());
77+
assert.deepEqual(topKFrequent([
78+
5,1,-1,-8,-7,8,-5,0,1,10,8,0,-4,3,-1,-1,4,-5,4,-3,0,2,2,2,4,-2,-4,8,-7,-7,2,-8,0,-8,10,8,-8,-2,-9,4,-7,6,6,-1,4,2,8,-3,5,-9,-3,6,-8,-5,5,10,2,-5,-1,-5,1,-3,7,0,8,-2,-3,-1,-5,4,7,-9,0,2,10,4,4,-4,-1,-1,6,-8,-9,-1,9,-9,3,5,1,6,-1,-2,4,2,4,-6,4,4,5,-5
79+
], 7).sort(), [
80+
4,-1,2,-5,-8,8,0
81+
].sort());
82+
}
83+
test();
84+
85+
86+
/*
87+
{
88+
freqToNum: Map {
89+
12 => [4],
90+
10 => [-1],
91+
8 => [2],
92+
7 => [-5],
93+
6 => [-8, 8, 0],
94+
5 => [5, -3, -9, 6],
95+
4 => [1, -7, 10, -2],
96+
3 => [-4],
97+
2 => [3, 7],
98+
1 => [9, -6]
99+
},
100+
f: [8, 7, 6, 5, 4, 3, 2, 12, 10, 1],
101+
v: [2, -5, -8, 8, 0, 5, -3, -9, 6, 1, -7, 10, -2, -4, 3, 7, 4, -1, 9, -6]
102+
}
103+
104+
other solutions: https://leetcode.com/submissions/detail/202508293/
105+
*/
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/* eslint-disable */
2+
3+
4+
/**
5+
* @param {number[]} nums
6+
* @param {number} k
7+
* @return {number[]}
8+
*/
9+
var topKFrequent2 = function (nums, k) {
10+
11+
let newObj = {};
12+
13+
for (let n of nums) {
14+
if (newObj[n]) {
15+
newObj[n]++;
16+
} else {
17+
newObj[n] = 1;
18+
}
19+
}
20+
21+
return Object.keys(newObj).sort((a, b) => newObj[b] - newObj[a]).splice(0, k);
22+
};
23+
24+
25+
/**
26+
* @param {number[]} nums
27+
* @param {number} k
28+
* @return {number[]}
29+
*/
30+
31+
var topKFrequent = function (nums, k) {
32+
var obj = {};
33+
nums.forEach(function (item) {
34+
if (!obj[item])
35+
obj[item] = 1;
36+
else
37+
obj[item]++;
38+
});
39+
40+
var arr = [];
41+
42+
for (var key in obj) {
43+
arr.push({
44+
key: key,
45+
value: obj[key]
46+
});
47+
}
48+
49+
arr.sort(function (a, b) {
50+
return b.value - a.value;
51+
});
52+
53+
var ans = [];
54+
for (var i = 0; i < k; i++)
55+
ans.push(+arr[i].key);
56+
57+
58+
// console.log(JSON.stringify({
59+
// obj,
60+
// arr,
61+
// ans
62+
// }))
63+
64+
return ans;
65+
};
66+
67+
// ---
68+
69+
const assert = require('assert');
70+
71+
function test() {
72+
assert.deepEqual(topKFrequent([1], 1), [1]);
73+
assert.deepEqual(topKFrequent([1, 1, 1, 2, 2, 3], 2), [1, 2]);
74+
assert.deepEqual(topKFrequent([3, 1, 4, 4, 5, 2, 6, 1], 2), [1, 4]);
75+
// assert.deepEqual(topKFrequent([7, 10, 11, 5, 2, 5, 5, 7, 11, 8, 9], 4).sort(), [5, 11, 7, 10].sort());
76+
// assert.deepEqual(topKFrequent([7, 10, 11, 5, 2, 5, 5, 7, 11, 8, 9], 4).sort(), [5, 7, 11, 2].sort()); // also
77+
assert.deepEqual(topKFrequent([
78+
5, 1, -1, -8, -7, 8, -5, 0, 1, 10, 8, 0, -4, 3, -1, -1, 4, -5, 4, -3, 0, 2, 2, 2, 4, -2, -4, 8, -7, -7, 2, -8, 0, -8, 10, 8, -8, -2, -9, 4, -7, 6, 6, -1, 4, 2, 8, -3, 5, -9, -3, 6, -8, -5, 5, 10, 2, -5, -1, -5, 1, -3, 7, 0, 8, -2, -3, -1, -5, 4, 7, -9, 0, 2, 10, 4, 4, -4, -1, -1, 6, -8, -9, -1, 9, -9, 3, 5, 1, 6, -1, -2, 4, 2, 4, -6, 4, 4, 5, -5
79+
], 7).sort(), [
80+
4, -1, 2, -5, -8, 8, 0
81+
].sort());
82+
}
83+
test();
84+
85+
86+
/*
87+
{
88+
freqToNum: Map {
89+
12 => [4],
90+
10 => [-1],
91+
8 => [2],
92+
7 => [-5],
93+
6 => [-8, 8, 0],
94+
5 => [5, -3, -9, 6],
95+
4 => [1, -7, 10, -2],
96+
3 => [-4],
97+
2 => [3, 7],
98+
1 => [9, -6]
99+
},
100+
f: [8, 7, 6, 5, 4, 3, 2, 12, 10, 1],
101+
v: [2, -5, -8, 8, 0, 5, -3, -9, 6, 1, -7, 10, -2, -4, 3, 7, 4, -1, 9, -6]
102+
}
103+
104+
other solutions: https://leetcode.com/submissions/detail/202508293/
105+
*/

‎lab/exercises/medium/zigzag-conversion.js

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-disable */
2-
// 2d-array
2+
// 2d-array; time: O(n); space: O(n^2)
33

44
/**
55
* @param {string} s
@@ -59,9 +59,43 @@ function goDiagonal({ col, row, index, table, word, numRows }) {
5959

6060
const assert = require('assert');
6161
function test() {
62+
assert.equal(convert('PAYPALISHIRING', 1), 'PAYPALISHIRING');
63+
assert.equal(convert('PAYPALISHIRING', 2), 'PYAIHRNAPLSIIG');
6264
assert.equal(convert('PAYPALISHIRING', 3), 'PAHNAPLSIIGYIR');
6365
assert.equal(convert('PAYPALISHIRING', 4), 'PINALSIGYAHRPI');
64-
assert.equal(convert('AB', 1), 'AB');
6566
}
66-
6767
test();
68+
69+
/*
70+
char* convert(char* s, int numRows) {
71+
if (numRows == 1) {
72+
return s;
73+
}
74+
int len = strlen(s);
75+
char *buf = (char *) malloc(sizeof(char) * (len + 1));
76+
int i = 0;
77+
for (int row = 0; row < numRows; row++) {
78+
int step = (numRows - 1) * 2;
79+
int j = 0;
80+
while (j + row < len) {
81+
buf[i++] = s[j + row];
82+
j += step;
83+
if (row > 0 && row < numRows - 1 && j - row < len) {
84+
buf[i++] = s[j - row];
85+
}
86+
}
87+
}
88+
buf[len] = '\0';
89+
return buf;
90+
}
91+
*/
92+
93+
// function convert(s, numRows) {
94+
// if (numRows === 1) { return s; }
95+
96+
// let buffer;
97+
// let i = 0;
98+
// for(let row = 0; row < numRows; row++) {
99+
// const step = (numRows - 1 ) * 2; // Characters in row 0 are located at indexes
100+
// }
101+
// }

0 commit comments

Comments
 (0)
Please sign in to comment.