Lesson 5
Mastering Arrays and Two-Pointer Technique with TypeScript
Introduction

Welcome to our exciting TypeScript lesson! Today, you'll tackle a fascinating programming challenge that will enhance your problem-solving skills using TypeScript. This exercise involves working with arrays while employing advanced techniques like sorting and the two-pointer method. Let's dive right in!

Task Statement

Your challenge is to create a TypeScript function to work on two equally long arrays, A and B. The arrays have a length between 1 and 1000, and each element is a unique positive integer ranging from 1 to 1,000,000. Your task involves the following steps:

  1. For each element B[i] in the array B, double its value to get 2 * B[i].
  2. Identify the closest number to 2 * B[i] in array B, naming it B[j].
  3. For each index i, retrieve the value at index j in array A and assign it to the new array.
  4. Return a new array where each element corresponds to A[j] based on the closest value found in B.

To illustrate this, let's consider an example:

TypeScript
1const A: number[] = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110]; 2const B: number[] = [4, 12, 3, 9, 6, 1, 5, 8, 37, 25, 100];

After executing your function, the resulting array should appear as follows:

TypeScript
1const result: number[] = [80, 100, 50, 20, 20, 60, 40, 20, 110, 90, 110];
Create and Sort Array

Let's begin solving this problem by constructing a sorted structure for array B. We'll use TypeScript type annotations to define an array of objects, where each object contains the elements (value) from B and their respective indices (index).

Here’s how to start our TypeScript function with type annotations included:

TypeScript
1type BElement = { value: number; index: number }; 2 3function findAndReplace(A: number[], B: number[]): number[] { 4 let B_sorted: BElement[] = []; 5 for (let i = 0; i < B.length; i++) { 6 B_sorted.push({ value: B[i], index: i }); 7 } 8 B_sorted.sort((a, b) => a.value - b.value);

In this section, we define BElement to clearly structure B_sorted as an array of objects with defined types, which aids in improving the readability and type safety of our code.

Initialize Pointers and the Result Array

With our sorted array (B_sorted) prepared, we proceed by initializing the right pointer, j, and the result array, res. These will assist in navigating within the bounds of B_sorted and collecting our results, respectively. TypeScript enhances this process by providing type annotations for these variables.

TypeScript
1 let j: number = 0; // TypeScript enforces number type for pointer 2 let res: number[] = new Array(A.length); // Result array with number type
Traverse the Array and Compare

The core logic of this problem is implemented here. Using a loop, we iterate over each element in B_sorted. For every element, the function computes the target, which is twice the value of the current element. We adjust the position of the pointer j to locate the closest number smaller than or equal to the target.

TypeScript
1 for (let i = 0; i < B.length; i++) { 2 let target: number = 2 * B_sorted[i].value; // Calculate target number 3 while (j < B.length - 1 && B_sorted[j + 1].value < target) { 4 j++; // Adjust pointer to find closest number less than the target 5 } 6 if (j < B.length - 1 && 7 Math.abs(B_sorted[j + 1].value - target) < Math.abs(target - B_sorted[j].value)) { 8 j++; // Increment pointer if next number is closer to the target 9 }
Assemble the Result Array

Now, using the indices captured in B_sorted, we modify the elements in A to form our result array res. TypeScript ensures that all operations adhere to the designated types.

TypeScript
1 res[B_sorted[i].index] = A[B_sorted[j].index]; 2 // Align and assign the correct elements to the result array 3 } 4 5 return res; 6}
Full Code

Here is the complete TypeScript solution for this task, which successfully implements the outlined logic:

TypeScript
1type BElement = { value: number; index: number }; 2 3function findAndReplace(A: number[], B: number[]): number[] { 4 let B_sorted: BElement[] = []; 5 for (let i = 0; i < B.length; i++) { 6 B_sorted.push({ value: B[i], index: i }); 7 } 8 B_sorted.sort((a, b) => a.value - b.value); 9 10 let j: number = 0; // Pointer as a number type 11 let res: number[] = new Array(A.length); // Result array with number type 12 13 for (let i = 0; i < B.length; i++) { 14 let target: number = 2 * B_sorted[i].value; // Calculate target number 15 while (j < B.length - 1 && B_sorted[j + 1].value < target) { 16 j++; // Adjust pointer to find closest number 17 } 18 if (j < B.length - 1 && 19 Math.abs(B_sorted[j + 1].value - target) < Math.abs(target - B_sorted[j].value)) { 20 j++; // Increment pointer for closer match 21 } 22 res[B_sorted[i].index] = A[B_sorted[j].index]; 23 } 24 25 return res; 26} 27 28const A: number[] = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110]; 29const B: number[] = [4, 12, 3, 9, 6, 1, 5, 8, 37, 25, 100]; 30const result: number[] = findAndReplace(A, B); 31console.log(result); // Output: [80, 100, 50, 20, 20, 60, 40, 20, 110, 90, 110].
Lesson Summary

Congratulations on completing the lesson! You have successfully translated a complex problem into TypeScript, utilizing its robust type system to create type-safe arrays and pointers. The use of advanced programming techniques, like sorting and the two-pointer method, further enriched your TypeScript skills and solidified your understanding of functional problem-solving. We encourage you to continue practicing these techniques in varied scenarios to fully master them. Enjoy your coding journey with TypeScript!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.