diff --git a/Sprint-1/JavaScript/CHANGES-MADE.md b/Sprint-1/JavaScript/CHANGES-MADE.md new file mode 100644 index 00000000..a709b734 --- /dev/null +++ b/Sprint-1/JavaScript/CHANGES-MADE.md @@ -0,0 +1,49 @@ +This is a great way to document your learning and show the impact of your refactoring. Below is the content for your `changes-made.md` file, formatted exactly like the comparison table you provided. + +--- + +# Sprint 1: Complexity Analysis & Refactoring + +## 1. calculateSumAndProduct.js +| Feature | Original Code | Refactored Code | +| :--- | :--- | :--- | +| **Time Complexity** | **Linear $O(n)$** | **Linear $O(n)$** | +| **Why?** | Two separate loops ($n + n$). | Combined into a single loop ($n$). | +| **Space Complexity** | **Constant $O(1)$** | **Constant $O(1)$** | +| **Why?** | Only two scalar variables used. | Only two scalar variables used. | + +--- + +## 2. findCommonItems.js +| Feature | Original Code | Refactored Code | +| :--- | :--- | :--- | +| **Time Complexity** | **Quadratic $O(n \times m)$** | **Linear $O(n + m)$** | +| **Why?** | Nested loop: `.includes()` inside `.filter()`. | Set lookup: `.has()` inside `.filter()`. | +| **Space Complexity** | **Constant $O(1)$** | **Linear $O(m)$** | +| **Why?** | No extra search structure created. | Created a `Set` to store the second array. | + +--- + +## 3. hasPairWithSum.js +| Feature | Original Code | Refactored Code | +| :--- | :--- | :--- | +| **Time Complexity** | **Quadratic $O(n^2)$** | **Linear $O(n)$** | +| **Why?** | Nested `for` loops comparing every pair. | One loop with instant "Complement" lookup. | +| **Space Complexity** | **Constant $O(1)$** | **Linear $O(n)$** | +| **Why?** | No extra storage used. | Created a `Set` to store visited numbers. | + +--- + +## 4. removeDuplicates.js +| Feature | Original Code | Refactored Code | +| :--- | :--- | :--- | +| **Time Complexity** | **Quadratic $O(n^2)$** | **Linear $O(n)$** | +| **Why?** | Nested loop searching the result array. | One loop using a Set for "Seen" items. | +| **Space Complexity** | **Linear $O(n)$** | **Linear $O(n)$** | +| **Why?** | Stored unique items in an array. | Stored unique items in both an array and a Set. | + +--- + +### Key Takeaway: The Space-Time Trade-off +In the `findCommonItems.js`, `hasPairWithSum.js` and `removeDuplicates.js` tasks, I successfully reduced the **Time Complexity** from Quadratic to Linear. I did this by choosing a **Set** instead of an **Array** for searching. This is a classic "Space-Time Trade-off": I used a bit more memory (Space) to make the program run significantly faster (Time). + diff --git a/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js b/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js index ce738c33..1fdf3573 100644 --- a/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js +++ b/Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js @@ -18,12 +18,9 @@ */ 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 5619ae5d..0b6b9f13 100644 --- a/Sprint-1/JavaScript/findCommonItems/findCommonItems.js +++ b/Sprint-1/JavaScript/findCommonItems/findCommonItems.js @@ -9,6 +9,8 @@ * @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 secondArraySet = new Set(secondArray); + + return [...new Set(firstArray.filter((item) => secondArraySet.has(item)))]; +}; diff --git a/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js b/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js index dd2901f6..14b2ef35 100644 --- a/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js +++ b/Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js @@ -10,11 +10,14 @@ * @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 numbersSet = new Set(); + + for (let i=0; i Dict[str, int]: if not input_numbers: return {"sum": 0, "product": 1} - sum = 0 - for current_number in input_numbers: - sum += current_number - + total_sum = 0 product = 1 for current_number in input_numbers: + total_sum += current_number product *= current_number - - return {"sum": sum, "product": product} + + return {"sum": total_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 478e2efc..a5bda6e9 100644 --- a/Sprint-1/Python/find_common_items/find_common_items.py +++ b/Sprint-1/Python/find_common_items/find_common_items.py @@ -13,9 +13,17 @@ def find_common_items( 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 + # 1. Convert second_sequence into a Python set for O(1) lookups + second_set = set(second_sequence) + + # 2. Use a set to keep track of results (handles the "Unique Items" requirement) + common_items_set: Set[ItemType] = set() + + # 3. Use one loop to go through first_sequence + for item in first_sequence: + # 4. Check if the item is in the second_set + if item in second_set: + common_items_set.add(item) + + # 5. Convert final set back into a list + return list(common_items_set) \ No newline at end of file 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 fe2da517..9d22fca9 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 @@ -1,4 +1,4 @@ -from typing import List, TypeVar +from typing import List, Set, TypeVar Number = TypeVar("Number", int, float) @@ -11,8 +11,20 @@ def has_pair_with_sum(numbers: List[Number], target_sum: Number) -> bool: 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 + # 1. Initialize an empty set called seen. + seen: Set[Number] = set() + + # 2. Loop through each num in the numbers list. + for num in numbers: + # 3. Calculate the remaining_number_needed (the missing piece). + remaining_number_needed = target_sum - num + + # 4. Check: if remaining_number_needed in seen. + if remaining_number_needed in seen: + return True + + # 5. If not, add the current num to the set. + seen.add(num) + + # 6. If the loop finishes, return False. return False diff --git a/Sprint-1/Python/remove_duplicates/remove_duplicates.py b/Sprint-1/Python/remove_duplicates/remove_duplicates.py index c9fdbe80..1b6da606 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) + Space complexity: O(n) + Optimal time complexity: O(n) """ - unique_items = [] + # 1. Initialize your list and set + result: List[ItemType] = [] + element_seen: Set[ItemType] = set() + # 2. Start your loop 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 + # 3. Check if we have NOT seen this value yet + if value not in element_seen: + # 4. Remember it in the set and add it to the result + element_seen.add(value) + result.append(value) + + return result