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,24 +9,24 @@
* "product": 30 // 2 * 3 * 5
* }
*
* Time Complexity:
* Space Complexity:
* Optimal Time Complexity:
* Time Complexity:O(2n) originall have this as using 2 separate loops
* Space Complexity:O(1) no extra space used that rows with input
* Optimal Time Complexity:O(n) must at least visit each number once
*
* @param {Array<number>} numbers - Numbers to process
* @returns {Object} Object containing running total and product
*/

// here we are using 2 loops one for sum and other for product
// but we can do it only in one loop so code will be more simple and faster

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;
}

return {
sum: sum,
product: product,
Expand Down
23 changes: 17 additions & 6 deletions Sprint-1/JavaScript/findCommonItems/findCommonItems.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
/**
* Finds common items between two arrays.
*
* Time Complexity:
* Space Complexity:
* Optimal Time Complexity:
* Time Complexity:O(n+m) it build set and loop through arrays once
* Space Complexity: store second array in set
* Optimal Time Complexity:O(m+n)
*
* @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) => [
// ...new Set(firstArray.filter((item) => secondArray.includes(item))),
// ];
// Refactored to use a Set for faster lookups, making the code more efficient
export const findCommonItems = (firstArray, secondArray) => {
const secondArraySet = new Set(secondArray);
const resultSet = new Set();
for (const element of firstArray) {
if (secondArraySet.has(element)) {
resultSet.add(element);
}
}
return [...resultSet];
};
32 changes: 23 additions & 9 deletions Sprint-1/JavaScript/hasPairWithSum/hasPairWithSum.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
/**
* Find if there is a pair of numbers that sum to a given target value.
*
* Time Complexity:
* Space Complexity:
* Optimal Time Complexity:
* Time Complexity: o(n2) the function use 2 nested loop
* Space Complexity:o(1)no additional significant memory used
* Optimal Time Complexity: O(n) — in the refactored version using a Set for lookups
*
* @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;
// }
// }
// }
// return false;
// }

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 numbersNeeded = new Set(); // stores numbers we've already seen

for (const num of numbers) {
const requiredNumber = target - num;
if (numbersNeeded.has(requiredNumber)) {
return true; // found a pair!
}
numbersNeeded.add(num); // remember current number
}
return false;

return false; // no pair found
}
43 changes: 26 additions & 17 deletions Sprint-1/Python/remove_duplicates/remove_duplicates.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,32 @@
ItemType = TypeVar("ItemType")


def remove_duplicates(values: Sequence[ItemType]) -> List[ItemType]:
"""
Remove duplicate values from a sequence, preserving the order of the first occurrence of each value.
# 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:
"""
unique_items = []
# Time complexity:O(n²) Quadratic The outer loop runs n times, and for each value, the inner loop also runs up to n times.
# Space complexity:O(n) store n elements in worst possible case
# Optimal time complexity: O(n) can be improved useing set
# """
# 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)
# 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

return unique_items
def remove_duplicates(values: Sequence[ItemType]) -> List[ItemType]:
unique_element= set() # for unique element
order_element =[] # to order maintain
for value in values:
if value not in unique_element:
unique_element.add(value)
order_element.append(value)
return order_element
75 changes: 75 additions & 0 deletions Sprint-2/implement_lru_cache/lru_cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
class Node:
def __init__(self, key, value):
self.key = key
self.value = value
self.prev = None
self.next = None

class LruCache:
def __init__(self, limit: int):
if limit <= 0:
raise ValueError("Cache limit must be greater than zero")

self.limit = limit
self.cache = {}
self.head = None
self.tail = None
self.size = 0


#to remove a node frpm linkedlist
def _remove_node(self, node: Node):
if node.prev:
node.prev.next = node.next
else:
self.head = node.next

if node.next:
node.next.prev = node.prev
else:
self.tail = node.prev

node.prev = node.next = None


#Add a node to the head of the linked list
def _add_to_head(self, node: Node):
node.next = self.head
node.prev = None

if self.head:
self.head.prev = node
self.head = node

if not self.tail:
self.tail = node


def get(self, key):
if key not in self.cache:
return None
node = self.cache[key]
# Move node to head (most recently used)
self._remove_node(node)
self._add_to_head(node)
return node.value


def set(self, key, value):
if key in self.cache:
node = self.cache[key]
node.value = value
self._remove_node(node)
self._add_to_head(node)
else:
node = Node(key, value)
self.cache[key] = node
self._add_to_head(node)
self.size += 1

if self.size > self.limit:
# Evict LRU (tail node)
lru = self.tail
self._remove_node(lru)
del self.cache[lru.key]
self.size -= 1