- Notifications
You must be signed in to change notification settings - Fork5
📚 A list of popular JavaScript algorithms that you'll encounter in the real world. 🧠
License
AllThingsSmitty/javascript-algorithms
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
This repository contains a curated list of JavaScript algorithms, organized by category. These range from simple string manipulation to advanced searching and sorting techniques — perfect for interviews and foundational learning.
Note
Popularity is based on common interview topics, educational materials, and developer community usage.
- Prime Number Check
- Fibonacci Sequence (Recursive)
- Factorial of a Number
- Find the GCD (Greatest Common Divisor)
/** * Reverses a string *@param {string} str - The string to reverse *@returns {string} The reversed string */functionreverseString(str){if(typeofstr!=="string")thrownewTypeError("Input must be a string");return[...str].reverse().join("");}console.log(reverseString("hello"));// Output: "olleh"
Explanation: Reverses the characters in a string using the spread operator (modern alternative to split) and reverse. Includes type validation.
/** * Checks if a string is a palindrome (case-insensitive, ignores spaces) *@param {string} str - The string to check *@returns {boolean} True if palindrome, false otherwise */functionisPalindrome(str){if(typeofstr!=="string")thrownewTypeError("Input must be a string");constcleaned=str.toLowerCase().replace(/\s+/g,"");returncleaned===[...cleaned].reverse().join("");}console.log(isPalindrome("racecar"));// Output: trueconsole.log(isPalindrome("A man a plan a canal Panama"));// Output: true
Explanation: Determines if a string reads the same backward as forward. Now handles case-insensitivity and ignores spaces for real-world usage.
/** * Counts the frequency of each character in a string *@param {string} str - The string to analyze *@returns {Object} An object with characters as keys and frequencies as values */functioncharFrequency(str){if(typeofstr!=="string")thrownewTypeError("Input must be a string");return[...str].reduce((freq,char)=>{freq[char]=(freq[char]??0)+1;returnfreq;},{});}console.log(charFrequency("hello"));// Output: { h: 1, e: 1, l: 2, o: 1 }
Explanation: Counts how often each character appears in a string using modernreduce() and nullish coalescing (??). More functional approach.
/** * Determines if two strings are anagrams (ignores case and spaces) *@param {string} str1 - First string *@param {string} str2 - Second string *@returns {boolean} True if anagrams, false otherwise */functionisAnagram(str1,str2){if(typeofstr1!=="string"||typeofstr2!=="string"){thrownewTypeError("Both inputs must be strings");}constnormalize=(str)=>[...str.toLowerCase().replace(/\s+/g,"")].sort().join("");returnnormalize(str1)===normalize(str2);}console.log(isAnagram("listen","silent"));// Output: trueconsole.log(isAnagram("The Eyes","They See"));// Output: true
Explanation: Determines if two strings are anagrams by normalizing case/spaces and comparing sorted characters. Handles real-world edge cases.
/** * Checks if a number is prime *@param {number} num - The number to check *@returns {boolean} True if prime, false otherwise */functionisPrime(num){if(!Number.isInteger(num))thrownewTypeError("Input must be an integer");if(num<=1)returnfalse;if(num<=3)returntrue;if(num%2===0||num%3===0)returnfalse;for(leti=5;i*i<=num;i+=6){if(num%i===0||num%(i+2)===0)returnfalse;}returntrue;}console.log(isPrime(7));// Output: true
Explanation: Checks if a number is prime using an optimized approach with integer validation. Eliminates multiples of 2 and 3 for efficiency.
/** * Generates the nth Fibonacci number using memoization *@param {number} n - The position in Fibonacci sequence *@param {Map} memo - Cache for memoization *@returns {number} The nth Fibonacci number */functionfibonacci(n,memo=newMap()){if(!Number.isInteger(n)||n<0){thrownewTypeError("Input must be a non-negative integer");}if(n<=1)returnn;if(memo.has(n))returnmemo.get(n);constresult=fibonacci(n-1,memo)+fibonacci(n-2,memo);memo.set(n,result);returnresult;}console.log(fibonacci(6));// Output: 8console.log(fibonacci(50));// Output: 12586269025 (efficient with memoization)
Explanation: Generates the nth Fibonacci number recursively with memoization for efficiency. Solves the exponential time complexity problem of naive recursion. Time complexity:O(n) instead ofO(2^n).
/** * Calculates the factorial of a number *@param {number} n - The number to calculate factorial for *@returns {number} The factorial of n */functionfactorial(n){if(!Number.isInteger(n))thrownewTypeError("Input must be an integer");if(n<0)thrownewRangeError("Factorial is not defined for negative numbers");if(n===0||n===1)return1;returnn*factorial(n-1);}console.log(factorial(5));// Output: 120
Explanation: Calculates the factorial of a number recursively with comprehensive input validation using modern type-checking.
/** * Finds the greatest common divisor using Euclidean algorithm *@param {number} a - First number *@param {number} b - Second number *@returns {number} The GCD of a and b */functiongcd(a,b){if(!Number.isInteger(a)||!Number.isInteger(b)){thrownewTypeError("Both inputs must be integers");}a=Math.abs(a);b=Math.abs(b);returnb===0 ?a :gcd(b,a%b);}console.log(gcd(48,18));// Output: 6console.log(gcd(-48,18));// Output: 6
Explanation: Uses the Euclidean algorithm with support for negative numbers and type validation.
/** * Finds two indices in array whose values sum to target *@param {number[]} nums - Array of numbers *@param {number} target - Target sum *@returns {number[]} Array of two indices, or empty array if not found */functiontwoSum(nums,target){if(!Array.isArray(nums)||typeoftarget!=="number"){thrownewTypeError("Input must be an array and a number");}constmap=newMap();for(leti=0;i<nums.length;i++){constcomplement=target-nums[i];if(map.has(complement))return[map.get(complement),i];map.set(nums[i],i);}return[];}console.log(twoSum([2,7,11,15],9));// Output: [0, 1]
Explanation: Finds two indices whose values sum to target using a Map (hash map) for O(n) time complexity. Includes input validation.
/** * Searches for target in a sorted array using binary search *@param {number[]} arr - Sorted array to search in *@param {number} target - Value to search for *@returns {number} Index of target, or -1 if not found */functionbinarySearch(arr,target){if(!Array.isArray(arr)||typeoftarget!=="number"){thrownewTypeError("Input must be an array and a number");}letleft=0,right=arr.length-1;while(left<=right){constmid=left+Math.floor((right-left)/2);if(arr[mid]===target)returnmid;if(arr[mid]<target)left=mid+1;elseright=mid-1;}return-1;}console.log(binarySearch([1,2,3,4,5],4));// Output: 3
Explanation: Searches for target in sorted array using divide-and-conquer. Usesleft + Math.floor((right - left) / 2) to avoid overflow issues.
/** * Sorts an array using bubble sort algorithm *@param {number[]} arr - Array to sort *@returns {number[]} Sorted array */functionbubbleSort(arr){if(!Array.isArray(arr))thrownewTypeError("Input must be an array");constsorted=[...arr];// Create copy to avoid mutating originalfor(leti=0;i<sorted.length;i++){for(letj=0;j<sorted.length-i-1;j++){if(sorted[j]>sorted[j+1]){[sorted[j],sorted[j+1]]=[sorted[j+1],sorted[j]];}}}returnsorted;}console.log(bubbleSort([5,3,8,4,2]));// Output: [2, 3, 4, 5, 8]
Explanation: Sorts an array by repeatedly swapping adjacent elements. Modern version uses array spread to avoid mutating the original array.
/** * Sorts an array using quick sort algorithm *@param {number[]} arr - Array to sort *@returns {number[]} Sorted array */functionquickSort(arr){if(!Array.isArray(arr))thrownewTypeError("Input must be an array");if(arr.length<=1)returnarr;constpivot=arr[Math.floor(arr.length/2)];constleft=arr.filter((x)=>x<pivot);constmiddle=arr.filter((x)=>x===pivot);constright=arr.filter((x)=>x>pivot);return[...quickSort(left), ...middle, ...quickSort(right)];}console.log(quickSort([3,6,8,10,1,2,1]));// Output: [1, 1, 2, 3, 6, 8, 10]
Explanation: A divide-and-conquer sorting algorithm withO(n log n) average-case complexity. Uses middle pivot to handle duplicates better, and maintains immutability.
/** * Merges two sorted arrays into one sorted array *@param {number[]} arr1 - First sorted array *@param {number[]} arr2 - Second sorted array *@returns {number[]} Merged sorted array */functionmergeSortedArrays(arr1,arr2){if(!Array.isArray(arr1)||!Array.isArray(arr2)){thrownewTypeError("Both inputs must be arrays");}constmerged=[];leti=0,j=0;while(i<arr1.length&&j<arr2.length){if(arr1[i]<arr2[j]){merged.push(arr1[i++]);}else{merged.push(arr2[j++]);}}return[...merged, ...arr1.slice(i), ...arr2.slice(j)];}console.log(mergeSortedArrays([1,3,5],[2,4,6]));// Output: [1, 2, 3, 4, 5, 6]
Explanation: Merges two sorted arrays efficiently in O(n + m) time. Modern syntax with spread operator.
/** * Finds the maximum value in an array *@param {number[]} arr - Array to search *@returns {number} The maximum value */functionfindMax(arr){if(!Array.isArray(arr)||arr.length===0){thrownewTypeError("Input must be a non-empty array");}returnMath.max(...arr);}// Alternative for very large arrays (avoids stack overflow):functionfindMaxAlternative(arr){if(!Array.isArray(arr)||arr.length===0){thrownewTypeError("Input must be a non-empty array");}returnarr.reduce((max,current)=>(current>max ?current :max));}console.log(findMax([1,2,3,4,5]));// Output: 5
Explanation: Finds the largest number. Now includes validation and an alternative usingreduce() for very large arrays to avoid stack overflow from spread operator.
/** * Creates a debounced function that delays execution *@param {Function} fn - Function to debounce *@param {number} delay - Delay in milliseconds *@returns {Function} Debounced function */functiondebounce(fn,delay){if(typeoffn!=="function"||typeofdelay!=="number"){thrownewTypeError("First argument must be a function, second a number");}lettimerId;returnfunction(...args){clearTimeout(timerId);timerId=setTimeout(()=>fn.apply(this,args),delay);};}// Modern async version with promisesasyncfunctiondebounceAsync(fn,delay){if(typeoffn!=="function"||typeofdelay!=="number"){thrownewTypeError("First argument must be a function, second a number");}lettimerId;returnfunction(...args){returnnewPromise((resolve)=>{clearTimeout(timerId);timerId=setTimeout(()=>{resolve(fn.apply(this,args));},delay);});};}constlog=debounce(()=>console.log("Debounced!"),300);log();log();log();// Logs once after 300ms of inactivity
Explanation: Limits rate at which a function fires. Classic callback version and modern async/Promise version for modern use cases. Includes parameter validation.
About
📚 A list of popular JavaScript algorithms that you'll encounter in the real world. 🧠
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Releases
Packages0
Contributors2
Uh oh!
There was an error while loading.Please reload this page.