Skip to content

Commit 7108329

Browse files
committed
Update
1 parent 10e31cf commit 7108329

18 files changed

+1700
-3
lines changed

count-binary-substrings.js

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* Count Binary Substring
3+
*
4+
* Give a string s, count the number of non-empty (contiguous) substrings that have the same number of 0's and 1's, and all the 0's and all the 1's in these substrings are grouped consecutively.
5+
*
6+
* Substrings that occur multiple times are counted the number of times they occur.
7+
*
8+
* Example 1:
9+
*
10+
* Input: "00110011"
11+
* Output: 6
12+
* Explanation: There are 6 substrings that have equal number of consecutive 1's and 0's: "0011", "01", "1100", "10", "0011", and "01".
13+
*
14+
* Notice that some of these substrings repeat and are counted the number of times they occur.
15+
*
16+
* Also, "00110011" is not a valid substring because all the 0's (and 1's) are not grouped together.
17+
*
18+
* Example 2:
19+
*
20+
* Input: "10101"
21+
* Output: 4
22+
* Explanation: There are 4 substrings: "10", "01", "10", "01" that have equal number of consecutive 1's and 0's.
23+
*
24+
* Note:
25+
* s.length will be between 1 and 50,000.
26+
* s will only consist of "0" or "1" characters.
27+
*/
28+
29+
/**
30+
* Count Binary Substring
31+
* @param {string} s
32+
* @return {number}
33+
* @time complexity: O(n^2) where n is the length of s, in each iteration it might do O(n) work
34+
* @space complexity: O(1)
35+
*/
36+
var countBinarySubstrings = function(s) {
37+
let res = 0;
38+
let expandFromCenter = (s, left, right) => {
39+
let i = 1;
40+
41+
while (s.charAt(left - i) === s.charAt(left) && s.charAt(right + i) === s.charAt(right)) {
42+
i++;
43+
}
44+
45+
return i - 1;
46+
};
47+
48+
for (let i = 1; i < s.length; i++) {
49+
if (s.charAt(i - 1) !== s.charAt(i)) {
50+
res++; // 01 or 10
51+
res += expandFromCenter(s, i - 1, i);
52+
}
53+
}
54+
55+
return res;
56+
};
57+
58+
59+
const assert = require('chai').assert;
60+
61+
describe('Count Binary Substrings', () => {
62+
63+
it('should return 6 when \'00110011\' is given', () => {
64+
assert.strictEqual(countBinarySubstrings('00110011'), 6);
65+
});
66+
67+
it('should return 4 when \'10101\' is given', () => {
68+
assert.strictEqual(countBinarySubstrings('10101'), 4);
69+
});
70+
71+
it('should return 1 when \'0001\' is given', () => {
72+
assert.strictEqual(countBinarySubstrings('0001'), 1);
73+
});
74+
75+
it('should return 0 when \'1\' is given', () => {
76+
assert.strictEqual(countBinarySubstrings('1'), 0);
77+
});
78+
79+
});
80+

diagonal-traverse.js

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/**
2+
* Diagonal Traverse
3+
*
4+
* Given a matrix of M x N elements (M rows, N columns), return all elements of the matrix in diagonal order as shown in the below image.
5+
*
6+
* Example:
7+
*
8+
* Input:
9+
* [
10+
* [ 1, 2, 3 ],
11+
* [ 4, 5, 6 ],
12+
* [ 7, 8, 9 ]
13+
* ]
14+
*
15+
* Output: [1,2,4,7,5,3,6,8,9]
16+
*/
17+
18+
/**
19+
* Diagonal Order
20+
* @param {number[][]} matrix
21+
* @return {number[]}
22+
* @time complexity: O(n)
23+
* @space complexity: O(n)
24+
*/
25+
const findDiagonalOrder = (matrix) => {
26+
if (matrix.length === 0) {
27+
return [];
28+
}
29+
30+
const result = [];
31+
const rowCount = matrix.length;
32+
const colCount = matrix[0].length;
33+
const total = rowCount * colCount;
34+
35+
let row = 0;
36+
let col = 0;
37+
let rowMove = -1;
38+
let colMove = 1;
39+
40+
const reverse = () => {
41+
rowMove = -rowMove;
42+
colMove = -colMove;
43+
};
44+
45+
while (result.length < total) {
46+
result.push(matrix[row][col]);
47+
48+
row += rowMove;
49+
col += colMove;
50+
51+
if (row > rowCount - 1) { // Bottom outbound
52+
reverse();
53+
row -= 1;
54+
col += 2;
55+
} else if (col > colCount - 1) { // Right outbound
56+
reverse();
57+
row += 2;
58+
col -= 1;
59+
} else if (row < 0) { // Top outbound
60+
reverse();
61+
row = 0;
62+
} else if (col < 0) { // Left outbound
63+
reverse();
64+
col = 0;
65+
}
66+
}
67+
68+
return result;
69+
}
70+
71+
72+
/**
73+
* Diagonal Order
74+
* @param {number[][]} matrix
75+
* @return {number[]}
76+
* @time complexity: O(n)
77+
* @space complexity: O(n)
78+
*/
79+
const findDiagonalOrderAlternative = (matrix) => {
80+
if (matrix.length === 0) {
81+
return [];
82+
}
83+
84+
const result = [];
85+
const rowCount = matrix.length;
86+
const colCount = matrix[0].length;
87+
const total = rowCount * colCount;
88+
let row = 0;
89+
let col = 0;
90+
91+
while (result.length < total) {
92+
result.push(matrix[row][col]);
93+
94+
if ((row + col) % 2 === 0) { // Move up diagonally
95+
if (col === colCount - 1) {
96+
row++;
97+
} else if (row === 0) {
98+
col++;
99+
} else {
100+
row--;
101+
col++;
102+
}
103+
} else { // Move down diagonally
104+
if (row === rowCount - 1) {
105+
col++;
106+
} else if (col === 0) {
107+
row++;
108+
} else {
109+
row++;
110+
col--;
111+
}
112+
}
113+
}
114+
115+
return result;
116+
};
117+
118+
119+
const assert = require('chai').assert;
120+
121+
describe('Diagonal Traverse', () => {
122+
123+
it('should return numbers in diagonal order', () => {
124+
const matrix = [
125+
[1, 2, 3],
126+
[4, 5, 6],
127+
[7, 8, 9]
128+
];
129+
const expected = [1,2,4,7,5,3,6,8,9];
130+
assert.deepEqual(findDiagonalOrder(matrix), expected);
131+
});
132+
133+
it('should return empty array', () => {
134+
assert.deepEqual(findDiagonalOrder([]), []);
135+
});
136+
137+
});

