Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add algorithms for 2Sum, 3Sum, Kadane's Algorithm, and linked list pr… #1716

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
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
43 changes: 43 additions & 0 deletions Data-Structures/Array/3sum.js
Original file line number Diff line number Diff line change
@@ -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 }
27 changes: 27 additions & 0 deletions Data-Structures/Array/KandanesAlgo.js
Original file line number Diff line number Diff line change
@@ -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 }
12 changes: 12 additions & 0 deletions Data-Structures/Array/test/3sum.test.js
Original file line number Diff line number Diff line change
@@ -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
});
12 changes: 12 additions & 0 deletions Data-Structures/Array/test/KadanesAlgo.test.js
Original file line number Diff line number Diff line change
@@ -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
});
32 changes: 32 additions & 0 deletions Data-Structures/Linked-List/FindIntersectionPoint.js
Original file line number Diff line number Diff line change
@@ -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
49 changes: 49 additions & 0 deletions Data-Structures/Linked-List/SlowFast.js
Original file line number Diff line number Diff line change
@@ -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<number>} 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
25 changes: 25 additions & 0 deletions Data-Structures/Linked-List/test/FindIntersectionpoint.test.js
Original file line number Diff line number Diff line change
@@ -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
});
32 changes: 32 additions & 0 deletions Data-Structures/Linked-List/test/slowfast.test.js
Original file line number Diff line number Diff line change
@@ -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
});
});

Loading