From 9c36cab664943f512375c319f962c4b1af8582eb Mon Sep 17 00:00:00 2001 From: Droid-An Date: Thu, 9 Oct 2025 14:24:07 +0100 Subject: [PATCH 1/4] done task for the 1 sprint --- .../calculateSumAndProduct.js | 6 ++-- .../findCommonItems/findCommonItems.js | 26 ++++++++++---- .../has_pair_with_sum/has_pair_with_sum.py | 34 ++++++++++++++----- .../remove_duplicates/remove_duplicates.py | 30 +++++++++------- 4 files changed, 66 insertions(+), 30 deletions(-) diff --git a/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js b/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js index ce738c3..6c32c56 100644 --- a/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js +++ b/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js @@ -9,9 +9,9 @@ * "product": 30 // 2 * 3 * 5 * } * - * Time Complexity: - * Space Complexity: - * Optimal Time Complexity: + * Time Complexity: O(n) because this code has 2 loops that are separated from each other + * Space Complexity: O(n) for input array and O(1) for variables and loops, which result in O(n) in total + * Optimal Time Complexity: O(n) I think this algorithm is efficient enough * * @param {Array} numbers - Numbers to process * @returns {Object} Object containing running total and product diff --git a/Sprint-1/JavaScript/findCommonItems/findCommonItems.js b/Sprint-1/JavaScript/findCommonItems/findCommonItems.js index 5619ae5..0cf2624 100644 --- a/Sprint-1/JavaScript/findCommonItems/findCommonItems.js +++ b/Sprint-1/JavaScript/findCommonItems/findCommonItems.js @@ -1,14 +1,28 @@ /** * Finds common items between two arrays. * - * Time Complexity: - * Space Complexity: - * Optimal Time Complexity: + * Time Complexity: O(n*m) where n and m are length of each array + * Space Complexity: O(n) where n is a length of arrays + * Optimal Time Complexity: O(n) * * @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) => { + // [...new Set(firstArray.filter((item) => secondArray.includes(item))),] + // program flow: + // firstArray.filter go through the each item in first array (loop) + // secondArray.includes check if that item is in the second array (nested loop) + // nested loop result in O(n^2) time complexity + + // to reduce time complexity to sublinear on the number of elements in the arrays we can use Set and it's .intersection() method + + // complexity of this operation is O(n) + const firstArraySet = new Set(firstArray); + // complexity of this operation is O(m) + const secondArraySet = new Set(secondArray); + // intersection method uses has method which is considered to be faster than O(n) and since JS uses hash tables for has methods, the complexity should be + // has O(1) and intersection O(n) which result in O(n) overall time complexity + return Array.from(firstArraySet.intersection(secondArraySet)); +}; 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..1da09d8 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,30 @@ 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) + Space Complexity: O(n). It's memory for the input array arr + Optimal time complexity: 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 - return False + # nested loop result in O(n^2) 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 + + # it's better to use to pointers method here + # first: sort the list O(n) + numbers = sorted(numbers) + # declare the left and right pointers + left, right = 0, len(numbers)-1 + # and until we "squeezed" the list check if sum of the pointers is equal to target sum + # in worst case we need to do n-1 steps where n is length of the list, so overall complexity will be O(n) + while left < right: + currentSum = numbers[left]+numbers[right] + if currentSum == target_sum: + return True + if currentSum > target_sum: + right -= 1 + else: + left+=1 + return False \ No newline at end of file diff --git a/Sprint-1/Python/remove_duplicates/remove_duplicates.py b/Sprint-1/Python/remove_duplicates/remove_duplicates.py index c9fdbe8..a79dfd4 100644 --- a/Sprint-1/Python/remove_duplicates/remove_duplicates.py +++ b/Sprint-1/Python/remove_duplicates/remove_duplicates.py @@ -7,19 +7,23 @@ 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^2) + Space complexity: O(n) + Optimal time complexity: 0(n) """ - unique_items = [] + # 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) + # 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 + # return unique_items + # nested array O(n^2) complexity + + # here we iterate through the array to make a dict which is O(n) and than convert it to the list which is also 0(n) + return list(dict.fromkeys(values)) From 57a5d0f12af8cadc0ee4e4d2b40c211c3ffa8506 Mon Sep 17 00:00:00 2001 From: Droid-An Date: Tue, 21 Oct 2025 14:54:41 +0100 Subject: [PATCH 2/4] clarified explanation --- Sprint-1/JavaScript/findCommonItems/findCommonItems.js | 3 ++- Sprint-1/Python/remove_duplicates/remove_duplicates.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Sprint-1/JavaScript/findCommonItems/findCommonItems.js b/Sprint-1/JavaScript/findCommonItems/findCommonItems.js index 0cf2624..8207a00 100644 --- a/Sprint-1/JavaScript/findCommonItems/findCommonItems.js +++ b/Sprint-1/JavaScript/findCommonItems/findCommonItems.js @@ -1,7 +1,7 @@ /** * Finds common items between two arrays. * - * Time Complexity: O(n*m) where n and m are length of each array + * Time Complexity: O(n*m) or O(n^2) where n and m are length of each array * Space Complexity: O(n) where n is a length of arrays * Optimal Time Complexity: O(n) * @@ -14,6 +14,7 @@ export const findCommonItems = (firstArray, secondArray) => { // program flow: // firstArray.filter go through the each item in first array (loop) // secondArray.includes check if that item is in the second array (nested loop) + // then, from new filtered array we create a Set which is not a nested array, but still O(n) operation // nested loop result in O(n^2) time complexity // to reduce time complexity to sublinear on the number of elements in the arrays we can use Set and it's .intersection() method diff --git a/Sprint-1/Python/remove_duplicates/remove_duplicates.py b/Sprint-1/Python/remove_duplicates/remove_duplicates.py index a79dfd4..3756b82 100644 --- a/Sprint-1/Python/remove_duplicates/remove_duplicates.py +++ b/Sprint-1/Python/remove_duplicates/remove_duplicates.py @@ -23,7 +23,7 @@ def remove_duplicates(values: Sequence[ItemType]) -> List[ItemType]: # unique_items.append(value) # return unique_items - # nested array O(n^2) complexity + # nested array - O(n^2) complexity - # here we iterate through the array to make a dict which is O(n) and than convert it to the list which is also 0(n) + # here we iterate through the array to make a dict which is O(n) and than convert it to the list which is also O(n) return list(dict.fromkeys(values)) From 96299e7198f69ec9e459ca383e3aa563f3c3d4e0 Mon Sep 17 00:00:00 2001 From: Droid-An Date: Sat, 24 Jan 2026 12:13:54 +0000 Subject: [PATCH 3/4] used hash table method to find pair with sum --- .../has_pair_with_sum/has_pair_with_sum.py | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) 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 1da09d8..e358cb6 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 @@ -8,7 +8,7 @@ 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: O(n^2) - Space Complexity: O(n). It's memory for the input array arr + Space Complexity: O(n). It's memory for the hash table Optimal time complexity: O(n) """ # nested loop result in O(n^2) complexity @@ -17,20 +17,19 @@ def has_pair_with_sum(numbers: List[Number], target_sum: Number) -> bool: # if numbers[i] + numbers[j] == target_sum: # return True # return False - - # it's better to use to pointers method here - # first: sort the list O(n) - numbers = sorted(numbers) - # declare the left and right pointers - left, right = 0, len(numbers)-1 - # and until we "squeezed" the list check if sum of the pointers is equal to target sum - # in worst case we need to do n-1 steps where n is length of the list, so overall complexity will be O(n) - while left < right: - currentSum = numbers[left]+numbers[right] - if currentSum == target_sum: +# ------- + # it's better to use hash table here, where every item can be searched in O(1) time + # create a set + seen_numbers = set() + # loop through each element O(n) + for num in numbers: + # calculate the number we need to add to number in a list to get a target sum + complement = target_sum - num + # search hash table for number we need O(1) + # if have seen that number before, then pair found + if complement in seen_numbers: return True - if currentSum > target_sum: - right -= 1 - else: - left+=1 - return False \ No newline at end of file + # add the current number to set + seen_numbers.add(num) +# if the loop completes without finding a pair, return that no pair exists. + return False From 015a099fd9e008b1a57ea5e2bcca2fc0597c9535 Mon Sep 17 00:00:00 2001 From: Droid-An Date: Sat, 24 Jan 2026 12:20:22 +0000 Subject: [PATCH 4/4] made naming more clear --- Sprint-1/Python/has_pair_with_sum/has_pair_with_sum.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 e358cb6..3702c8f 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 @@ -8,7 +8,7 @@ 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: O(n^2) - Space Complexity: O(n). It's memory for the hash table + Space Complexity: O(n). It's memory for the hash set Optimal time complexity: O(n) """ # nested loop result in O(n^2) complexity @@ -18,14 +18,14 @@ def has_pair_with_sum(numbers: List[Number], target_sum: Number) -> bool: # return True # return False # ------- - # it's better to use hash table here, where every item can be searched in O(1) time + # it's better to use hash set here, where every item can be searched in O(1) time # create a set seen_numbers = set() # loop through each element O(n) for num in numbers: # calculate the number we need to add to number in a list to get a target sum complement = target_sum - num - # search hash table for number we need O(1) + # search hash set for number we need O(1) # if have seen that number before, then pair found if complement in seen_numbers: return True