Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions Sprint-1/JavaScript/CHANGES-MADE.md
Original file line number Diff line number Diff line change
@@ -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).

Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
8 changes: 5 additions & 3 deletions Sprint-1/JavaScript/findCommonItems/findCommonItems.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)))];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could also take advantage of Set's build-in methods. Set implementation in most programming languages typically supports standard set operations like union, intersect, diff, etc.

};
13 changes: 8 additions & 5 deletions Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js
Original file line number Diff line number Diff line change
Expand Up @@ -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<numbers.length; i++) {
const remainingNumberNeeded = target - numbers[i];
if (numbersSet.has(remainingNumberNeeded)) {
return true;
} else {
numbersSet.add(numbers[i]);
}
}
return false;
Expand Down
28 changes: 7 additions & 21 deletions Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,14 @@
* @returns {Array} New sequence with duplicates removed
*/
export function removeDuplicates(inputSequence) {
const uniqueItems = [];
const result = [];
const elementSeen = new Set();

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 (let i=0; i<inputSequence.length; i++) {
if (!elementSeen.has(inputSequence[i])) {
elementSeen.add(inputSequence[i]);
result.push(inputSequence[i]);
}
}

return uniqueItems;
return result;
}
51 changes: 51 additions & 0 deletions Sprint-1/Python/CHANGES-MADE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Sprint 1: Complexity Analysis & Refactoring (Python)

## 1. calculate_sum_and_product.py
| Feature | Original Code | Refactored Code |
| :--- | :--- | :--- |
| **Time Complexity** | **Linear $O(n)$** | **Linear $O(n)$** |
| **Why?** | Two separate `for` loops ($n + n$). | Combined into a single `for` loop ($n$). |
| **Space Complexity** | **Constant $O(1)$** | **Constant $O(1)$** |
| **Why?** | Used two scalar variables. | Used two scalar variables. |

**Note:** Renamed the variable `sum` to `total_sum` to avoid shadowing Python's built-in `sum()` function.

---

## 2. find_common_items.py
| Feature | Original Code | Refactored Code |
| :--- | :--- | :--- |
| **Time Complexity** | **Quadratic $O(n \times m)$** | **Linear $O(n + m)$** |
| **Why?** | Nested loops searching a **list** with the `in` keyword ($O(m)$). | Used a **set** for $O(1)$ membership lookups with the `in` keyword. |
| **Space Complexity** | **Constant $O(1)$** | **Linear $O(m)$** |
| **Why?** | No extra storage created. | Created a `set` to store the second sequence for fast lookups. |

---

## 3. has_pair_with_sum.py
| Feature | Original Code | Refactored Code |
| :--- | :--- | :--- |
| **Time Complexity** | **Quadratic $O(n^2)$** | **Linear $O(n)$** |
| **Why?** | Nested loops comparing every index. | Single pass with a `set` to find the `remaining_number_needed`. |
| **Space Complexity** | **Constant $O(1)$** | **Linear $O(n)$** |
| **Why?** | No extra storage used. | Created a `seen` set to store visited numbers. |

---

## 4. remove_duplicates.py
| Feature | Original Code | Refactored Code |
| :--- | :--- | :--- |
| **Time Complexity** | **Quadratic $O(n^2)$** | **Linear $O(n)$** |
| **Why?** | Nested loops checking if an item was `not in` the result **list**. | Used an `element_seen` **set** for $O(1)$ "already seen" checks. |
| **Space Complexity** | **Linear $O(n)$** | **Linear $O(n)$** |
| **Why?** | Stored unique items in a list. | Stored items in both a result list (for order) and a set (for speed). |

---

### Key Python Takeaways

1. **The `in` Keyword Efficiency:** In Python, the `in` operator is very readable, but its speed depends on the container. Checking `in` for a **list** is $O(n)$, while checking `in` for a **set** is $O(1)$. Leveraging this difference allowed me to optimize three of the four tasks.
2. **Space-Time Trade-off:** To improve the runtime of `find_common_items`, `has_pair_with_sum`, and `remove_duplicates` from $O(n^2)$ to $O(n)$, I utilized extra memory (Space) by creating Python **sets**.
3. **Built-in Shadowing:** I learned to be careful with variable naming (e.g., using `total_sum` instead of `sum`) to avoid overwriting Python’s built-in functions.
4. **Preserving Order:** In `remove_duplicates`, I learned that while sets are fast, they don't preserve order. Using a list for results and a set for tracking allowed for both $O(n)$ speed and correct ordering.

Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,10 @@ def calculate_sum_and_product(input_numbers: List[int]) -> 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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could just use either total or sum.

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}
20 changes: 14 additions & 6 deletions Sprint-1/Python/find_common_items/find_common_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
22 changes: 17 additions & 5 deletions Sprint-1/Python/has_pair_with_sum/has_pair_with_sum.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List, TypeVar
from typing import List, Set, TypeVar

Number = TypeVar("Number", int, float)

Expand All @@ -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
27 changes: 14 additions & 13 deletions Sprint-1/Python/remove_duplicates/remove_duplicates.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading