Skip to content

Commit 54ee678

Browse files
authored
Merge pull request #55 from aikhelis/typescript_solutions_hash_maps_and_sets
Typescript: Chapter 2 Hash Maps and Sets
2 parents 09b5b78 + b9a370f commit 54ee678

8 files changed

+191
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
function geometric_sequence_triplets(nums: number[], r: number): number {
2+
const left_map: { [key: number]: number } = {};
3+
const right_map: { [key: number]: number } = {};
4+
let count = 0;
5+
// Populate 'right_map' with the frequency of each element in the array.
6+
for (const x of nums)
7+
right_map[x] = (right_map[x] ?? 0) + 1;
8+
// Search for geometric triplets that have x as the center.
9+
for (const x of nums) {
10+
// Decrement the frequency of x in right_map since x is now being
11+
// processed and is no longer to the right.
12+
right_map[x] -= 1;
13+
if (x % r === 0)
14+
count += (left_map[x / r] ?? 0) * (right_map[x * r] ?? 0);
15+
// Increment the frequency of x in left_map since it'll be a part of the
16+
// left side of the array once we iterate to the next value of x.
17+
left_map[x] = (left_map[x] ?? 0) + 1;
18+
}
19+
return count;
20+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
function longest_chain_of_consecutive_numbers(nums: number[]): number {
2+
if (nums.length === 0)
3+
return 0;
4+
const num_set = new Set(nums);
5+
let longest_chain = 0;
6+
for (const num of num_set) {
7+
// If the current number is the smallest number in its chain, search for
8+
// the length of its chain.
9+
if (!num_set.has(num - 1)) {
10+
let currentNum = num;
11+
let currentChain = 1;
12+
// Continue to find the next consecutive numbers in the chain.
13+
while (num_set.has(currentNum + 1)) {
14+
currentNum += 1;
15+
currentChain += 1;
16+
}
17+
longest_chain = Math.max(longest_chain, currentChain);
18+
}
19+
}
20+
return longest_chain;
21+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
function longest_chain_of_consecutive_numbers_brute_force(nums: number[]): number {
2+
if (nums.length === 0)
3+
return 0;
4+
let longest_chain = 0;
5+
// Look for chains of consecutive numbers that start from each number.
6+
for (const num of nums) {
7+
let current_num = num;
8+
let current_chain = 1;
9+
// Continue to find the next consecutive numbers in the chain.
10+
while (nums.includes(current_num + 1)) {
11+
current_num += 1;
12+
current_chain += 1;
13+
}
14+
longest_chain = Math.max(longest_chain, current_chain);
15+
}
16+
return longest_chain;
17+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
function pair_sum_unsorted(nums: number[], target: number): number[] {
2+
const hashmap = {}
3+
for (let i = 0; i < nums.length; i++) {
4+
if (hashmap[target - nums[i]] !== undefined)
5+
return [hashmap[target - nums[i]], i]
6+
hashmap[nums[i]] = i
7+
}
8+
return []
9+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
function pair_sum_unsorted_two_pass(nums: number[], target: number): number[] {
2+
const num_map = {}
3+
// First pass: Populate the hash map with each number and its
4+
// index.
5+
for (let i = 0; i < nums.length; i++)
6+
num_map[nums[i]] = i
7+
// Second pass: Check for each number's complement in the hash map.
8+
for (let i = 0; i < nums.length; i++) {
9+
const complement = target - nums[i]
10+
if (num_map[complement] !== undefined && num_map[complement] !== i)
11+
return [i, num_map[complement]]
12+
}
13+
return []
14+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
function verify_sudoku_board(board: number[][]): boolean {
2+
// Create hash sets for each row, column, and subgrid to keep
3+
// track of numbers previously seen on any given row, column, or
4+
// subgrid.
5+
const row_sets: Set<number>[] = Array.from({ length: 9 }, () => new Set());
6+
const column_sets: Set<number>[] = Array.from({ length: 9 }, () => new Set());
7+
const subgrid_sets: Set<number>[][] = Array.from({ length: 3 }, () => Array.from({ length: 3 }, () => new Set()));
8+
for (let r = 0; r < 9; r++) {
9+
for (let c = 0; c < 9; c++) {
10+
const num = board[r][c];
11+
if (num === 0)
12+
continue;
13+
// Check if 'num' has been seen in the current row,
14+
// column, or subgrid.
15+
if (row_sets[r].has(num))
16+
return false;
17+
if (column_sets[c].has(num))
18+
return false;
19+
if (subgrid_sets[Math.floor(r / 3)][Math.floor(c / 3)].has(num))
20+
return false;
21+
// If we passed the above checks, mark this value as seen
22+
// by adding it to its corresponding hash sets.
23+
row_sets[r].add(num);
24+
column_sets[c].add(num);
25+
subgrid_sets[Math.floor(r / 3)][Math.floor(c / 3)].add(num);
26+
}
27+
}
28+
return true;
29+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
function zero_striping(matrix: number[][]): void {
2+
if (!matrix || !matrix[0])
3+
return;
4+
const m = matrix.length, n = matrix[0].length;
5+
// Check if the first row initially contains a zero.
6+
let first_row_has_zero = false;
7+
for (let c = 0; c < n; c++) {
8+
if (matrix[0][c] === 0) {
9+
first_row_has_zero = true;
10+
break;
11+
}
12+
}
13+
// Check if the first column initially contains a zero.
14+
let first_col_has_zero = false;
15+
for (let r = 0; r < m; r++) {
16+
if (matrix[r][0] === 0) {
17+
first_col_has_zero = true;
18+
break;
19+
}
20+
}
21+
// Use the first row and column as markers. If an element in the
22+
// submatrix is zero, mark its corresponding row and column in the
23+
// first row and column as 0.
24+
for (let r = 1; r < m; r++) {
25+
for (let c = 1; c < n; c++) {
26+
if (matrix[r][c] === 0) {
27+
matrix[0][c] = 0;
28+
matrix[r][0] = 0;
29+
}
30+
}
31+
}
32+
// Update the submatrix using the markers in the first row and
33+
// column.
34+
for (let r = 1; r < m; r++) {
35+
for (let c = 1; c < n; c++) {
36+
if (matrix[0][c] === 0 || matrix[r][0] === 0) {
37+
matrix[r][c] = 0;
38+
}
39+
}
40+
}
41+
// If the first row had a zero initially, set all elements in the
42+
// first row to zero.
43+
if (first_row_has_zero) {
44+
for (let c = 0; c < n; c++) {
45+
matrix[0][c] = 0;
46+
}
47+
}
48+
// If the first column had a zero initially, set all elements in
49+
// the first column to zero.
50+
if (first_col_has_zero) {
51+
for (let r = 0; r < m; r++) {
52+
matrix[r][0] = 0;
53+
}
54+
}
55+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
function zero_striping_hash_sets(matrix: number[][]): void {
2+
if (!matrix || !matrix[0])
3+
return;
4+
const m = matrix.length, n = matrix[0].length;
5+
const zero_rows = new Set<number>(), zero_cols = new Set<number>();
6+
// Pass 1: Traverse through the matrix to identify the rows and
7+
// columns containing zeros and store their indexes in the
8+
// appropriate hash sets.
9+
for (let r = 0; r < m; r++) {
10+
for (let c = 0; c < n; c++) {
11+
if (matrix[r][c] === 0) {
12+
zero_rows.add(r);
13+
zero_cols.add(c);
14+
}
15+
}
16+
}
17+
// Pass 2: Set any cell in the matrix to zero if its row index is
18+
// in 'zero_rows' or its column index is in 'zero_cols'.
19+
for (let r = 0; r < m; r++) {
20+
for (let c = 0; c < n; c++) {
21+
if (zero_rows.has(r) || zero_cols.has(c)) {
22+
matrix[r][c] = 0;
23+
}
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)