euclidean-distance.js

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
/**
3+
* Calculate the distance between two points in one dimensional space
4+
* @param {number} a first point
5+
* @param {number} b second point
6+
* @return {number}
7+
* @time complexity: O(1)
8+
* @space complexity: O(1)
9+
*/
10+
function oneDimensional(a, b) {
11+
let dist = a - b;
12+
13+
if (dist < 0) {
14+
dist = Math.sqrt(Math.pow(dist, 2));
15+
}
16+
17+
return dist;
18+
19+
// Or
20+
// return Math.abs(a - b);
21+
};
22+
23+
/**
24+
* Calculate the distance between two points in two dimensional space
25+
* @param {number[]} a first point, Ex. [2, 4]
26+
* @param {number[]} b second point, Ex. [-3, 8]
27+
* @return {number}
28+
* @time complexity: O(1)
29+
* @space complexity: O(1)
30+
*/
31+
function twoDimensional(a, b) {
32+
return Math.sqrt(Math.pow(b[0] - a[0], 2) + Math.pow(b[1] - a[1], 2));
33+
}
34+
35+
console.log(oneDimensional(8, -3));
36+
console.log(twoDimensional([2, 4], [-3, 8]));

largest-rectangle-in-histogram.js

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* Largest Rectangle in Histogram
3+
*
4+
* Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.
5+
*
6+
* Example:
7+
*
8+
* ___
9+
* __| |
10+
* | | |
11+
* | | |__
12+
* ___ | | | |
13+
* | |_| | | |
14+
* | | | | | |
15+
* ----------------
16+
* ___
17+
* __| |
18+
* |x|x|
19+
* |x|x|__
20+
* ___ |x|x| |
21+
* | |_|x|x| |
22+
* | | |x|x| |
23+
* ----------------
24+
*
25+
* Input: [2,1,5,6,2,3]
26+
* Output: 10
27+
*
28+
*/
29+
30+
/**
31+
* @param {number[]} heights
32+
* @return {number}
33+
*/
34+
const largestRectangleArea = heights => {
35+
36+
const n = heights.length,
37+
stack = [];
38+
39+
let maxArea = 0;
40+
41+
for (let i = 0; i < n; i++) {
42+
43+
while (stack.length && heights[i] <= heights[stack[stack.length-1]]) {
44+
maxArea = Math.max(maxArea, getArea(i, heights, stack));
45+
}
46+
47+
stack.push(i);
48+
}
49+
50+
while (stack.length) {
51+
maxArea = Math.max(maxArea, getArea(n, heights, stack));
52+
}
53+
54+
return maxArea;
55+
};
56+
57+
const getArea = (i, heights, stack) => {
58+
const h = heights[stack.pop()],
59+
w = stack.length ? i - stack[stack.length-1] - 1 : i;
60+
61+
return h * w;
62+
};
63+
64+
65+
const assert = require('chai').assert;
66+
67+
describe('Largest Rectangle in Histogram', () => {
68+
69+
it('should find the longest path', () => {
70+
const input = [2,1,5,6,2,3],
71+
output = 10;
72+
73+
assert.strictEqual(largestRectangleArea(input), output);
74+
});
75+
76+
it('should return 2 for [1, 1]', () => {
77+
const input = [1, 1],
78+
output = 2;
79+
80+
assert.strictEqual(largestRectangleArea(input), output);
81+
})
82+
83+
});

0 commit comments

Comments
 (0)