Skip to content

Commit 5ef5c80

Browse files
authored
Merge pull request #54 from aikhelis/typescript-solutions-two-pointers
Adding TypeScript with Two Pointers chapter
2 parents 4c03f0b + 3a5208b commit 5ef5c80

10 files changed

+194
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
function is_palindrome_valid(s: string): boolean {
2+
let left = 0, right = s.length - 1
3+
while (left < right) {
4+
// Skip non-alphanumeric characters from the left.
5+
while (left < right && !isalnum(s[left]))
6+
left++
7+
// Skip non-alphanumeric characters from the right.
8+
while (left < right && !isalnum(s[right]))
9+
right--
10+
// If the characters at the left and right pointers don't
11+
// match, the string is not a palindrome.
12+
if (s[left] !== s[right])
13+
return false
14+
left++
15+
right--
16+
}
17+
return true
18+
}
19+
20+
const isalnum = (c: string): boolean => /^[a-z0-9]+$/i.test(c);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
function largest_container(heights: number[]): number {
2+
let max_water = 0
3+
let left = 0, right = heights.length - 1
4+
while (left < right) {
5+
// Calculate the water contained between the current pair of
6+
// lines.
7+
let water = Math.min(heights[left], heights[right]) * (right - left)
8+
max_water = Math.max(max_water, water)
9+
// Move the pointers inward, always moving the pointer at the
10+
// shorter line. If both lines have the same height, move both
11+
// pointers inward.
12+
if (heights[left] < heights[right])
13+
left++
14+
else if (heights[left] > heights[right])
15+
right--
16+
else
17+
left++, right--
18+
}
19+
return max_water
20+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
function largest_container_brute_force(heights: number[]): number {
2+
let n = heights.length
3+
let max_water = 0
4+
// Find the maximum amount of water stored between all pairs of
5+
// lines.
6+
for (let i = 0; i < n - 1; i++) {
7+
for (let j = i + 1; j < n; j++) {
8+
let water = Math.min(heights[i], heights[j]) * (j - i)
9+
max_water = Math.max(max_water, water)
10+
}
11+
}
12+
return max_water
13+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
function next_lexicographical_sequence(s: string): string {
2+
let letters = [...s];
3+
// Locate the pivot, which is the first character from the right that breaks
4+
// non-increasing order. Start searching from the second-to-last position.
5+
let pivot = letters.length - 2;
6+
while (pivot >= 0 && letters[pivot] >= letters[pivot + 1])
7+
pivot--;
8+
// If pivot is not found, the string is already in its largest permutation. In
9+
// this case, reverse the string to obtain the smallest permutation.
10+
if (pivot === -1)
11+
return letters.reverse().join('');
12+
// Find the rightmost successor to the pivot.
13+
let rightmost_successor = letters.length - 1;
14+
while (letters[rightmost_successor] <= letters[pivot])
15+
rightmost_successor--;
16+
// Swap the rightmost successor with the pivot to increase the lexicographical
17+
// order of the suffix.
18+
[letters[pivot], letters[rightmost_successor]] = [letters[rightmost_successor], letters[pivot]];
19+
// Reverse the suffix after the pivot to minimize its permutation.
20+
const suffix = letters.slice(pivot + 1).reverse();
21+
letters.splice(pivot + 1, suffix.length, ...suffix);
22+
return letters.join('');
23+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
function pair_sum_sorted(nums: number[], target: number): number[] {
2+
let left = 0, right = nums.length - 1
3+
while (left < right) {
4+
let sum = nums[left] + nums[right]
5+
// If the sum is smaller, increment the left pointer, aiming
6+
// to increase the sum toward the target value.
7+
if (sum < target)
8+
left++
9+
// If the sum is larger, decrement the right pointer, aiming
10+
// to decrease the sum toward the target value.
11+
else if (sum > target)
12+
right--
13+
// If the target pair is found, return its indexes.
14+
else
15+
return [left, right]
16+
}
17+
return []
18+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
function pair_sum_sorted_brute_force(nums: number[], target: number): number[] {
2+
const n = nums.length;
3+
for (let i = 0; i < n; i++) {
4+
for (let j = i + 1; j < n; j++) {
5+
if (nums[i] + nums[j] === target)
6+
return [i, j]
7+
}
8+
}
9+
return []
10+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
function shift_zeros_to_the_end(nums: number[]): void {
2+
// The 'left' pointer is used to position non-zero elements.
3+
let left = 0
4+
// Iterate through the array using a 'right' pointer to locate non-zero
5+
// elements.
6+
for (let right = 0; right < nums.length; right++) {
7+
if (nums[right] !== 0) {
8+
[nums[left], nums[right]] = [nums[right], nums[left]]
9+
// Increment 'left' since it now points to a position already occupied
10+
// by a non-zero element.
11+
left++
12+
}
13+
}
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
function shift_zeros_to_the_end_naive(nums: number[]): void {
2+
let temp = Array(nums.length).fill(0);
3+
let i = 0
4+
// Add all non-zero elements to the left of 'temp'.
5+
for (let number of nums) {
6+
if (number !== 0) {
7+
temp[i] = number
8+
i++
9+
}
10+
}
11+
// Set 'nums' to 'temp'.
12+
for (let j = 0; j < nums.length; j++) {
13+
nums[j] = temp[j]
14+
}
15+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
function triplet_sum(nums: number[]): number[][] {
2+
const triplets = []
3+
nums.sort()
4+
for (let i = 0; i < nums.length; i++) {
5+
// Optimization: triplets consisting of only positive numbers
6+
// will never sum to 0.
7+
if (nums[i] > 0 )
8+
break
9+
// To avoid duplicate triplets, skip 'a' if it's the same as
10+
// the previous number.
11+
if (i > 0 && nums[i] === nums[i - 1])
12+
continue
13+
// Find all pairs that sum to a target of '-a' (-nums[i]).
14+
const pairs = pair_sum_sorted_all_pairs(nums, i + 1, -nums[i])
15+
for (const pair of pairs) {
16+
triplets.push([nums[i]].concat(pair))
17+
}
18+
}
19+
return triplets
20+
}
21+
22+
function pair_sum_sorted_all_pairs(nums: number[], start: number, target: number): number[]{
23+
const pairs = []
24+
let left = start, right = nums.length - 1
25+
while (left < right) {
26+
const sum = nums[left] + nums[right]
27+
if (sum === target) {
28+
pairs.push([nums[left], nums[right]])
29+
left++
30+
// To avoid duplicate '[b, c]' pairs, skip 'b' if it's the
31+
// same as the previous number.
32+
while (left < right && nums[left] === nums[left - 1])
33+
left++
34+
} else if (sum < target) {
35+
left++
36+
} else {
37+
right--
38+
}
39+
}
40+
return pairs
41+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
function triplet_sum_brute_force(nums: number[]): number[][] {
2+
let n = nums.length
3+
// Use a hash set to ensure we don't add duplicate triplets.
4+
let triplets = new Set()
5+
// Iterate through the indexes of all triplets.
6+
for (let i = 0; i < n - 2; i++) {
7+
for (let j = i + 1; j < n - 1; j++) {
8+
for (let k = j + 1; k < n; k++) {
9+
if (nums[i] + nums[j] + nums[k] === 0) {
10+
// Sort the triplet before including it in the hash set.
11+
// [javascript] convert triplet array into a JSON string to use as a unqiue Set value.
12+
let triplet = JSON.stringify([nums[i], nums[j], nums[k]].sort())
13+
triplets.add(triplet)
14+
}
15+
}
16+
}
17+
}
18+
// [javascript] convert the Set back into an array of triplets.
19+
return Array.from(triplets).map(JSON.parse)
20+
}

0 commit comments

Comments
 (0)