Week 1: Foundations (TypeScript + Basic DSA)
Week 1: Foundations (TypeScript + Basic DSA)
Focus: loops, arrays, functions, time complexity
Day 1: TypeScript Language Basics
Learning Objectives
- Master TypeScript functions, arrays, and objects
- Understand for/while loops
- Practice array manipulations
Core Concepts
1. Functions in TypeScript
// Basic function
function add(a: number, b: number): number {
return a + b;
}
// Arrow function
const multiply = (a: number, b: number): number => a * b;
// Function with array parameter
function sumArray(arr: number[]): number {
let sum = 0;
for (let num of arr) {
sum += num;
}
return sum;
}
2. Arrays & Objects
// Array declaration
const numbers: number[] = [1, 2, 3, 4, 5];
// Array methods
numbers.push(6); // Add to end
numbers.pop(); // Remove from end
numbers.shift(); // Remove from start
numbers.unshift(0); // Add to start
// Object
interface Person {
name: string;
age: number;
}
const user: Person = {
name: "John",
age: 25
};
3. Loops
// For loop
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
// For...of loop (recommended for arrays)
for (const item of arr) {
console.log(item);
}
// While loop
let i = 0;
while (i < arr.length) {
console.log(arr[i]);
i++;
}
Practice Tasks (10 Array Manipulations)
Task 1: Reverse Array
function reverseArray(arr: number[]): number[] {
const result: number[] = [];
for (let i = arr.length - 1; i >= 0; i--) {
result.push(arr[i]);
}
return result;
}
// Test
console.log(reverseArray([1, 2, 3, 4, 5])); // [5, 4, 3, 2, 1]
Task 2: Find Maximum
function findMax(arr: number[]): number {
if (arr.length === 0) throw new Error("Empty array");
let max = arr[0];
for (const num of arr) {
if (num > max) {
max = num;
}
}
return max;
}
// Test
console.log(findMax([3, 7, 2, 9, 1])); // 9
Task 3: Count Even Numbers
function countEven(arr: number[]): number {
let count = 0;
for (const num of arr) {
if (num % 2 === 0) {
count++;
}
}
return count;
}
// Test
console.log(countEven([1, 2, 3, 4, 5, 6])); // 3
Task 4: Sum of Elements
function sumArray(arr: number[]): number {
let sum = 0;
for (const num of arr) {
sum += num;
}
return sum;
}
// Test
console.log(sumArray([1, 2, 3, 4, 5])); // 15
Task 5: Filter Positive Numbers
function filterPositive(arr: number[]): number[] {
const result: number[] = [];
for (const num of arr) {
if (num > 0) {
result.push(num);
}
}
return result;
}
// Test
console.log(filterPositive([-1, 2, -3, 4, 5])); // [2, 4, 5]
Task 6: Double Each Element
function doubleElements(arr: number[]): number[] {
const result: number[] = [];
for (const num of arr) {
result.push(num * 2);
}
return result;
}
// Test
console.log(doubleElements([1, 2, 3, 4])); // [2, 4, 6, 8]
Task 7: Find Index of Element
function findIndex(arr: number[], target: number): number {
for (let i = 0; i < arr.length; i++) {
if (arr[i] === target) {
return i;
}
}
return -1;
}
// Test
console.log(findIndex([10, 20, 30, 40], 30)); // 2
console.log(findIndex([10, 20, 30, 40], 50)); // -1
Task 8: Check if Array Contains Element
function contains(arr: number[], target: number): boolean {
for (const num of arr) {
if (num === target) {
return true;
}
}
return false;
}
// Test
console.log(contains([1, 2, 3, 4, 5], 3)); // true
console.log(contains([1, 2, 3, 4, 5], 6)); // false
Task 9: Get First N Elements
function firstN(arr: number[], n: number): number[] {
const result: number[] = [];
for (let i = 0; i < Math.min(n, arr.length); i++) {
result.push(arr[i]);
}
return result;
}
// Test
console.log(firstN([1, 2, 3, 4, 5], 3)); // [1, 2, 3]
Task 10: Remove Duplicates (Simple)
function removeDuplicates(arr: number[]): number[] {
const result: number[] = [];
for (const num of arr) {
if (!contains(result, num)) {
result.push(num);
}
}
return result;
}
// Test
console.log(removeDuplicates([1, 2, 2, 3, 4, 4, 5])); // [1, 2, 3, 4, 5]
Day 2: Big-O (Beginner Level)
Learning Objectives
- Understand time complexity notation
- Recognize O(n), O(n²), O(log n)
- Identify slow vs fast solutions
Core Concepts
What is Big-O?
Big-O describes how running time grows as input size increases.
Common Complexities
O(1) - Constant Time
function getFirst(arr: number[]): number {
return arr[0]; // Always 1 operation, regardless of array size
}
O(n) - Linear Time
function findSum(arr: number[]): number {
let sum = 0;
for (const num of arr) { // n operations
sum += num;
}
return sum;
}
O(n²) - Quadratic Time
function printPairs(arr: number[]): void {
for (let i = 0; i < arr.length; i++) { // n times
for (let j = 0; j < arr.length; j++) { // n times each
console.log(arr[i], arr[j]);
}
}
// Total: n * n = n² operations
}
O(log n) - Logarithmic Time
function binarySearch(arr: number[], target: number): number {
let left = 0;
let right = arr.length - 1;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
if (arr[mid] === target) return mid;
if (arr[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1;
}
// Each iteration cuts search space in half
Comparison Chart
n = 100 elements
O(1): 1 operation
O(log n): ~7 operations
O(n): 100 operations
O(n log n): ~664 operations
O(n²): 10,000 operations
O(2^n): 1,267,650,600,228,229,401,496,703,205,376 operations š±
Codility Challenge: BinaryGap
Problem: Find the longest sequence of consecutive zeros in binary representation of an integer.
Example: - Input: 9 (binary: 1001) - Output: 2 (gap between the two 1's)
Solution:
function solution(N: number): number {
// Convert to binary string
const binary = N.toString(2);
let maxGap = 0;
let currentGap = 0;
let foundOne = false;
for (const char of binary) {
if (char === '1') {
// If we found a 1, update max gap
if (foundOne) {
maxGap = Math.max(maxGap, currentGap);
}
foundOne = true;
currentGap = 0;
} else if (foundOne) {
// Count zeros only after finding first 1
currentGap++;
}
}
return maxGap;
}
// Test cases
console.log(solution(9)); // 2 (1001)
console.log(solution(529)); // 4 (1000010001)
console.log(solution(20)); // 1 (10100)
console.log(solution(15)); // 0 (1111)
console.log(solution(1041)); // 5 (10000010001)
Time Complexity: O(log N) - we process each bit once Space Complexity: O(log N) - binary string storage
Day 3: Arrays I
Codility Challenge 1: OddOccurrencesInArray
Problem: Find the value that occurs an odd number of times in an array where every other value occurs an even number of times.
Example:
Input: [9, 3, 9, 3, 9, 7, 9]
Output: 7
Solution Approach 1 - Using Hash Map (O(n) time, O(n) space):
function solution(A: number[]): number {
const counts = new Map<number, number>();
// Count occurrences
for (const num of A) {
counts.set(num, (counts.get(num) || 0) + 1);
}
// Find the one with odd count
for (const [num, count] of counts.entries()) {
if (count % 2 === 1) {
return num;
}
}
return 0; // Should never reach here based on problem constraints
}
Solution Approach 2 - XOR Trick (O(n) time, O(1) space):
function solution(A: number[]): number {
let result = 0;
// XOR all elements
// Same numbers cancel out (a XOR a = 0)
// Only the odd occurrence remains
for (const num of A) {
result ^= num;
}
return result;
}
// How XOR works:
// 9 ^ 3 ^ 9 ^ 3 ^ 9 ^ 7 ^ 9
// = (9 ^ 9) ^ (3 ^ 3) ^ (9 ^ 9) ^ 7
// = 0 ^ 0 ^ 0 ^ 7
// = 7
Codility Challenge 2: CyclicRotation
Problem: Rotate array to the right by K steps.
Example:
Input: A = [3, 8, 9, 7, 6], K = 3
Output: [9, 7, 6, 3, 8]
Solution:
function solution(A: number[], K: number): number[] {
if (A.length === 0) return A;
// Optimize K (rotating by length brings back to original)
K = K % A.length;
if (K === 0) return A;
// Take last K elements and put them at the front
return [...A.slice(-K), ...A.slice(0, -K)];
}
// Test cases
console.log(solution([3, 8, 9, 7, 6], 3)); // [9, 7, 6, 3, 8]
console.log(solution([1, 2, 3, 4], 4)); // [1, 2, 3, 4] (full rotation)
console.log(solution([], 1)); // []
Alternative Solution (In-place):
function solution(A: number[], K: number): number[] {
if (A.length === 0) return A;
K = K % A.length;
// Reverse entire array
reverse(A, 0, A.length - 1);
// Reverse first K elements
reverse(A, 0, K - 1);
// Reverse remaining elements
reverse(A, K, A.length - 1);
return A;
}
function reverse(A: number[], start: number, end: number): void {
while (start < end) {
[A[start], A[end]] = [A[end], A[start]];
start++;
end--;
}
}
Day 4: Arrays II (LeetCode Practice)
Challenge 1: Two Sum
Problem: Find two numbers that add up to a target.
Example:
Input: nums = [2, 7, 11, 15], target = 9
Output: [0, 1] (nums[0] + nums[1] = 2 + 7 = 9)
Solution:
function twoSum(nums: number[], target: number): number[] {
const seen = new Map<number, number>();
for (let i = 0; i < nums.length; i++) {
const complement = target - nums[i];
if (seen.has(complement)) {
return [seen.get(complement)!, i];
}
seen.set(nums[i], i);
}
return [];
}
Time Complexity: O(n) Space Complexity: O(n)
Challenge 2: Remove Duplicates from Sorted Array
Problem: Remove duplicates in-place, return new length.
Example:
Input: [1, 1, 2, 2, 3]
Output: 3 (array becomes [1, 2, 3, _, _])
Solution:
function removeDuplicates(nums: number[]): number {
if (nums.length === 0) return 0;
let writeIndex = 1; // Position to write next unique element
for (let readIndex = 1; readIndex < nums.length; readIndex++) {
if (nums[readIndex] !== nums[readIndex - 1]) {
nums[writeIndex] = nums[readIndex];
writeIndex++;
}
}
return writeIndex;
}
Time Complexity: O(n) Space Complexity: O(1)
Day 5: Edge Cases
Codility Challenge 1: TapeEquilibrium
Problem: Minimize the difference between two parts when splitting an array.
Example:
Input: [3, 1, 2, 4, 3]
Output: 1
Explanation:
Split at position 1: |3 - 1| - (2 + 4 + 3)| = |3 - 9| = 6
Split at position 2: |3 + 1 - (2 + 4 + 3)| = |4 - 9| = 5
Split at position 3: |3 + 1 + 2 - (4 + 3)| = |6 - 7| = 1 ā minimum
Split at position 4: |3 + 1 + 2 + 4 - 3| = |10 - 3| = 7
Solution:
function solution(A: number[]): number {
// Calculate total sum
let totalSum = 0;
for (const num of A) {
totalSum += num;
}
let leftSum = 0;
let minDiff = Infinity;
// Try each split point (can't split at the end)
for (let i = 0; i < A.length - 1; i++) {
leftSum += A[i];
const rightSum = totalSum - leftSum;
const diff = Math.abs(leftSum - rightSum);
minDiff = Math.min(minDiff, diff);
}
return minDiff;
}
Codility Challenge 2: PermMissingElem
Problem: Find the missing element in a permutation.
Example:
Input: [2, 3, 1, 5]
Output: 4
Solution 1 - Sum Formula:
function solution(A: number[]): number {
const n = A.length + 1;
// Sum of 1 to n = n * (n + 1) / 2
const expectedSum = n * (n + 1) / 2;
let actualSum = 0;
for (const num of A) {
actualSum += num;
}
return expectedSum - actualSum;
}
Solution 2 - XOR:
function solution(A: number[]): number {
let xor = 0;
// XOR all array elements
for (const num of A) {
xor ^= num;
}
// XOR with all numbers from 1 to n+1
for (let i = 1; i <= A.length + 1; i++) {
xor ^= i;
}
return xor;
}
Edge Cases to Always Consider
- Empty array:
[] - Single element:
[5] - All same elements:
[1, 1, 1, 1] - Negative numbers:
[-5, -3, -1] - Zero:
[0, 1, 2] - Very large/small values:
[1000000, -1000000] - Maximum constraints: Array of size 100,000
Day 6: Review + Fix Weakness
Review Checklist
ā TypeScript Fundamentals - Can you write functions with proper types? - Do you understand array methods? - Are you comfortable with loops?
ā Big-O Understanding - Can you identify O(1), O(n), O(n²) code? - Do you know when code is too slow?
ā Array Skills - Can you iterate arrays efficiently? - Do you handle edge cases? - Can you manipulate arrays without errors?
Practice Tasks (Redo for Speed)
- BinaryGap - Target: < 5 minutes
- OddOccurrencesInArray - Target: < 3 minutes
- CyclicRotation - Target: < 5 minutes
- TapeEquilibrium - Target: < 7 minutes
Common Mistakes to Fix
ā Off-by-one errors
// WRONG
for (let i = 0; i <= arr.length; i++) // Will go out of bounds!
// RIGHT
for (let i = 0; i < arr.length; i++)
ā Not handling empty arrays
// WRONG
function getMax(arr: number[]): number {
let max = arr[0]; // Error if arr is empty!
...
}
// RIGHT
function getMax(arr: number[]): number {
if (arr.length === 0) return -1; // or throw error
let max = arr[0];
...
}
ā Inefficient nested loops when not needed
// WRONG - O(n²)
function hasDuplicate(arr: number[]): boolean {
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) return true;
}
}
return false;
}
// RIGHT - O(n)
function hasDuplicate(arr: number[]): boolean {
const seen = new Set<number>();
for (const num of arr) {
if (seen.has(num)) return true;
seen.add(num);
}
return false;
}
Day 7: REST
Take a break! You've earned it.
Recommended activities: - Review your notes - Watch coding interview videos - Read about algorithms (no heavy coding) - Plan for Week 2
Week 1 Summary
What You Learned
ā TypeScript basics (functions, arrays, loops) ā Time complexity (Big-O notation) ā Array manipulation techniques ā Edge case handling ā Problem-solving patterns
Key Takeaways
- Always consider edge cases (empty, single element, duplicates)
- Think about time complexity before coding
- Use hash maps for O(1) lookups
- XOR trick for finding odd occurrences
- Sum formula for finding missing elements
Prepare for Week 2
Next week focuses on: - Counting elements - Prefix sums (very important!) - Hash maps in depth - Your first mock test!
Keep practicing and stay consistent! š