From c5ecc4e6857785554b378fb09bdbca8aea0083be Mon Sep 17 00:00:00 2001 From: zohrehKazemianpour <129424353+zohrehKazemianpour@users.noreply.github.com> Date: Thu, 5 Feb 2026 14:36:21 +0000 Subject: [PATCH 1/5] refactor calculateSumAndProduct by reducing the number of iteration --- .../calculateSumAndProduct.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js b/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js index ce738c3..8715c47 100644 --- a/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js +++ b/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js @@ -9,21 +9,23 @@ * "product": 30 // 2 * 3 * 5 * } * - * Time Complexity: - * Space Complexity: - * Optimal Time Complexity: + * Time Complexity: O(n) the previous solution iterates through the lists twice, once for the sum and once for the product, but this solution iterates through the list only once, calculating both the sum and product in a single pass. + + + + * Space Complexity: O(1) the space complexity is constant because we are using only a fixed amount of space to store the sum and product, regardless of the size of the input list. + + * Optimal Time Complexity: O(n) because we need to iterate through all the numbers in the list at least once to calculate the sum and product. so even though the performance improves by reducing the number of iterations, the overall time complexity remains O(n) since we still need to process each element in the list. * * @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; } From a2582ed47bc6a415d1fcb631a463dacbb120d5d2 Mon Sep 17 00:00:00 2001 From: zohrehKazemianpour <129424353+zohrehKazemianpour@users.noreply.github.com> Date: Fri, 6 Feb 2026 15:08:44 +0000 Subject: [PATCH 2/5] refactor: findCommonItems.j,changed implementation from nested .includes() loop to a Set-based --- .../findCommonItems/findCommonItems.js | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/Sprint-1/JavaScript/findCommonItems/findCommonItems.js b/Sprint-1/JavaScript/findCommonItems/findCommonItems.js index 5619ae5..d8c9e22 100644 --- a/Sprint-1/JavaScript/findCommonItems/findCommonItems.js +++ b/Sprint-1/JavaScript/findCommonItems/findCommonItems.js @@ -1,14 +1,25 @@ /** * Finds common items between two arrays. * - * Time Complexity: - * Space Complexity: - * Optimal Time Complexity: + * Time Complexity: O(n + m) where n is the length of the first array and m is the length of the second array. This is because we create a Set from the second array (which takes O(m) time) and then filter the first array (which takes O(n) time). The overall time complexity is linear. + + + + * Space Complexity: O(m) where m is the length of the second array. This is because we create a Set from the second array, which requires additional space The space complexity is linear with respect to the size of the second array. + + +* Optimal Time Complexity: O(n + m) because we need to process each element in both arrays at least once to find the common items. The use of a Set allows us to achieve this optimal time complexity. * * @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 bSet = new Set(secondArray); + return firstArray.filter((e) => bSet.has(e)); +} + +const arr1 = [2, 3, 5]; +const arr2 = [1, 2, 3]; +const commonItems = findCommonItems(arr1, arr2); +console.log(commonItems); \ No newline at end of file From 250a9157e7b24520ec29ef2c1537a6fc9f857d8c Mon Sep 17 00:00:00 2001 From: zohrehKazemianpour <129424353+zohrehKazemianpour@users.noreply.github.com> Date: Fri, 6 Feb 2026 15:51:04 +0000 Subject: [PATCH 3/5] refactor hasPairWithSum: Replaced nested O(n^2) loops with a one pass Set based approach --- .../hasPairWithSum/hasPairWithSum.js | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js b/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js index dd2901f..5cc694c 100644 --- a/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js +++ b/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js @@ -1,21 +1,32 @@ /** * 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) where n is the length of the input array. This is because we iterate through the array once to check for pairs, and each lookup in the Set is O(1) on average. The overall time complexity is linear. + * + * + * + * Space Complexity: O(n) in the worst case, if all numbers in the input array are unique and we end up storing all of them in the Set. The space complexity is linear with respect to the size of the input array. + * + * + * + * Optimal Time Complexity: O(n) because we need to iterate through the array at least once to check for pairs. The use of a Set allows us to achieve this optimal time complexity by providing constant time lookups for the complement values. * * @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 seenNumbers = new Set(); + +for (const num of numbers) { + const complement = target - num; + if (seenNumbers.has(complement)) { + return true; } - return false; + seenNumbers.add(num); + } + +return false; +} +console.log(hasPairWithSum([4, 4], 8)) From 648dc36011c747f50b09310372c54440b9d4e460 Mon Sep 17 00:00:00 2001 From: zohrehKazemianpour <129424353+zohrehKazemianpour@users.noreply.github.com> Date: Thu, 12 Feb 2026 11:01:05 +0000 Subject: [PATCH 4/5] refactor: removeDuplicates --- .../removeDuplicates/removeDuplicates.mjs | 38 ++++++++----------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs b/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs index dc5f771..f8b36da 100644 --- a/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs +++ b/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs @@ -1,36 +1,30 @@ /** * 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) - where n is the length of the input sequence, as we need to iterate through it once to create the Set. + * Space Complexity: O(n) - in the worst case, if all elements are unique, the Set will contain all elements of the input sequence. so we need memory to store the unique elements. + * Optimal Time Complexity: O(n)- using a Set to track seen values allows us to achieve linear time complexity for removing duplicates. * * @param {Array} inputSequence - Sequence to remove duplicates from * @returns {Array} New sequence with duplicates removed */ export function removeDuplicates(inputSequence) { + + return [...new Set(inputSequence)]; +} + + +// approach 2: map and look up object +/*export function removeDuplicates(inputSequence) { + const seen = {}; 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[item]) { + seen[item] = true; + uniqueItems.push(item); } } return uniqueItems; -} +}*/ \ No newline at end of file From 1f29d8e72c4bf33db5e14d5eaf630482cb99b033 Mon Sep 17 00:00:00 2001 From: zohrehKazemianpour <129424353+zohrehKazemianpour@users.noreply.github.com> Date: Sat, 25 Apr 2026 12:54:37 +0100 Subject: [PATCH 5/5] Address PR feedback --- .../calculate_sum_and_product.py | 18 +++++++-------- .../find_common_items/find_common_items.py | 21 ++++++++++++------ .../has_pair_with_sum/has_pair_with_sum.py | 22 +++++++++++++------ .../remove_duplicates/remove_duplicates.py | 19 ++++++++-------- 4 files changed, 47 insertions(+), 33 deletions(-) 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..c901821 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,18 @@ 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(2n) = O(n) - We iterate through the list twice (once for sum, once for product) + Space Complexity: O(1) - Only using constant extra space for variables + Optimal time complexity: O(n) - We can achieve O(n) by combining both loops into one single pass """ # Edge case: empty list if not input_numbers: return {"sum": 0, "product": 1} - sum = 0 + sum_value = 0 + product_value = 1 for current_number in input_numbers: - sum += current_number + sum_value += current_number + product_value *= current_number - product = 1 - for current_number in input_numbers: - product *= current_number - - return {"sum": sum, "product": product} + return {"sum": sum_value, "product": product_value} 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..58a46d4 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,20 @@ def find_common_items( """ Find common items between two arrays. - Time Complexity: - Space Complexity: - Optimal time complexity: + Time Complexity: O(n * m) - where n is the length of the first array and m is the length of the second array. + We iterate through each element in the first array and for each element, we check if it exists + in the second array using the 'in' operator, which takes O(m) time. We also check if the item + is already in common_items using 'not in', which takes O(k) time where k is the size of common_items. + Space Complexity: O(k) - where k is the number of common items found. We store each common item in the list. + Optimal time complexity: O(n + m) - Using a hash set (dictionary/set) for the second sequence allows us to achieve + linear time by avoiding the nested loop. This reduces the lookup from O(m) to O(1). """ + # Create a set from the second sequence for O(1) lookups + second_set = set(second_sequence) 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) + + for item in first_sequence: + if item in second_set and item not in common_items: + common_items.append(item) + return common_items 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..82394ba 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,20 @@ 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²) - where n is the length of the input array. We use two nested loops, where the outer loop + iterates through each element, and the inner loop iterates through all subsequent elements. + In the worst case, we need to check all pairs. + Space Complexity: O(1) - We only use constant extra space for loop variables. + Optimal time complexity: O(n) - Using a hash set allows us to check if the complement (target_sum - current_number) + exists in O(1) time, reducing the overall complexity from O(n²) to O(n) with one pass through the array. """ - for i in range(len(numbers)): - for j in range(i + 1, len(numbers)): - if numbers[i] + numbers[j] == target_sum: - return True + # Optimised approach: Use a set to store seen numbers for O(1) lookups + seen_numbers = set() + + for num in numbers: + complement = target_sum - num + if complement in seen_numbers: + return True + seen_numbers.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..c343011 100644 --- a/Sprint-1/Python/remove_duplicates/remove_duplicates.py +++ b/Sprint-1/Python/remove_duplicates/remove_duplicates.py @@ -7,19 +7,20 @@ 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: + Time Complexity: O(n²) - where n is the length of the input sequence. For each element in the values sequence, + we iterate through all existing items in unique_items to check if it's a duplicate. + In the worst case, this requires checking all previous elements. + Space Complexity: O(k) - where k is the number of unique items. We store up to k items in the unique_items list. + Optimal time complexity: O(n) - Using a set to track seen items allows us to check for duplicates in O(1) time, + reducing the overall complexity from O(n²) to O(n). """ + # Optimised approach: Use a set to track seen items for O(1) lookups + seen_items = set() 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: + if value not in seen_items: + seen_items.add(value) unique_items.append(value) return unique_items