diff --git a/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js b/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js index ce738c3..a41932f 100644 --- a/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js +++ b/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js @@ -9,21 +9,19 @@ * "product": 30 // 2 * 3 * 5 * } * - * Time Complexity: - * Space Complexity: - * Optimal Time Complexity: - * + * Time Complexity: There are two separate loops. Total operation O(n)+O(n) ---> O(n) + * Space Complexity:We are only using two variables sum and product --->O(1) + * Optimal Time Complexity:To calculate sum and product, every element must be visited at least once, so the optimal time complexity is O(n) + * Refactor Note: We can combine both calculations into a single loop for cleaner and more readable code + * * @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; } diff --git a/Sprint-1/JavaScript/findCommonItems/findCommonItems.js b/Sprint-1/JavaScript/findCommonItems/findCommonItems.js index 5619ae5..913f4b9 100644 --- a/Sprint-1/JavaScript/findCommonItems/findCommonItems.js +++ b/Sprint-1/JavaScript/findCommonItems/findCommonItems.js @@ -1,14 +1,16 @@ /** * Finds common items between two arrays. * - * Time Complexity: - * Space Complexity: - * Optimal Time Complexity: - * + * Time Complexity: We are checking two arrays. If the first array has length n and the second has length m, the time complexity is O(n * m), + because filter iterates over the first array and includes scans the second array for each element. + * Space Complexity: A new Set is created to store unique common items, which in the worst case can be the size of the first array --> O(n). + * Optimal Time Complexity: By converting one array to a Set, we can check membership in O(1) for each element of the other array, reducing the time complexity to O(n + m). * @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 firstArr = new Set(firstArray); //O(n) + const commons = secondArray.filter((el) => firstArr.has(el)); //O(m) + return [...new Set(commons)]; // remove duplicates +}; diff --git a/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js b/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js index dd2901f..6321269 100644 --- a/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js +++ b/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js @@ -1,20 +1,22 @@ /** * Find if there is a pair of numbers that sum to a given target value. * - * Time Complexity: - * Space Complexity: - * Optimal Time Complexity: + * Time Complexity:To using nested loop for compare elements time complexity will be ---> O(n*n) + * Space Complexity:We only use few variables -->O(1) + * Optimal Time Complexity:Iterate array only once and use a Set for O(1) lookups / total----->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) { + const seen = new Set(); 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 neededNumber = target - numbers[i]; + if (seen.has(neededNumber)) { + return true; + } else { + seen.add(numbers[i]); } } return false; diff --git a/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs b/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs index dc5f771..e5d1ce5 100644 --- a/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs +++ b/Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs @@ -1,36 +1,14 @@ /** * 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*n) --> there is a nested loop + * Space Complexity:0(n)--> we are creating a array + * Optimal Time Complexity: we can use a new Set to remove all duplicates -->O(n) * - * @param {Array} inputSequence - Sequence to remove duplicates from + * @param {Array} inputSequence - Sequence to remove duplicates from //[1,1,2,2,3,4,5,5] * @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; + const uniqueSequence = [...new Set(inputSequence)]; + return uniqueSequence; } 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..4a432a2 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:There are two separate loops O(n)+O(n) total --->O(n) + Space Complexity:We have two variables sum and product O(1) total --->O(1) + Optimal time complexity: O(n) cannot be improved because we need to process each element at least once + but the code can be refactored for better readability. """ # Edge case: empty list if not input_numbers: return {"sum": 0, "product": 1} sum = 0 - for current_number in input_numbers: - sum += current_number - product = 1 for current_number in input_numbers: + sum += current_number product *= current_number - return {"sum": sum, "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..538924d 100644 --- a/Sprint-1/Python/find_common_items/find_common_items.py +++ b/Sprint-1/Python/find_common_items/find_common_items.py @@ -8,14 +8,16 @@ def find_common_items( ) -> List[ItemType]: """ Find common items between two arrays. + Time Complexity: O(n * m * k) in the worst case, where: + - n = length of first_sequence (outer loop) + - m = length of second_sequence (inner loop) + - k = length of common_items, because "i not in common_items" requires scanning this list - Time Complexity: - Space Complexity: - Optimal time complexity: + Space Complexity:In first implementation We only store the common items in a new list.--> O(n) + + + Optimal time complexity:This can be improved to O(n + m) by using a set for faster lookups. """ - 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) # O(n) + commons=[item for item in second_sequence if item in first_set] # O(m) + return list(set(commons)) # remove duplicates 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..9e183a4 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,13 @@ 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: We have nested loop --> O(n*n) + Space Complexity:We have variables -->O(1) + Optimal time complexity:We can use only one loop -->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: + if target_sum - num 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..4cce08e 100644 --- a/Sprint-1/Python/remove_duplicates/remove_duplicates.py +++ b/Sprint-1/Python/remove_duplicates/remove_duplicates.py @@ -7,19 +7,14 @@ 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: Outer loop O(n) Inner loop (worst case) O(n) total --->O(n*n) + Space complexity: We have an array ,unique_items, total --->O(n) + Optimal time complexity: O(n) using a set for fast lookups """ 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) - + seen = set() + for value in values: # O(n) + if value not in seen: # O(1) + seen.add(value) # O(1) + unique_items.append(value) # O(1) return unique_items