Skip to content

Commit 786f8a9

Browse files
committed
refactor(js): calculateSumAndProduct single-pass optimization
1 parent eebcb62 commit 786f8a9

File tree

8 files changed

+336
-74
lines changed

8 files changed

+336
-74
lines changed

Sprint-1/JavaScript/calculateSumAndProduct/calculateSumAndProduct.js

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,53 @@
99
* "product": 30 // 2 * 3 * 5
1010
* }
1111
*
12-
* Time Complexity:
13-
* Space Complexity:
14-
* Optimal Time Complexity:
12+
* Time Complexity: O(n) - Single pass through the array
13+
* Space Complexity: O(1) - Only using constant extra space
14+
* Optimal Time Complexity: O(n) - Cannot do better than linear time
1515
*
1616
* @param {Array<number>} numbers - Numbers to process
1717
* @returns {Object} Object containing running total and product
1818
*/
1919
export function calculateSumAndProduct(numbers) {
20-
let sum = 0;
21-
for (const num of numbers) {
22-
sum += num;
23-
}
20+
// OPTIMIZED IMPLEMENTATION: Single pass algorithm
21+
// Previous implementation used two separate loops (2n operations)
22+
// This version combines both calculations in one loop (n operations)
23+
24+
let sum = 0; // O(1) space
25+
let product = 1; // O(1) space
2426

25-
let product = 1;
27+
// Single pass through array: O(n) time complexity
2628
for (const num of numbers) {
27-
product *= num;
29+
sum += num; // O(1) operation per element
30+
product *= num; // O(1) operation per element
2831
}
2932

30-
return {
31-
sum: sum,
32-
product: product,
33-
};
33+
// Return optimized object syntax: O(1) space
34+
return { sum, product };
3435
}
36+
37+
/*
38+
* ORIGINAL IMPLEMENTATION (for comparison):
39+
*
40+
* export function calculateSumAndProduct(numbers) {
41+
* let sum = 0;
42+
* for (const num of numbers) { // First pass: O(n)
43+
* sum += num;
44+
* }
45+
*
46+
* let product = 1;
47+
* for (const num of numbers) { // Second pass: O(n)
48+
* product *= num;
49+
* }
50+
*
51+
* return { // Total: O(2n) = O(n) time
52+
* sum: sum, // O(1) space
53+
* product: product,
54+
* };
55+
* }
56+
*
57+
* IMPROVEMENTS MADE:
58+
* 1. Reduced from 2n to n operations (50% fewer iterations)
59+
* 2. Better cache locality (single pass through memory)
60+
* 3. Same O(n) time complexity but with better constant factors
61+
*/
Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,46 @@
11
/**
22
* Finds common items between two arrays.
33
*
4-
* Time Complexity:
5-
* Space Complexity:
6-
* Optimal Time Complexity:
4+
* Time Complexity: O(n + m) - Single pass through both arrays
5+
* Space Complexity: O(min(n, m)) - Set size bounded by smaller array
6+
* Optimal Time Complexity: O(n + m) - Cannot do better than linear time
77
*
88
* @param {Array} firstArray - First array to compare
99
* @param {Array} secondArray - Second array to compare
1010
* @returns {Array} Array containing unique common items
1111
*/
12-
export const findCommonItems = (firstArray, secondArray) => [
13-
...new Set(firstArray.filter((item) => secondArray.includes(item))),
14-
];
12+
export const findCommonItems = (firstArray, secondArray) => {
13+
// OPTIMIZED IMPLEMENTATION: O(n + m) time complexity
14+
// Previous implementation: O(n × m) due to nested includes() calls
15+
16+
// Convert second array to Set for O(1) lookup: O(m) time, O(m) space
17+
const secondSet = new Set(secondArray);
18+
19+
// Find common items using Set lookup: O(n) time
20+
const commonItems = firstArray.filter((item) => secondSet.has(item));
21+
22+
// Remove duplicates: O(n) time in worst case
23+
return [...new Set(commonItems)];
24+
};
25+
26+
/*
27+
* ORIGINAL IMPLEMENTATION (for comparison):
28+
*
29+
* export const findCommonItems = (firstArray, secondArray) => [
30+
* ...new Set(firstArray.filter((item) => secondArray.includes(item))),
31+
* ];
32+
*
33+
* COMPLEXITY ANALYSIS OF ORIGINAL:
34+
* - firstArray.filter(): O(n) iterations
35+
* - secondArray.includes(): O(m) for each iteration
36+
* - Total: O(n × m) time complexity
37+
* - Space: O(n) for Set creation
38+
*
39+
40+
* IMPROVEMENTS MADE:
41+
* 1. Reduced from O(n × m) to O(n + m) time complexity
42+
* 2. Set lookup is O(1) vs Array.includes() O(m)
43+
* 3. Significant performance gain for large arrays
44+
* 4. Same functionality with better algorithmic efficiency
45+
46+
*/
Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,59 @@
11
/**
22
* Find if there is a pair of numbers that sum to a given target value.
33
*
4-
* Time Complexity:
5-
* Space Complexity:
6-
* Optimal Time Complexity:
4+
* Time Complexity: O(n) - Single pass through the array
5+
* Space Complexity: O(n) - Set to store seen numbers
6+
* Optimal Time Complexity: O(n) - Cannot do better than linear time
77
*
88
* @param {Array<number>} numbers - Array of numbers to search through
99
* @param {number} target - Target sum to find
1010
* @returns {boolean} True if pair exists, false otherwise
1111
*/
1212
export function hasPairWithSum(numbers, target) {
13-
for (let i = 0; i < numbers.length; i++) {
14-
for (let j = i + 1; j < numbers.length; j++) {
15-
if (numbers[i] + numbers[j] === target) {
16-
return true;
17-
}
13+
// OPTIMIZED IMPLEMENTATION: O(n) time complexity
14+
// Previous implementation: O(n²) due to nested loops
15+
16+
const seen = new Set(); // O(n)
17+
18+
// O(n) time complexity
19+
for (const num of numbers) {
20+
const complement = target - num;
21+
// O(1) lookup
22+
if (seen.has(complement)) {
23+
return true;
1824
}
25+
26+
// O(1) operation
27+
seen.add(num);
1928
}
2029
return false;
2130
}
31+
console.log(hasPairWithSum([3, 2, 3, 4, 5], 9));
32+
/*
33+
* ORIGINAL IMPLEMENTATION (for comparison):
34+
*
35+
* export function hasPairWithSum(numbers, target) {
36+
* for (let i = 0; i < numbers.length; i++) { // O(n) iterations
37+
* for (let j = i + 1; j < numbers.length; j++) { // O(n) iterations each
38+
* if (numbers[i] + numbers[j] === target) { // O(1) comparison
39+
* return true;
40+
* }
41+
* }
42+
* }
43+
* return false;
44+
* }
45+
*
46+
* COMPLEXITY ANALYSIS OF ORIGINAL:
47+
* - Outer loop: O(n) iterations
48+
* - Inner loop: O(n) iterations for each outer iteration
49+
* - Total: O(n²) time complexity
50+
* - Space: O(1) - only using loop variables
51+
*
52+
* PERFORMANCE ISSUES:
53+
* - Quadratic time complexity O(n²)
54+
*
55+
* IMPROVEMENTS MADE:
56+
* 1. Reduced from O(n²) to O(n) time complexity
57+
* 2. Single pass through array instead of nested loops
58+
* 3. Set lookup is O(1) vs nested iteration O(n)
59+
*/
Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,65 @@
11
/**
22
* Remove duplicate values from a sequence, preserving the order of the first occurrence of each value.
33
*
4-
* Time Complexity:
5-
* Space Complexity:
6-
* Optimal Time Complexity:
4+
* Time Complexity: O(n) - Single pass through the array
5+
* Space Complexity: O(n) - Set to track seen elements
6+
* Optimal Time Complexity: O(n) - Cannot do better than linear time
77
*
88
* @param {Array} inputSequence - Sequence to remove duplicates from
99
* @returns {Array} New sequence with duplicates removed
1010
*/
1111
export function removeDuplicates(inputSequence) {
12-
const uniqueItems = [];
12+
// OPTIMIZED IMPLEMENTATION: O(n) time complexity
13+
// Previous implementation: O(n²) due to nested loops checking each element
1314

14-
for (
15-
let currentIndex = 0;
16-
currentIndex < inputSequence.length;
17-
currentIndex++
18-
) {
19-
let isDuplicate = false;
20-
for (
21-
let compareIndex = 0;
22-
compareIndex < uniqueItems.length;
23-
compareIndex++
24-
) {
25-
if (inputSequence[currentIndex] === uniqueItems[compareIndex]) {
26-
isDuplicate = true;
27-
break;
28-
}
29-
}
30-
if (!isDuplicate) {
31-
uniqueItems.push(inputSequence[currentIndex]);
15+
const seen = new Set(); // O(n)
16+
const uniqueItems = []; // O(n)
17+
18+
// O(n) time complexity
19+
for (const item of inputSequence) {
20+
// O(1) lookup
21+
if (!seen.has(item)) {
22+
seen.add(item); // O(1) operation
23+
uniqueItems.push(item); // O(1) operation
3224
}
3325
}
3426

3527
return uniqueItems;
3628
}
29+
console.log(removeDuplicates([1, 2, 3, 4, 5, 1, 2, 3, 4, 5]));
30+
/*
31+
* ORIGINAL IMPLEMENTATION (for comparison):
32+
*
33+
* export function removeDuplicates(inputSequence) {
34+
* const uniqueItems = [];
35+
*
36+
* for (let currentIndex = 0; currentIndex < inputSequence.length; currentIndex++) {
37+
* let isDuplicate = false;
38+
* for (let compareIndex = 0; compareIndex < uniqueItems.length; compareIndex++) {
39+
* if (inputSequence[currentIndex] === uniqueItems[compareIndex]) {
40+
* isDuplicate = true;
41+
* break;
42+
* }
43+
* }
44+
* if (!isDuplicate) {
45+
* uniqueItems.push(inputSequence[currentIndex]);
46+
* }
47+
* }
48+
*
49+
* return uniqueItems;
50+
* }
51+
*
52+
* COMPLEXITY ANALYSIS OF ORIGINAL:
53+
* - Outer loop: O(n) iterations through input array
54+
* - Inner loop: O(k) iterations through uniqueItems array (k grows with each unique element)
55+
* - Worst case: O(n²) when all elements are unique
56+
* - Space: O(n) for uniqueItems array
57+
*
58+
* PERFORMANCE ISSUES:
59+
* - Quadratic time complexity O(n²) in worst case
60+
*
61+
* IMPROVEMENTS MADE:
62+
* 1. Reduced from O(n²) to O(n) time complexity
63+
* 2. Set lookup is O(1) vs linear search O(k)
64+
* 3. Single pass through input array
65+
*/

Sprint-1/Python/calculate_sum_and_product/calculate_sum_and_product.py

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,50 @@ def calculate_sum_and_product(input_numbers: List[int]) -> Dict[str, int]:
1212
"sum": 10, // 2 + 3 + 5
1313
"product": 30 // 2 * 3 * 5
1414
}
15-
Time Complexity:
16-
Space Complexity:
17-
Optimal time complexity:
15+
16+
Time Complexity: O(n) - Single pass through the list
17+
Space Complexity: O(1) - Only using constant extra space
18+
Optimal Time Complexity: O(n) - Cannot do better than linear time
1819
"""
20+
# OPTIMIZED IMPLEMENTATION: O(n) time complexity
21+
# Previous implementation: O(2n) due to two separate loops
22+
23+
sum_total = 0 # O(1) space
24+
product = 1 # O(1) space
25+
26+
# O(n) time complexity
27+
for current_number in input_numbers:
28+
sum_total += current_number # O(1)
29+
product *= current_number # O(1)
30+
31+
return {"sum": sum_total, "product": product}
32+
33+
34+
# ORIGINAL IMPLEMENTATION (for comparison):
35+
"""
36+
def calculate_sum_and_product(input_numbers: List[int]) -> Dict[str, int]:
1937
# Edge case: empty list
2038
if not input_numbers:
2139
return {"sum": 0, "product": 1}
2240
2341
sum = 0
24-
for current_number in input_numbers:
42+
for current_number in input_numbers: # First pass: O(n)
2543
sum += current_number
2644
2745
product = 1
28-
for current_number in input_numbers:
46+
for current_number in input_numbers: # Second pass: O(n)
2947
product *= current_number
3048
31-
return {"sum": sum, "product": product}
49+
return {"sum": sum, "product": product} # Total: O(2n) = O(n) time
50+
51+
COMPLEXITY ANALYSIS OF ORIGINAL:
52+
- First loop: O(n) iterations to calculate sum
53+
- Second loop: O(n) iterations to calculate product
54+
- Total: O(2n) = O(n) time complexity
55+
- Space: O(1) - only using loop variables
56+
57+
IMPROVEMENTS MADE:
58+
1. Reduced from 2n to n operations (50% fewer iterations)
59+
2. Single pass through list instead of two separate loops
60+
3. Same O(n) time complexity but with better constant factors
61+
"""

Sprint-1/Python/find_common_items/find_common_items.py

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,49 @@ def find_common_items(
99
"""
1010
Find common items between two arrays.
1111
12-
Time Complexity:
13-
Space Complexity:
14-
Optimal time complexity:
12+
Time Complexity: O(n + m) - Single pass through both sequences
13+
Space Complexity: O(min(n, m)) - Set size bounded by smaller sequence
14+
Optimal Time Complexity: O(n + m) - Cannot do better than linear time
1515
"""
16+
# OPTIMIZED IMPLEMENTATION: O(n + m) time complexity
17+
# Previous implementation: O(n × m) due to nested loops with linear search
18+
19+
# Convert second sequence to set for O(1) lookup: O(m) time, O(m) space
20+
second_set = set(second_sequence)
21+
22+
# Find common items using set lookup: O(n) time
23+
common_items = []
24+
for item in first_sequence:
25+
if item in second_set and item not in common_items:
26+
common_items.append(item)
27+
28+
return common_items
29+
30+
31+
# ORIGINAL IMPLEMENTATION (for comparison):
32+
"""
33+
def find_common_items(
34+
first_sequence: Sequence[ItemType], second_sequence: Sequence[ItemType]
35+
) -> List[ItemType]:
1636
common_items: List[ItemType] = []
17-
for i in first_sequence:
18-
for j in second_sequence:
19-
if i == j and i not in common_items:
37+
for i in first_sequence: # O(n) iterations
38+
for j in second_sequence: # O(m) iterations each
39+
if i == j and i not in common_items: # O(k) linear search
2040
common_items.append(i)
2141
return common_items
42+
43+
COMPLEXITY ANALYSIS OF ORIGINAL:
44+
- Outer loop: O(n) iterations through first_sequence
45+
- Inner loop: O(m) iterations through second_sequence
46+
- Linear search: O(k) for 'i not in common_items' check
47+
- Total: O(n × m × k) time complexity in worst case
48+
- Space: O(n) for common_items list
49+
50+
PERFORMANCE ISSUES:
51+
- Quadratic time complexity O(n × m) from nested loops
52+
53+
IMPROVEMENTS MADE:
54+
1. Reduced from O(n × m × k) to O(n + m) time complexity
55+
2. Set lookup is O(1) vs nested iteration O(m)
56+
3. Single pass through first_sequence
57+
"""

0 commit comments

Comments
 (0)