Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,26 @@
* "product": 30 // 2 * 3 * 5
* }
*
* Time Complexity:
* Space Complexity:
* Optimal Time Complexity:
* Time Complexity: O(n) - one loop through the list (the original used two
* loops, 2n steps, which is also O(n)).
*
* Space Complexity: O(1) - only two variables (sum, product), regardless of
* input size
*
* Optimal Time Complexity: O(n) - every number must be read at least once, so * we can't do better than linear time
*
* Refactor: the complexity can't be reduced, but merging the two loops into
* one makes the code cleaner and does half the steps.
*
* @param {Array<number>} 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;
}

Expand Down
53 changes: 40 additions & 13 deletions Sprint-1/JavaScript/findCommonItems/findCommonItems.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,41 @@
/**
* Finds common items between two arrays.
*
* Time Complexity:
* Space Complexity:
* Optimal Time Complexity:
*
* @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))),
];
* Finds common items between two arrays.

* Inefficiency: the original used secondArray.includes() inside firstArray
filter(), which is a loop inside a loop.

* Originally:
* Time Complexity: O(n × m) - filter runs n times and each includes call can
* scan up to m items (O(n²) if the arrays are the same size).

* Space Complexity: O(n) - the filtered array and the Set hold up to n items.

* Optimal Time Complexity: O(n + m) - every item in both arrays must be read at
least once.

* After refactor (the complexity was reduced from quadratic to linear time by
using a Set for O(1) average lookups instead of includes):

* Time Complexity: O(n + m) - building secondSet is O(m); the loop over
firstArray is O(n) with O(1) average has() checks.

* Space Complexity: O(n + m) - secondSet holds up to m items; commonElements
and the final Set hold up to n items.

* Optimal Time Complexity: O(n + m) - every item in both arrays must be read at least once, so we can't do better than linear
*
* @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) => {
const secondSet = new Set(secondArray);
let commonElements = [];

for (let ele of firstArray) {
if (secondSet.has(ele)) {
commonElements.push(ele);
}
}
return [...new Set(commonElements)];
};
38 changes: 30 additions & 8 deletions Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,43 @@
/**
* Find if there is a pair of numbers that sum to a given target value.
*
* Time Complexity:
* Space Complexity:
* Optimal Time Complexity:
* Inefficiency: the original used a loop inside a loop to check every
* possible pair of numbers.
*
* Originally:
* Time Complexity: O(n²) - for each number, the inner loop scans the
* remaining numbers, so about n * (n - 1) / 2 pair checks.
*
* Space Complexity: O(1) - only the loop counters i and j are used.
*
* Optimal Time Complexity: O(n) - every number must be read at least once,
* and a Set gives O(1) average lookups, so one pass is enough
*
* After Refactor (reduced from quadratic to linear time by remembering the
* numbers already seen in a Set instead of re-scanning the list):
*
* Time Complexity: O(n) - one loop, with O(1) average has() and add().
*
* Space Complexity: O(n) - visitedNumbers can hold up to n numbers.
*
* Optimal Time Complexity: O(n) - every number must be read at least once,
* so we can't do better than linear.
*
* @param {Array<number>} 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) {
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 visitedNumbers = new Set();

for (let num of numbers) {
const partnerNum = target - num;

if (visitedNumbers.has(partnerNum)) {
return true;
}
visitedNumbers.add(num);
}

return false;
}
59 changes: 26 additions & 33 deletions Sprint-1/JavaScript/removeDuplicates/removeDuplicates.mjs
Original file line number Diff line number Diff line change
@@ -1,36 +1,29 @@
/**
* Remove duplicate values from a sequence, preserving the order of the first occurrence of each value.
*
* Time Complexity:
* Space Complexity:
* Optimal Time Complexity:
*
* @param {Array} inputSequence - Sequence to remove duplicates from
* @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]);
}
}
* Remove duplicate values from a sequence, preserving the order of the first
* occurrence of each value.
*
* Originally (nested loops):
* Time Complexity: O(n²) - the outer loop runs n times and the inner loop
* scans uniqueItems, which can grow up to n items (about n(n - 1) / 2
* checks in the worst case, when all items are unique).
*
* Space Complexity: O(n) - uniqueItems can hold up to n items.
*
* Optimal Time Complexity: O(n) - every item must be read at least once, and
* a Set gives O(1) average lookups.

return uniqueItems;
* After refactor ([...new Set(inputSequence)]):
* Time Complexity: O(n) - building the Set visits each item once with O(1)
* average inserts; spreading it into an array is also O(n).
*
* Space Complexity: O(n) - the Set and the result array each hold up to n items.
*
* Optimal Time Complexity: O(n) - every item must be read at least once, so we
* can't do better than linear.
*
* @param {Array} inputSequence - Sequence to remove duplicates from
* @returns {Array} New sequence with duplicates removed
*/
export function removeDuplicates(inputSequence) {
return [...new Set(inputSequence)];
}
Loading