diff --git a/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js b/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js index ce738c3..a2686c0 100644 --- a/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js +++ b/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js @@ -18,17 +18,24 @@ */ export function calculateSumAndProduct(numbers) { let sum = 0; - for (const num of numbers) { - sum += num; - } - let product = 1; for (const num of numbers) { + sum += num; product *= num; } - return { sum: sum, product: product, }; } +// Time Complexity: O(n) +// The original implementation also had O(n) time complexity, +// but it iterated through the array twice (approximately 2n operations). +// The refactored version calculates both the sum and product in one loop, +// so it only traverses the array once (approximately n iterations). +// +// Space Complexity: O(1) +// We only store two variables regardless of the size of the input. +// Optimal Time Complexity: O(n) +// We must iterate through every element at least once +// to calculate both the sum and the product. diff --git a/Sprint-1/JavaScript/findCommonItems/findCommonItems.js b/Sprint-1/JavaScript/findCommonItems/findCommonItems.js index 5619ae5..61814f4 100644 --- a/Sprint-1/JavaScript/findCommonItems/findCommonItems.js +++ b/Sprint-1/JavaScript/findCommonItems/findCommonItems.js @@ -9,6 +9,33 @@ * @param {Array} secondArray - Second array to compare * @returns {Array} Array containing unique common items */ -export const findCommonItems = (firstArray, secondArray) => [ - ...new Set(firstArray.filter((item) => secondArray.includes(item))), -]; +// export const findCommonItems2 = (firstArray, secondArray) => [ +// ...new Set(firstArray.filter((item) => secondArray.includes(item))), //O(N*M) +// ]; +export const findCommonItems = (firstArray, secondArray) => { + const secondSet = new Set(secondArray); //O(M) + const commonSet = new Set(); + + for (const item of firstArray) { + //O(N) + if (secondSet.has(item)) { + commonSet.add(item); + } + } + + return [...commonSet]; //O(K) +}; +// Time Complexity: O(n + m) +// We create a Set from secondArray and loop through firstArray once. + +// Original Time Complexity: O(n * m) +// includes() may search all of secondArray for every item in firstArray. + +// Space Complexity: O(m + n) +// We store secondArray in a Set and up to n common items. + +// Original Space Complexity: O(n) +// filter() and Set create temporary collections of up to n items. + +// Optimal Time Complexity: O(n + m) +// We need to inspect both arrays to find all common items. diff --git a/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js b/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js index dd2901f..e38d9f3 100644 --- a/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js +++ b/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js @@ -9,13 +9,38 @@ * @param {number} target - Target sum to find * @returns {boolean} True if pair exists, false otherwise */ +// export function hasPairWithSum2(numbers, target) { +// for (let i = 0; i < numbers.length; i++) { +// for (let j = i + 1; j < numbers.length; j++) { +// if (numbers[i] + numbers[j] === target) { +// return true; +// } +// } +// } +// return false; +// } +// Time Complexity: O(N^2) +// Space Complexity: O(1) +// Optimal Time Complexity: O(N) + export function hasPairWithSum(numbers, target) { - for (let i = 0; i < numbers.length; i++) { - for (let j = i + 1; j < numbers.length; j++) { - if (numbers[i] + numbers[j] === target) { - return true; - } - } + const seen = new Set(); + for (const num of numbers) { + const needed = target - num; + if (seen.has(needed)) return true; + + seen.add(num); } + return false; } +// Original Time Complexity: O(n^2) +//two nested loop compare each number with remaining numbers + +// Time Complexity: O(n) +// we iterate through the arr once and Set.has() for O(1) lookup + +// Space Complexity: O(n) +// We may store up to n numbers in the Set. +// Optimal Time Complexity: O(n) +//we might need to inspect every number at least once. diff --git a/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs b/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs index dc5f771..96ebf7d 100644 --- a/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs +++ b/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs @@ -8,29 +8,46 @@ * @param {Array} inputSequence - Sequence to remove duplicates from * @returns {Array} New sequence with duplicates removed */ +// export function removeDuplicates(inputSequence) { +// const uniqueItems = []; + +// for ( +// let currentIndex = 0; +// currentIndex < inputSequence.length; +// currentIndex++ +// ) { +// let isDuplicate = false; +// for ( +// let compareIndex = 0; +// compareIndex < uniqueItems.length; +// compareIndex++ +// ) { +// if (inputSequence[currentIndex] === uniqueItems[compareIndex]) { +// isDuplicate = true; +// break; +// } +// } +// if (!isDuplicate) { +// uniqueItems.push(inputSequence[currentIndex]); +// } +// } + +// return uniqueItems; +// } + export function removeDuplicates(inputSequence) { - const uniqueItems = []; - - for ( - let currentIndex = 0; - currentIndex < inputSequence.length; - currentIndex++ - ) { - let isDuplicate = false; - for ( - let compareIndex = 0; - compareIndex < uniqueItems.length; - compareIndex++ - ) { - if (inputSequence[currentIndex] === uniqueItems[compareIndex]) { - isDuplicate = true; - break; - } - } - if (!isDuplicate) { - uniqueItems.push(inputSequence[currentIndex]); - } - } - - return uniqueItems; + + return [...new Set(inputSequence)]; //O(N+N) } + +// Original Time Complexity: O(n * k), worst case O(n^2) +// For each item, the code may scan all uniqueItems to check for duplicates. + +// Time Complexity: O(n) +// Creating the Set processes each item once, and spreading it back to an array is also O(n). + +// Space Complexity: O(n) +// The Set and returned array can store up to n unique items. + +// Optimal Time Complexity: O(n) +// We must inspect every element at least once to remove duplicates. \ No newline at end of file diff --git a/Sprint-1/Python/calculate_sum_and_product/calculate_sum_and_product.py b/Sprint-1/Python/calculate_sum_and_product/calculate_sum_and_product.py index cfd5cfd..2da0cd3 100644 --- a/Sprint-1/Python/calculate_sum_and_product/calculate_sum_and_product.py +++ b/Sprint-1/Python/calculate_sum_and_product/calculate_sum_and_product.py @@ -1,31 +1,39 @@ from typing import Dict, List +# def calculate_sum_and_product(input_numbers: List[int]) -> Dict[str, int]: +# """ +# Calculate the sum and product of integers in a list. -def calculate_sum_and_product(input_numbers: List[int]) -> Dict[str, int]: - """ - Calculate the sum and product of integers in a list. +# Note: the sum is every number added together +# and the product is every number multiplied together +# so for example: [2, 3, 5] would return +# { +# "sum": 10, // 2 + 3 + 5 +# "product": 30 // 2 * 3 * 5 +# } +# Time Complexity: +# Space Complexity: +# Optimal time complexity: +# """ +# # Edge case: empty list +# if not input_numbers: +# return {"sum": 0, "product": 1} + +# sum = 0 +# for current_number in input_numbers: +# sum += current_number - Note: the sum is every number added together - and the product is every number multiplied together - so for example: [2, 3, 5] would return - { - "sum": 10, // 2 + 3 + 5 - "product": 30 // 2 * 3 * 5 - } - Time Complexity: - Space Complexity: - Optimal time complexity: - """ - # Edge case: empty list - if not input_numbers: - return {"sum": 0, "product": 1} +# product = 1 +# for current_number in input_numbers: +# product *= current_number - sum = 0 - for current_number in input_numbers: - sum += current_number - product = 1 - for current_number in input_numbers: - product *= current_number +# return {"sum": sum, "product": product} +def calculate_sum_and_product(input_numbers: List[int]) -> Dict[str, int]: + total: int = 0 + product: int = 1 + for num in input_numbers: + total += num + product *= num - return {"sum": sum, "product": product} + return {"sum": total, "product": product} diff --git a/Sprint-1/Python/find_common_items/find_common_items.py b/Sprint-1/Python/find_common_items/find_common_items.py index 478e2ef..b59c198 100644 --- a/Sprint-1/Python/find_common_items/find_common_items.py +++ b/Sprint-1/Python/find_common_items/find_common_items.py @@ -3,19 +3,31 @@ ItemType = TypeVar("ItemType") +# def find_common_items( +# first_sequence: Sequence[ItemType], second_sequence: Sequence[ItemType] +# ) -> List[ItemType]: +# """ +# Find common items between two arrays. + +# Time Complexity: +# Space Complexity: +# Optimal time complexity: +# """ +# common_items: List[ItemType] = [] +# for i in first_sequence: +# for j in second_sequence: +# if i == j and i not in common_items: +# common_items.append(i) +# return common_items + + def find_common_items( first_sequence: Sequence[ItemType], second_sequence: Sequence[ItemType] ) -> List[ItemType]: - """ - Find common items between two arrays. - - Time Complexity: - Space Complexity: - Optimal time complexity: - """ - common_items: List[ItemType] = [] - for i in first_sequence: - for j in second_sequence: - if i == j and i not in common_items: - common_items.append(i) - return common_items + first_set = set(first_sequence) + second_set = set(second_sequence) + + common = first_set.intersection(second_set) + # common = first_set & second_set + + return list(common) diff --git a/Sprint-1/Python/has_pair_with_sum/has_pair_with_sum.py b/Sprint-1/Python/has_pair_with_sum/has_pair_with_sum.py index fe2da51..d0bcbdf 100644 --- a/Sprint-1/Python/has_pair_with_sum/has_pair_with_sum.py +++ b/Sprint-1/Python/has_pair_with_sum/has_pair_with_sum.py @@ -3,16 +3,27 @@ Number = TypeVar("Number", int, float) +# def has_pair_with_sum(numbers: List[Number], target_sum: Number) -> bool: +# """ +# Find if there is a pair of numbers that sum to a target value. + +# Time Complexity: +# Space Complexity: +# Optimal time complexity: +# """ +# for i in range(len(numbers)): +# for j in range(i + 1, len(numbers)): +# if numbers[i] + numbers[j] == target_sum: +# return True +# return False + def has_pair_with_sum(numbers: List[Number], target_sum: Number) -> bool: - """ - Find if there is a pair of numbers that sum to a target value. + seen = set() + for num in numbers: + needed = target_sum - num + if needed in seen: + return True + + seen.add(num) - Time Complexity: - Space Complexity: - Optimal time complexity: - """ - for i in range(len(numbers)): - for j in range(i + 1, len(numbers)): - if numbers[i] + numbers[j] == target_sum: - return True return False diff --git a/Sprint-1/Python/remove_duplicates/remove_duplicates.py b/Sprint-1/Python/remove_duplicates/remove_duplicates.py index c9fdbe8..67f9b02 100644 --- a/Sprint-1/Python/remove_duplicates/remove_duplicates.py +++ b/Sprint-1/Python/remove_duplicates/remove_duplicates.py @@ -3,23 +3,34 @@ ItemType = TypeVar("ItemType") -def remove_duplicates(values: Sequence[ItemType]) -> List[ItemType]: - """ - Remove duplicate values from a sequence, preserving the order of the first occurrence of each value. - - Time complexity: - Space complexity: - Optimal time complexity: - """ - unique_items = [] - - for value in values: - is_duplicate = False - for existing in unique_items: - if value == existing: - is_duplicate = True - break - if not is_duplicate: - unique_items.append(value) - - return unique_items +# def remove_duplicates(values: Sequence[ItemType]) -> List[ItemType]: +# """ +# Remove duplicate values from a sequence, preserving the order of the first occurrence of each value. + +# Time complexity: +# Space complexity: +# Optimal time complexity: +# """ +# unique_items = [] + +# for value in values: +# is_duplicate = False +# for existing in unique_items: +# if value == existing: +# is_duplicate = True +# break +# if not is_duplicate: +# unique_items.append(value) + +# return unique_items + +def remove_duplicates(values): + seen = set() + result = [] + + for item in values: + if item not in seen: + seen.add(item) + result.append(item) + + return result \ No newline at end of file