diff --git a/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js b/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js index ce738c3..8ba9985 100644 --- a/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js +++ b/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js @@ -9,26 +9,29 @@ * "product": 30 // 2 * 3 * 5 * } * - * Time Complexity: - * Space Complexity: - * Optimal Time Complexity: + * Time Complexity: O(n) + * Space Complexity: O(1) + * Optimal Time Complexity: O(n) + * Explanation: The function iterates through the list of numbers twice, + * once to calculate the sum and once to calculate the product. + * Each iteration takes O(n) time, resulting in a total time complexity of O(n). + * The space complexity is O(1) because we are using a constant amount of space to store the sum and product, + * regardless of the size of the input list. + * + * Refactor: + * I combined the two loops into a single loop + * to calculate both the sum and product simultaneously. * * @param {Array} numbers - Numbers to process * @returns {Object} Object containing running total and product */ 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, - }; + return {sum,product}; } diff --git a/Sprint-1/JavaScript/findCommonItems/findCommonItems.js b/Sprint-1/JavaScript/findCommonItems/findCommonItems.js index 5619ae5..c9e0823 100644 --- a/Sprint-1/JavaScript/findCommonItems/findCommonItems.js +++ b/Sprint-1/JavaScript/findCommonItems/findCommonItems.js @@ -1,14 +1,26 @@ /** * Finds common items between two arrays. * - * Time Complexity: - * Space Complexity: - * Optimal Time Complexity: - * + * Time Complexity: O(n * m) + * Space Complexity: O(k)---> where k is the number of common items + * Optimal Time Complexity: O(n + m) + * Explanation: The function uses the filter method to iterate through each item in the first array and + * checks if it exists in the second array using the includes method. + * This results in a time complexity of O(n * m) because for each item in the first array, + * we are checking against all items in the second array. + * The space complexity is O(k) because we are creating a new array to store the common items, + * where k is the number of common items found. * @param {Array} firstArray - First array to compare * @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 findCommonItems = (firstArray, secondArray) => { + const lookup = new Set(secondArray); + const result = new Set(); + for (const item of firstArray) { + if (lookup.has(item)) { + result.add(item); + } + } + return [...result]; +}; diff --git a/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js b/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js index dd2901f..e51665f 100644 --- a/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js +++ b/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js @@ -1,21 +1,26 @@ /** * Find if there is a pair of numbers that sum to a given target value. * - * Time Complexity: - * Space Complexity: - * Optimal Time Complexity: - * + * Time Complexity: O(n²) + * Space Complexity: O(1) + * Optimal Time Complexity: O(n) + * Explanation: The function uses a nested loop to check every possible pair of numbers in the array + * to see if they sum up to the target value. + * This results in a time complexity of O(n²) because for each number in the array, + * we are checking it against every other number. + *The refactored version uses a Set to check for the existence of the complement, reducing the overall complexity to O(n). * @param {Array} numbers - Array of numbers to search through * @param {number} target - Target sum to find * @returns {boolean} True if pair exists, false otherwise */ 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 complement = target - num; + if (seen.has(complement)) { + return true; } + seen.add(num); } return false; } diff --git a/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs b/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs index dc5f771..b62ef4e 100644 --- a/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs +++ b/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs @@ -1,36 +1,27 @@ /** * Remove duplicate values from a sequence, preserving the order of the first occurrence of each value. * - * Time Complexity: - * Space Complexity: - * Optimal Time Complexity: + * Time Complexity: O(n²) + * Space Complexity: O(n) + * Optimal Time Complexity: O(n) + * Explanation: The function checks each element against all previously seen elements to determine, + * if it is a duplicate, resulting in a time complexity of O(n²) in the worst case. + * The space complexity is O(n) because we are storing unique items in a new array. + * The optimal time complexity can be achieved by using a Set to track seen items, + * which allows for O(1) average time complexity for lookups, resulting in an overall time complexity of O(n). + * Refactor: Using Set allows to constant-time membership checks, which significantly reduces the time complexity from O(n²) to O(n). * * @param {Array} inputSequence - Sequence to remove duplicates from * @returns {Array} New sequence with duplicates removed */ export function removeDuplicates(inputSequence) { + const seen = new Set(); 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]); + for (const item of inputSequence) { + if (!seen.has(item)) { + seen.add(item); + uniqueItems.push(item); } } - return uniqueItems; } 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..999551e 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 @@ -12,20 +12,24 @@ def calculate_sum_and_product(input_numbers: List[int]) -> Dict[str, int]: "sum": 10, // 2 + 3 + 5 "product": 30 // 2 * 3 * 5 } - Time Complexity: - Space Complexity: - Optimal time complexity: + Time Complexity: O(n) + Space Complexity: O(1) + Optimal time complexity: O(n) + Explanation: The function loops through the list of input numbers twice, once to calculate the + sum and once to calculate the product. The results in O(n n) = O(n) time. It uses only + + Refactor: We can calculate both the sum and product in a single loop, + which reduces the time complexity to O(n). """ # Edge case: empty list if not input_numbers: return {"sum": 0, "product": 1} - sum = 0 - for current_number in input_numbers: - sum += current_number + total_sum = 0 + total_product = 1 - product = 1 - for current_number in input_numbers: - product *= current_number + for num in input_numbers: + total_sum += num + total_product *= num - return {"sum": sum, "product": product} + return {"sum": total_sum, "product": total_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..6d8283d 100644 --- a/Sprint-1/Python/find_common_items/find_common_items.py +++ b/Sprint-1/Python/find_common_items/find_common_items.py @@ -9,13 +9,22 @@ def find_common_items( """ Find common items between two arrays. - Time Complexity: - Space Complexity: - Optimal time complexity: + Time Complexity: O(n * m) + Space Complexity: O(n) + Optimal time complexity: O(n + m) + Explanation: The function uses a nested loop to check every possible pair of items in the two + sequences to see if they are common. + This results in a time complexity of O(n * m). + Using a set for constant-time lookups can reduce the time complexity to O(n + m) + by first converting one of the sequences into a set and then checking for common items in a single loop. """ - 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 + lookup = set(second_sequence) + result = [] + seen = set() + + for item in first_sequence: + if item in lookup and item not in seen: + seen.add(item) + result.append(item) + + return result 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..835a9ea 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 @@ -7,12 +7,17 @@ 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: + Time Complexity: O(n^2) because we have two nested loops that iterate through the list of numbers. + Space Complexity: O(1) + Optimal time complexity: O(n) + Explanation: The function checks every possible pair of numbers using two nested loops, resulting in O(n^2) time complexity. + Refactor: It uses constant extra space. The optimal solution uses a set to check complements in O(1) time, reducing the overall complexity to O(n). """ - for i in range(len(numbers)): - for j in range(i + 1, len(numbers)): - if numbers[i] + numbers[j] == target_sum: - return True + seen = set() + for num in numbers: + complement = target_sum - num + if complement in seen: + return True + seen.add(num) + return False diff --git a/Sprint-1/Python/remove_duplicates/remove_duplicates.py b/Sprint-1/Python/remove_duplicates/remove_duplicates.py index c9fdbe8..ee5760b 100644 --- a/Sprint-1/Python/remove_duplicates/remove_duplicates.py +++ b/Sprint-1/Python/remove_duplicates/remove_duplicates.py @@ -6,20 +6,18 @@ 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: + Outer loop runs n times (each value in values) + Inner loop runs up to k times (size of unique_items, worst case k = n) + Time complexity: O(n^2) + Space complexity: O(n) + Optimal time complexity: O(n) """ - unique_items = [] + seen = set() + result = [] 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) + if value not in seen: + seen.add(value) + result.append(value) - return unique_items + return result