diff --git a/Data-Structures/Array/3sum.js b/Data-Structures/Array/3sum.js new file mode 100644 index 0000000000..37969b817a --- /dev/null +++ b/Data-Structures/Array/3sum.js @@ -0,0 +1,43 @@ +// threeSum.js + +/** + * Time Complexity: O(n^2) — The outer loop runs in O(n), and the inner two-pointer approach runs in O(n). +Space Complexity: O(1) — The output list is the only extra space used (not counting input). + * + * + * Finds all unique triplets in the array that sum up to zero. + * @param {number[]} nums - An array of numbers. + * @returns {number[][]} - A list of unique triplets. + */ +function threeSum(nums) { + const result = []; + nums.sort((a, b) => a - b); // Sort the array + + for (let i = 0; i < nums.length - 2; i++) { + // Skip duplicate values + if (i > 0 && nums[i] === nums[i - 1]) continue; + + let left = i + 1; + let right = nums.length - 1; + + while (left < right) { + const sum = nums[i] + nums[left] + nums[right]; + + if (sum === 0) { + result.push([nums[i], nums[left], nums[right]]); + while (left < right && nums[left] === nums[left + 1]) left++; // Skip duplicates + while (left < right && nums[right] === nums[right - 1]) right--; // Skip duplicates + left++; + right--; + } else if (sum < 0) { + left++; + } else { + right--; + } + } + } + + return result; // Return the list of triplets +} + +export { threeSum } \ No newline at end of file diff --git a/Data-Structures/Array/KandanesAlgo.js b/Data-Structures/Array/KandanesAlgo.js new file mode 100644 index 0000000000..6816a14c2b --- /dev/null +++ b/Data-Structures/Array/KandanesAlgo.js @@ -0,0 +1,27 @@ + +// kadanesAlgorithm.js + +/** + * + * + * Time Complexity: O(n) — The algorithm processes each element of the array once. +Space Complexity: O(1) — Only a constant amount of additional space is used. + + + * Finds the maximum sum of a contiguous subarray using Kadane's Algorithm. + * @param {number[]} nums - An array of numbers. + * @returns {number} - The maximum sum of the contiguous subarray. + */ +function kadane(nums) { + let maxSoFar = nums[0]; + let maxEndingHere = nums[0]; + + for (let i = 1; i < nums.length; i++) { + maxEndingHere = Math.max(nums[i], maxEndingHere + nums[i]); + maxSoFar = Math.max(maxSoFar, maxEndingHere); + } + + return maxSoFar; // Return the maximum sum +} + +export { kadane } \ No newline at end of file diff --git a/Data-Structures/Array/test/3sum.test.js b/Data-Structures/Array/test/3sum.test.js new file mode 100644 index 0000000000..13d868ef87 --- /dev/null +++ b/Data-Structures/Array/test/3sum.test.js @@ -0,0 +1,12 @@ +import { threeSum } from '../3sum.js'; // Adjust the path as necessary + +describe('Three Sum', () => { + it('should return all unique triplets that add up to zero', () => { + const nums = [-1, 0, 1, 2, -1, -4]; + const expected = [[-1, -1, 2], [-1, 0, 1]]; + const result = threeSum(nums); + expect(result).toEqual(expected); + }); + + // Add more test cases as needed +}); diff --git a/Data-Structures/Array/test/KadanesAlgo.test.js b/Data-Structures/Array/test/KadanesAlgo.test.js new file mode 100644 index 0000000000..c7fe4b11ff --- /dev/null +++ b/Data-Structures/Array/test/KadanesAlgo.test.js @@ -0,0 +1,12 @@ +import { kadane } from '../KandanesAlgo.js'; // Adjust the path as necessary + +describe('Kadane\'s Algorithm', () => { + it('should return the maximum sum of a contiguous subarray', () => { + const nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4]; + const expected = 6; // 4 + -1 + 2 + 1 + const result = kadane(nums); + expect(result).toBe(expected); + }); + + // Add more test cases as needed +}); diff --git a/Data-Structures/Linked-List/FindIntersectionPoint.js b/Data-Structures/Linked-List/FindIntersectionPoint.js new file mode 100644 index 0000000000..58d87ca0c0 --- /dev/null +++ b/Data-Structures/Linked-List/FindIntersectionPoint.js @@ -0,0 +1,32 @@ +// FindIntersectionPoint.js + +// Definition for singly-linked list node +class ListNode { + constructor(value) { + this.value = value; + this.next = null; + } +} + +/** + * Finds the intersection point of two linked lists. + * @param {ListNode} headA - The head of the first linked list. + * @param {ListNode} headB - The head of the second linked list. + * @returns {ListNode|null} The intersection node or null if no intersection. + */ +function findIntersection(headA, headB) { + if (!headA || !headB) return null; + + let a = headA; + let b = headB; + + // Traverse both lists + while (a !== b) { + a = a ? a.next : headB; // When reaching the end of list A, redirect to list B + b = b ? b.next : headA; // When reaching the end of list B, redirect to list A + } + + return a; // This will be either the intersection node or null +} + +export { ListNode, findIntersection }; // Ensure ListNode is exported diff --git a/Data-Structures/Linked-List/SlowFast.js b/Data-Structures/Linked-List/SlowFast.js new file mode 100644 index 0000000000..001de0579e --- /dev/null +++ b/Data-Structures/Linked-List/SlowFast.js @@ -0,0 +1,49 @@ +// SlowFast.js + +// Definition for singly-linked list node +class ListNode { + constructor(value) { + this.value = value; + this.next = null; + } +} + +/** + * Detects if a linked list has a cycle. + * @param {ListNode} head - The head of the linked list. + * @returns {boolean} - True if there's a cycle, false otherwise. + */ +function hasCycle(head) { + let slow = head; + let fast = head; + + while (fast && fast.next) { + slow = slow.next; // Move slow pointer one step + fast = fast.next.next; // Move fast pointer two steps + + if (slow === fast) { + return true; // Cycle detected + } + } + return false; // No cycle +} + +/** + * Creates a linked list from an array of values. + * @param {Array} values - The values to create the linked list from. + * @returns {ListNode|null} - The head of the created linked list. + */ +function createLinkedList(values) { + const dummyHead = new ListNode(0); + let current = dummyHead; + + for (const value of values) { + current.next = new ListNode(value); + current = current.next; + } + + return dummyHead.next; // Return the head of the created linked list +} + +// Exporting the ListNode class and functions for testing +export { ListNode, hasCycle, createLinkedList }; // Ensure ListNode is exported diff --git a/Data-Structures/Linked-List/test/FindIntersectionpoint.test.js b/Data-Structures/Linked-List/test/FindIntersectionpoint.test.js new file mode 100644 index 0000000000..5ee820f8f8 --- /dev/null +++ b/Data-Structures/Linked-List/test/FindIntersectionpoint.test.js @@ -0,0 +1,25 @@ +// FindIntersectionPoint.test.js + +import { ListNode, findIntersection } from '../FindIntersectionPoint.js'; // Ensure the path is correct +import { createLinkedList } from '../SlowFast.js'; // Ensure the path is correct + +describe('Find Intersection Point', () => { + it('should find the intersection point in two linked lists', () => { + // Create linked list 1: 1 -> 2 -> 3 -> 6 -> 7 + const list1 = createLinkedList([1, 2, 3]); + const intersection = new ListNode(6); // ListNode should be correctly imported + intersection.next = new ListNode(7); + list1.next.next.next = intersection; // Connect 3 -> 6 + + // Create linked list 2: 4 -> 5 -> 6 -> 7 + const list2 = createLinkedList([4, 5]); + list2.next.next = intersection; // Connect 5 -> 6 + + const expected = intersection; // We expect the intersection node + + const result = findIntersection(list1, list2); + expect(result).toBe(expected); // Check if the result matches the expected output + }); + + // Additional test cases can be added here +}); diff --git a/Data-Structures/Linked-List/test/slowfast.test.js b/Data-Structures/Linked-List/test/slowfast.test.js new file mode 100644 index 0000000000..82fa69b78a --- /dev/null +++ b/Data-Structures/Linked-List/test/slowfast.test.js @@ -0,0 +1,32 @@ +// slowfast.test.js + +import { ListNode, hasCycle, createLinkedList } from '../SlowFast.js'; // Adjust the path as necessary + +describe('Slow and Fast Pointer', () => { + it('should detect if a linked list has a cycle', () => { + // Create a linked list: 1 -> 2 -> 3 -> 4 -> 5 -> (cycle to 3) + const node1 = new ListNode(1); + const node2 = new ListNode(2); + const node3 = new ListNode(3); + const node4 = new ListNode(4); + const node5 = new ListNode(5); + + node1.next = node2; + node2.next = node3; + node3.next = node4; + node4.next = node5; + node5.next = node3; // Create a cycle here + + const result = hasCycle(node1); + expect(result).toBe(true); // Expecting a cycle + }); + + it('should not detect a cycle in a linear linked list', () => { + // Create a linked list: 1 -> 2 -> 3 + const head = createLinkedList([1, 2, 3]); + + const result = hasCycle(head); + expect(result).toBe(false); // Expecting no cycle + }); +}); +