├── Javascript ├── 001_twoSum.js ├── 002_addTwoNumbers.js ├── 003_longestSubstringWithoutRepeatingCharacters.js ├── 005_longestPalindromicSubstring.js ├── 007_reverseInteger.js ├── 008_stringToInteger.js ├── 009_palindromeNumber.js ├── 011_ContainerWithMostWater.js ├── 012_integerToRoman.js ├── 013_romanToInteger.js ├── 014_longestCommonPrefix.js ├── 015_3Sum.js ├── 016_ThreeSumClosest.js ├── 017_letterCombinationsOfAPhoneNumber.js ├── 019_removeNthNodeFromEnd.js ├── 020_validParentheses.js ├── 021_mergeTwoSortedLists.js ├── 022_generateParentheses.js ├── 023_mergeKSortedLists.js ├── 025_reverseNodesInKGroup.js ├── 026_removeDuplicatedFromSortedArray.js ├── 027_removeElement.js ├── 028_implementstrStr.js ├── 033_searchInRotatedSortedArray.js ├── 034_searchForARange.js ├── 035_searchInsertPosition.js ├── 036_validSudoku.js ├── 037_sudokuSolver.js ├── 039_combinationSum.js ├── 042_trappingRainWater.js ├── 045_jumpGameII.js ├── 046_permutations.js ├── 047_permutationsII.js ├── 048_rotateImage.js ├── 049_groupAnagrams.js ├── 050_pow(x,n).js ├── 053_maximumSubarray.js ├── 054_spiralMatrix.js ├── 055_jumpGame.js ├── 056_mergeIntervals.js ├── 057_insertInterval.js ├── 058_lengthOfLastWord.js ├── 059_spiralMatrixII.js ├── 060_permutationSequence.js ├── 061_rotateList.js ├── 062_uniquePaths.js ├── 063_uniquePathsII.js ├── 064_minimumPathSum.js ├── 065_validNumber.js ├── 066_plusOne.js ├── 067_addBinary.js ├── 069_Sqrt(x).js ├── 070_climbingStairs.js ├── 072_editDistance.js ├── 073_setMatrixZeroes.js ├── 078_subsets.js ├── 079_wordSearch.js ├── 083_removeDuplicatesFromSortedList.js ├── 088_mergeSortedArray.js ├── 091_decodeWays.js ├── 094_binaryTreeInorderTraversal.js ├── 097_interleavingString.js ├── 098_validateBinarySearchTree.js ├── 100_sameTree.js ├── 101_symmetricTree.js ├── 102_binaryTreeLevelOrderTraversal.js ├── 103_binaryTreeZigzagLevelOrderTraversal.js ├── 104_maximumDepthOfBT.js ├── 107_binaryTreeLevelOrderTraversalII.js ├── 110_balancedBinaryTree.js ├── 116_populatingNextRightPointerInEachNode.js ├── 117_populatingNextRightPointersInEachNodeII.js ├── 120_triangle.js ├── 121_bestTimeToBuyAndSellStock.js ├── 122_bestTimeToBuyAndSellStockII.js ├── 125_validPalindrome.js ├── 127_wordLadder.js ├── 128_longestConsecutiveSequence.js ├── 129_sumRootToLeafNumbers.js ├── 133_cloneGraph.js ├── 136_singleNumber.js ├── 137_singleNumberII.js ├── 138_copyListWithRandomPointer.js ├── 139_wordBreak.js ├── 140_wordBreakII.js ├── 141_linkedListCycle.js ├── 142_linkedListCycleII.js ├── 146_lruCache.js ├── 147_insertionSortList.js ├── 148_sortList.js ├── 149_maxPointsOnALine.js ├── 150_evaluteaRPN.js ├── 151_reverseWordsInAString.js ├── 152_maximumProductSubarray.js ├── 155_minStack.js ├── 156_binaryTreeUpsideDown.js ├── 160_intersectionOfTwoLinkedLists.js ├── 161_oneEditDistance.js ├── 165_compareVersionNumbers.js ├── 167_twoSumII-InputArraySorted.js ├── 170_twoSumIII-DataStructureDesign.js ├── 172_factorialTrailingZeroes.js ├── 173_binarySearchTreeIterator.js ├── 186_reverseWordsInAStringII.js ├── 187_repeatedDNASequences.js ├── 189_rotateArray.js ├── 190_reverseBits.js ├── 191_numberOf1Bits.js ├── 198_houseRobber.js ├── 200_numberOfIslands.js ├── 202_happyNumber.js ├── 203_removeLinkedListElements.js ├── 205_isomorphicStrings.js ├── 206_reverseLinkedList.js ├── 208_implementTrie.js ├── 209_minimumSizeSubarraySum.js ├── 212_wordSearchII.js ├── 215_kthLargestElementInAnArray.js ├── 217_containsDuplicate.js ├── 219_containsDuplicateII.js ├── 223_rectanlgeArea.js ├── 225_implementStackUsingQueues.js ├── 226_invertBinaryTree.js ├── 231_powerOfTwo.js ├── 232_implementQueueUsingStacks.js ├── 234_palindromeLinkedList.js ├── 235_lowestCommonAncestorBST.js ├── 236_lowestCommonAncestorBT.js ├── 237_deleteNodeInLinkedList.js ├── 238_productofArrayExceptSelf.js ├── 239_slidingWindowMaximum.js ├── 240_searchA2DMatrixII.js ├── 242_validAnagram.js ├── 243_shortestWordDistance.js ├── 244_shortestWordDistanceII.js ├── 245_shortestWordDistanceIII.js ├── 252_meetingRooms.js ├── 253_meetingRoomsII.js ├── 254_factorCombinations.js ├── 256_paintHouse.js ├── 257_binaryTreePaths.js ├── 266_palindromePermutations.js ├── 268_missingNumber.js ├── 269_alienDictionary.js ├── 270_closestBinarySearchTreeValue.js ├── 273_integerToEnglishWords.js ├── 276_paintFence.js ├── 277_findTheCelebrity.js ├── 283_moveZeroes.js ├── 285_inorderSuccesorInBST.js ├── 287_findTheDuplicateNumber.js ├── 295_findMeanfromDataStream.js ├── 297_serializeAndDeserializeBT.js ├── 300_longestIncreasingSubsequence.js ├── 301_removeInvalidParanthese.js ├── 311_sparseMatrixMultiplication.js ├── 314_binaryTreeVerticalOrderTraversal.js ├── 325_maximumSizeSubarraySumEqualsk.js ├── 339_nestedListWeightSum.js ├── 342_powerOfFour.js ├── 344_reverseString.js ├── 345_reverseVowelsOfAString.js ├── 346_moveingAverageFromDataStream.js ├── 347_topKFrequentElements.js ├── 348_designTicTacToe.js ├── 349_intersectionofTwoArrays.js ├── 350_intersectionsofTwoArraysII.js ├── 362_designHitCounter.js ├── 364_nestedListWeightSumII.js ├── 366_findLeavesOfBinaryTree.js ├── 367_validPerfectSquare.js ├── 383_ransomNote.js ├── 387_firstUniqueCharacterInAString.js ├── 412_fizzBuzz.js ├── 438_findAllAnagramsInAString.js ├── 442_findAllDuplicatesInAnArray.js ├── 445_addTwoNumbersII.js ├── 449_serializeAndDeserializeBST.js ├── 461_hammingDistance.js ├── 485_maxConsecutiveOnes.js ├── 487_maxConsecutiveOnesII.js ├── 515_finaLargestValueInEachTreeRow.js ├── 518_CoinChange2.js ├── 532_kDiffPairsInArray.js ├── 545_BoundaryOfBinaryTree.js ├── 572_subtreeOfAnotherTree.js ├── 581_shortestUnsortedContinuousSubarray.js ├── 605_canPlaceFlowers.js ├── 633_sumofSquareNumbers.js ├── 647_palindromicSubstrings.js ├── 653_TwoSumIV-InputIsABST.js ├── 654_maximumBinaryTree.js ├── 671_secondMinimumNodeInABT.js ├── 680_validPalindromeII.js ├── 682_baseballGame.js ├── 692_topKFrequentWords.js ├── 693_binaryNumberWithAlternatingBits.js ├── 698_partitionToKEqualSumSubsets.js ├── 714_BestTimeToBuyAndSellStockWithTransactionFee.js ├── 716_MaxStack.js ├── 744_FindSmallestLetterGreaterThanTarget.js ├── 763_partitionLabels.js └── RELATIVE_PATH_HERE.js ├── MySQL ├── average-salary-departments-vs-company.sql ├── big-countries.sql ├── biggest-single-number.sql ├── classes-more-than-5-students.sql ├── combine-two-tables.sql ├── consecutive-available-seats.sql ├── consecutive-numbers.sql ├── count-student-number-in-departments.sql ├── customer-placing-the-largest-number-of-orders.sql ├── customers-who-never-order.sql ├── delete-duplicate-emails.sql ├── department-highest-salary.sql ├── department-top-three-salaries.sql ├── duplicate-emails.sql ├── employee-bonus.sql ├── employees-earning-more-than-their-managers.sql ├── exchange-seats.sql ├── find-cumulative-salary-of-an-employee.sql ├── find-customer-referee.sql ├── find-median-given-frequency-of-numbers.sql ├── friend-requests-i-overall-acceptance-rate.sql ├── friend-requests-ii-who-has-the-most-friends.sql ├── get-highest-answer-rate-question.sql ├── human-traffic-of-stadium.sql ├── investments-in-2016.sql ├── managers-with-at-least-5-direct-reports.sql ├── median-employee-salary.sql ├── not-boring-movies.sql ├── nth-highest-salary.sql ├── rank-scores.sql ├── rising-temperature.sql ├── sales-person.sql ├── second-degree-follower.sql ├── second-highest-salary.sql ├── shortest-distance-in-a-line.sql ├── shortest-distance-in-a-plane.sql ├── students-report-by-geography.sql ├── swap-salary.sql ├── tree-node.sql ├── triangle-judgement.sql ├── trips-and-users.sql └── winning-candidate.sql ├── README.md └── Shell ├── tenth-line.sh ├── transpose-file.sh ├── valid-phone-numbers.sh └── word-frequency.sh /Javascript/001_twoSum.js: -------------------------------------------------------------------------------- 1 | // Time: O(N) 2 | // Space: O(N) 3 | 4 | var twoSum = function(nums, target) { 5 | 6 | const hMap = {}; 7 | 8 | for (let i = 0; i < nums.length; i++) { 9 | const curEle = nums[i]; 10 | const goal = target - curEle; 11 | 12 | if (goal in hMap) { 13 | return [hMap[goal], i]; 14 | } 15 | 16 | hMap[curEle] = i; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /Javascript/002_addTwoNumbers.js: -------------------------------------------------------------------------------- 1 | var addTwoNumbers = function(l1, l2) { 2 | 3 | // Edge Cases 4 | if (!l1) return l2; 5 | else if (!l2) return l1; 6 | 7 | let ptr1 = l1; 8 | let ptr2 = l2; 9 | let sum = ptr1.val + ptr2.val; 10 | 11 | const newHead = new ListNode(sum % 10); 12 | let ptrNew = newHead; 13 | ptr1 = ptr1.next; 14 | ptr2 = ptr2.next; 15 | let carry = sum >= 10 ? 1 : 0; 16 | 17 | while (ptr1 || ptr2 || carry) { 18 | let val1 = ptr1 ? ptr1.val : 0; 19 | let val2 = ptr2 ? ptr2.val : 0; 20 | sum = val1 + val2 + carry; 21 | 22 | // Set up carry for next iteration 23 | carry = sum >= 10 ? 1 : 0; 24 | ptrNew.next = new ListNode(sum % 10); 25 | 26 | ptrNew = ptrNew.next; 27 | if (ptr1) ptr1 = ptr1.next; 28 | if (ptr2) ptr2 = ptr2.next; 29 | } 30 | 31 | return newHead; 32 | }; 33 | 34 | /** 35 | * Definition for singly-linked list. 36 | * function ListNode(val) { 37 | * this.val = val; 38 | * this.next = null; 39 | * } 40 | */ 41 | -------------------------------------------------------------------------------- /Javascript/003_longestSubstringWithoutRepeatingCharacters.js: -------------------------------------------------------------------------------- 1 | var lengthOfLongestSubstring = function(str) { 2 | const hSet = new Set(); 3 | let lead = 0; 4 | let trail = 0; 5 | let maxLength = 0; 6 | 7 | while (lead < str.length) { 8 | if (!hSet.has(str[lead])) { 9 | hSet.add(str[lead]); 10 | lead++; 11 | maxLength = Math.max(maxLength, lead - trail); 12 | } 13 | else { 14 | hSet.delete(str[trail]); 15 | trail++; 16 | } 17 | } 18 | return maxLength; 19 | }; 20 | -------------------------------------------------------------------------------- /Javascript/005_longestPalindromicSubstring.js: -------------------------------------------------------------------------------- 1 | var longestPalindrome = function(string) { 2 | let longestPalSS = ''; 3 | 4 | // Treat each i as the center of a possible palindrome 5 | for (let i = 0; i < string.length; i++) { 6 | // Check for even palindromes 7 | let evenPal = getPalindromeSS(string, i, i+1); 8 | // Check for odd palindromes, reset values 9 | let oddPal = getPalindromeSS(string, i, i); 10 | 11 | let currentPal = evenPal.length > oddPal.length ? evenPal : oddPal; 12 | 13 | if (currentPal.length > longestPalSS.length) { 14 | longestPalSS = currentPal; 15 | } 16 | } 17 | return longestPalSS; 18 | }; 19 | 20 | function getPalindromeSS(string, left, right) { 21 | let currentLongestPalSS = ''; 22 | while (left >= 0 && right < string.length) { 23 | 24 | if (string[left] !== string[right]) break; 25 | 26 | let palSS = string.substring(left, right + 1); 27 | 28 | // Check if current substring palindrome is greater than the longest one 29 | if (palSS.length > currentLongestPalSS.length) { 30 | currentLongestPalSS = palSS; 31 | } 32 | left--; 33 | right++; 34 | } 35 | return currentLongestPalSS; 36 | } 37 | -------------------------------------------------------------------------------- /Javascript/007_reverseInteger.js: -------------------------------------------------------------------------------- 1 | var reverse = function(x) { 2 | var neg = 1; 3 | x = x.toString().split(''); 4 | if (x[0] === '-') { 5 | var neg = -1; 6 | x.shift(); 7 | } 8 | x = x.reverse().join(''); 9 | var num = neg * Number(x); 10 | 11 | if (num > 2147483647 || num < -2147483647) { 12 | return 0; 13 | } 14 | 15 | return num; 16 | }; 17 | -------------------------------------------------------------------------------- /Javascript/008_stringToInteger.js: -------------------------------------------------------------------------------- 1 | var myAtoi = function(str) { 2 | // Edge Cases 3 | if (!str || !str.length) return 0; 4 | 5 | let result = 0; 6 | 7 | // remove whitespaces 8 | str = str.trim(); 9 | if (isNotNumeric(str[0]) && isNotNumeric(str[1])) return 0; 10 | // handle positive and negative sign 11 | let isNegative = false; 12 | // First numerical character 13 | let startIdx = 0; 14 | 15 | // Handle first character not numerical 16 | if (str[0] === '+' || str[0] === '-') startIdx++; 17 | if (str[0] === '-') isNegative = true; 18 | 19 | 20 | // Handle normal case 21 | for (let i = startIdx; i < str.length; i++) { 22 | // Handle non-numerical character 23 | if (isNotNumeric(str[i])) break; 24 | 25 | const digitValue = str[i].charCodeAt(0) - '0'.charCodeAt(0); 26 | result = result * 10 + digitValue; 27 | } 28 | if (isNegative) result = -result; 29 | 30 | // Handle out of integer range 31 | if (result >= Math.pow(2, 31) - 1) return Math.pow(2,31) - 1; 32 | else if (result <= -Math.pow(2, 31)) return -Math.pow(2,31); 33 | 34 | return result; 35 | }; 36 | 37 | function isNotNumeric (char) { 38 | return char < '0' || char > '9'; 39 | } 40 | -------------------------------------------------------------------------------- /Javascript/009_palindromeNumber.js: -------------------------------------------------------------------------------- 1 | var isPalindrome = function (x) { 2 | if (x < 0 || (x % 10 == 0 && x != 0)) { 3 | return false; 4 | } 5 | 6 | let revertedNumber = 0; 7 | while (x > revertedNumber) { 8 | revertedNumber = revertedNumber * 10 + x % 10; 9 | x = Math.floor(x/10); 10 | } 11 | 12 | return (x == revertedNumber) || (x == Math.floor(revertedNumber / 10)); 13 | }; 14 | -------------------------------------------------------------------------------- /Javascript/011_ContainerWithMostWater.js: -------------------------------------------------------------------------------- 1 | var maxArea = function(height) { 2 | let lo = 0; 3 | let hi = height.length - 1; 4 | let max = 0; 5 | 6 | while (lo < hi) { 7 | let w = hi - lo; 8 | let h = Math.min(height[lo], height[hi]); 9 | max = Math.max(w * h, max); 10 | 11 | if (height[lo] < height[hi]) lo++; 12 | else hi--; 13 | } 14 | 15 | return max; 16 | }; 17 | -------------------------------------------------------------------------------- /Javascript/012_integerToRoman.js: -------------------------------------------------------------------------------- 1 | var intToRoman = function(num) { 2 | const romanMap = { 3 | 1: 'I', 4 | 4: 'IV', 5 | 5: 'V', 6 | 9: 'IX', 7 | 10: 'X', 8 | 40: 'XL', 9 | 50: 'L', 10 | 90: 'XC', 11 | 100: 'C', 12 | 400: 'CD', 13 | 500: 'D', 14 | 900: 'CM', 15 | 1000: 'M' 16 | }; 17 | 18 | let romanStr = ''; 19 | 20 | while (num) { 21 | const highestNum = getHighestNum(num, romanMap); 22 | romanStr += romanMap[highestNum]; 23 | num -= highestNum; 24 | } 25 | 26 | return romanStr; 27 | }; 28 | 29 | function getHighestNum (num, romanMap) { 30 | let highest = 1; 31 | 32 | for (let key in romanMap) { 33 | if (key <= num) { 34 | highest = key; 35 | } 36 | } 37 | 38 | return highest; 39 | } 40 | -------------------------------------------------------------------------------- /Javascript/013_romanToInteger.js: -------------------------------------------------------------------------------- 1 | var romanToInt = function(s) { 2 | const romanMap = { 3 | I: 1, 4 | V: 5, 5 | X: 10, 6 | L: 50, 7 | C: 100, 8 | D: 500, 9 | M: 1000 10 | }; 11 | 12 | const edgeCases = { 13 | IV: 4, 14 | IX: 9, 15 | XL: 40, 16 | XC: 90, 17 | CD: 400, 18 | CM: 900 19 | }; 20 | 21 | let num = 0; 22 | 23 | for (let i = 0; i < s.length; i++) { 24 | const normal = s[i]; 25 | const edge = s.slice(i, i + 2); 26 | 27 | if (edge in edgeCases) { 28 | num += edgeCases[edge]; 29 | i++; 30 | } 31 | else { 32 | num += romanMap[normal]; 33 | } 34 | } 35 | 36 | return num; 37 | }; 38 | -------------------------------------------------------------------------------- /Javascript/014_longestCommonPrefix.js: -------------------------------------------------------------------------------- 1 | var longestCommonPrefix = function(strs) { 2 | if (strs.length === 0 || strs[0].length === 0) return ''; 3 | let j; 4 | let prefix = ''; 5 | 6 | for (j = 0; j < strs[0].length; j++) { 7 | for (let i = 0; i < strs.length - 1; i++) { 8 | if (strs[i][j] !== strs[i+1][j]) return prefix; 9 | } 10 | prefix += strs[0][j]; 11 | } 12 | return prefix; 13 | }; 14 | -------------------------------------------------------------------------------- /Javascript/015_3Sum.js: -------------------------------------------------------------------------------- 1 | var threeSum = (nums) => { 2 | let finalArr = [], 3 | trackObj = {}; 4 | nums = nums.sort((a,b) => a-b) 5 | for(let i = 0; i < nums.length; i++) { 6 | let leftPos = 0, 7 | rightPos = nums.length -1, 8 | secondPos = i+1; 9 | while(leftPos <= rightPos) { 10 | let left = nums[leftPos], 11 | right = nums[rightPos], 12 | second = nums[secondPos]; 13 | 14 | let sum = left + right + second; 15 | if (sum === 0) { 16 | let sortedSum = [left, second, right].sort((a,b) => a-b); 17 | if(!trackObj[sortedSum.toString()] && (leftPos !== rightPos && rightPos !== secondPos && leftPos !== secondPos)) { 18 | trackObj[sortedSum.toString()] = true 19 | finalArr.push(sortedSum) 20 | } 21 | while(nums[leftPos] === nums[leftPos+1]) { 22 | leftPos++ 23 | } 24 | leftPos++ 25 | } else { 26 | if (sum > 0) rightPos -- 27 | else leftPos++ 28 | } 29 | 30 | } 31 | } 32 | return finalArr 33 | }; -------------------------------------------------------------------------------- /Javascript/016_ThreeSumClosest.js: -------------------------------------------------------------------------------- 1 | var threeSumClosest = function(nums, target) { 2 | 3 | nums = nums.sort((a,b) => a-b) 4 | let sumArr = [], 5 | final = []; 6 | for(let i = 0; i target ? rightPos-- : leftPos++ 18 | } else { 19 | if(leftPos !== rightPos && leftPos !== secondPos && secondPos !== rightPos) sumArr.push(sum) 20 | leftPos++ 21 | rightPos-- 22 | } 23 | } 24 | } 25 | final.push(sumArr[0]) 26 | for(let i = 0; i Math.abs(sumArr[i] - target)) { 30 | final[final.length-1] = sumArr[i] 31 | } 32 | } 33 | return final[0] 34 | }; -------------------------------------------------------------------------------- /Javascript/017_letterCombinationsOfAPhoneNumber.js: -------------------------------------------------------------------------------- 1 | function letterCombinations (digits) { 2 | // Edge Case 3 | if (!digits || !digits.length) return []; 4 | 5 | // If contains 1 or 0 return empty array 6 | for (let digit of digits) { 7 | if (digit === '0' || digit === '1') return []; 8 | } 9 | 10 | // Create letter matches for keypad 11 | const map = { 12 | 2: ['a', 'b', 'c'], 13 | 3: ['d', 'e', 'f'], 14 | 4: ['g', 'h', 'i'], 15 | 5: ['j', 'k', 'l'], 16 | 6: ['m', 'n', 'o'], 17 | 7: ['p', 'q', 'r', 's'], 18 | 8: ['t', 'u', 'v'], 19 | 9: ['w', 'y', 'x', 'z'] 20 | } 21 | const sols = []; 22 | letterCombinationsHelper(digits, map, 0, '', sols); 23 | return sols; 24 | } 25 | 26 | function letterCombinationsHelper (digits, map, startIdx, curComb, sols) { 27 | // Base Case 28 | if (startIdx === digits.length) { 29 | sols.push(curComb); 30 | return; 31 | } 32 | 33 | const curNum = digits[startIdx]; 34 | const letters = map[curNum]; 35 | 36 | for (let letter of letters) { 37 | letterCombinationsHelper(digits, map, startIdx + 1, curComb + letter, sols); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Javascript/019_removeNthNodeFromEnd.js: -------------------------------------------------------------------------------- 1 | var removeNthFromEnd = function(head, n) { 2 | // Edge Case 3 | if (!head || !n) return head; 4 | 5 | let lead = head; 6 | let trail = head; 7 | 8 | // Move lead 9 | while (n--) { 10 | lead = lead.next; 11 | } 12 | 13 | // If lead is null, we need to remove the head 14 | if (!lead) return head.next; 15 | 16 | // Move both lead and trail until lead is at the last node 17 | while (lead.next) { 18 | lead = lead.next; 19 | trail = trail.next; 20 | } 21 | 22 | // Bypass node infront of trail 23 | trail.next = trail.next.next; 24 | 25 | return head; 26 | }; 27 | -------------------------------------------------------------------------------- /Javascript/020_validParentheses.js: -------------------------------------------------------------------------------- 1 | var isValid = function(str) { 2 | const stack = []; 3 | const bracketMap = {')': '(', '}':'{', ']':'['}; 4 | const openBrackSet = new Set(['(', '[', '{']); 5 | 6 | for (let i = 0; i < str.length; i++) { 7 | const char = str[i]; 8 | 9 | // Check if char is an open bracket 10 | if (openBrackSet.has(char)) { 11 | stack.push(char); 12 | } 13 | // Not an open bracket, must be a closing bracket. Check if it matches the top of the stack 14 | else if (bracketMap[char] !== stack.pop() ) { 15 | return false; 16 | } 17 | } 18 | 19 | return stack.length === 0; 20 | }; 21 | -------------------------------------------------------------------------------- /Javascript/021_mergeTwoSortedLists.js: -------------------------------------------------------------------------------- 1 | var mergeTwoLists = function(l1, l2) { 2 | // Edge Cases 3 | if (!l1) return l2; 4 | else if (!l2) return l1; 5 | 6 | let mergedHead; 7 | // Set mergedHead 8 | 9 | if (l1.val < l2.val) { 10 | mergedHead = l1; 11 | l1 = l1.next; 12 | } 13 | else { 14 | mergedHead = l2; 15 | l2 = l2.next; 16 | } 17 | 18 | let ptr1 = l1; 19 | let ptr2 = l2; 20 | let ptrM = mergedHead; 21 | 22 | while (ptr1 || ptr2) { 23 | const val1 = ptr1 ? ptr1.val : Infinity; 24 | const val2 = ptr2 ? ptr2.val : Infinity; 25 | 26 | if (val1 < val2) { 27 | ptrM.next = ptr1; 28 | ptr1 = ptr1.next; 29 | } 30 | else { 31 | ptrM.next = ptr2; 32 | ptr2 = ptr2.next; 33 | } 34 | ptrM = ptrM.next; 35 | } 36 | 37 | return mergedHead; 38 | }; 39 | -------------------------------------------------------------------------------- /Javascript/022_generateParentheses.js: -------------------------------------------------------------------------------- 1 | let print_all_parentheses_rec = function(n, left_count, right_count, output, sol) { 2 | 3 | if (left_count >= n && right_count >= n) { 4 | sol.push(output.join('')); 5 | } 6 | 7 | if (left_count < n) { 8 | output.push('('); 9 | print_all_parentheses_rec(n, left_count + 1, right_count, output, sol); 10 | output.pop(); 11 | } 12 | if (right_count < left_count) { 13 | output.push(')'); 14 | print_all_parentheses_rec(n, left_count, right_count + 1, output, sol); 15 | output.pop(); 16 | } 17 | }; 18 | 19 | let generateParenthesis = function(n) { 20 | let sol = []; 21 | let output = []; 22 | print_all_parentheses_rec(n, 0, 0, output, sol ); 23 | return sol; 24 | }; 25 | -------------------------------------------------------------------------------- /Javascript/023_mergeKSortedLists.js: -------------------------------------------------------------------------------- 1 | var mergeKLists = function(lists) { 2 | 3 | if (!lists || !lists.length) return null; 4 | 5 | let mergedLists = lists; 6 | 7 | while (mergedLists.length !== 1) { 8 | const nextLists = []; 9 | let len = mergedLists.length; 10 | 11 | for (let i = 0; i < len; i += 2) { 12 | const list1 = mergedLists[i]; 13 | const list2 = mergedLists[i+1]; 14 | 15 | const merged = mergeTwoLists(list1, list2); 16 | nextLists.push(merged); 17 | } 18 | mergedLists = nextLists; 19 | } 20 | 21 | return mergedLists[0]; 22 | }; 23 | 24 | function mergeTwoLists (l1, l2) { 25 | // Edge Cases 26 | if (!l1) return l2; 27 | else if (!l2) return l1; 28 | 29 | let mergedHead; 30 | // Set mergedHead 31 | 32 | if (l1.val < l2.val) { 33 | mergedHead = l1; 34 | l1 = l1.next; 35 | } 36 | else { 37 | mergedHead = l2; 38 | l2 = l2.next; 39 | } 40 | 41 | let ptr1 = l1; 42 | let ptr2 = l2; 43 | let ptrM = mergedHead; 44 | 45 | while (ptr1 || ptr2) { 46 | const val1 = ptr1 ? ptr1.val : Infinity; 47 | const val2 = ptr2 ? ptr2.val : Infinity; 48 | 49 | if (val1 < val2) { 50 | ptrM.next = ptr1; 51 | ptr1 = ptr1.next; 52 | } 53 | else { 54 | ptrM.next = ptr2; 55 | ptr2 = ptr2.next; 56 | } 57 | ptrM = ptrM.next; 58 | } 59 | 60 | return mergedHead; 61 | } 62 | -------------------------------------------------------------------------------- /Javascript/025_reverseNodesInKGroup.js: -------------------------------------------------------------------------------- 1 | var reverseKGroup = function(head, k) { 2 | // Edge Case 3 | if (!head || !head.next || k <= 1) return head; 4 | 5 | let tempA = head; 6 | let count = 1; 7 | let ptr = head; 8 | while (ptr && count % k !== 0) { 9 | count++; 10 | ptr = ptr.next; 11 | } 12 | if (!ptr) return head; 13 | 14 | let tempB = ptr.next; 15 | ptr.next = null; 16 | let newHead = reverseList(head); 17 | tempA.next = tempB; 18 | ptr = tempB; 19 | count++; 20 | let prevTail; 21 | while (ptr) { 22 | prevTail = tempA; 23 | tempA = ptr; 24 | while (ptr && count % k !== 0) { 25 | count++; 26 | ptr = ptr.next; 27 | } 28 | 29 | if (!ptr) break; 30 | 31 | tempB = ptr.next; 32 | ptr.next = null; 33 | prevTail.next = reverseList(tempA); 34 | tempA.next = tempB; 35 | ptr = tempB; 36 | count++; 37 | } 38 | 39 | return newHead; 40 | }; 41 | 42 | 43 | function reverseList(head) { 44 | // Edge Case 45 | if (!head) return null; 46 | 47 | let trail = null; 48 | let lead = head; 49 | 50 | while (lead !== null) { 51 | let nextNode = lead.next; 52 | lead.next = trail 53 | trail = lead; 54 | lead = nextNode; 55 | } 56 | return trail; 57 | } 58 | -------------------------------------------------------------------------------- /Javascript/026_removeDuplicatedFromSortedArray.js: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space O(n) 3 | // Doesn't mutate the original array; 4 | // but it will require additional space 5 | const removeDupes = (arr) => { 6 | const newArr = [arr[0]]; 7 | for (let i = 1; i < arr.length; i++){ 8 | const lastPushed = newArr[newArr.length - 1]; 9 | const arrElem = arr[i]; 10 | if (arrElem !== lastPushed) newArr.push(arrElem); 11 | } 12 | return newArr; 13 | }; 14 | 15 | // Tests 16 | 17 | const sampleArr = [1, 2, 2, 3, 3, 4, 4, 4, 5]; 18 | 19 | 20 | // console.log(removeDupes(sampleArr)); 21 | // console.log(sampleArr); 22 | // expect this to be [1, 2, 3, 4, 5] 23 | 24 | // ** Solution 2 ** 25 | // TIme: O(n) 26 | // Space: O(1) 27 | 28 | 29 | const removeDupes2 = (arr) => { 30 | let last = 0; 31 | for (let i = 0; i < arr.length; i++){ 32 | if (!last || arr[i] !== arr[last - 1]){ 33 | arr[last++] = arr[i]; 34 | } 35 | } 36 | // we want to pop of those last elems 37 | // const oldLength = arr.length; 38 | while (arr.length > last){ 39 | arr.pop(); 40 | } 41 | return arr; 42 | }; 43 | 44 | 45 | console.log(removeDupes2(sampleArr)); 46 | console.log(sampleArr); 47 | -------------------------------------------------------------------------------- /Javascript/027_removeElement.js: -------------------------------------------------------------------------------- 1 | var removeElement = function(nums, val) { 2 | let i = 0; 3 | 4 | let n = nums.length; 5 | 6 | while (i < n) { 7 | if (nums[i] === val) { 8 | nums[i] = nums[n - 1]; 9 | n--; 10 | } else { 11 | i++; 12 | } 13 | } 14 | return n; 15 | }; 16 | -------------------------------------------------------------------------------- /Javascript/028_implementstrStr.js: -------------------------------------------------------------------------------- 1 | var strStr = function(haystack, needle) { 2 | if (haystack === needle || needle === "") return 0; 3 | 4 | for (let i = 0; i < haystack.length - needle.length + 1; i++) { 5 | for (let j = 0; j < needle.length; j++) { 6 | if (j == needle.length - 1 && haystack[i + j] === needle[j]) return i; 7 | if (needle[j] !== haystack[i + j]) break; 8 | } 9 | } 10 | return -1; 11 | }; 12 | -------------------------------------------------------------------------------- /Javascript/033_searchInRotatedSortedArray.js: -------------------------------------------------------------------------------- 1 | function search(arr, target) { 2 | let lo = 0; 3 | let hi = arr.length - 1; 4 | 5 | while (lo <= hi) { 6 | let mid = Math.floor((lo + hi) / 2); 7 | // Hit 8 | if (arr[mid] === target) { 9 | return mid; 10 | } 11 | else if (arr[lo] <= arr[mid]) { 12 | // Left half of array is correctly sorted 13 | if (target >= arr[lo] && target < arr[mid]) { 14 | hi = mid - 1; 15 | } 16 | else { 17 | lo = mid + 1; 18 | } 19 | continue; 20 | } 21 | 22 | // Right half of array is correctly sorted 23 | if (target <= arr[hi] && target > arr[mid]) { 24 | lo = mid + 1; 25 | } 26 | else { 27 | hi = mid - 1; 28 | } 29 | 30 | } 31 | return -1; 32 | } 33 | -------------------------------------------------------------------------------- /Javascript/034_searchForARange.js: -------------------------------------------------------------------------------- 1 | var searchRange = function(nums, target) { 2 | const lo = searchLow(nums, target); 3 | const hi = searchHigh(nums, target); 4 | return [lo, hi]; 5 | }; 6 | 7 | function searchLow(nums, target) { 8 | let lo = 0; 9 | let hi = nums.length - 1; 10 | 11 | while (lo <= hi) { 12 | let mid = Math.floor((hi + lo)/2); 13 | if (target <= nums[mid]) hi = mid -1; 14 | else lo = mid + 1; 15 | } 16 | if (nums[lo] === target) return lo; 17 | return -1; 18 | } 19 | 20 | function searchHigh(nums, target) { 21 | let lo = 0; 22 | let hi = nums.length - 1; 23 | 24 | while (lo <= hi) { 25 | let mid = Math.floor((hi + lo)/2); 26 | if (target >= nums[mid]) lo = mid + 1; 27 | else hi = mid - 1; 28 | } 29 | 30 | if (nums[hi] === target) return hi; 31 | return -1; 32 | } 33 | -------------------------------------------------------------------------------- /Javascript/035_searchInsertPosition.js: -------------------------------------------------------------------------------- 1 | var searchInsert = function(nums, target) { 2 | // Edge Case 3 | if (target > nums[nums.length - 1]) return nums.length; 4 | 5 | let lo = 0; 6 | let hi = nums.length; 7 | 8 | while (lo <= hi) { 9 | let mid = Math.floor((lo + hi) / 2); 10 | 11 | if (target === nums[mid]) return mid; 12 | else if (target < nums[mid]) hi = mid - 1; 13 | else lo = mid + 1; 14 | } 15 | return lo; 16 | }; 17 | -------------------------------------------------------------------------------- /Javascript/036_validSudoku.js: -------------------------------------------------------------------------------- 1 | var isValidSudoku = function(board) { 2 | if (areRowsValid(board) && areColsValid(board) && areSubBoardsValid(board)) return true; 3 | return false; 4 | } 5 | 6 | function areRowsValid (board) { 7 | for (let r = 0; r < board.length; r++) { 8 | const colSet = new Set(); 9 | 10 | for (let c = 0; c < board[0].length; c++) { 11 | const ele = board[r][c]; 12 | if (ele === '.') continue; 13 | else if (colSet.has(ele)) return false; 14 | else colSet.add(ele) 15 | } 16 | } 17 | 18 | return true; 19 | } 20 | 21 | function areColsValid (board) { 22 | for (let c = 0; c < board[0].length; c++) { 23 | const rowSet = new Set(); 24 | 25 | for (let r = 0; r < board.length; r++) { 26 | const ele = board[r][c]; 27 | if (ele === '.') continue; 28 | if (rowSet.has(ele)) return false; 29 | else rowSet.add(ele); 30 | } 31 | } 32 | return true; 33 | } 34 | 35 | function areSubBoardsValid (board) { 36 | const ranges = [[0, 2], [3, 5], [6, 8]]; 37 | 38 | for (let rowRangeIdx = 0; rowRangeIdx < ranges.length; rowRangeIdx++) { 39 | for (let colRangeIdx = 0; colRangeIdx < ranges.length; colRangeIdx++) { 40 | const rowMin = ranges[rowRangeIdx][0]; 41 | const rowMax = ranges[rowRangeIdx][1]; 42 | const colMin = ranges[colRangeIdx][0]; 43 | const colMax = ranges[colRangeIdx][1]; 44 | 45 | const subboardSet = new Set(); 46 | 47 | for (let r = rowMin; r <= rowMax; r++) { 48 | for (let c = colMin; c <= colMax; c++) { 49 | const ele = board[r][c]; 50 | if (ele === '.') continue; 51 | else if (subboardSet.has(ele)) return false; 52 | else subboardSet.add(ele); 53 | } 54 | } 55 | } 56 | } 57 | 58 | return true; 59 | } 60 | -------------------------------------------------------------------------------- /Javascript/037_sudokuSolver.js: -------------------------------------------------------------------------------- 1 | function solveSudoku(board) { 2 | solveSudokuHelp(board); 3 | } 4 | 5 | function solveSudokuHelp(board) { 6 | // Base Case 7 | if (isFilled(board)) { 8 | return true; 9 | } 10 | 11 | // Iterate over each cell 12 | for (let r = 0; r < board.length; r++) { 13 | for (let c = 0; c < board[r].length; c++) { 14 | if (board[r][c] === '.') { 15 | const possNums = getPossNums(board, r, c); 16 | 17 | for (let pos of possNums) { 18 | board[r][c] = pos; 19 | if (solveSudokuHelp(board)) return true; 20 | board[r][c] = '.'; 21 | } 22 | return false; 23 | } 24 | } 25 | } 26 | 27 | return false; 28 | } 29 | 30 | function getPossNums (board, row, col) { 31 | 32 | const rowSet = new Set(); 33 | const colSet = new Set(); 34 | const subBoardSet = new Set(); 35 | 36 | const rangesMap = { 37 | 0: [0, 2], 38 | 1: [0, 2], 39 | 2: [0, 2], 40 | 3: [3, 5], 41 | 4: [3, 5], 42 | 5: [3, 5], 43 | 6: [6, 8], 44 | 7: [6, 8], 45 | 8: [6, 8], 46 | } 47 | 48 | // Add row elements to row set 49 | for (let c = 0; c < 9; c++) { 50 | rowSet.add(board[row][c]); 51 | } 52 | 53 | // Add col elements to col set 54 | for (let r = 0; r < 9; r++) { 55 | colSet.add(board[r][col]); 56 | } 57 | 58 | // Add suboardElements to subboardSet 59 | let rowRange = rangesMap[row]; 60 | let colRange = rangesMap[col]; 61 | 62 | for (let r = rowRange[0]; r <= rowRange[1]; r++) { 63 | for (let c = colRange[0]; c <= colRange[1]; c++) { 64 | subBoardSet.add(board[r][c]); 65 | } 66 | } 67 | const possibleNums = []; 68 | 69 | // Iterate and find min number 70 | for (let i = 1; i <= 9; i++) { 71 | i = String(i); 72 | if (!rowSet.has(i) && !colSet.has(i) && !subBoardSet.has(i)) { 73 | possibleNums.push(i); 74 | } 75 | } 76 | 77 | return possibleNums; 78 | } 79 | 80 | function isFilled(board) { 81 | for (let r = 0; r < board.length; r++) { 82 | for (let c = 0; c < board[0].length; c++) { 83 | if (board[r][c] === '.') return false; 84 | } 85 | } 86 | 87 | return true; 88 | } 89 | -------------------------------------------------------------------------------- /Javascript/039_combinationSum.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | General Algorithms: 4 | 5 | Recursively try out each number and explore using like a DFS, if we hit the target sum, then add the combinations 6 | that we took to get there to the total combinatios array. 7 | 8 | */ 9 | var combinationSum = function(candidates, target) { 10 | candidates.sort((a,b) => a-b); 11 | return combinationSumDFS(candidates, target, 0, 0, [], []); 12 | } 13 | 14 | function combinationSumDFS(candidates, target, startIdx, curSum, curComb, sumCombs) { 15 | 16 | // Iterate candidates from startIdx 17 | for (let i = startIdx; i < candidates.length; i++) { 18 | let val = candidates[i]; 19 | let newSum = curSum + val; 20 | 21 | if (newSum === target) { 22 | sumCombs.push(curComb.concat(val)) 23 | break; 24 | } 25 | else if (newSum < target) { 26 | combinationSumDFS(candidates, target, i, newSum, curComb.concat(val), sumCombs); 27 | } 28 | else break; 29 | } 30 | 31 | return sumCombs; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Javascript/042_trappingRainWater.js: -------------------------------------------------------------------------------- 1 | var trap = function(heights) { 2 | let maxSoFar = 0; 3 | const leftMax = new Array(heights.length).fill(0); 4 | const rightMax = leftMax.slice(); 5 | 6 | // Find left max at each index 7 | for (let i = 0; i < heights.length; i++) { 8 | leftMax[i] = maxSoFar; 9 | maxSoFar = Math.max(maxSoFar, heights[i]); 10 | } 11 | // Reset maxSoFar 12 | maxSoFar = 0; 13 | 14 | // Find right max at each index 15 | for (let i = heights.length - 1; i >= 0; i--) { 16 | rightMax[i] = maxSoFar; 17 | maxSoFar = Math.max(maxSoFar, heights[i]); 18 | } 19 | let totalArea = 0; 20 | 21 | // iterate through heights and calculate total area at each index 22 | for (let i = 0; i < heights.length; i++) { 23 | let idxArea = Math.min(leftMax[i], rightMax[i]) - heights[i]; 24 | if (idxArea > 0) totalArea += idxArea; 25 | } 26 | 27 | return totalArea; 28 | }; 29 | 30 | // Alternate solution: O(n) time | O(1) space 31 | function waterArea(heights) { 32 | let left = 0 33 | let right = heights.length - 1 34 | let leftMax = 0 35 | let rightMax = 0 36 | let water = 0 37 | 38 | while (left < right) { 39 | if (heights[left] < heights[right]) { 40 | heights[left] >= leftMax 41 | ? (leftMax = heights[left]) 42 | : (water += leftMax - heights[left]) 43 | left++ 44 | } else { 45 | heights[right] >= rightMax 46 | ? (rightMax = heights[right]) 47 | : (water += rightMax - heights[right]) 48 | right-- 49 | } 50 | } 51 | 52 | return water 53 | } 54 | -------------------------------------------------------------------------------- /Javascript/045_jumpGameII.js: -------------------------------------------------------------------------------- 1 | var jump = function(nums) { 2 | // Edge Cases 3 | if (nums.length <= 1) return 0; 4 | if (nums[0] >= nums.length - 1) return 1; 5 | 6 | let maxReach = nums[0]; 7 | let steps = nums[0]; 8 | let i = 1; 9 | let jumps = 1; 10 | 11 | while (steps && i < nums.length - 1) { 12 | steps--; 13 | maxReach = Math.max(maxReach, nums[i] + i); 14 | 15 | if (maxReach >= nums.length - 1) { 16 | jumps++; 17 | break; 18 | } 19 | if (!steps) { 20 | steps = maxReach - i; 21 | jumps++; 22 | } 23 | i++; 24 | } 25 | return jumps; 26 | }; 27 | -------------------------------------------------------------------------------- /Javascript/046_permutations.js: -------------------------------------------------------------------------------- 1 | var permute = function(nums, perms = [[nums.shift()]]) { 2 | if (!nums || !nums.length) return perms; 3 | 4 | let firstVal = nums.shift(); 5 | let newPerms = []; 6 | 7 | for (let i = 0; i < perms.length; i++) { 8 | for (let j = 0; j <= perms[i].length; j++) { 9 | let perm = insertAt(perms[i], j, firstVal); 10 | newPerms.push(perm); 11 | } 12 | } 13 | 14 | return permute(nums, newPerms); 15 | }; 16 | 17 | function insertAt(arr, idx, val) { 18 | let firstHalf = arr.slice(0, idx); 19 | let secondHalf = arr.slice(idx); 20 | 21 | firstHalf.push(val); 22 | 23 | return firstHalf.concat(secondHalf); 24 | } 25 | -------------------------------------------------------------------------------- /Javascript/047_permutationsII.js: -------------------------------------------------------------------------------- 1 | var permuteUnique = function(nums) { 2 | const res = []; 3 | const map = buildFreqTable(nums); 4 | permuteUniqueHelper(map, [], nums.length, res); 5 | return res; 6 | }; 7 | 8 | function buildFreqTable(nums) { 9 | const hMap = {}; 10 | 11 | for (let n of nums) { 12 | if (n in hMap) hMap[n] += 1; 13 | else hMap[n] = 1; 14 | } 15 | 16 | return hMap; 17 | } 18 | 19 | function permuteUniqueHelper(map, prev, remaining, res) { 20 | if (!remaining) { 21 | res.push(prev); 22 | return; 23 | } 24 | 25 | // Try remaining numbers 26 | for (let n in map) { 27 | 28 | let count = map[n]; 29 | 30 | if (count > 0) { 31 | map[n] = count - 1; 32 | permuteUniqueHelper(map, prev.concat(+n), remaining - 1, res); 33 | map[n] = count; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Javascript/048_rotateImage.js: -------------------------------------------------------------------------------- 1 | function rotate(matrix) { 2 | 3 | let layerMin = 0; 4 | let layerMax = matrix.length - 1; 5 | 6 | while (layerMin <= layerMax) { 7 | 8 | for (let i = layerMin; i < layerMax; i++) { 9 | // Get values 10 | let top = matrix[layerMin][i]; 11 | let right = matrix[i][layerMax]; 12 | let bottom = matrix[layerMax][layerMax - i + layerMin]; 13 | let left = matrix[layerMax - i + layerMin][layerMin]; 14 | 15 | // Reassign values 16 | 17 | // Top will now be left 18 | matrix[layerMin][i] = left; 19 | 20 | // Right will now be top 21 | matrix[i][layerMax] = top; 22 | 23 | // Bottom will now be right 24 | matrix[layerMax][layerMax - i + layerMin] = right; 25 | 26 | // Left will now be bottom 27 | matrix[layerMax - i + layerMin][layerMin] = bottom; 28 | } 29 | layerMin++; 30 | layerMax--; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Javascript/049_groupAnagrams.js: -------------------------------------------------------------------------------- 1 | var groupAnagrams = function(strs) { 2 | const anagramMap = {}; 3 | 4 | for (let str of strs) { 5 | const freqStr = (getFreqString(str)); 6 | 7 | if (freqStr in anagramMap) anagramMap[freqStr].push(str); 8 | else anagramMap[freqStr] = [str]; 9 | } 10 | const sol = []; 11 | for (let key in anagramMap) { 12 | sol.push(anagramMap[key]); 13 | } 14 | 15 | return sol; 16 | }; 17 | 18 | function getFreqString (str) { 19 | const freqArr = new Array(26).fill(0); 20 | 21 | for (let l of str) { 22 | let idx = l.charCodeAt(0) - 'a'.charCodeAt(0); 23 | freqArr[idx] += 1; 24 | } 25 | 26 | return freqArr.join(','); 27 | } 28 | -------------------------------------------------------------------------------- /Javascript/050_pow(x,n).js: -------------------------------------------------------------------------------- 1 | function powPositive(x, n) { 2 | // Edge Case 3 | if (n === 0) return 1; 4 | // Base Case 5 | if (n === 1) return x; 6 | 7 | let p = powPositive(x, Math.floor(n/2)); 8 | if (n % 2 === 0) return p * p; 9 | return x * p * p; 10 | } 11 | 12 | function myPow (x, n) { 13 | if (n >= 0) return powPositive(x, n); 14 | // n is negative 15 | let positiveValue = powPositive(x, Math.abs(n)); 16 | 17 | return 1 / positiveValue; 18 | } 19 | -------------------------------------------------------------------------------- /Javascript/053_maximumSubarray.js: -------------------------------------------------------------------------------- 1 | var maxSubArray = function(nums) { 2 | let maxSum = nums[0]; 3 | let curSum = nums[0]; 4 | 5 | for (let i = 1; i < nums.length; i++) { 6 | curSum = Math.max(nums[i], curSum + nums[i]); 7 | maxSum = Math.max(curSum, maxSum); 8 | } 9 | 10 | return maxSum; 11 | }; 12 | -------------------------------------------------------------------------------- /Javascript/054_spiralMatrix.js: -------------------------------------------------------------------------------- 1 | var spiralOrder = function(matrix) { 2 | if (!matrix.length) return []; 3 | 4 | let rowMin = 0; 5 | let rowMax = matrix.length - 1; 6 | let colMin = 0; 7 | let colMax = matrix[0].length - 1; 8 | const sol = []; 9 | 10 | while (rowMin <= rowMax && colMin <= colMax) { 11 | 12 | // Top 13 | for (let i = colMin; i <= colMax; i++) { 14 | sol.push(matrix[rowMin][i]) 15 | } 16 | rowMin++; 17 | 18 | // Right 19 | for (let i = rowMin; i <= rowMax; i++) { 20 | sol.push(matrix[i][colMax]); 21 | } 22 | colMax--; 23 | 24 | if (rowMin <= rowMax) { 25 | // Bottom 26 | for (let i = colMax; i >= colMin; i--) { 27 | sol.push(matrix[rowMax][i]); 28 | } 29 | rowMax--; 30 | } 31 | 32 | if (colMin <= colMax) { 33 | // Left 34 | for (let i = rowMax; i >= rowMin; i--) { 35 | sol.push(matrix[i][colMin]) 36 | } 37 | colMin++ 38 | } 39 | } 40 | 41 | return sol; 42 | }; 43 | -------------------------------------------------------------------------------- /Javascript/055_jumpGame.js: -------------------------------------------------------------------------------- 1 | var canJump = function(nums) { 2 | // Edge Cases 3 | if (!nums || !nums.length) return false 4 | if (nums.length === 1) return true; 5 | 6 | let maxReach = nums[0]; 7 | let steps = nums[0]; 8 | let i = 1; 9 | 10 | while (steps > 0 && i < nums.length) { 11 | const curEle = nums[i]; 12 | 13 | maxReach = Math.max(maxReach, curEle + i); 14 | if (maxReach >= nums.length - 1) return true; 15 | steps--; 16 | if (!steps) { 17 | steps = maxReach - i; 18 | } 19 | i++; 20 | } 21 | 22 | return false; 23 | }; 24 | -------------------------------------------------------------------------------- /Javascript/056_mergeIntervals.js: -------------------------------------------------------------------------------- 1 | var merge = function(meetings) { 2 | // Edge Case 3 | if (!meetings || !meetings.length) return []; 4 | 5 | meetings.sort((a,b) => a.start - b.start); 6 | 7 | const mIs = []; 8 | let mS = meetings[0].start; 9 | let mE = meetings[0].end; 10 | 11 | for (let i = 1; i < meetings.length; i++) { 12 | let cS = meetings[i].start; 13 | let cE = meetings[i].end; 14 | 15 | if (cS <= mE) { 16 | mE = Math.max(mE, cE); 17 | } 18 | else { 19 | mIs.push([mS, mE]); 20 | mS = cS; 21 | mE = cE; 22 | } 23 | } 24 | mIs.push([mS, mE]); 25 | return mIs; 26 | }; 27 | -------------------------------------------------------------------------------- /Javascript/057_insertInterval.js: -------------------------------------------------------------------------------- 1 | var insert = function(intervals, newInterval) { 2 | // Edge Case 3 | if (!intervals || !intervals.length) return [newInterval]; 4 | // Insert new interval in correct position 5 | insertion(intervals, newInterval); 6 | 7 | // Merge intervals 8 | return merge(intervals); 9 | }; 10 | 11 | function insertion(intervals, newInterval) { 12 | // Add interval 13 | intervals.push(newInterval); 14 | 15 | // Insert in correct position 16 | let i = intervals.length - 1; 17 | 18 | while (i > 0 && intervals[i].start < intervals[i-1].start) { 19 | swap(intervals, i, i-1); 20 | i--; 21 | } 22 | } 23 | 24 | function merge(intervals) { 25 | let mergedArr = []; 26 | let mS = intervals[0].start; 27 | let mE = intervals[0].end; 28 | 29 | for (let i = 1; i < intervals.length; i++) { 30 | const cS = intervals[i].start; 31 | const cE = intervals[i].end; 32 | 33 | // check if we can merge 34 | if (cS <= mE) { 35 | mE = Math.max(mE, cE); 36 | } 37 | else { 38 | mergedArr.push(new Interval(mS, mE)); 39 | mS = cS; 40 | mE = cE; 41 | } 42 | } 43 | mergedArr.push(new Interval(mS, mE)); 44 | return mergedArr; 45 | } 46 | 47 | function swap(arr, i, j) { 48 | let temp = arr[i]; 49 | arr[i] = arr[j]; 50 | arr[j] = temp; 51 | } 52 | -------------------------------------------------------------------------------- /Javascript/058_lengthOfLastWord.js: -------------------------------------------------------------------------------- 1 | var lengthOfLastWord = function(s) { 2 | let count = 0; 3 | for (let i = s.length - 1; i >= 0; i--) { 4 | if (s[i] === ' ' && count === 0) { 5 | continue; 6 | } 7 | count++; 8 | if (s[i] === ' ' && count > 0) { 9 | return count - 1; 10 | } 11 | } 12 | return count; 13 | }; 14 | -------------------------------------------------------------------------------- /Javascript/059_spiralMatrixII.js: -------------------------------------------------------------------------------- 1 | var generateMatrix = function(n) { 2 | 3 | let rowMin = 0; 4 | let rowMax = n - 1; 5 | let colMin = 0; 6 | let colMax = n - 1; 7 | 8 | // Make spiral matrix 9 | const spiralMatrix = new Array(n); 10 | 11 | for (let i = 0; i < n; i++) { 12 | spiralMatrix[i] = new Array(n).fill(0); 13 | } 14 | let count = 1; 15 | 16 | while (rowMin <= rowMax && colMin <= colMax) { 17 | // Top 18 | for (let c = colMin; c <= colMax; c++) { 19 | spiralMatrix[rowMin][c] = count; 20 | count++; 21 | } 22 | rowMin++; 23 | 24 | // Right 25 | for (let r = rowMin; r <= rowMax; r++) { 26 | spiralMatrix[r][colMax] = count; 27 | count++; 28 | } 29 | colMax--; 30 | 31 | // Bottom 32 | if (rowMin <= rowMax) { 33 | for (let c = colMax; c >= colMin; c--) { 34 | spiralMatrix[rowMax][c] = count; 35 | count++; 36 | } 37 | rowMax--; 38 | } 39 | 40 | // Left 41 | if (colMin <= colMax) { 42 | for (let r = rowMax; r >= rowMin; r--) { 43 | spiralMatrix[r][colMin] = count; 44 | count++; 45 | } 46 | colMin++; 47 | } 48 | } 49 | 50 | return spiralMatrix; 51 | }; 52 | -------------------------------------------------------------------------------- /Javascript/060_permutationSequence.js: -------------------------------------------------------------------------------- 1 | var getPermutation = function(n, k) { 2 | const set = []; 3 | for (let i = 1; i <= n; i++) { 4 | set.push(i); 5 | } 6 | return findKthPerm(set, k).join(''); 7 | }; 8 | 9 | function findKthPerm (elements, k, kthPerm = []) { 10 | if (!elements || !elements.length) return kthPerm; 11 | 12 | let n = elements.length; 13 | let factNMinus1 = fact(n-1); 14 | let startIdx = Math.floor((k-1)/factNMinus1); 15 | let newK = k - factNMinus1 * startIdx; 16 | 17 | let startEle = elements.splice(startIdx, 1)[0]; 18 | kthPerm.push(startEle); 19 | 20 | return findKthPerm(elements, newK, kthPerm) 21 | } 22 | 23 | function fact (n) { 24 | let factorial = 1; 25 | while (n > 1) { 26 | factorial *= n; 27 | n--; 28 | } 29 | 30 | return factorial; 31 | } 32 | -------------------------------------------------------------------------------- /Javascript/061_rotateList.js: -------------------------------------------------------------------------------- 1 | var rotateRight = function(head, k) { 2 | // Edge Case 3 | if (!head) return null; 4 | 5 | const length = getLength(head); 6 | 7 | k = k % length; 8 | if (k < 0) k = k + length; 9 | 10 | // No rotatition needed 11 | if (k === 0) return head; 12 | 13 | let count = 0; 14 | let ptr = head; 15 | 16 | while (count < length - k - 1) { 17 | ptr = ptr.next; 18 | count++; 19 | } 20 | 21 | let partitionHead2 = ptr.next; 22 | ptr.next = null; 23 | ptr = partitionHead2; 24 | 25 | while (ptr.next !== null) { 26 | ptr = ptr.next; 27 | } 28 | 29 | ptr.next = head; 30 | 31 | return partitionHead2; 32 | }; 33 | 34 | function getLength (head) { 35 | let count = 0; 36 | while (head !== null) { 37 | head = head.next; 38 | count++; 39 | } 40 | return count; 41 | } 42 | -------------------------------------------------------------------------------- /Javascript/062_uniquePaths.js: -------------------------------------------------------------------------------- 1 | var uniquePaths = function(m, n) { 2 | return mark(m-1, n-1); 3 | }; 4 | 5 | 6 | function mark(r, c, memo = {}) { 7 | // Out of bounds 8 | if (r < 0 || c < 0) return 0; 9 | 10 | // Success 11 | if (r === 0 && c === 0) return 1; 12 | 13 | const str = r + ',' + c; 14 | if (str in memo) return memo[str]; 15 | 16 | let count = 0; 17 | 18 | // Mark top 19 | count += mark(r - 1, c, memo); 20 | 21 | // Mark left 22 | count += mark(r, c - 1, memo); 23 | 24 | memo[str] = count; 25 | return count; 26 | } 27 | -------------------------------------------------------------------------------- /Javascript/063_uniquePathsII.js: -------------------------------------------------------------------------------- 1 | var uniquePathsWithObstacles = function(obstacleGrid) { 2 | let m = obstacleGrid.length; 3 | let n = obstacleGrid[0].length; 4 | return mark(obstacleGrid, m-1, n-1) 5 | }; 6 | 7 | 8 | function mark(grid, r, c, memo = {}) { 9 | // Out of bounds 10 | if (r < 0 || c < 0 || grid[r][c] === 1) return 0; 11 | 12 | // Success 13 | if (r === 0 && c === 0) return 1; 14 | 15 | const str = r + ',' + c; 16 | if (str in memo) return memo[str]; 17 | 18 | let count = 0; 19 | 20 | // Mark top 21 | count += mark(grid, r - 1, c, memo); 22 | 23 | // Mark left 24 | count += mark(grid, r, c - 1, memo); 25 | 26 | memo[str] = count; 27 | return count; 28 | } 29 | -------------------------------------------------------------------------------- /Javascript/064_minimumPathSum.js: -------------------------------------------------------------------------------- 1 | var minPathSum = function(grid) { 2 | let rows = grid.length; 3 | let cols = grid[0].length; 4 | 5 | for (let r = rows - 1; r >= 0; r--) { 6 | for (let c = cols - 1; c >= 0; c--) { 7 | 8 | const bottomCost = r + 1 < rows ? grid[r+1][c] : Infinity; 9 | const rightCost = c + 1 < cols ? grid[r][c+1] : Infinity; 10 | 11 | if (bottomCost !== Infinity || rightCost !== Infinity) { 12 | grid[r][c] += Math.min(bottomCost, rightCost); 13 | } 14 | 15 | } 16 | } 17 | return grid[0][0] 18 | }; 19 | -------------------------------------------------------------------------------- /Javascript/065_validNumber.js: -------------------------------------------------------------------------------- 1 | var isNumber = function(s) { 2 | s = s.trim(); 3 | let decimalCount = 0; 4 | let eCount = 0; 5 | let signCount = 0; 6 | 7 | let start = 0; 8 | if (s[start] === '+' || s[start] === '-') start++; 9 | 10 | // Check for bullshit in beginning or end 11 | if (s[start] === 'e' || 12 | s[s.length - 1] === 'e' || 13 | s.slice(start, start + 2) === '.e' || 14 | (s[start] === '.' && s.length - start === 1) || 15 | !s.length || 16 | s[s.length - 1] === '+' || 17 | s[s.length - 1] === '-') return false; 18 | 19 | 20 | for (let i = start; i < s.length; i++) { 21 | const c = s[i]; 22 | 23 | if (s.slice(i, i+2) === 'e.') return false; 24 | else if (c === '.' && eCount > 0) return false; 25 | else if (eCount && (c === '-' || c === '+') ) signCount++; 26 | else if (c === '.') decimalCount++; 27 | else if (c === 'e') eCount++; 28 | else if (c < '0' || c > '9') return false; 29 | 30 | if (decimalCount > 1 || eCount > 1 || signCount > 1) return false; 31 | } 32 | 33 | return true; 34 | }; 35 | -------------------------------------------------------------------------------- /Javascript/066_plusOne.js: -------------------------------------------------------------------------------- 1 | var plusOne = function(digits) { 2 | 3 | let digitRev = digits.reverse(); 4 | digitRev[0]++; 5 | for (let i = 0; i < digitRev.length; i++) { 6 | if (digitRev[i] === 10) { 7 | digitRev[i] = 0; 8 | if ( i+1 === digitRev.length) { 9 | digitRev[i+1] = 1; 10 | } else{ 11 | digitRev[i + 1] += 1; 12 | } 13 | } else { 14 | break; 15 | } 16 | } 17 | return digitRev.reverse(); 18 | }; 19 | -------------------------------------------------------------------------------- /Javascript/067_addBinary.js: -------------------------------------------------------------------------------- 1 | var addBinary = function(a, b) { 2 | const sums = []; 3 | let i = a.length - 1; 4 | let j = b.length - 1; 5 | let carry = 0; 6 | 7 | while (i >= 0 || j >= 0 || carry) { 8 | const bitA = a[i] !== undefined ? +a[i] : 0; 9 | const bitB = b[j] !== undefined ? +b[j] : 0; 10 | const sum = bitA + bitB + carry; 11 | 12 | if (sum <= 1) { 13 | sums.unshift(sum); 14 | carry = 0; 15 | } 16 | else if (sum === 2) { 17 | sums.unshift(0); 18 | carry = 1; 19 | } 20 | else { 21 | sums.unshift(1); 22 | carry = 1; 23 | } 24 | i--; 25 | j--; 26 | } 27 | return sums.join('') 28 | }; 29 | -------------------------------------------------------------------------------- /Javascript/069_Sqrt(x).js: -------------------------------------------------------------------------------- 1 | 2 | //Utilizes binary search 3 | //Solution only valid for truncated result 4 | //Removing 'Math.floor' from line 13 will return inaccuate result for square root 5 | 6 | const mySqrt = number => { 7 | let lo = 0 8 | let hi = number; 9 | while (lo <= hi) { 10 | const mid = Math.floor((lo + hi) / 2); 11 | if (mid * mid > number) hi = mid - 1; 12 | else lo = mid + 1; 13 | } 14 | return Math.floor((lo + hi) / 2); 15 | } 16 | 17 | // The Babylonian Method 18 | // http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method 19 | // @param n - the number to compute the square root of 20 | // @param g - the best guess so far (can omit from initial call) 21 | // Removing 'Math.floor()' from line 34 fails these test specs (returns non truncated, but accurate, square root result) 22 | 23 | function mySqrt(n, g) { 24 | //edge cases 25 | if (!n || n === 1) return n 26 | if (!g) { 27 | // Take an initial guess at the square root 28 | g = n / 2; 29 | } 30 | var d = n / g; // Divide our guess into the number 31 | var ng = (d + g) / 2; // Use average of g and d as our new guess 32 | //base case 33 | if (g == ng) { 34 | // The new guess is the same as the old guess; further guesses 35 | // can get no more accurate so we return this guess 36 | return Math.floor(g); 37 | } 38 | // Recursively solve for closer and closer approximations of the square root 39 | return mySqrt(n, ng); 40 | } 41 | -------------------------------------------------------------------------------- /Javascript/070_climbingStairs.js: -------------------------------------------------------------------------------- 1 | var climbStairs = function(num, memo = {}) { 2 | 3 | if (num === 0) return 1; 4 | if (num < 0) return 0; 5 | if (memo[num]) return memo[num]; 6 | 7 | memo[num] = climbStairs(num - 1, memo) + climbStairs(num - 2, memo); 8 | 9 | return memo[num]; 10 | } 11 | -------------------------------------------------------------------------------- /Javascript/072_editDistance.js: -------------------------------------------------------------------------------- 1 | var minDistance = function(word1, word2) { 2 | if (word1.length < word2.length) { 3 | return editDistance(word1, word2); 4 | } 5 | return editDistance(word2, word1); 6 | }; 7 | 8 | function editDistance (word1, word2) { 9 | let topRow = new Array(word1.length + 1); 10 | 11 | for (let c = 0; c < topRow.length; c++) { 12 | topRow[c] = c; 13 | } 14 | 15 | let rowCount = 1; 16 | while (rowCount <= word2.length) { 17 | let bottomRow = new Array(word1.length + 1); 18 | bottomRow[0] = rowCount; 19 | for (let c = 1; c < bottomRow.length; c++) { 20 | if (word1[c-1] === word2[rowCount - 1]) { 21 | bottomRow[c] = topRow[c - 1]; 22 | } 23 | else { 24 | let minAdj = Math.min(bottomRow[c - 1], topRow[c], topRow[c - 1]); 25 | bottomRow[c] = minAdj + 1; 26 | } 27 | } 28 | topRow = bottomRow; 29 | rowCount++; 30 | } 31 | return topRow[topRow.length - 1]; 32 | } 33 | -------------------------------------------------------------------------------- /Javascript/073_setMatrixZeroes.js: -------------------------------------------------------------------------------- 1 | var setZeroes = function(matrix) { 2 | // Edge Case 3 | if (!matrix || matrix.length === 0) return; 4 | 5 | let rows = new Set(); 6 | let cols = new Set(); 7 | 8 | for (let r = 0; r < matrix.length; r++) { 9 | for (let c = 0; c < matrix[0].length; c++) { 10 | if (matrix[r][c] === 0) { 11 | rows.add(r); 12 | cols.add(c); 13 | } 14 | } 15 | } 16 | 17 | rows.forEach((row) => { 18 | for (let c = 0; c < matrix[0].length; c++) { 19 | matrix[row][c] = 0; 20 | } 21 | }) 22 | 23 | cols.forEach((col) => { 24 | for (let r = 0; r < matrix.length; r++) { 25 | matrix[r][col] = 0; 26 | } 27 | }) 28 | }; 29 | -------------------------------------------------------------------------------- /Javascript/078_subsets.js: -------------------------------------------------------------------------------- 1 | function subsets (nums, subsetsArr = [[]]) { 2 | // Base Case 3 | if (nums.length === 0) return subsetsArr; 4 | 5 | // Take element off nums 6 | const ele = nums.shift(); 7 | 8 | // Add it to every element in the subsetsArr 9 | let len = subsetsArr.length; 10 | 11 | for (let i = 0; i < len; i++) { 12 | const copy = subsetsArr[i].slice(); 13 | // add ele to copy 14 | copy.push(ele); 15 | subsetsArr.push(copy); 16 | } 17 | 18 | subsets(nums, subsetsArr); 19 | return subsetsArr; 20 | } 21 | -------------------------------------------------------------------------------- /Javascript/079_wordSearch.js: -------------------------------------------------------------------------------- 1 | function exist (grid, word) { 2 | // Edge Case 3 | if (!grid || !grid.length) return false; 4 | for (let row = 0; row < grid.length; row++) { 5 | for (let col = 0; col < grid[0].length; col++) { 6 | if (wordSearchDFS(grid, word, row, col, 0)) return true; 7 | } 8 | } 9 | return false; 10 | } 11 | 12 | function wordSearchDFS (grid, word, row, col, wordIdx) { 13 | 14 | const curLetter = grid[row][col]; 15 | // Check for fail 16 | if (curLetter !== word[wordIdx]) return false; 17 | // Check for success 18 | if (wordIdx === word.length - 1 && curLetter === word[wordIdx]) return true; 19 | 20 | // Mark visited for current DFS search 21 | grid[row][col] = "#"; 22 | // DFS 23 | // Top 24 | if (isValid(row - 1, col, grid) && wordSearchDFS(grid, word, row - 1, col, wordIdx + 1)) return true; 25 | // Right 26 | if (isValid(row, col + 1, grid) && wordSearchDFS(grid, word, row, col + 1, wordIdx + 1)) return true; 27 | // Bottom 28 | if (isValid(row + 1, col, grid) && wordSearchDFS(grid, word, row + 1, col, wordIdx + 1)) return true; 29 | // Left 30 | if (isValid(row, col - 1, grid) && wordSearchDFS(grid, word, row, col - 1, wordIdx + 1)) return true; 31 | 32 | // Change back to allow visit 33 | grid[row][col] = curLetter; 34 | return false; 35 | } 36 | 37 | function isValid(row, col, grid) { 38 | // Check to make sure in bounds 39 | if (row < 0 || row >= grid.length || col < 0 || col >= grid[0].length) return false; 40 | return true; 41 | } 42 | -------------------------------------------------------------------------------- /Javascript/083_removeDuplicatesFromSortedList.js: -------------------------------------------------------------------------------- 1 | var deleteDuplicates = function(head) { 2 | if (head === null) return null; 3 | const visited = new Set(); 4 | let ptr = head; 5 | 6 | while (ptr.next !== null) { 7 | visited.add(ptr.val) 8 | if (visited.has(ptr.next.val)) { 9 | ptr.next = ptr.next.next; 10 | } 11 | else { 12 | ptr = ptr.next; 13 | } 14 | } 15 | return head; 16 | }; 17 | -------------------------------------------------------------------------------- /Javascript/088_mergeSortedArray.js: -------------------------------------------------------------------------------- 1 | var merge = function(nums1, m, nums2, n) { 2 | let i = m - 1; 3 | let j = n - 1; 4 | let p = nums1.length -1; 5 | 6 | while (i >= 0 || j >= 0) { 7 | const num1 = i >= 0 ? nums1[i] : -Infinity; 8 | const num2 = j >= 0 ? nums2[j] : -Infinity; 9 | 10 | if (num1 >= num2) { 11 | nums1[p] = nums1[i]; 12 | i--; 13 | } 14 | else { 15 | nums1[p] = nums2[j]; 16 | j--; 17 | } 18 | p--; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /Javascript/091_decodeWays.js: -------------------------------------------------------------------------------- 1 | var numDecodings = function(str) { 2 | // Edge Case 3 | if (str.length === 0) return 0; 4 | // Initialze array for dynamic programming 5 | const dp = new Array(str.length + 1).fill(0); 6 | 7 | // Set initial conditions 8 | dp[0] = 1; 9 | if (+str[0]) dp[1] = 1; 10 | 11 | for (let i = 1; i < str.length; i++) { 12 | const num1 = +str[i]; 13 | const num2 = +str.slice(i-1, i+1); 14 | 15 | if (num1) { 16 | dp[i+1] += dp[i]; 17 | } 18 | 19 | if (num2 >= 10 && num2 <= 26) { 20 | dp[i+1] += dp[i-1]; 21 | } 22 | } 23 | return dp[str.length]; 24 | 25 | }; 26 | -------------------------------------------------------------------------------- /Javascript/094_binaryTreeInorderTraversal.js: -------------------------------------------------------------------------------- 1 | var inorderTraversal = function(treeRoot) { 2 | // Edge Case 3 | if (!treeRoot) return []; 4 | 5 | const stack = []; 6 | const inorderArr = []; 7 | 8 | while (stack.length || treeRoot) { 9 | // Go Left 10 | if (treeRoot) { 11 | stack.push(treeRoot); 12 | treeRoot = treeRoot.left; 13 | continue; 14 | } 15 | 16 | // Visit 17 | const curNode = stack.pop(); 18 | inorderArr.push(curNode.val); 19 | 20 | // Go right 21 | treeRoot = curNode.right; 22 | } 23 | 24 | return inorderArr; 25 | }; 26 | -------------------------------------------------------------------------------- /Javascript/097_interleavingString.js: -------------------------------------------------------------------------------- 1 | var isInterleave = function(s1, s2, s3, memo = {}) { 2 | if (s1.length + s2.length !== s3.length) return false; 3 | let str = s1 + ',' + s2 + ',' + s3; 4 | 5 | if (str in memo) return memo[str]; 6 | 7 | let p1 = 0 8 | let p2 = 0 9 | let p3 = 0; 10 | 11 | while (p1 < s1.length || p2 < s2.length) { 12 | const l1 = s1[p1] ? s1[p1] : null; 13 | const l2 = s2[p2] ? s2[p2] : null; 14 | const l3 = s3[p3]; 15 | 16 | if (l1 === l2 && l2 === l3) { 17 | let res = isInterleave(s1.slice(p1 + 1), s2.slice(p2), s3.slice(p3 + 1), memo) || isInterleave(s1.slice(p1), s2.slice(p2 + 1), s3.slice(p3 + 1), memo); 18 | memo[str] = res; 19 | return res; 20 | } 21 | else if (l1 === l3) { 22 | p1++; 23 | p3++; 24 | } 25 | else if (l2 === l3) { 26 | p2++; 27 | p3++; 28 | } 29 | else { 30 | memo[str] = false; 31 | return false; 32 | } 33 | } 34 | memo[str] = true; 35 | return true; 36 | }; 37 | -------------------------------------------------------------------------------- /Javascript/098_validateBinarySearchTree.js: -------------------------------------------------------------------------------- 1 | function isValidBST(tree, minVal = -Infinity, maxVal = Infinity) { 2 | // Base Case 3 | if (!tree) return true; 4 | 5 | // Check if current node is valid 6 | if (tree.val <= minVal || tree.val >= maxVal) return false; 7 | 8 | let isLeftValid = isValidBST(tree.left, minVal, tree.val); 9 | let isRightValid = isValidBST(tree.right, tree.val, maxVal); 10 | return isLeftValid && isRightValid; 11 | } 12 | -------------------------------------------------------------------------------- /Javascript/100_sameTree.js: -------------------------------------------------------------------------------- 1 | var isSameTree = function(p, q) { 2 | if (!p && q || p && !q) return false; 3 | else if (!p && !q) return true; 4 | 5 | if (p.val !== q.val) return false; 6 | 7 | return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); 8 | }; 9 | -------------------------------------------------------------------------------- /Javascript/101_symmetricTree.js: -------------------------------------------------------------------------------- 1 | var isSymmetric = function(root) { 2 | // Edge Case 3 | if (!root) return true; 4 | 5 | return symmetricDFS(root.left, root.right); 6 | }; 7 | 8 | function symmetricDFS(leftNode, rightNode) { 9 | 10 | // Base Cases 11 | if (!leftNode && !rightNode) return true; 12 | else if (!leftNode || !rightNode) return false; 13 | else if (leftNode.val !== rightNode.val) return false; 14 | 15 | // Go left for left, and right for right 16 | if (!symmetricDFS(leftNode.left, rightNode.right)) return false; 17 | 18 | // Go right for left, and left for right 19 | if (!symmetricDFS(leftNode.right, rightNode.left)) return false; 20 | 21 | // If subtrees are symmetric then return true 22 | return true; 23 | } 24 | -------------------------------------------------------------------------------- /Javascript/102_binaryTreeLevelOrderTraversal.js: -------------------------------------------------------------------------------- 1 | var levelOrder = function(root) { 2 | // Edge Case 3 | if (!root) return []; 4 | 5 | const queue = [root]; 6 | const sol = []; 7 | 8 | let lC = 1; 9 | 10 | while (queue.length) { 11 | let curLevel = []; 12 | let nLC = 0; 13 | 14 | while (lC--) { 15 | const curNode = queue.shift(); 16 | 17 | // Check left 18 | if (curNode.left) { 19 | queue.push(curNode.left); 20 | nLC++; 21 | } 22 | 23 | // Check right 24 | if (curNode.right) { 25 | queue.push(curNode.right); 26 | nLC++; 27 | } 28 | 29 | curLevel.push(curNode.val); 30 | } 31 | 32 | sol.push(curLevel); 33 | lC = nLC; 34 | } 35 | 36 | return sol; 37 | }; 38 | -------------------------------------------------------------------------------- /Javascript/103_binaryTreeZigzagLevelOrderTraversal.js: -------------------------------------------------------------------------------- 1 | var zigzagLevelOrder = function(root) { 2 | // Edge Case 3 | if (!root) return [] 4 | 5 | const queue = [root] 6 | const sol = []; 7 | let levelCount = 1; 8 | let leftToRight = true; 9 | 10 | while (queue.length) { 11 | let nextLevelCount = 0; 12 | let level = []; 13 | 14 | while (levelCount--) { 15 | const node = queue.shift(); 16 | 17 | if (node.left) { 18 | queue.push(node.left); 19 | nextLevelCount++; 20 | } 21 | 22 | if (node.right) { 23 | queue.push(node.right); 24 | nextLevelCount++; 25 | } 26 | 27 | if (leftToRight) level.push(node.val); 28 | else level.unshift(node.val); 29 | 30 | } 31 | 32 | leftToRight = !leftToRight; 33 | levelCount = nextLevelCount; 34 | sol.push(level); 35 | } 36 | 37 | return sol; 38 | }; 39 | -------------------------------------------------------------------------------- /Javascript/104_maximumDepthOfBT.js: -------------------------------------------------------------------------------- 1 | var maxDepth = function(root, length = 0) { 2 | if (root === null) return length; 3 | 4 | return Math.max(maxDepth(root.left, length + 1), maxDepth(root.right, length + 1)); 5 | }; 6 | -------------------------------------------------------------------------------- /Javascript/107_binaryTreeLevelOrderTraversalII.js: -------------------------------------------------------------------------------- 1 | var levelOrderBottom = function(root) { 2 | 3 | // Edge Case 4 | if (!root) return []; 5 | 6 | const queue = [root]; 7 | const sols = []; 8 | 9 | let levelCount = 1; 10 | 11 | while (queue.length) { 12 | let nextLevelCount = 0; 13 | const curLevel = []; 14 | 15 | while (levelCount) { 16 | levelCount--; 17 | const node = queue.shift(); 18 | 19 | // Check left 20 | if (node.left) { 21 | queue.push(node.left); 22 | nextLevelCount++; 23 | } 24 | 25 | // Check right 26 | if (node.right) { 27 | queue.push(node.right); 28 | nextLevelCount++; 29 | } 30 | 31 | curLevel.push(node.val); 32 | } 33 | 34 | levelCount = nextLevelCount; 35 | sols.unshift(curLevel); 36 | } 37 | 38 | return sols; 39 | 40 | }; 41 | -------------------------------------------------------------------------------- /Javascript/110_balancedBinaryTree.js: -------------------------------------------------------------------------------- 1 | var isBalanced = function(root) { 2 | if (!root) return true 3 | const left = getMaxHeight(root.left) 4 | const right = getMaxHeight(root.right) 5 | if (Math.abs(left - right) > 1) return false 6 | return isBalanced(root.left) && isBalanced(root.right) 7 | } 8 | 9 | function getMaxHeight(root) { 10 | if (!root) return 0 11 | const left = getMaxHeight(root.left) 12 | const right = getMaxHeight(root.right) 13 | return 1 + Math.max(left, right) 14 | }; -------------------------------------------------------------------------------- /Javascript/116_populatingNextRightPointerInEachNode.js: -------------------------------------------------------------------------------- 1 | var connect = function(root) { 2 | // Edge Case 3 | if (!root) return; 4 | 5 | let levelStart = root; 6 | 7 | while (levelStart.left) { 8 | let ptr = levelStart; 9 | while(ptr) { 10 | ptr.left.next = ptr.right; 11 | if (ptr.next) ptr.right.next = ptr.next.left; 12 | ptr = ptr.next; 13 | } 14 | levelStart = levelStart.left; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /Javascript/117_populatingNextRightPointersInEachNodeII.js: -------------------------------------------------------------------------------- 1 | var connect = function(root) { 2 | // Edge Case 3 | if (!root) return; 4 | 5 | let levelStart = root; 6 | 7 | while (levelStart) { 8 | let ptr = levelStart; 9 | 10 | while (ptr) { 11 | // Check left 12 | if (ptr.left) { 13 | if (ptr.right) { 14 | ptr.left.next = ptr.right; 15 | } 16 | else { 17 | ptr = linkNextNode(ptr.next, ptr.left); 18 | continue; 19 | } 20 | } 21 | // Check right 22 | if (ptr.right) { 23 | ptr = linkNextNode(ptr.next, ptr.right); 24 | continue; 25 | } 26 | ptr = ptr.next; 27 | } 28 | levelStart = getNextLevelStart(levelStart); 29 | } 30 | }; 31 | 32 | function getNextLevelStart (ptr) { 33 | // Edge Case 34 | if (!ptr) return null; 35 | 36 | while (ptr) { 37 | if (ptr.left) return ptr.left; 38 | else if (ptr.right) return ptr.right; 39 | ptr = ptr.next; 40 | } 41 | return null; 42 | } 43 | 44 | function linkNextNode(ptr, nodeToLink) { 45 | // Edge Case 46 | if (!ptr) return null; 47 | 48 | while (ptr) { 49 | if (ptr.left) { 50 | nodeToLink.next = ptr.left; 51 | return ptr; 52 | } 53 | else if (ptr.right) { 54 | nodeToLink.next = ptr.right; 55 | return ptr; 56 | } 57 | ptr = ptr.next; 58 | } 59 | return null; 60 | } 61 | -------------------------------------------------------------------------------- /Javascript/120_triangle.js: -------------------------------------------------------------------------------- 1 | var minimumTotal = function(tri) { 2 | let startRow = tri.length - 2; 3 | 4 | for (let row = startRow; row >= 0; row--) { 5 | for (let col = 0; col < tri[row].length; col++) { 6 | // Figure out which child is smaller 7 | let minChild = Math.min(tri[row + 1][col], tri[row+ 1][col + 1]); 8 | tri[row][col] += minChild; 9 | } 10 | } 11 | // Return the root 12 | return tri[0][0]; 13 | }; 14 | -------------------------------------------------------------------------------- /Javascript/121_bestTimeToBuyAndSellStock.js: -------------------------------------------------------------------------------- 1 | var maxProfit = function(prices) { 2 | // Initialize min price to the first price 3 | let min = prices[0]; 4 | 5 | // Initialzie max profit to 0 6 | let maxP = 0; 7 | 8 | for (let i = 1; i < prices.length; i++) { 9 | const price = prices[i]; 10 | 11 | min = Math.min(min, price); 12 | maxP = Math.max(maxP, price - min); 13 | } 14 | 15 | return maxP; 16 | }; 17 | -------------------------------------------------------------------------------- /Javascript/122_bestTimeToBuyAndSellStockII.js: -------------------------------------------------------------------------------- 1 | var maxProfit = function(prices) { 2 | let maxprofit = 0; 3 | for (let i = 1; i < prices.length; i++) { 4 | if (prices[i] > prices[i - 1]) 5 | maxprofit += prices[i] - prices[i - 1]; 6 | } 7 | return maxprofit; 8 | }; 9 | -------------------------------------------------------------------------------- /Javascript/125_validPalindrome.js: -------------------------------------------------------------------------------- 1 | var isPalindrome = function(s) { 2 | let i = 0, j = s.length - 1; 3 | 4 | while (i <= j) { 5 | // Move i and j until both on valid letters 6 | if (!isLetter(s[i])) { 7 | i++; 8 | continue; 9 | } 10 | if(!isLetter(s[j])) { 11 | j--; 12 | continue; 13 | } 14 | // check if they satisfy a palindrome 15 | if (s[i].toLowerCase() !== s[j].toLowerCase()) { 16 | return false; 17 | } 18 | else { 19 | i++; 20 | j--; 21 | } 22 | } 23 | return true; 24 | }; 25 | 26 | function isLetter(str) { 27 | return str.length === 1 && str.match(/[a-z]/i) || (str >= '0' && str <= '9'); 28 | } 29 | -------------------------------------------------------------------------------- /Javascript/127_wordLadder.js: -------------------------------------------------------------------------------- 1 | var ladderLength = function(beginWord, endWord, wordList) { 2 | const wordSet = new Set(wordList); 3 | const queue = [beginWord]; 4 | let count = 1; 5 | let levelCount = 1 6 | 7 | 8 | while (queue.length) { 9 | 10 | let nextLevelCount = 0; 11 | 12 | while (levelCount) { 13 | levelCount--; 14 | let curWord = queue.shift(); 15 | for (let word of wordSet.values()) { 16 | if (isTransformation(curWord, word)) { 17 | if (word === endWord) return count + 1; 18 | queue.push(word); 19 | wordSet.delete(word); 20 | nextLevelCount++; 21 | } 22 | } 23 | } 24 | count++; 25 | levelCount = nextLevelCount; 26 | } 27 | 28 | return 0; 29 | 30 | }; 31 | 32 | function isTransformation (word1, word2) { 33 | if (word1.length !== word2.length || word1 === word2) return false; 34 | let count = 0; 35 | 36 | for (let i = 0; i < word1.length; i++) { 37 | if (word1[i] !== word2[i]) count++; 38 | if (count > 1) return false; 39 | } 40 | 41 | return true; 42 | } 43 | -------------------------------------------------------------------------------- /Javascript/128_longestConsecutiveSequence.js: -------------------------------------------------------------------------------- 1 | var longestConsecutive = function(array) { 2 | if (array.length === 0) return 0; 3 | 4 | const hMap = {}; 5 | 6 | for (let i = 0; i < array.length; i++) { 7 | hMap[array[i]] = false; 8 | } 9 | 10 | let count = 0; 11 | 12 | for (let i = 0; i < array.length; i++) { 13 | if (hMap[array[i]] === false) { 14 | hMap[array[i]] = true; 15 | let hi = array[i] + 1; 16 | let lo = array[i] - 1; 17 | 18 | while (hMap[lo] === false) { 19 | hMap[lo] = true; 20 | lo--; 21 | } 22 | while (hMap[hi] === false) { 23 | hMap[hi] = true; 24 | hi++; 25 | } 26 | 27 | if ((hi - 1) - (lo + 1) >= count) { 28 | count = (hi - 1) - (lo + 1); 29 | } 30 | } 31 | } 32 | return count + 1; 33 | }; 34 | -------------------------------------------------------------------------------- /Javascript/129_sumRootToLeafNumbers.js: -------------------------------------------------------------------------------- 1 | var sumNumbers = function(root) { 2 | 3 | const pathSums = [0]; 4 | sumNumbersHelper(root, pathSums); 5 | return pathSums[0]; 6 | }; 7 | 8 | function sumNumbersHelper(root, pathSums, curSum = 0) { 9 | // Edge case 10 | if (!root) return; 11 | 12 | // Update sum 13 | let newSum = curSum * 10 + root.val; 14 | 15 | // if we hit a leaf node 16 | if (!root.left && !root.right) { 17 | pathSums[0] += newSum; 18 | return; 19 | } 20 | 21 | // Go left 22 | sumNumbersHelper(root.left, pathSums, newSum); 23 | 24 | // Go right 25 | sumNumbersHelper(root.right, pathSums, newSum); 26 | } 27 | -------------------------------------------------------------------------------- /Javascript/133_cloneGraph.js: -------------------------------------------------------------------------------- 1 | function cloneGraph (gNode, map = new Map()) { 2 | // Edge Case 3 | if (!gNode) return gNode; 4 | 5 | const cNode = new UndirectedGraphNode(gNode.label); 6 | map.set(gNode, cNode); 7 | 8 | for (let adjNode of gNode.neighbors) { 9 | if (!map.has(adjNode)) { 10 | cloneGraph(adjNode, map); 11 | } 12 | } 13 | 14 | for (let adjNode of gNode.neighbors) { 15 | cNode.neighbors.push(map.get(adjNode)); 16 | } 17 | return cNode; 18 | } 19 | -------------------------------------------------------------------------------- /Javascript/136_singleNumber.js: -------------------------------------------------------------------------------- 1 | /* 2 | Given an array of integers, every element appears twice except for one. Find that single one. 3 | 4 | Note: 5 | Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 6 | 7 | 8 | ** First Solution ** 9 | Time: O(n) 10 | Space: O(n) 11 | 12 | We use an object to keep track of what numbers we've seen and then at the end iterate over the object to see what number was only seen once. 13 | */ 14 | 15 | const singleNumber = (nums) => { 16 | const numsSeen = {}; 17 | for(let i = 0; i < nums.length; i++){ 18 | const currentNum = nums[i]; 19 | if(!numsSeen[currentNum]){ 20 | numsSeen[currentNum] = 1; 21 | } else { 22 | numsSeen[currentNum]++; 23 | } 24 | } 25 | 26 | for (let key in numsSeen){ 27 | if(numsSeen[key] === 1) 28 | return +key; 29 | } 30 | } 31 | 32 | 33 | 34 | /* 35 | 36 | ** Second Solution ** 37 | 38 | Time: O(n) 39 | Space: O(1) 40 | 41 | Here we make use of XOR. Why XOR? because this allows doubles to cancel out. 42 | When you XOR a number by itself it become 0. 43 | 4 ^ 3 ^ 3 ^ 4 = (4^4) ^ (3^3) = (0) ^ (0) = 0 44 | 45 | Now consider these numbers: [1, 8, 9, 7, 1, 9, 7] 46 | If we XOR them we get: 47 | 1 ^ 8 ^ 9 ^ 7 ^ 1 ^ 9 ^ 7 = (1 ^ 1) ^ (9 ^ 9) ^ (7 ^ 7) ^ 8 = (0) ^ (0) ^ (0) ^ 8 = 9 48 | 49 | 8 is the non repeated number 50 | 51 | */ 52 | 53 | const singleNumber = (nums) => { 54 | let result = 0; 55 | for(let i = 0; i <= nums.length; i++){ 56 | const currentNum = nums[i]; 57 | result = result ^ currentNum; 58 | } 59 | return result; 60 | } -------------------------------------------------------------------------------- /Javascript/137_singleNumberII.js: -------------------------------------------------------------------------------- 1 | /* 2 | **First Solution** 3 | Time: O(n) 4 | Space: O(n) 5 | 6 | */ 7 | 8 | const singleNumber = (nums) => { 9 | const numsSeen = {}; 10 | for(let i = 0; i < nums.length; i++){ 11 | const currentNum = nums[i]; 12 | if(!numsSeen[currentNum]){ 13 | numsSeen[currentNum] = 1; 14 | } else { 15 | numsSeen[currentNum]++; 16 | } 17 | } 18 | for(let key in numsSeen){ 19 | if(numsSeen[key] == 1) 20 | return key; 21 | } 22 | }; 23 | 24 | 25 | 26 | 27 | /* 28 | **Second Solution** 29 | Time: O(n) 30 | Space: O(1) 31 | 32 | */ 33 | 34 | const singleNumber = (nums) => { 35 | let one = 0; 36 | let two = 0; 37 | for(let i = 0; i < nums.length; i++){ 38 | const currentNum = nums[i]; 39 | const new_one = (~currentNum & one) | (currentNum & ~one & ~two) 40 | const new_two = (~currentNum & two) | (currentNum & one); 41 | one = new_one; 42 | two = new_two; 43 | } 44 | 45 | return one 46 | }; -------------------------------------------------------------------------------- /Javascript/138_copyListWithRandomPointer.js: -------------------------------------------------------------------------------- 1 | var copyRandomList = function(head) { 2 | // Edge Case 3 | if (!head) return head; 4 | 5 | const hMap = new Map(); 6 | let newHead = new RandomListNode(head.label); 7 | hMap.set(head, newHead); 8 | 9 | let ptr = head.next; 10 | let ptrCopy = newHead; 11 | 12 | while (ptr) { 13 | ptrCopy.next = new RandomListNode(ptr.label); 14 | ptrCopy = ptrCopy.next; 15 | // Store key value matching of nodes 16 | hMap.set(ptr, ptrCopy); 17 | ptr = ptr.next; 18 | } 19 | // Move pointers back to start 20 | ptr = head; 21 | ptrCopy = newHead; 22 | 23 | while (ptr) { 24 | if (ptr.random === null) { 25 | ptrCopy.random = null; 26 | } 27 | else { 28 | ptrCopy.random = hMap.get(ptr.random); 29 | } 30 | ptr = ptr.next; 31 | ptrCopy = ptrCopy.next; 32 | } 33 | 34 | return newHead; 35 | }; 36 | -------------------------------------------------------------------------------- /Javascript/139_wordBreak.js: -------------------------------------------------------------------------------- 1 | function wordBreak(word, dict) { 2 | return wordBreakH(word, new Set(dict)); 3 | } 4 | 5 | const wordBreakH = (word, set, memo = {}) => { 6 | if(word.length === 0) return true; 7 | if(memo[word] !== undefined) return memo[word]; 8 | 9 | for(let i = 1; i <= word.length; i++){ // 10 | let head = word.slice(0,i) 11 | 12 | if(set.has(head)){ 13 | if(wordBreakH(word.slice(i),set, memo)){ 14 | memo[head] = true 15 | return true 16 | } 17 | } 18 | } 19 | 20 | memo[word] = false 21 | return false 22 | } 23 | -------------------------------------------------------------------------------- /Javascript/140_wordBreakII.js: -------------------------------------------------------------------------------- 1 | function wordBreak (s, dict) { 2 | const dictSet = new Set(dict); 3 | return wordSplitH(s, dictSet); 4 | } 5 | 6 | function wordSplitH (s, dictS, memo = {}) { 7 | if (s.length === 0) { 8 | return [""]; 9 | } 10 | if (s in memo) return memo[s]; 11 | 12 | const sols = []; 13 | 14 | for (let i = 1; i <= s.length; i++) { 15 | const sub = s.slice(0, i); 16 | 17 | if (dictS.has(sub)) { 18 | const remaining = wordSplitH(s.slice(i), dictS, memo); 19 | for (let str of remaining) { 20 | if (str === "") sols.push(sub); 21 | else sols.push(sub + " " + str); 22 | } 23 | } 24 | } 25 | memo[s] = sols; 26 | return sols; 27 | } 28 | -------------------------------------------------------------------------------- /Javascript/141_linkedListCycle.js: -------------------------------------------------------------------------------- 1 | var hasCycle = function(head) { 2 | let leadPtr = head; 3 | let trailPtr = head; 4 | 5 | while (leadPtr !== null && leadPtr.next !== null) { 6 | leadPtr = leadPtr.next.next; 7 | trailPtr = trailPtr.next; 8 | 9 | if (leadPtr === trailPtr) { 10 | return true; 11 | } 12 | } 13 | return false; 14 | }; 15 | -------------------------------------------------------------------------------- /Javascript/142_linkedListCycleII.js: -------------------------------------------------------------------------------- 1 | var detectCycle = function(head) { 2 | 3 | let hSet = new Set(); 4 | 5 | if (hasCycle(head)) { 6 | let ptr = head; 7 | 8 | while(!hSet.has(ptr)) { 9 | hSet.add(ptr); 10 | ptr = ptr.next; 11 | } 12 | return ptr; 13 | } 14 | 15 | return null; 16 | }; 17 | 18 | function hasCycle (head) { 19 | let leadPtr = head; 20 | let trailPtr = head; 21 | 22 | while (leadPtr !== null && leadPtr.next !== null) { 23 | leadPtr = leadPtr.next.next; 24 | trailPtr = trailPtr.next; 25 | 26 | if (leadPtr === trailPtr) { 27 | return true; 28 | } 29 | } 30 | return false; 31 | } 32 | -------------------------------------------------------------------------------- /Javascript/146_lruCache.js: -------------------------------------------------------------------------------- 1 | class LRUCache { 2 | constructor(maxSize) { 3 | this.maxSize = maxSize; 4 | this.map = new Map(); 5 | this.size = 0; 6 | this.head = null; 7 | this.tail = null; 8 | } 9 | get (key) { 10 | if (this.map.has(key)) { 11 | const node = this.map.get(key); 12 | this.update(node); 13 | return node.val; 14 | } 15 | return -1; 16 | } 17 | put (key, val) { 18 | if (this.map.has(key)) { 19 | const node = this.map.get(key); 20 | node.val = val; 21 | this.update(node); 22 | } 23 | else if (this.size === this.maxSize) { 24 | const evicted = this.removeFromTail(); 25 | this.map.delete(evicted.key); 26 | const newNode = new LLN(key, val); 27 | this.map.set(key, newNode); 28 | this.addToHead(newNode); 29 | } 30 | else { 31 | const newNode = new LLN(key, val); 32 | this.map.set(key, newNode); 33 | this.addToHead(newNode); 34 | this.size++; 35 | } 36 | } 37 | update (node) { 38 | if (this.head === node) return; 39 | if (this.tail === node) { 40 | this.removeFromTail(); 41 | this.addToHead(node); 42 | return; 43 | } 44 | const prevNode = node.prev; 45 | const nextNode = node.next; 46 | prevNode.next = nextNode; 47 | nextNode.prev = prevNode; 48 | node.next = null; 49 | node.prev = null; 50 | this.addToHead(node); 51 | } 52 | removeFromTail () { 53 | const oldTail = this.tail; 54 | this.tail = this.tail.prev; 55 | if (this.tail) this.tail.next = null; 56 | oldTail.prev = null; 57 | return oldTail; 58 | } 59 | addToHead(node) { 60 | if (this.size === 0) { 61 | this.head = node; 62 | this.tail = node; 63 | return; 64 | } 65 | node.next = this.head; 66 | this.head.prev = node; 67 | this.head = node; 68 | } 69 | } 70 | 71 | function LLN (key, val) { 72 | this.key = key; 73 | this.val = val; 74 | this.next = null; 75 | this.prev = null; 76 | } 77 | -------------------------------------------------------------------------------- /Javascript/147_insertionSortList.js: -------------------------------------------------------------------------------- 1 | var insertionSortList = function(head) { 2 | // Edge Case 3 | if (!head) return null; 4 | 5 | let sortedHead = head; 6 | let ptr = head.next; 7 | sortedHead.next = null 8 | 9 | while (ptr) { 10 | let nextPtr = ptr.next; 11 | if (ptr.val < sortedHead.val) { 12 | ptr.next = sortedHead; 13 | sortedHead = ptr; 14 | ptr = nextPtr; 15 | continue; 16 | } 17 | 18 | let ptrS = sortedHead; 19 | while (ptrS.next && ptrS.next.val < ptr.val) { 20 | ptrS = ptrS.next; 21 | } 22 | 23 | ptr.next = ptrS.next; 24 | ptrS.next = ptr; 25 | ptr = nextPtr; 26 | } 27 | 28 | return sortedHead; 29 | }; 30 | -------------------------------------------------------------------------------- /Javascript/148_sortList.js: -------------------------------------------------------------------------------- 1 | function sortList (head) { 2 | if (!head || !head.next) return head; 3 | 4 | let prev = null; 5 | let trail = head; 6 | let lead = head; 7 | 8 | while (lead && lead.next) { 9 | lead = lead.next.next; 10 | prev = trail; 11 | trail = trail.next; 12 | } 13 | // Detach linked lists 14 | prev.next = null; 15 | 16 | head = sortList (head); 17 | trail = sortList (trail); 18 | 19 | return mergeTwoLists(head, trail); 20 | } 21 | 22 | function mergeTwoLists (l1, l2) { 23 | // Check for edge cases 24 | if (!l1 && !l2) return null; 25 | else if (l1 && !l2) return l1; 26 | else if (!l1 && l2) return l2; 27 | 28 | let lead1 = l1; 29 | let trail1 = null; 30 | let lead2 = l2; 31 | let trail2 = null; 32 | 33 | while (lead1 !== null && lead2 !== null) { 34 | if (lead1.val < lead2.val) { 35 | trail1 = lead1; 36 | lead1 = lead1.next; 37 | 38 | if (lead1 === null || lead1.val >= lead2.val) { 39 | trail1.next = lead2; 40 | } 41 | } 42 | else { 43 | trail2 = lead2; 44 | lead2 = lead2.next; 45 | 46 | if (lead2 === null || lead2.val > lead1.val) { 47 | trail2.next = lead1; 48 | } 49 | } 50 | } 51 | 52 | if (l1.val < l2.val) return l1; 53 | return l2; 54 | } 55 | -------------------------------------------------------------------------------- /Javascript/149_maxPointsOnALine.js: -------------------------------------------------------------------------------- 1 | function maxPoints(points) { 2 | if (!points) return 0; 3 | if (points.length <= 2) return points.length; 4 | 5 | const map = new Map(); 6 | let res = 0; 7 | 8 | for (let i = 0; i < points.length; i++) { 9 | map.clear(); 10 | let overlap = 0; 11 | let max = 0; 12 | 13 | for (let j = i + 1; j < points.length; j++) { 14 | let x = points[j].x - points[i].x; 15 | let y = points[j].y - points[i].y; 16 | 17 | if (!x && !y) { 18 | overlap++; 19 | continue; 20 | } 21 | const gcdVal = gcd(x,y); 22 | x /= gcdVal; 23 | y /= gcdVal; 24 | 25 | const key = x + ',' + y; 26 | 27 | if (map.has(key)) { 28 | map.set(key, map.get(key) + 1); 29 | } 30 | else { 31 | map.set(key, 1); 32 | } 33 | 34 | max = Math.max(max, map.get(key)); 35 | } 36 | res = Math.max(res, max + overlap + 1); 37 | } 38 | 39 | return res; 40 | } 41 | 42 | function gcd(y,x){ 43 | 44 | if (x === 0) return y; 45 | return gcd(x, y % x); 46 | } 47 | -------------------------------------------------------------------------------- /Javascript/150_evaluteaRPN.js: -------------------------------------------------------------------------------- 1 | var evalRPN = function(tokens) { 2 | // Edge Case 3 | if (!tokens || !tokens.length) return 0; 4 | 5 | let stack = [+tokens[0]]; 6 | 7 | for (let i = 1; i < tokens.length; i++) { 8 | const token = tokens[i]; 9 | if (isOperator(token)) { 10 | let operand2 = +stack.pop(); 11 | let operand1 = +stack.pop(); 12 | 13 | if (token === '*') stack.push(operand1 * operand2); 14 | else if (token === '/') { 15 | const val = operand1 / operand2; 16 | if (val < 0) stack.push(Math.ceil(val)); 17 | else stack.push(Math.floor(val)); 18 | } 19 | else if (token === '+') stack.push(operand1 + operand2); 20 | else stack.push(operand1 - operand2); 21 | } 22 | else stack.push(+token) 23 | } 24 | return stack[0]; 25 | }; 26 | 27 | function isOperator(char) { 28 | return char === '*' || char === '/' || char === '+' || char === '-'; 29 | } 30 | -------------------------------------------------------------------------------- /Javascript/151_reverseWordsInAString.js: -------------------------------------------------------------------------------- 1 | var reverseWords = function(str) { 2 | 3 | const wordsArr = str.split(' ').reverse(); 4 | const wordsOnly = []; 5 | 6 | for (let i = wordsArr.length - 1; i >= 0; i--) { 7 | if (wordsArr[i] !== '') wordsOnly.push(wordsArr[i]); 8 | } 9 | 10 | return wordsOnly.reverse().join(' '); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /Javascript/152_maximumProductSubarray.js: -------------------------------------------------------------------------------- 1 | var maxProduct = function(nums) { 2 | let curMaxProduct = nums[0]; 3 | let curMinProduct = nums[0]; 4 | let maxProduct = nums[0]; 5 | 6 | for (let i = 1; i < nums.length; i++) { 7 | const prevMax = curMaxProduct; 8 | const prevMin = curMinProduct; 9 | 10 | curMaxProduct = Math.max(curMaxProduct * nums[i], prevMin * nums[i], nums[i]); 11 | curMinProduct = Math.min(curMinProduct * nums[i], prevMax * nums[i], nums[i]); 12 | maxProduct = Math.max(maxProduct, curMaxProduct); 13 | } 14 | 15 | return maxProduct; 16 | }; 17 | -------------------------------------------------------------------------------- /Javascript/155_minStack.js: -------------------------------------------------------------------------------- 1 | var MinStack = function() { 2 | this.stack = []; 3 | this.minStack = []; 4 | }; 5 | 6 | /** 7 | * @param {number} x 8 | * @return {void} 9 | */ 10 | MinStack.prototype.push = function(val) { 11 | if (this.minStack.length === 0) this.minStack.push(val); 12 | else if (this.minStack[this.minStack.length - 1] >= val) this.minStack.push(val); 13 | this.stack.push(val); 14 | }; 15 | 16 | /** 17 | * @return {void} 18 | */ 19 | MinStack.prototype.pop = function() { 20 | let val = this.stack.pop(); 21 | 22 | if (val === this.minStack[this.minStack.length - 1]) { 23 | this.minStack.pop(); 24 | } 25 | return val; 26 | }; 27 | 28 | /** 29 | * @return {number} 30 | */ 31 | MinStack.prototype.top = function() { 32 | return this.stack[this.stack.length - 1]; 33 | }; 34 | 35 | /** 36 | * @return {number} 37 | */ 38 | MinStack.prototype.getMin = function() { 39 | return this.minStack[this.minStack.length - 1]; 40 | }; 41 | 42 | /** 43 | * Your MinStack object will be instantiated and called as such: 44 | * var obj = Object.create(MinStack).createNew() 45 | * obj.push(x) 46 | * obj.pop() 47 | * var param_3 = obj.top() 48 | * var param_4 = obj.getMin() 49 | */ 50 | -------------------------------------------------------------------------------- /Javascript/156_binaryTreeUpsideDown.js: -------------------------------------------------------------------------------- 1 | var upsideDownBinaryTree = function(root) { 2 | if(root === null || root.left === null) { 3 | return root; 4 | } 5 | 6 | let newRoot = upsideDownBinaryTree(root.left); 7 | root.left.left = root.right; // node 2 left children 8 | root.left.right = root; // node 2 right children 9 | root.left = null; 10 | root.right = null; 11 | return newRoot; 12 | }; 13 | -------------------------------------------------------------------------------- /Javascript/160_intersectionOfTwoLinkedLists.js: -------------------------------------------------------------------------------- 1 | var getIntersectionNode = function(head1, head2) { 2 | let ptr1 = head1; 3 | let ptr2 = head2; 4 | 5 | let length1 = findLengthLL(head1); 6 | let length2 = findLengthLL(head2); 7 | 8 | if (length1 > length2) { 9 | ptr1 = adjustPtr(ptr1, length1 - length2); 10 | } 11 | else if (length1 < length2) { 12 | ptr2 = adjustPtr(ptr2, length2 - length1); 13 | } 14 | 15 | while (ptr1 !== null && ptr2 !== null) { 16 | if (ptr1 === ptr2) { 17 | return ptr1; 18 | } 19 | ptr1 = ptr1.next; 20 | ptr2 = ptr2.next; 21 | } 22 | 23 | return null; 24 | }; 25 | 26 | // Helper functions 27 | function adjustPtr(ptr, moves) { 28 | while(moves > 0) { 29 | ptr = ptr.next; 30 | moves--; 31 | } 32 | return ptr; 33 | } 34 | 35 | function findLengthLL (head) { 36 | let count = 0; 37 | 38 | while (head !== null) { 39 | head = head.next; 40 | count++; 41 | } 42 | return count; 43 | } 44 | -------------------------------------------------------------------------------- /Javascript/161_oneEditDistance.js: -------------------------------------------------------------------------------- 1 | var isOneEditDistance = function(s, t) { 2 | if (Math.abs(s.length - t.length) > 1) return false; 3 | 4 | let count = 0; 5 | 6 | let i = 0; 7 | let j = 0; 8 | 9 | while (i < s.length || j < t.length) { 10 | if (s[i] === t[j]) { 11 | i++; 12 | j++; 13 | } 14 | else if (s[i+1] === t[j]) { 15 | i++; 16 | count++; 17 | } 18 | else if (s[i] === t[j+1]) { 19 | j++; 20 | count++; 21 | } 22 | else { 23 | i++; 24 | j++; 25 | count++ 26 | } 27 | if (count > 1) return false; 28 | } 29 | 30 | return count === 1; 31 | }; 32 | -------------------------------------------------------------------------------- /Javascript/165_compareVersionNumbers.js: -------------------------------------------------------------------------------- 1 | function compareVersion (version1, version2) { 2 | let split1 = version1.split('.'); 3 | let split2 = version2.split('.'); 4 | 5 | let i = 0; 6 | 7 | while (i < version1.length || i < version2.length) { 8 | let dec1 = i < split1.length ? split1[i] : '0'; 9 | let dec2 = i < split2.length ? split2[i] : '0'; 10 | 11 | dec1 = removeLeadingZeros(dec1); 12 | dec2 = removeLeadingZeros(dec2); 13 | 14 | let decimalCompare = compareVersionHelper(dec1, dec2); 15 | if (decimalCompare !== 0) return decimalCompare; 16 | i++; 17 | } 18 | 19 | return 0; 20 | } 21 | 22 | var compareVersionHelper = function(version1, version2) { 23 | 24 | if (version1.length > version2.length) return 1; 25 | else if (version1.length < version2.length) return -1; 26 | 27 | let ptr1 = 0; 28 | let ptr2 = 0; 29 | 30 | while (ptr1 < version1.length || ptr2 < version2.length) { 31 | let val1 = ptr1 < version1.length ? +version1[ptr1] : -1; 32 | let val2 = ptr2 < version2.length ? +version2[ptr2] : -1; 33 | 34 | if (val1 < val2) return -1; 35 | else if (val1 > val2) return 1; 36 | ptr1++; 37 | ptr2++; 38 | } 39 | 40 | return 0; 41 | }; 42 | 43 | function removeLeadingZeros(str) { 44 | let i = 0; 45 | while (i < str.length) { 46 | if (str[i] !== '0') return str.slice(i); 47 | i++; 48 | } 49 | return ''; 50 | } 51 | -------------------------------------------------------------------------------- /Javascript/167_twoSumII-InputArraySorted.js: -------------------------------------------------------------------------------- 1 | var twoSum = function(numbers, target) { 2 | let lo = 0; 3 | let hi = numbers.length - 1; 4 | 5 | while (lo < hi) { 6 | const sum = numbers[lo] + numbers[hi]; 7 | if (sum === target) return [lo+1, hi+1]; 8 | else if (sum < target) lo++; 9 | else hi--; 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /Javascript/170_twoSumIII-DataStructureDesign.js: -------------------------------------------------------------------------------- 1 | var TwoSum = function() { 2 | this.arr = []; 3 | this.map = {}; 4 | }; 5 | 6 | /** 7 | * Add the number to an internal data structure.. 8 | * @param {number} number 9 | * @return {void} 10 | */ 11 | // O(1) 12 | TwoSum.prototype.add = function(number) { 13 | this.arr.push(number); 14 | if (this.map[number]) { 15 | this.map[number] += 1; 16 | } 17 | else { 18 | this.map[number] = 1; 19 | } 20 | }; 21 | 22 | /** 23 | * Find if there exists any pair of numbers which sum is equal to the value. 24 | * @param {number} value 25 | * @return {boolean} 26 | */ 27 | // O(N) 28 | TwoSum.prototype.find = function(value) { 29 | for (let i = 0; i < this.arr.length; i++) { 30 | const num = this.arr[i]; 31 | // Special case where we need to consider a duplicate 32 | if (value - num === num) { 33 | if (this.map[num] >= 2) return true; 34 | } 35 | // Not a duplicate value 36 | else if (this.map[value - num]) return true; 37 | } 38 | 39 | return false; 40 | }; 41 | -------------------------------------------------------------------------------- /Javascript/172_factorialTrailingZeroes.js: -------------------------------------------------------------------------------- 1 | var trailingZeroes = function(n) { 2 | // Edge Case 3 | if (n < 0) return -1; 4 | 5 | let count = 0; 6 | 7 | for (let i = 5; Math.floor(n/i) > 0; i *= 5) { 8 | count += Math.floor(n/i); 9 | } 10 | 11 | return count; 12 | }; 13 | -------------------------------------------------------------------------------- /Javascript/173_binarySearchTreeIterator.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @constructor 4 | * @param {TreeNode} root - root of the binary search tree 5 | */ 6 | var BSTIterator = function(root) { 7 | this.stack = []; 8 | this.pushAll(root); 9 | }; 10 | 11 | 12 | /** 13 | * @this BSTIterator 14 | * @returns {boolean} - whether we have a next smallest number 15 | */ 16 | BSTIterator.prototype.hasNext = function() { 17 | return this.stack.length !== 0; 18 | }; 19 | 20 | /** 21 | * @this BSTIterator 22 | * @returns {number} - the next smallest number 23 | */ 24 | BSTIterator.prototype.next = function() { 25 | const node = this.stack.pop(); 26 | this.pushAll(node.right); 27 | return node.val; 28 | }; 29 | 30 | BSTIterator.prototype.pushAll = function(node) { 31 | while (node) { 32 | this.stack.push(node); 33 | node = node.left; 34 | } 35 | } 36 | 37 | /** 38 | * Your BSTIterator will be called like this: 39 | * var i = new BSTIterator(root), a = []; 40 | * while (i.hasNext()) a.push(i.next()); 41 | */ 42 | -------------------------------------------------------------------------------- /Javascript/186_reverseWordsInAStringII.js: -------------------------------------------------------------------------------- 1 | var reverseWords = function(str) { 2 | // Edge Case 3 | if (str.length === 0) return; 4 | 5 | // Reverse the string once 6 | str = str.reverse(); 7 | 8 | let start = 0; 9 | let end = 0; 10 | 11 | while (end <= str.length) { 12 | if (str[end] === ' ' || end === str.length) { 13 | reverseWordsHelper(str, start, end - 1); 14 | start = end + 1; 15 | } 16 | end++; 17 | } 18 | 19 | }; 20 | 21 | function reverseWordsHelper (str, startIdx, endIdx) { 22 | 23 | while (startIdx < endIdx) { 24 | swap(str, startIdx, endIdx); 25 | startIdx++; 26 | endIdx--; 27 | } 28 | 29 | } 30 | 31 | function swap (arr, i, j) { 32 | let temp = arr[i]; 33 | arr[i] = arr[j]; 34 | arr[j] = temp; 35 | } 36 | -------------------------------------------------------------------------------- /Javascript/187_repeatedDNASequences.js: -------------------------------------------------------------------------------- 1 | var findRepeatedDnaSequences = function(s) { 2 | const set = new Set(); 3 | const counted = new Set(); 4 | const repeatedDNA = []; 5 | 6 | for (let i = 0; i < s.length - 9; i++) { 7 | const substr = s.slice(i, i + 10); 8 | if (set.has(substr) && !counted.has(substr)) { 9 | repeatedDNA.push(substr); 10 | counted.add(substr); 11 | } 12 | else set.add(substr); 13 | } 14 | 15 | return repeatedDNA; 16 | }; 17 | -------------------------------------------------------------------------------- /Javascript/189_rotateArray.js: -------------------------------------------------------------------------------- 1 | function rotate (nums, k) { 2 | const n = nums.length; 3 | k = k % n; 4 | if (k < 0) k = k + n; 5 | 6 | // Reverse the entire array 7 | reverse(nums, 0, n - 1); 8 | // Reverse the subarray from k to n 9 | reverse(nums, k, n - 1); 10 | // Reverse the subarray from 0 to k -1 11 | reverse(nums, 0, k - 1); 12 | } 13 | 14 | function reverse (nums, startIdx, endIdx) { 15 | while (startIdx < endIdx) { 16 | swap(nums, startIdx, endIdx); 17 | startIdx++; 18 | endIdx--; 19 | } 20 | } 21 | 22 | function swap (nums, i, j) { 23 | const temp = nums[i]; 24 | nums[i] = nums[j]; 25 | nums[j] = temp; 26 | } 27 | -------------------------------------------------------------------------------- /Javascript/190_reverseBits.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | In other languages we allocate 32 bits for an integer, in JS this is not the case. 4 | we allocate just the number that we need. 5 | 6 | 7 | Time: O(logn) 8 | Space: O(1) 9 | */ 10 | 11 | 12 | const reverseBits = (num) => { 13 | if (!num) return num; 14 | let result = 0; 15 | let count = 32; 16 | while (--count){ 17 | result <<= 1; // bit shift over by 1 18 | result |= num & 1; // newly shifted bit is n's leftmost bit 19 | num >>= 1; 20 | } 21 | 22 | return result >>> 0; 23 | }; 24 | -------------------------------------------------------------------------------- /Javascript/191_numberOf1Bits.js: -------------------------------------------------------------------------------- 1 | /* 2 | In other languages we allocate 32 bits to an interger. This is why we what 3 | Time: O(logn) 4 | Space: O(1) 5 | */ 6 | 7 | const numberofOnes = (num) => { 8 | let count = 0; 9 | while(num){ 10 | count++; 11 | num = (num) & (num - 1); 12 | } 13 | return count; 14 | } 15 | -------------------------------------------------------------------------------- /Javascript/198_houseRobber.js: -------------------------------------------------------------------------------- 1 | var rob = function(nums) { 2 | // Edge Cases 3 | if (!nums || !nums.length) return 0; 4 | else if (nums.length === 1) return nums[0]; 5 | else if (nums.length === 2) return Math.max(nums[0], nums[1]); 6 | 7 | let nMinus2 = nums[0]; 8 | let nMinus1 = Math.max(nums[0], nums[1]); 9 | let curMax; 10 | 11 | for (let i = 2; i < nums.length; i++) { 12 | curMax = Math.max(nMinus1, nMinus2 + nums[i]); 13 | nMinus2 = nMinus1; 14 | nMinus1 = curMax; 15 | } 16 | return curMax; 17 | }; 18 | -------------------------------------------------------------------------------- /Javascript/200_numberOfIslands.js: -------------------------------------------------------------------------------- 1 | var numIslands = function(grid) { 2 | // Edge 3 | if (!grid || !grid.length) return 0; 4 | 5 | const rowLen = grid.length; 6 | const colLen = grid[0].length; 7 | let islandCount = 0; 8 | 9 | for (let r = 0; r < rowLen; r++) { 10 | for (let c = 0; c < colLen; c++) { 11 | 12 | // See if touch an island 13 | if (grid[r][c] === '1') { 14 | dfsIslandSearch(grid, r, c, rowLen, colLen); 15 | islandCount++; 16 | } 17 | } 18 | } 19 | return islandCount; 20 | }; 21 | 22 | function dfsIslandSearch(grid, r, c, rowLen, colLen) { 23 | // Base case of recursive calls 24 | // Check to see if current r and c are inbounds 25 | if (r < 0 || r >= rowLen || c < 0 || c >= colLen || grid[r][c] !== '1') return; 26 | 27 | grid[r][c] = '-1'; 28 | 29 | // Top 30 | dfsIslandSearch(grid, r - 1, c, rowLen, colLen); 31 | 32 | // Right 33 | dfsIslandSearch(grid, r, c + 1, rowLen, colLen); 34 | 35 | // Bottom 36 | dfsIslandSearch(grid, r + 1, c, rowLen, colLen); 37 | 38 | // Left 39 | dfsIslandSearch(grid, r, c - 1, rowLen, colLen); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /Javascript/202_happyNumber.js: -------------------------------------------------------------------------------- 1 | 2 | const isHappy = (n) => { 3 | const hashMap = {} 4 | n = n.toString() 5 | while (n !== '1') { 6 | if (hashMap[n]) return false 7 | hashMap[n] = true 8 | let sum = 0 9 | for (const num of n) sum += Math.pow(+num, 2) 10 | n = sum.toString() 11 | } 12 | return true 13 | }; 14 | 15 | //Recursive Solution 16 | 17 | const isHappy = (n, hashMap = {}) => { 18 | n = n.toString() 19 | if (n !== '1') { 20 | if (hashMap[n]) return false 21 | hashMap[n] = true 22 | let sum = 0 23 | for (const num of n) sum += Math.pow(+num, 2) 24 | n = sum.toString() 25 | return isHappy(n, hashMap) 26 | } 27 | return true 28 | }; 29 | -------------------------------------------------------------------------------- /Javascript/203_removeLinkedListElements.js: -------------------------------------------------------------------------------- 1 | var removeElements = function(head, val) { 2 | 3 | // Edgecase 4 | if (head === null) { 5 | return null; 6 | } 7 | 8 | // Edgecase, head is a val 9 | while(head !== null && head.val === val) { 10 | head = head.next; 11 | } 12 | 13 | let ptr = head; 14 | 15 | while (ptr !== null && ptr.next !== null) { 16 | if (ptr.next.val === val) { 17 | // By pass value that is val 18 | ptr.next = ptr.next.next; 19 | } else { 20 | ptr = ptr.next; 21 | } 22 | } 23 | return head; 24 | }; 25 | -------------------------------------------------------------------------------- /Javascript/205_isomorphicStrings.js: -------------------------------------------------------------------------------- 1 | var isIsomorphic = function(s, t) { 2 | // Edge Cases 3 | if (s.length !== t.length) return false; 4 | 5 | const map1 = {}; 6 | const map2 = {}; 7 | 8 | for (let i = 0; i < s.length; i++) { 9 | const c1 = s[i]; 10 | const c2 = t[i]; 11 | 12 | if (!map1[c1]) map1[c1] = c2; 13 | else if (map1[c1] !== c2) return false; 14 | 15 | if (!map2[c2]) map2[c2] = c1; 16 | else if (map2[c2] !== c1) return false; 17 | } 18 | 19 | return true; 20 | }; 21 | -------------------------------------------------------------------------------- /Javascript/206_reverseLinkedList.js: -------------------------------------------------------------------------------- 1 | var reverseList = function(head) { 2 | let prev = null; 3 | let cur = head; 4 | 5 | while (cur) { 6 | let next = cur.next; 7 | cur.next = prev; 8 | 9 | prev = cur; 10 | cur = next; 11 | } 12 | 13 | return prev; 14 | }; 15 | -------------------------------------------------------------------------------- /Javascript/208_implementTrie.js: -------------------------------------------------------------------------------- 1 | function TrieNode (val) { 2 | this.val = val; 3 | this.children = []; 4 | } 5 | 6 | 7 | var Trie = function() { 8 | this.root = new TrieNode('root'); 9 | }; 10 | 11 | /** 12 | * Inserts a word into the trie. 13 | * @param {string} word 14 | * @return {void} 15 | */ 16 | Trie.prototype.insert = function(word) { 17 | let ptr = this.root; 18 | 19 | for (const c of word) { 20 | const nextNode = this.getChild(ptr, c); 21 | if (nextNode) { 22 | ptr = nextNode; 23 | } 24 | else { 25 | const newNode = new TrieNode(c); 26 | ptr.children.push(newNode); 27 | ptr = newNode; 28 | } 29 | } 30 | ptr.children.push('*'); 31 | }; 32 | 33 | Trie.prototype.getChild = function (ptr, char) { 34 | 35 | for (let i = 0; i < ptr.children.length; i++) { 36 | let curLetter = ptr.children[i]; 37 | if (curLetter.val === char) return curLetter; 38 | } 39 | return null; 40 | } 41 | 42 | /** 43 | * Returns if the word is in the trie. 44 | * @param {string} word 45 | * @return {boolean} 46 | */ 47 | Trie.prototype.search = function(word) { 48 | let ptr = this.root; 49 | 50 | for (const c of word) { 51 | const nextNode = this.getChild(ptr, c); 52 | if (!nextNode) return false; 53 | ptr = nextNode; 54 | } 55 | 56 | for (let i = 0; i < ptr.children.length; i++) { 57 | if (ptr.children[i] === '*') return true; 58 | } 59 | return false; 60 | }; 61 | 62 | /** 63 | * Returns if there is any word in the trie that starts with the given prefix. 64 | * @param {string} prefix 65 | * @return {boolean} 66 | */ 67 | Trie.prototype.startsWith = function(prefix) { 68 | let ptr = this.root; 69 | 70 | for (const c of prefix) { 71 | const nextNode = this.getChild(ptr, c); 72 | if (!nextNode) return false; 73 | ptr = nextNode; 74 | } 75 | 76 | return true; 77 | }; 78 | -------------------------------------------------------------------------------- /Javascript/209_minimumSizeSubarraySum.js: -------------------------------------------------------------------------------- 1 | var minSubArrayLen = function(s, nums) { 2 | 3 | if (!nums || !nums.length) return 0; 4 | 5 | let total = nums[0]; 6 | let min = Infinity; 7 | let lo = 0; 8 | let hi = 1; 9 | 10 | while (hi <= nums.length) { 11 | if (total >= s) { 12 | min = Math.min(hi - lo, min); 13 | total -= nums[lo]; 14 | lo++; 15 | } 16 | else if (total < s && hi < nums.length) { 17 | total += nums[hi]; 18 | hi++; 19 | } 20 | else break; 21 | } 22 | 23 | return min !== Infinity ? min : 0; 24 | }; 25 | -------------------------------------------------------------------------------- /Javascript/215_kthLargestElementInAnArray.js: -------------------------------------------------------------------------------- 1 | var findKthLargest = function(array, k, idx = array.length - k, lo = 0, hi = array.length - 1) { 2 | // Edge Cases 3 | if (lo === hi) return array[lo]; 4 | else if (lo > hi) return null; 5 | 6 | // Get pivot 7 | let p = hi; 8 | hi--; 9 | 10 | let initialLo = 0; 11 | 12 | while (lo <= hi) { 13 | // Move lo to a value > pivot 14 | while (lo < array.length && array[lo] < array[p]) lo++; 15 | 16 | // Move hi to a value < pivot 17 | while (hi >= 0 && array[hi] >= array[p]) hi--; 18 | 19 | if (lo <= hi) { 20 | swap(array, lo, hi); 21 | lo++; 22 | hi--; 23 | } 24 | } 25 | 26 | // Check if lo, which is where we will swap p to, is at array.length - k; 27 | if (lo === idx) return array[p]; 28 | 29 | // Swap 30 | swap(array, lo, p) 31 | 32 | if (idx > lo) return findKthLargest(array, k, idx, lo + 1, p); 33 | else return findKthLargest(array, k, idx, initialLo, hi); 34 | 35 | } 36 | 37 | function swap (arr, i, j) { 38 | let temp = arr[i]; 39 | arr[i] = arr[j]; 40 | arr[j] = temp; 41 | } 42 | -------------------------------------------------------------------------------- /Javascript/217_containsDuplicate.js: -------------------------------------------------------------------------------- 1 | var containsDuplicate = function(nums) { 2 | const hSet = new Set(); 3 | 4 | for (let i = 0; i < nums.length; i++) { 5 | if (hSet.has(nums[i])) return true; 6 | else hSet.add(nums[i]) 7 | } 8 | return false; 9 | }; 10 | -------------------------------------------------------------------------------- /Javascript/219_containsDuplicateII.js: -------------------------------------------------------------------------------- 1 | var containsNearbyDuplicate = function(nums, k) { 2 | // Put everything in a HashMap, key ele, val idx 3 | const hMap = {}; 4 | 5 | for (let i = 0; i < nums.length; i++) { 6 | const num = nums[i]; 7 | if (num in hMap) { 8 | if ((i - hMap[num]) <= k) return true; 9 | else hMap[num] = i 10 | } 11 | else hMap[num] = i; 12 | } 13 | 14 | return false; 15 | }; 16 | -------------------------------------------------------------------------------- /Javascript/223_rectanlgeArea.js: -------------------------------------------------------------------------------- 1 | var computeArea = function(M, N, C, D, E, F, G, H) { 2 | const A = {}; 3 | const B = {}; 4 | 5 | // Rectangle A 6 | A.xMin = M; 7 | A.yMin = N; 8 | A.xMax = C; 9 | A.yMax = D; 10 | A.xLength = A.xMax - A.xMin; 11 | A.yLength = A.yMax - A.yMin; 12 | 13 | // Rectangle B 14 | B.xMin = E; 15 | B.yMin = F; 16 | B.xMax = G; 17 | B.yMax = H; 18 | B.xLength = B.xMax - B.xMin; 19 | B.yLength = B.yMax - B.yMin; 20 | 21 | let xIntersect = null; 22 | let yIntersect = null; 23 | 24 | // Find x Intersect length 25 | if (A.xLength > B.xLength) { 26 | xIntersect = getIntersect(B.xMin, B.xMax, A.xMin, A.xMax); 27 | } else { 28 | xIntersect = getIntersect(A.xMin, A.xMax, B.xMin, B.xMax); 29 | } 30 | 31 | // Find y Intersect length 32 | if (A.yLength > B.yLength) { 33 | yIntersect = getIntersect(B.yMin, B.yMax, A.yMin, A.yMax); 34 | } else { 35 | yIntersect = getIntersect(A.yMin, A.yMax, B.yMin, B.yMax); 36 | } 37 | 38 | let intersect = xIntersect * yIntersect; 39 | return A.xLength * A.yLength + B.xLength * B.yLength - intersect; 40 | 41 | }; 42 | 43 | function getIntersect (sMin, sMax, gMin, gMax) { 44 | // No Interset 45 | if (sMin >= gMax || sMax <= gMin) return 0; 46 | // Left Overlap 47 | else if (sMin < gMin) return sMax - gMin; 48 | // Internal Overlap 49 | else if (sMin >= gMin && sMax <= gMax) return sMax - sMin; 50 | // Right Overlap 51 | else if (sMin > gMin) return gMax - sMin; 52 | } 53 | -------------------------------------------------------------------------------- /Javascript/225_implementStackUsingQueues.js: -------------------------------------------------------------------------------- 1 | var MyStack = function() { 2 | this.qA = []; 3 | this.qB = []; 4 | }; 5 | 6 | /** 7 | * Push element x onto stack. 8 | * @param {number} x 9 | * @return {void} 10 | */ 11 | MyStack.prototype.push = function(val) { 12 | if (this.qA.length) this.qA.unshift(val); 13 | else this.qB.unshift(val); 14 | }; 15 | 16 | /** 17 | * Removes the element on top of the stack and returns that element. 18 | * @return {number} 19 | */ 20 | MyStack.prototype.pop = function() { 21 | if (this.qA.length) { 22 | while(this.qA.length !== 1) this.qB.unshift(this.qA.pop()); 23 | return this.qA.pop(); 24 | } 25 | else if (this.qB.length) { 26 | while(this.qB.length !== 1) this.qA.unshift(this.qB.pop()); 27 | return this.qB.pop(); 28 | } 29 | }; 30 | 31 | /** 32 | * Get the top element. 33 | * @return {number} 34 | */ 35 | MyStack.prototype.top = function() { 36 | if (this.qA.length) return this.qA[0]; 37 | return this.qB[0]; 38 | }; 39 | 40 | /** 41 | * Returns whether the stack is empty. 42 | * @return {boolean} 43 | */ 44 | MyStack.prototype.empty = function() { 45 | return !this.qA.length && !this.qB.length; 46 | }; 47 | -------------------------------------------------------------------------------- /Javascript/226_invertBinaryTree.js: -------------------------------------------------------------------------------- 1 | var invertTree = function(root) { 2 | // Base Case/Edge Case 3 | if (!root || (!root.left && !root.right)) return root; 4 | 5 | // Go left 6 | invertTree(root.left); 7 | 8 | // Go right 9 | invertTree(root.right); 10 | 11 | // Make a temp and swap 12 | let temp = root.left; 13 | root.left = root.right; 14 | root.right = temp; 15 | 16 | return root; 17 | }; 18 | -------------------------------------------------------------------------------- /Javascript/231_powerOfTwo.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Time: O(1) 4 | Space: O(1) 5 | 6 | */ 7 | 8 | const isPowerOfTwo = (num) => { 9 | return (num > 0 && !(num & (num - 1))) 10 | } 11 | -------------------------------------------------------------------------------- /Javascript/232_implementQueueUsingStacks.js: -------------------------------------------------------------------------------- 1 | var MyQueue = function() { 2 | this.stackA = []; 3 | this.stackB = []; 4 | }; 5 | 6 | /** 7 | * Push element x to the back of queue. 8 | * @param {number} x 9 | * @return {void} 10 | */ 11 | MyQueue.prototype.push = function(val) { 12 | if (this.stackA.length || this.empty() ) { 13 | this.stackA.push(val); 14 | } 15 | else { 16 | while(this.stackB.length) { 17 | this.stackA.push(this.stackB.pop()); 18 | } 19 | this.stackA.push(val); 20 | } 21 | }; 22 | 23 | /** 24 | * Removes the element from in front of queue and returns that element. 25 | * @return {number} 26 | */ 27 | MyQueue.prototype.pop = function() { 28 | if (this.stackA.length) { 29 | while(this.stackA.length) { 30 | this.stackB.push(this.stackA.pop()); 31 | } 32 | return this.stackB.pop(); 33 | } else { 34 | return this.stackB.pop(); 35 | } 36 | }; 37 | 38 | /** 39 | * Get the front element. 40 | * @return {number} 41 | */ 42 | MyQueue.prototype.peek = function() { 43 | if (this.stackA.length) { 44 | while(this.stackA.length) { 45 | this.stackB.push(this.stackA.pop()); 46 | } 47 | return this.stackB[this.stackB.length - 1]; 48 | } else { 49 | return this.stackB[this.stackB.length - 1]; 50 | } 51 | }; 52 | 53 | /** 54 | * Returns whether the queue is empty. 55 | * @return {boolean} 56 | */ 57 | MyQueue.prototype.empty = function() { 58 | return this.stackA.length === 0 && this.stackB.length === 0; 59 | }; 60 | -------------------------------------------------------------------------------- /Javascript/234_palindromeLinkedList.js: -------------------------------------------------------------------------------- 1 | var isPalindrome = function(head) { 2 | // Send runner, and walker pointers to get midpoint 3 | // Once we got midpoint then get new pointer to start at the head and check to see if they are the same 4 | 5 | // Get midpoint pointer 6 | let ptrFast = head; 7 | let ptrSlow = head; 8 | 9 | while (ptrFast !== null) { 10 | if (ptrFast.next !== null) { 11 | ptrFast = ptrFast.next.next; 12 | } else { 13 | ptrFast = ptrFast.next; 14 | } 15 | ptrSlow = ptrSlow.next; 16 | } 17 | 18 | let stack = []; 19 | 20 | while (ptrSlow !== null) { 21 | stack.push(ptrSlow.val); 22 | ptrSlow = ptrSlow.next; 23 | } 24 | 25 | let ptrStart = head; 26 | 27 | while (stack.length > 0) { 28 | let stackVal = stack.pop(); 29 | if (stackVal !== ptrStart.val) { 30 | return false; 31 | } 32 | ptrStart = ptrStart.next; 33 | } 34 | 35 | return true; 36 | 37 | }; 38 | -------------------------------------------------------------------------------- /Javascript/235_lowestCommonAncestorBST.js: -------------------------------------------------------------------------------- 1 | var lowestCommonAncestor = function(root, p, q) { 2 | let ptr1 = root; 3 | let ptr2 = root; 4 | let common = root; 5 | 6 | while (ptr1 === ptr2 && ptr1 && ptr2) { 7 | if (ptr1 === ptr2) common = ptr1; 8 | 9 | if (ptr1 !== p) { 10 | if (p.val < ptr1.val) ptr1 = ptr1.left 11 | else ptr1 = ptr2.right; 12 | } 13 | 14 | if (ptr2 !== q) { 15 | if (q.val < ptr2.val) ptr2 = ptr2.left; 16 | else ptr2 = ptr2.right; 17 | } 18 | } 19 | 20 | return common; 21 | }; 22 | -------------------------------------------------------------------------------- /Javascript/236_lowestCommonAncestorBT.js: -------------------------------------------------------------------------------- 1 | function lowestCommonAncestor(root, nodeA, nodeB) { 2 | // Base Cases 3 | if (!root || root === nodeA || root === nodeB) return root; 4 | 5 | let left = lowestCommonAncestor(root.left, nodeA, nodeB); 6 | let right = lowestCommonAncestor(root.right, nodeA, nodeB); 7 | 8 | // Failure 9 | if (!left && !right) return null; 10 | 11 | // LCA 12 | if (left && right) return root; 13 | 14 | // One of the children hit 15 | return left ? left : right; 16 | } 17 | -------------------------------------------------------------------------------- /Javascript/237_deleteNodeInLinkedList.js: -------------------------------------------------------------------------------- 1 | var deleteNode = function(node) { 2 | node.val = node.next.val; 3 | node.next = node.next.next; 4 | }; 5 | -------------------------------------------------------------------------------- /Javascript/238_productofArrayExceptSelf.js: -------------------------------------------------------------------------------- 1 | var productExceptSelf = function(nums) { 2 | // Initialize solutions array 3 | const sol = new Array(nums.length).fill(1); 4 | let pSF = 1; 5 | 6 | // Go left to right 7 | for (let i = 0; i < nums.length; i++) { 8 | sol[i] *= pSF; 9 | pSF *= nums[i]; 10 | } 11 | 12 | // Reset product so far 13 | pSF = 1; 14 | 15 | // Go right to left 16 | for (let i = nums.length - 1; i >= 0; i--) { 17 | sol[i] *= pSF; 18 | pSF *= nums[i]; 19 | } 20 | 21 | return sol; 22 | }; 23 | -------------------------------------------------------------------------------- /Javascript/239_slidingWindowMaximum.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Approach: 4 | - Add the first k elements onto a doubly linked list 5 | 6 | - If the new element is greater than, the prev element, remove the prev element 7 | 8 | - If the head of the LL (the max) has an index location that is out of the current window, remove it 9 | 10 | Ex: 11 | 0 1 2 3 4 5 6 7 12 | Given nums = [1,3,-1,-3,5,3,6,7], and k = 3. 13 | 14 | 7 15 | 7 16 | 17 | 18 | [3, 3, 5, 5, 6, 7] 19 | 20 | */ 21 | 22 | function addToLL(LL, val, idx, wS) { 23 | // Remove nodes from end of LL that are less than new node we are add 24 | while (!LL.isEmpty() && LL.tail.val < val) LL.removeFromTail(); 25 | 26 | // Add the current node 27 | LL.addToTail(val, idx); 28 | 29 | // Remove elements from the head of the LL that are out of our current window 30 | while (!LL.isEmpty() && LL.head.idx < wS) LL.removeFromHead(); 31 | 32 | } 33 | 34 | // Double LinkedList 35 | function DLL () { 36 | this.head = null; 37 | this.tail = null; 38 | } 39 | 40 | DLL.prototype.printLL = function() { 41 | 42 | let str = []; 43 | let ptr = this.head; 44 | 45 | while (ptr) { 46 | str.push(ptr.val); 47 | ptr = ptr.next; 48 | } 49 | 50 | console.log(str.join(' -> ')); 51 | } 52 | 53 | DLL.prototype.removeFromHead = function () { 54 | 55 | // If empty 56 | if (!this.head && !this.tail) return; 57 | // One element 58 | else if (this.head === this.tail) { 59 | this.head = null; 60 | this.tail = null; 61 | } 62 | // More than one element 63 | else { 64 | this.head = this.head.next; 65 | this.head.prev = null; 66 | } 67 | 68 | }; 69 | 70 | DLL.prototype.addToTail = function (val, idx) { 71 | 72 | const newNode = new DLL_Node(val, idx); 73 | 74 | // If the LL is empty 75 | if (!this.head && !this.tail) { 76 | this.head = newNode; 77 | this.tail = newNode; 78 | } 79 | // One node 80 | else if (this.head === this.tail) { 81 | this.tail = newNode; 82 | this.head.next = this.tail; 83 | this.tail.prev = this.head; 84 | } 85 | // More than 1 element 86 | else { 87 | this.tail.next = newNode; 88 | newNode.prev = this.tail; 89 | this.tail = newNode; 90 | } 91 | }; 92 | 93 | DLL.prototype.removeFromTail = function () { 94 | // If the LL empty 95 | if (!this.head && !this.tail) return; 96 | 97 | // If the LL has one node 98 | else if (this.head === this.tail) { 99 | this.head = null; 100 | this.tail = null; 101 | } 102 | 103 | // More than 1 element 104 | else { 105 | this.tail = this.tail.prev; 106 | this.tail.next = null; 107 | } 108 | }; 109 | 110 | DLL.prototype.isEmpty = function () { 111 | return !this.head && !this.tail; 112 | }; 113 | 114 | 115 | function DLL_Node (val, idx) { 116 | this.val = val; 117 | this.idx = idx; 118 | this.next = null; 119 | this.prev = null; 120 | } 121 | 122 | var maxSlidingWindow = function(nums, k) { 123 | // Edge Cases 124 | if (!nums.length) return []; 125 | 126 | const dll = new DLL(); 127 | const maxOfWindows = []; 128 | 129 | let i = 0; 130 | 131 | while (i < k && i < nums.length) { 132 | addToLL(dll, nums[i], i, 0); 133 | i++; 134 | } 135 | 136 | maxOfWindows.push(dll.head.val); 137 | let windowStart = 1; 138 | 139 | while (i < nums.length) { 140 | addToLL(dll, nums[i], i, windowStart); 141 | maxOfWindows.push(dll.head.val); 142 | i++; 143 | windowStart++; 144 | } 145 | 146 | return maxOfWindows; 147 | }; 148 | -------------------------------------------------------------------------------- /Javascript/240_searchA2DMatrixII.js: -------------------------------------------------------------------------------- 1 | var searchMatrix = function(matrix, target) { 2 | // Edge Case 3 | if (!matrix || !matrix.length) return false; 4 | 5 | let row = 0; 6 | let col = matrix[0].length - 1; 7 | let rows = matrix.length; 8 | 9 | while (row < rows && col >= 0) { 10 | if (matrix[row][col] > target) col--; 11 | else if (matrix[row][col] < target) row++; 12 | else return true; 13 | } 14 | return false; 15 | }; 16 | -------------------------------------------------------------------------------- /Javascript/242_validAnagram.js: -------------------------------------------------------------------------------- 1 | var isAnagram = function(s, t) { 2 | const hMap = {}; 3 | 4 | for (let i = 0; i < s.length; i++) { 5 | if (s[i] in hMap) hMap[s[i]] += 1; 6 | else hMap[s[i]] = 1; 7 | } 8 | 9 | for (let i = 0; i < t.length; i++) { 10 | if (t[i] in hMap) hMap[t[i]] -= 1; 11 | else return false; 12 | } 13 | 14 | 15 | for (let key in hMap) { 16 | if (hMap[key] !== 0) return false; 17 | } 18 | 19 | return true; 20 | }; 21 | -------------------------------------------------------------------------------- /Javascript/243_shortestWordDistance.js: -------------------------------------------------------------------------------- 1 | var shortestDistance = function(words, word1, word2) { 2 | let minDist = Infinity; 3 | let w1Idx = -1; 4 | let w2Idx = -1; 5 | 6 | for (let i = 0; i < words.length; i++) { 7 | // Get current word 8 | const word = words[i]; 9 | 10 | // Update last seen index 11 | if (word === word1) w1Idx = i; 12 | else if (word === word2) w2Idx = i; 13 | 14 | if (w1Idx !== -1 && w2Idx !== -1) { 15 | minDist = Math.min(minDist, Math.abs(w1Idx - w2Idx)); 16 | } 17 | } 18 | 19 | return minDist; 20 | }; 21 | -------------------------------------------------------------------------------- /Javascript/244_shortestWordDistanceII.js: -------------------------------------------------------------------------------- 1 | var WordDistance = function(words) { 2 | this.map = {}; 3 | 4 | for (let i = 0; i < words.length; i++) { 5 | const word = words[i]; 6 | 7 | if (word in this.map) this.map[word].push(i); 8 | else this.map[word] = [i]; 9 | } 10 | }; 11 | 12 | /** 13 | * @param {string} word1 14 | * @param {string} word2 15 | * @return {number} 16 | */ 17 | WordDistance.prototype.shortest = function(word1, word2) { 18 | let idx1Arr = this.map[word1]; 19 | let idx2Arr = this.map[word2]; 20 | 21 | let minDist = Infinity; 22 | let i = 0; 23 | let j = 0; 24 | 25 | while (i < idx1Arr.length && j < idx2Arr.length) { 26 | minDist = Math.min(minDist, Math.abs(idx1Arr[i] - idx2Arr[j])); 27 | if (idx1Arr[i] < idx2Arr[j]) i++; 28 | else j++; 29 | } 30 | 31 | return minDist; 32 | }; 33 | -------------------------------------------------------------------------------- /Javascript/245_shortestWordDistanceIII.js: -------------------------------------------------------------------------------- 1 | var shortestWordDistance = function(words, word1, word2) { 2 | let dist = Infinity 3 | let idx1 = dist, idx2 = -dist; 4 | 5 | 6 | let isSame = word1 === word2; 7 | 8 | for (let i = 0; i < words.length; i++) { 9 | const curWord = words[i]; 10 | 11 | if (curWord === word1) { 12 | if (isSame) { 13 | idx1 = idx2; 14 | idx2 = i; 15 | } 16 | else idx1 = i; 17 | } 18 | else if (curWord === word2) idx2 = i; 19 | 20 | dist = Math.min(dist, Math.abs(idx1 - idx2)); 21 | } 22 | return dist; 23 | }; 24 | -------------------------------------------------------------------------------- /Javascript/252_meetingRooms.js: -------------------------------------------------------------------------------- 1 | function canAttendMeetings (intervals) { 2 | // Sort based off start time 3 | intervals.sort((a,b) => a.start - b.start); 4 | 5 | for (let i = 0; i < intervals.length - 1; i++) { 6 | const curMeeting = intervals[i]; 7 | const nextMeeting = intervals[i + 1]; 8 | if (curMeeting.end > nextMeeting.start) return false; 9 | } 10 | return true; 11 | } 12 | -------------------------------------------------------------------------------- /Javascript/253_meetingRoomsII.js: -------------------------------------------------------------------------------- 1 | var minMeetingRooms = function(intervals) { 2 | // Edge Case 3 | if (!intervals.length) return 0; 4 | 5 | // Sort based off start time 6 | intervals.sort((a,b) => a.start - b.start); 7 | 8 | const meetingsMinHeap = new MinHeap([intervals[0].end]); 9 | 10 | for (let i = 1; i < intervals.length; i++) { 11 | const curMeeting = intervals[i]; 12 | 13 | if (curMeeting.start >= meetingsMinHeap.peek()) { 14 | meetingsMinHeap.remove(); 15 | meetingsMinHeap.insert(curMeeting.end); 16 | } 17 | else { 18 | meetingsMinHeap.insert(curMeeting.end); 19 | } 20 | } 21 | return meetingsMinHeap.size(); 22 | }; 23 | 24 | 25 | class MinHeap { 26 | constructor(arr = []) { 27 | this.heap = this.buildHeap(arr); 28 | } 29 | 30 | buildHeap(arr) { 31 | for (let i = arr.length - 1; i >= 0; i--) { 32 | this.siftDown(i, arr); 33 | } 34 | return arr; 35 | } 36 | 37 | siftDown(idx, arr) { 38 | const left = this.getLeftChild(idx); 39 | const right = this.getRightChild(idx); 40 | 41 | // No children, base case return; 42 | if (!arr[left] && !arr[right]) return; 43 | 44 | // One Child, must be on the left 45 | if (arr[left] && !arr[right]) { 46 | if (arr[idx] > arr[left]) { 47 | this.swap(arr, idx, left); 48 | this.siftDown(left, arr); 49 | } 50 | return; 51 | } 52 | 53 | // Must be two children, check any are less than ele at idx 54 | if (arr[idx] > arr[left] || arr[idx] > arr[right]) { 55 | const min = arr[left] < arr[right] ? left : right; 56 | this.swap(arr, idx, min); 57 | this.siftDown(min, arr); 58 | } 59 | 60 | } 61 | 62 | siftUp(idx, arr) { 63 | while (idx > 0) { 64 | const parent = this.getParent(idx); 65 | if (arr[idx] < arr[parent]) { 66 | this.swap(arr, idx, parent); 67 | idx = parent; 68 | } 69 | else break; 70 | } 71 | } 72 | 73 | peek() { 74 | return this.heap[0]; 75 | } 76 | 77 | remove() { 78 | const min = this.heap.shift(); 79 | this.heap = this.buildHeap(this.heap); 80 | return min; 81 | } 82 | 83 | insert(value) { 84 | this.heap.push(value); 85 | const lastIdx = this.heap.length - 1; 86 | this.siftUp(lastIdx, this.heap); 87 | } 88 | getParent(idx) { 89 | return Math.floor((idx-1)/2); 90 | } 91 | getLeftChild(idx) { 92 | return 2 * idx + 1; 93 | } 94 | getRightChild(idx) { 95 | return 2 * idx + 2; 96 | } 97 | swap(arr, i, j) { 98 | let temp = arr[i]; 99 | arr[i] = arr[j]; 100 | arr[j] = temp; 101 | } 102 | size () { 103 | return this.heap.length; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Javascript/254_factorCombinations.js: -------------------------------------------------------------------------------- 1 | function getFactors(n, startNum = 2, curProduct = 1, curComb = [], sols = []) { 2 | // Edge Case 3 | if (n <= 1) return []; 4 | if (startNum > Math.floor(Math.sqrt(n))) return []; 5 | 6 | let half = Math.floor(n/2) 7 | 8 | for (let num = startNum; num <= half; num++) { 9 | if (num * curProduct > n) break; 10 | else if (num * curProduct === n) { 11 | sols.push(curComb.concat(num)); 12 | return; 13 | } 14 | else if (n % num === 0) { 15 | getFactors(n, num, curProduct * num, curComb.concat(num), sols); 16 | } 17 | } 18 | 19 | return sols; 20 | } 21 | -------------------------------------------------------------------------------- /Javascript/256_paintHouse.js: -------------------------------------------------------------------------------- 1 | var minCost = function(costs) { 2 | // Edge Case 3 | if(!costs || !costs.length) return 0 4 | 5 | // Each row represents the house, each col is the price to paint it that color 6 | for (let row = 1; row < costs.length; row++) { 7 | 8 | // Painting red 9 | costs[row][0] += Math.min(costs[row-1][1], costs[row-1][2]); 10 | 11 | // Painting green 12 | costs[row][1] += Math.min(costs[row-1][0], costs[row-1][2]); 13 | 14 | // Painting blue 15 | costs[row][2] += Math.min(costs[row-1][0], costs[row-1][1]); 16 | } 17 | let lastRow = costs.length - 1; 18 | 19 | return Math.min(costs[lastRow][0], costs[lastRow][1], costs[lastRow][2]); 20 | }; 21 | -------------------------------------------------------------------------------- /Javascript/257_binaryTreePaths.js: -------------------------------------------------------------------------------- 1 | var binaryTreePaths = function(root, curPath = [], paths = []) { 2 | // Edge Case, root is null 3 | if (!root) return []; 4 | 5 | // Base Case, hit a leaf 6 | if (!root.left && !root.right) { 7 | curPath.push(root.val); 8 | paths.push(curPath.join('->')); 9 | return paths; 10 | } 11 | // Go left 12 | binaryTreePaths(root.left, curPath.concat(root.val), paths); 13 | 14 | // Go right 15 | binaryTreePaths(root.right, curPath.concat(root.val), paths); 16 | 17 | return paths; 18 | 19 | }; 20 | -------------------------------------------------------------------------------- /Javascript/266_palindromePermutations.js: -------------------------------------------------------------------------------- 1 | var canPermutePalindrome = function(s) { 2 | // Populate array to store frequency 3 | const freqHMap = {}; 4 | 5 | for (let i = 0; i < s.length; i++) { 6 | const c = s[i]; 7 | if (c in freqHMap) freqHMap[c] += 1; 8 | else freqHMap[c] = 1; 9 | } 10 | 11 | let oddCount = 0; 12 | 13 | for (let key in freqHMap) { 14 | if (freqHMap[key] % 2 === 1) oddCount++; 15 | if (oddCount > 1) return false; 16 | } 17 | 18 | return true; 19 | }; 20 | -------------------------------------------------------------------------------- /Javascript/268_missingNumber.js: -------------------------------------------------------------------------------- 1 | var missingNumber = function (nums) { 2 | const hSet = new Set(nums); 3 | const size = nums.length; 4 | 5 | for (let i = 0; i <= size; i++) { 6 | if (!hSet.has(i)) return i; 7 | } 8 | 9 | return -1; 10 | }; 11 | 12 | //Time O(n), Space 0(1) 13 | 14 | const missingNumber = nums => { 15 | for (let i in nums) { 16 | if (nums[nums[i]] || nums[nums[i]] === 0) nums[nums[i]] = nums[nums[i]].toString() 17 | } 18 | for (let i in nums) { 19 | if (typeof nums[i] !== 'string') return +i 20 | } 21 | return nums.length 22 | } 23 | -------------------------------------------------------------------------------- /Javascript/269_alienDictionary.js: -------------------------------------------------------------------------------- 1 | var alienOrder = function(words) { 2 | // Edge Cases 3 | if (words.length === 0) return ''; 4 | if (words.length === 1) return words[0]; 5 | 6 | // Make directed graph 7 | const adjList = new Array(26).fill(null); 8 | 9 | const lettersSet = getLetters(words); 10 | 11 | lettersSet.forEach(letter => { 12 | adjList[getIdx(letter)] = []; 13 | }) 14 | 15 | // For each pair of words, find an ordering 16 | for (let i = 0; i < words.length - 1; i++) { 17 | 18 | let idx = findEdge(words[i], words[i+1]); 19 | 20 | if (idx !== -1) { 21 | const u = getIdx(words[i][idx]); 22 | const v = getIdx(words[i+1][idx]); 23 | if (adjList[u].indexOf(v) === -1) adjList[u].push(v); 24 | } 25 | } 26 | 27 | // Check if graph is cyclic 28 | if (isCyclic(adjList)) return ''; 29 | 30 | return getTopologicalOrder(adjList).reverse().map(idx => idxToAlpha(idx)).join(''); 31 | }; 32 | 33 | function getLetters(words) { 34 | 35 | const lettersSet = new Set(); 36 | 37 | for (let word of words) { 38 | for (let letter of word) { 39 | lettersSet.add(letter); 40 | } 41 | } 42 | 43 | return lettersSet; 44 | } 45 | 46 | function getTopologicalOrder(adjList) { 47 | 48 | const visited = new Array(26).fill(false); 49 | const stack = []; 50 | 51 | for (let i = 0; i < adjList.length; i++) { 52 | if (adjList[i] && !visited[i]) { 53 | dfs(i, adjList, visited, stack); 54 | } 55 | } 56 | 57 | return stack; 58 | } 59 | 60 | function dfs(root, adjList, visited, stack) { 61 | if (visited[root]) return; 62 | 63 | visited[root] = true; 64 | 65 | for (let i = 0; i < adjList[root].length; i++) { 66 | dfs(adjList[root][i], adjList, visited, stack) 67 | } 68 | 69 | stack.push(root); 70 | } 71 | 72 | function idxToAlpha(idx) { 73 | idx += 'a'.charCodeAt(0); 74 | 75 | return String.fromCharCode(idx); 76 | } 77 | 78 | function getIdx(alpha) { 79 | return alpha.charCodeAt(0) - 'a'.charCodeAt(0); 80 | } 81 | 82 | function findEdge(word1, word2) { 83 | let idx = 0; 84 | 85 | while (word1[idx] === word2[idx] && idx < word1.length && idx < word2.length) { 86 | idx++; 87 | } 88 | if (idx === word1.length || idx === word2.length) return -1; 89 | 90 | return idx; 91 | } 92 | 93 | function isCyclic(adjList) { 94 | for (let i = 0; i < adjList.length; i++) { 95 | const recStack = new Set(); 96 | 97 | if(isCyclicFrom(i, adjList, recStack)) return true; 98 | } 99 | 100 | return false; 101 | } 102 | 103 | function isCyclicFrom(vertex, adjList, recStack) { 104 | // Edge/Base Cases 105 | if (adjList[vertex] === null) return false; 106 | else if (recStack.has(vertex)) return true; 107 | 108 | recStack.add(vertex); 109 | 110 | for (let i = 0; i < adjList[vertex].length; i++) { 111 | if (isCyclicFrom(adjList[vertex][i], adjList, recStack)) return true; 112 | } 113 | recStack.delete(vertex); 114 | return false; 115 | } 116 | -------------------------------------------------------------------------------- /Javascript/270_closestBinarySearchTreeValue.js: -------------------------------------------------------------------------------- 1 | var closestValue = function(root, target) { 2 | let minD = Infinity; 3 | let cV = root.val; 4 | let ptr = root; 5 | 6 | while (ptr) { 7 | let diff = Math.abs(target - ptr.val); 8 | 9 | // Check if we found a new closest value 10 | if (diff < minD) { 11 | minD = diff; 12 | cV = ptr.val; 13 | } 14 | 15 | // Go the next possible closest val 16 | if (target > ptr.val) ptr = ptr.right; 17 | else if (target < ptr.val) ptr = ptr.left; 18 | else break; 19 | } 20 | 21 | return cV; 22 | }; 23 | -------------------------------------------------------------------------------- /Javascript/273_integerToEnglishWords.js: -------------------------------------------------------------------------------- 1 | const lessThanTwenty = ['', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen']; 2 | const tens = ['', 'Ten', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety']; 3 | const thousands = ['', 'Thousand', 'Million', 'Billion']; 4 | 5 | var numberToWords = function(num) { 6 | // Edge Case 7 | if (num === 0) return 'Zero'; 8 | 9 | // results str 10 | let result = ''; 11 | let tIdx = 0; 12 | 13 | // 123, 105 14 | 15 | while (num) { 16 | const hundredChunk = num % 1000; 17 | num = Math.floor(num / 1000); 18 | const part = getHundreds(hundredChunk).trim(); 19 | 20 | if (hundredChunk !== 0) { 21 | result = part + ' ' + thousands[tIdx] + ' ' + result; 22 | } 23 | tIdx++; 24 | } 25 | 26 | return result.trim(); 27 | }; 28 | 29 | 30 | function getHundreds (num) { 31 | 32 | // Less than 20 33 | if (num < 20) { 34 | return lessThanTwenty[num]; 35 | } 36 | // Less than 100 37 | else if (num < 100) { 38 | return tens[Math.floor(num/10)] + ' ' + getHundreds(num % 10); 39 | } 40 | // Number between 100 - 999 41 | return lessThanTwenty[Math.floor(num/100)] + ' Hundred ' + getHundreds(num % 100); 42 | } 43 | -------------------------------------------------------------------------------- /Javascript/276_paintFence.js: -------------------------------------------------------------------------------- 1 | var numWays = function(n, k) { 2 | if (n === 0) return 0; 3 | if (n === 1) return k; 4 | 5 | const diffColor = [0, k, k*(k-1)]; 6 | const sameColor = [0, k, k]; 7 | 8 | for (let i = 3; i <= n; i++) { 9 | diffColor[i] = (k-1)*(diffColor[i-1] + sameColor[i-1]); 10 | sameColor[i] = diffColor[i-1]; 11 | } 12 | 13 | return diffColor[n] + sameColor[n]; 14 | }; 15 | -------------------------------------------------------------------------------- /Javascript/277_findTheCelebrity.js: -------------------------------------------------------------------------------- 1 | var solution = function(knows) { 2 | /** 3 | * @param {integer} n Total people 4 | * @return {integer} The celebrity 5 | */ 6 | return function(n) { 7 | let x = 0; 8 | for (let i = 0; i < n; i++) if (knows(x, i)) x = i; 9 | for (let i = 0; i < x; i++) if (knows(x, i)) return -1; 10 | for (let i = 0; i < n; i++) if (!knows(i, x)) return -1; 11 | return x; 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /Javascript/283_moveZeroes.js: -------------------------------------------------------------------------------- 1 | var moveZeroes = function(arr) { 2 | let trail = 0; 3 | 4 | // Find left most zero 5 | while (arr[trail] !== 0 && trail < arr.length) { 6 | trail++; 7 | } 8 | 9 | for (let i = trail + 1; i < arr.length; i++) { 10 | if (arr[i] !== 0) { 11 | swap(arr, i, trail); 12 | trail++; 13 | } 14 | } 15 | }; 16 | 17 | function swap (array, i, j) { 18 | let temp = array[i]; 19 | array[i] = array[j]; 20 | array[j] = temp; 21 | } 22 | -------------------------------------------------------------------------------- /Javascript/285_inorderSuccesorInBST.js: -------------------------------------------------------------------------------- 1 | var inorderSuccessor = function(root, p) { 2 | // Edge Case 3 | if (!root || !p) return null; 4 | 5 | let ptr = root; 6 | let successor = null; 7 | 8 | while (ptr !== p && ptr) { 9 | if (ptr.val > p.val) { 10 | if (!successor) successor = ptr; 11 | else if (ptr.val < successor.val) successor = ptr; 12 | } 13 | 14 | if (p.val > ptr.val) ptr = ptr.right; 15 | else ptr = ptr.left; 16 | } 17 | 18 | // Edge Case, p not found 19 | if (!p) return null; 20 | 21 | // Check if it has a right child 22 | if (ptr.right) return getMinimum(ptr.right); 23 | 24 | // No right child, return the successor we found on the way to the node 25 | return successor; 26 | }; 27 | 28 | function getMinimum(root) { 29 | while (root.left) root = root.left; 30 | return root; 31 | } 32 | -------------------------------------------------------------------------------- /Javascript/287_findTheDuplicateNumber.js: -------------------------------------------------------------------------------- 1 | var findDuplicate = function(nums) { 2 | // Initialize lo and hi pointers 3 | let lo = 0; 4 | let hi = nums.length - 1; 5 | 6 | while (lo < hi) { 7 | let mid = Math.floor((lo + hi) / 2); 8 | let count = 0; 9 | 10 | for (let i = 0; i < nums.length; i++) { 11 | if (nums[i] <= mid) count++; 12 | } 13 | 14 | if (count > mid) hi = mid; 15 | else lo = mid + 1; 16 | } 17 | 18 | return lo; 19 | }; 20 | -------------------------------------------------------------------------------- /Javascript/297_serializeAndDeserializeBT.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * function TreeNode(val) { 4 | * this.val = val; 5 | * this.left = this.right = null; 6 | * } 7 | */ 8 | 9 | /** 10 | * Encodes a tree to a single string. 11 | * 12 | * @param {TreeNode} root 13 | * @return {string} 14 | */ 15 | var serialize = function(root, arr = []) { 16 | 17 | // Return if null 18 | if (root === null) { 19 | arr.push(null); 20 | return arr; 21 | } 22 | 23 | // Add val to array, 24 | arr.push(root.val); 25 | serialize(root.left, arr); 26 | serialize(root.right, arr); 27 | 28 | return arr; 29 | }; 30 | 31 | /** 32 | * Decodes your encoded data to tree. 33 | * 34 | * @param {string} data 35 | * @return {TreeNode} 36 | */ 37 | var deserialize = function(data) { 38 | if (data[0] === null) { 39 | data.shift(); 40 | return null; 41 | } 42 | let val = data.shift(); 43 | 44 | let node = new TreeNode(val); 45 | node.left = deserialize(data); 46 | node.right = deserialize(data); 47 | 48 | return node; 49 | }; 50 | -------------------------------------------------------------------------------- /Javascript/300_longestIncreasingSubsequence.js: -------------------------------------------------------------------------------- 1 | var lengthOfLIS = function(nums) { 2 | // Edge Case 3 | if (!nums || !nums.length) return 0; 4 | 5 | const dp = new Array(nums.length).fill(1); 6 | let maxSub = 1; 7 | 8 | for (let i = nums.length - 2; i >= 0; i--) { 9 | const curNum = nums[i]; 10 | let curMaxSubSeq = 1; 11 | 12 | for (let j = i + 1; j < nums.length; j++) { 13 | 14 | if (nums[j] > curNum) { 15 | curMaxSubSeq = Math.max(curMaxSubSeq, dp[j] + 1) 16 | } 17 | } 18 | dp[i] = curMaxSubSeq; 19 | maxSub = Math.max(maxSub, curMaxSubSeq); 20 | } 21 | return maxSub; 22 | }; 23 | -------------------------------------------------------------------------------- /Javascript/301_removeInvalidParanthese.js: -------------------------------------------------------------------------------- 1 | function isParenthesis(char) { 2 | return (char === '(') || (char === ')'); 3 | } 4 | 5 | function isValid(str) { 6 | let count = 0; 7 | 8 | for (let l of str) { 9 | if (l === '(') count++; 10 | else if (l === ')') count--; 11 | 12 | if (count < 0) return false; 13 | } 14 | 15 | return count === 0; 16 | } 17 | 18 | function removeInvalidParentheses(str) { 19 | if (str.length === 0) return ['']; 20 | 21 | const sols = []; 22 | 23 | // visit set to ignore already visited string 24 | const visit = new Set(); 25 | 26 | // queue to maintain BFS 27 | const queue = []; 28 | 29 | // Used for temp string 30 | let temp; 31 | 32 | // Used to check if current level is valid 33 | let level; 34 | 35 | // pushing given string as starting node into queue 36 | queue.push(str); 37 | visit.add(str); 38 | 39 | while (queue.length) { 40 | 41 | str = queue.shift(); 42 | 43 | if (isValid(str)) { 44 | sols.push(str); 45 | 46 | // If answer is found, make level true 47 | // so that valid string of only that level 48 | // are processed. 49 | level = true; 50 | } 51 | if (level) continue; 52 | 53 | for (let i = 0; i < str.length; i++) { 54 | if (!isParenthesis(str[i])) continue; 55 | 56 | // Removing parenthesis from str and 57 | // pushing into queue,if not visited already 58 | temp = str.slice(0, i) + str.slice(i + 1); 59 | //console.log(temp); 60 | if (!visit.has(temp)) { 61 | queue.push(temp); 62 | visit.add(temp); 63 | } 64 | } 65 | } 66 | 67 | return sols; 68 | } 69 | -------------------------------------------------------------------------------- /Javascript/311_sparseMatrixMultiplication.js: -------------------------------------------------------------------------------- 1 | var multiply = function(A, B) { 2 | let mA = A.length; 3 | let nA = A[0].length; // colA 4 | let mB = B.length; // rowB 5 | let nB = B[0].length; 6 | 7 | let multMatrix = newMatrix(mA, nB); 8 | 9 | for (let r = 0; r < multMatrix.length; r++) { 10 | for (let c = 0; c < multMatrix[0].length; c++) { 11 | let res = 0; 12 | for (let i = 0; i < nA; i++) { 13 | res += A[r][i] * B[i][c] 14 | } 15 | multMatrix[r][c] = res; 16 | } 17 | } 18 | 19 | return multMatrix; 20 | }; 21 | 22 | function newMatrix(rows, cols) { 23 | let matrix = new Array(rows); 24 | for (let i = 0; i < matrix.length; i++) { 25 | matrix[i] = new Array(cols); 26 | } 27 | 28 | return matrix; 29 | } 30 | -------------------------------------------------------------------------------- /Javascript/314_binaryTreeVerticalOrderTraversal.js: -------------------------------------------------------------------------------- 1 | var verticalOrder = function(root) { 2 | if (!root) return []; 3 | 4 | root.level = 0; 5 | const lM = {}; 6 | const queue = [root]; 7 | let cLC = 1, minL = Infinity, maxL = -Infinity; 8 | 9 | while(queue.length) { 10 | let nLC = 0; 11 | 12 | while (cLC--) { 13 | const cN = queue.shift(); 14 | 15 | if (cN.left) { 16 | cN.left.level = cN.level - 1; 17 | queue.push(cN.left); 18 | nLC++; 19 | } 20 | 21 | if (cN.right) { 22 | cN.right.level = cN.level + 1; 23 | queue.push(cN.right); 24 | nLC++; 25 | } 26 | 27 | if (cN.level in lM) lM[cN.level].push(cN.val); 28 | else lM[cN.level] = [cN.val]; 29 | minL = Math.min(minL, cN.level); 30 | maxL = Math.max(maxL, cN.level); 31 | } 32 | cLC = nLC; 33 | } 34 | 35 | const vertOrderArr = []; 36 | 37 | for (let key = minL; key <= maxL; key++) { 38 | vertOrderArr.push(lM[key]); 39 | } 40 | 41 | return vertOrderArr; 42 | } 43 | -------------------------------------------------------------------------------- /Javascript/325_maximumSizeSubarraySumEqualsk.js: -------------------------------------------------------------------------------- 1 | var maxSubArrayLen = function(nums, k) { 2 | let sum = 0; 3 | let max = 0; 4 | const map = {}; 5 | 6 | 7 | for (let i = 0; i < nums.length; i++) { 8 | // Add the current element 9 | sum = sum + nums[i]; 10 | 11 | // Max must be i + 1 now since we are starting calculating sum from index 0 and we want the max subaray 12 | if (sum === k) { 13 | max = i + 1; 14 | } 15 | // Check if we've seen sum - k before, so that we can remove that subarray from our current subarray from 0 to i 16 | else if ((sum - k) in map) { 17 | max = Math.max(max, i - map[sum - k]); 18 | } 19 | // If we haven't encountered this current sum before than we want to store it in our map with the index location that it's at 20 | if (!(sum in map)) { 21 | map[sum] = i; 22 | } 23 | } 24 | 25 | return max; 26 | 27 | }; 28 | -------------------------------------------------------------------------------- /Javascript/339_nestedListWeightSum.js: -------------------------------------------------------------------------------- 1 | var depthSum = function(nestedList, level = 1) { 2 | let curSum = 0; 3 | let depthSumTotal = 0; 4 | 5 | for (let i = 0; i < nestedList.length; i++) { 6 | const curEle = nestedList[i]; 7 | 8 | if (curEle.isInteger()) { 9 | curSum += curEle.getInteger(); 10 | } 11 | else { 12 | depthSumTotal += depthSum(curEle.getList(), level + 1); 13 | } 14 | } 15 | 16 | return curSum * level + depthSumTotal; 17 | }; 18 | -------------------------------------------------------------------------------- /Javascript/342_powerOfFour.js: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Time:O(logn) 4 | Space:O(1) 5 | 6 | as long as the two rightmost bits are zero we keep shifting them off 7 | at the end we check to make sure it's 1 8 | */ 9 | const powerOfFour = (num) => { 10 | while(num && !(num & 3)){ 11 | num = num >> 2; 12 | } 13 | return (num === 1); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /Javascript/344_reverseString.js: -------------------------------------------------------------------------------- 1 | var reverseString = function(s) { 2 | let lo = 0; 3 | let hi = s.length - 1; 4 | let charArr = s.split(''); 5 | 6 | while (lo < hi) { 7 | swap(charArr, lo, hi); 8 | lo++; 9 | hi--; 10 | } 11 | 12 | return charArr.join(''); 13 | }; 14 | 15 | function swap (array, i, j) { 16 | let temp = array[i]; 17 | array[i] = array[j]; 18 | array[j] = temp; 19 | } 20 | -------------------------------------------------------------------------------- /Javascript/345_reverseVowelsOfAString.js: -------------------------------------------------------------------------------- 1 | var reverseVowels = function(s) { 2 | charArr = s.split(''); 3 | 4 | const vowels = {a: true, e: true, i: true, o: true, u: true, A: true, E: true, I: true, O: true, U: true}; 5 | 6 | let i = 0; 7 | let j = s.length - 1; 8 | 9 | while (i < j) { 10 | 11 | // Find left vowel 12 | while (!vowels[charArr[i]] && i < charArr.length ) i++; 13 | // Find right vowel 14 | while(!vowels[charArr[j]] && j >= 0) j--; 15 | 16 | if (i >= j) break; 17 | 18 | swap(charArr, i , j); 19 | i++; 20 | j--; 21 | } 22 | return charArr.join(''); 23 | }; 24 | 25 | function swap (array, i, j) { 26 | let temp = array[i]; 27 | array[i] = array[j]; 28 | array[j] = temp; 29 | } 30 | -------------------------------------------------------------------------------- /Javascript/346_moveingAverageFromDataStream.js: -------------------------------------------------------------------------------- 1 | var MovingAverage = function(size) { 2 | this.size = size; 3 | this.nums = []; 4 | this.sum = 0; 5 | }; 6 | 7 | /** 8 | * @param {number} val 9 | * @return {number} 10 | */ 11 | MovingAverage.prototype.next = function(val) { 12 | if (this.nums.length === this.size) { 13 | this.sum -= this.nums.shift(); 14 | } 15 | this.nums.push(val); 16 | this.sum += val; 17 | 18 | return this.sum/this.nums.length; 19 | }; 20 | -------------------------------------------------------------------------------- /Javascript/347_topKFrequentElements.js: -------------------------------------------------------------------------------- 1 | var topKFrequent = function(nums, k) { 2 | const hMap = new Map(); 3 | 4 | for (let i = 0; i < nums.length; i++) { 5 | if (hMap.has(nums[i]) ) hMap.set(nums[i], hMap.get(nums[i]) + 1); 6 | else hMap.set(nums[i], 1); 7 | } 8 | 9 | const buckets = new Array(nums.length + 1); 10 | 11 | hMap.forEach((val, key) => { 12 | if (!buckets[val]) buckets[val] = [key]; 13 | else buckets[val].push(key); 14 | }); 15 | 16 | const sols = []; 17 | let i = nums.length; 18 | while (i >= 0 && k > 0) { 19 | if (buckets[i] && buckets[i].length) { 20 | sols.push(buckets[i].pop()); 21 | k--; 22 | } 23 | else { 24 | i--; 25 | } 26 | } 27 | return sols; 28 | }; 29 | -------------------------------------------------------------------------------- /Javascript/348_designTicTacToe.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Initialize your data structure here. 3 | * @param {number} n 4 | */ 5 | var TicTacToe = function(n) { 6 | this.n = n; 7 | this.rows = new Array(n).fill(0); 8 | this.cols = new Array(n).fill(0); 9 | this.diag = 0; 10 | this.antiDiag = 0; 11 | 12 | }; 13 | 14 | /** 15 | * Player {player} makes a move at ({row}, {col}). 16 | @param row The row of the board. 17 | @param col The column of the board. 18 | @param player The player, can be either 1 or 2. 19 | @return The current winning condition, can be either: 20 | 0: No one wins. 21 | 1: Player 1 wins. 22 | 2: Player 2 wins. 23 | * @param {number} row 24 | * @param {number} col 25 | * @param {number} player 26 | * @return {number} 27 | [4, 0], [3, 1], [2, 2], [1, 3], [0, 4] 28 | */ 29 | TicTacToe.prototype.move = function(row, col, player) { 30 | 31 | const piece = player === 1 ? 1 : -1; 32 | 33 | this.rows[row] += piece; 34 | this.cols[col] += piece; 35 | if (row === col) this.diag += piece; 36 | if (row + col + 1 === this.n) this.antiDiag += piece; 37 | 38 | if (Math.abs(this.rows[row]) === this.n || 39 | Math.abs(this.cols[col]) === this.n || 40 | Math.abs(this.diag) === this.n || 41 | Math.abs(this.antiDiag) === this.n 42 | ) { 43 | return player; 44 | } 45 | return 0; 46 | }; 47 | -------------------------------------------------------------------------------- /Javascript/349_intersectionofTwoArrays.js: -------------------------------------------------------------------------------- 1 | var intersection = function(nums1, nums2) { 2 | let hSet = new Set(); 3 | 4 | // Add elements from nums1 to hSet 5 | for (let i = 0; i < nums1.length; i++) { 6 | hSet.add(nums1[i]); 7 | } 8 | let intersect = new Set(); 9 | 10 | for (let i = 0; i < nums2.length; i++) { 11 | if (hSet.has(nums2[i])) intersect.add(nums2[i]); 12 | } 13 | 14 | return Array.from(intersect); 15 | }; 16 | -------------------------------------------------------------------------------- /Javascript/350_intersectionsofTwoArraysII.js: -------------------------------------------------------------------------------- 1 | var intersect = function(nums1, nums2) { 2 | const hMap = {}; 3 | const intersections = []; 4 | 5 | for (let i = 0; i < nums1.length; i++) { 6 | if (hMap[nums1[i]]) hMap[nums1[i]] += 1; 7 | else hMap[nums1[i]] = 1; 8 | } 9 | 10 | for (let i = 0; i < nums2.length; i++) { 11 | if (hMap[nums2[i]]) { 12 | intersections.push(nums2[i]) 13 | hMap[nums2[i]] -= 1; 14 | } 15 | } 16 | 17 | return intersections; 18 | }; 19 | -------------------------------------------------------------------------------- /Javascript/362_designHitCounter.js: -------------------------------------------------------------------------------- 1 | var HitCounter = function() { 2 | this.hitMap = {}; 3 | }; 4 | 5 | /** 6 | * Record a hit. 7 | @param timestamp - The current timestamp (in seconds granularity). 8 | * @param {number} timestamp 9 | * @return {void} 10 | */ 11 | HitCounter.prototype.hit = function(timestamp) { 12 | if (timestamp in this.hitMap) this.hitMap[timestamp] += 1; 13 | else this.hitMap[timestamp] = 1; 14 | }; 15 | 16 | /** 17 | * Return the number of hits in the past 5 minutes. 18 | @param timestamp - The current timestamp (in seconds granularity). 19 | * @param {number} timestamp 20 | * @return {number} 21 | */ 22 | HitCounter.prototype.getHits = function(timestamp) { 23 | let startTime = timestamp - 299; 24 | let hits = 0; 25 | 26 | for (let i = startTime; i <= timestamp; i++) { 27 | if (i in this.hitMap) hits += this.hitMap[i]; 28 | } 29 | 30 | return hits; 31 | }; 32 | -------------------------------------------------------------------------------- /Javascript/364_nestedListWeightSumII.js: -------------------------------------------------------------------------------- 1 | 2 | function depthSumInverse (nestedList) { 3 | const maxDepth = getMaxDepth(nestedList); 4 | 5 | return depthSumInverseHelper(nestedList, maxDepth); 6 | } 7 | 8 | function getMaxDepth(nestedList) { 9 | let depth = 1; 10 | 11 | for (let nI of nestedList) { 12 | if (!nI.isInteger()) { 13 | depth = Math.max(depth, getMaxDepth(nI.getList()) + 1); 14 | } 15 | } 16 | return depth; 17 | } 18 | 19 | function depthSumInverseHelper(nestedList, depth) { 20 | let curSum = 0; 21 | let depthSum = 0; 22 | 23 | for (let nI of nestedList) { 24 | if (nI.isInteger()) curSum += nI.getInteger(); 25 | else depthSum += depthSumInverseHelper(nI.getList(), depth - 1); 26 | } 27 | 28 | return curSum * depth + depthSum; 29 | } 30 | -------------------------------------------------------------------------------- /Javascript/366_findLeavesOfBinaryTree.js: -------------------------------------------------------------------------------- 1 | var findLeaves = function(root) { 2 | // Edge Case 3 | if (!root) return [] 4 | 5 | const leaves = []; 6 | while (root.left || root.right) { 7 | const l = []; 8 | leaveRemover(root, l); 9 | leaves.push(l); 10 | } 11 | leaves.push(root); 12 | return leaves; 13 | }; 14 | 15 | function leaveRemover(root, leafArr) { 16 | if (!root) return false; 17 | if (!root.left && !root.right) return true; 18 | 19 | if (leaveRemover(root.left, leafArr)) { 20 | leafArr.push(root.left.val); 21 | root.left = null; 22 | } 23 | if (leaveRemover(root.right, leafArr)) { 24 | leafArr.push(root.right.val); 25 | root.right = null; 26 | } 27 | return false; 28 | } 29 | -------------------------------------------------------------------------------- /Javascript/367_validPerfectSquare.js: -------------------------------------------------------------------------------- 1 | var isPerfectSquare = function(num) { 2 | let lo = 0; 3 | let hi = num; 4 | let mid; 5 | let sqr; 6 | 7 | while (lo < hi) { 8 | mid = (lo + hi)/2; 9 | sqr = mid * mid; 10 | if (Math.abs(sqr-num) < 1) break; 11 | 12 | else if (sqr < num) lo = mid; 13 | else hi = mid; 14 | } 15 | let rounded = Math.round(mid); 16 | 17 | if (rounded * rounded === num) return true; 18 | return false; 19 | }; 20 | -------------------------------------------------------------------------------- /Javascript/383_ransomNote.js: -------------------------------------------------------------------------------- 1 | var canConstruct = function(ransomNote, magazine) { 2 | const hMap = {}; 3 | 4 | for (const c of magazine) { 5 | if (c in hMap) hMap[c] += 1; 6 | else hMap[c] = 1; 7 | } 8 | 9 | for (const c of ransomNote) { 10 | if (c in hMap && hMap[c] !== 0) { 11 | hMap[c] -= 1; 12 | } 13 | else return false; 14 | } 15 | 16 | return true; 17 | }; 18 | -------------------------------------------------------------------------------- /Javascript/387_firstUniqueCharacterInAString.js: -------------------------------------------------------------------------------- 1 | var firstUniqChar = function(s) { 2 | 3 | // Initialize hMap 4 | const hMap = {}; 5 | 6 | // Put everything in a hashMap, where the key is the letter and the val is the frequency 7 | for (let i = 0; i < s.length; i++) { 8 | const letter = s[i]; 9 | if (letter in hMap) hMap[letter] += 1; 10 | else hMap[letter] = 1; 11 | } 12 | 13 | // Iterate through string and if we encounter a letter with frequency 1 return that index; 14 | for (let i = 0; i < s.length; i++) { 15 | const l = s[i]; 16 | if (hMap[l] === 1) return i; 17 | } 18 | 19 | return -1; 20 | }; 21 | -------------------------------------------------------------------------------- /Javascript/412_fizzBuzz.js: -------------------------------------------------------------------------------- 1 | var fizzBuzz = function(n) { 2 | let arr = []; 3 | let str = '' 4 | for (let i = 1; i <= n; i++) { 5 | if (i % 3 === 0 || i % 5 === 0) { 6 | if (i % 3 === 0) str += 'Fizz'; 7 | if (i % 5 === 0) str += 'Buzz'; 8 | arr.push(str); 9 | } else { 10 | arr.push(String(i)); 11 | } 12 | str = ''; 13 | } 14 | return arr; 15 | }; 16 | -------------------------------------------------------------------------------- /Javascript/438_findAllAnagramsInAString.js: -------------------------------------------------------------------------------- 1 | var findAnagrams = function(s, p) { 2 | if (!s.length || !p.length || p.length > s.length) return []; 3 | 4 | const letters = new Array(26).fill(0); 5 | const curLetters = new Array(26).fill(0); 6 | const sols = []; 7 | 8 | for (let i = 0; i < p.length; i++) { 9 | let idx1 = p[i].charCodeAt(0) - 'a'.charCodeAt(0); 10 | let idx2 = s[i].charCodeAt(0) - 'a'.charCodeAt(0); 11 | letters[idx1] += 1; 12 | curLetters[idx2] += 1; 13 | } 14 | 15 | let lo = 0; 16 | let hi = p.length; 17 | 18 | while (hi <= s.length) { 19 | 20 | if (isAnagram(curLetters, letters)) sols.push(lo); 21 | if (hi === s.length) break; 22 | 23 | // Add new letter 24 | let idx1 = s[hi].charCodeAt(0) - 'a'.charCodeAt(0); 25 | curLetters[idx1] += 1; 26 | 27 | // Remove old letter 28 | let idx2 = s[lo].charCodeAt(0) - 'a'.charCodeAt(0); 29 | curLetters[idx2] -= 1; 30 | lo++; 31 | hi++; 32 | } 33 | 34 | return sols; 35 | }; 36 | 37 | function isAnagram(arr1, arr2) { 38 | for (let i = 0; i < arr1.length; i++) { 39 | if (arr1[i] !== arr2[i]) return false; 40 | } 41 | 42 | return true; 43 | } 44 | -------------------------------------------------------------------------------- /Javascript/442_findAllDuplicatesInAnArray.js: -------------------------------------------------------------------------------- 1 | var findDuplicates = function(nums) { 2 | let hashSet = new Set(); 3 | let returnArr = []; 4 | 5 | for (let i = 0; i < nums.length; i++) { 6 | if (hashSet.has(nums[i])) { 7 | returnArr.push(nums[i]); 8 | } 9 | else { 10 | hashSet.add(nums[i]); 11 | } 12 | } 13 | 14 | return returnArr; 15 | }; 16 | -------------------------------------------------------------------------------- /Javascript/445_addTwoNumbersII.js: -------------------------------------------------------------------------------- 1 | var addTwoNumbers = function(l1, l2) { 2 | l1 = reverseList(l1); 3 | l2 = reverseList(l2); 4 | let sum = addTwoNumbersNormal(l1, l2); 5 | return reverseList(sum); 6 | }; 7 | 8 | var reverseList = function(head) { 9 | let trail = null; 10 | let lead = head; 11 | 12 | while (lead !== null) { 13 | let nextNode = lead.next; 14 | lead.next = trail 15 | trail = lead; 16 | lead = nextNode; 17 | } 18 | return trail; 19 | }; 20 | 21 | var addTwoNumbersNormal = function(l1, l2) { 22 | // Edge Cases 23 | if (l1 === null) return l2; 24 | else if (l2 === null) return l1; 25 | 26 | // Set up variables and first node 27 | let sum = l1.val + l2.val; 28 | let carry = sum >= 10 ? 1 : 0; 29 | 30 | let newHead = new ListNode(sum % 10); 31 | 32 | let ptr1 = l1.next; 33 | let ptr2 = l2.next; 34 | let ptrNew = newHead; 35 | 36 | while (ptr1 !== null || ptr2 !== null) { 37 | // Get Values 38 | let val1 = ptr1 ? ptr1.val : 0; 39 | let val2 = ptr2 ? ptr2.val : 0; 40 | 41 | // Set up summed node 42 | let sum = val1 + val2 + carry; 43 | carry = sum >= 10 ? 1 : 0; 44 | 45 | ptrNew.next = new ListNode(sum % 10); 46 | 47 | // Move pointers 48 | ptrNew = ptrNew.next; 49 | if (ptr1) ptr1 = ptr1.next; 50 | if (ptr2) ptr2 = ptr2.next; 51 | 52 | } 53 | 54 | if (carry === 1) ptrNew.next = new ListNode(1); 55 | 56 | return newHead; 57 | 58 | }; 59 | -------------------------------------------------------------------------------- /Javascript/449_serializeAndDeserializeBST.js: -------------------------------------------------------------------------------- 1 | var serialize = function(root) { 2 | // Edge Case 3 | if (!root) return '*'; 4 | 5 | const data = []; 6 | preorderSerialize(root, data); 7 | return data.join(','); 8 | }; 9 | 10 | function preorderSerialize(root, data) { 11 | // Base Case 12 | if (!root) { 13 | data.push('*'); 14 | return; 15 | } 16 | 17 | // add to data 18 | data.push(root.val); 19 | 20 | 21 | // Go left 22 | preorderSerialize(root.left, data); 23 | 24 | // Go right 25 | preorderSerialize(root.right, data); 26 | } 27 | 28 | /** 29 | * Decodes your encoded data to tree. 30 | * 31 | * @param {string} data 32 | * @return {TreeNode} 33 | */ 34 | var deserialize = function(data) { 35 | // Edge Case 36 | if (data[0] === '*' && data.length === 1) return null; 37 | 38 | data = data.split(',').reverse(); 39 | const root = new TreeNode(+data.pop()); 40 | 41 | preorderDeserialize(root, data); 42 | 43 | return root; 44 | }; 45 | 46 | function preorderDeserialize(root, data) { 47 | // Add left node 48 | let val = data.pop(); 49 | 50 | if (val !== '*') { 51 | root.left = new TreeNode(+val); 52 | preorderDeserialize(root.left, data); 53 | } 54 | 55 | // Add right node 56 | val = data.pop(); 57 | 58 | if (val !== '*') { 59 | root.right = new TreeNode(+val); 60 | preorderDeserialize(root.right, data); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Javascript/461_hammingDistance.js: -------------------------------------------------------------------------------- 1 | var hammingDistance = function(x, y) { 2 | 3 | const one = 1; 4 | let bits = 32; 5 | let count = 0; 6 | 7 | while (bits) { 8 | if ( (x & one) !== (y & one)) count++; 9 | x = x >> 1; 10 | y = y >> 1; 11 | bits--; 12 | } 13 | 14 | return count; 15 | }; 16 | -------------------------------------------------------------------------------- /Javascript/485_maxConsecutiveOnes.js: -------------------------------------------------------------------------------- 1 | var findMaxConsecutiveOnes = function(nums) { 2 | 3 | let count = 0; 4 | let max = 0; 5 | 6 | for (let i = 0; i < nums.length; i++) { 7 | if (nums[i] === 1) count++; 8 | else count = 0; 9 | 10 | max = Math.max(count, max); 11 | } 12 | 13 | return max; 14 | }; 15 | -------------------------------------------------------------------------------- /Javascript/487_maxConsecutiveOnesII.js: -------------------------------------------------------------------------------- 1 | var findMaxConsecutiveOnes = function(nums) { 2 | let zeroCount = 0; 3 | let lastZeroIdx = -1; 4 | let count = 0; 5 | let maxCount = 0; 6 | 7 | for (let i = 0; i < nums.length; i++) { 8 | if (nums[i] === 1) count++; 9 | else { 10 | zeroCount++; 11 | if (zeroCount > 1) { 12 | count = i - lastZeroIdx; 13 | zeroCount = 1; 14 | } 15 | else count++; 16 | lastZeroIdx = i; 17 | } 18 | maxCount = Math.max(count, maxCount); 19 | } 20 | 21 | return maxCount; 22 | }; 23 | -------------------------------------------------------------------------------- /Javascript/515_finaLargestValueInEachTreeRow.js: -------------------------------------------------------------------------------- 1 | var largestValues = function(root) { 2 | // Edge Case 3 | if (!root) return []; 4 | 5 | const queue = [root]; 6 | const sol = []; 7 | let levelCount = 1; 8 | 9 | while (queue.length) { 10 | let nextLevelCount = 0 11 | let max = -Infinity; 12 | 13 | while (levelCount--) { 14 | const node = queue.pop(); 15 | 16 | if (node.left) { 17 | queue.unshift(node.left); 18 | nextLevelCount++; 19 | } 20 | 21 | if (node.right) { 22 | queue.unshift(node.right); 23 | nextLevelCount++; 24 | } 25 | 26 | max = Math.max(max, node.val); 27 | } 28 | sol.push(max); 29 | levelCount = nextLevelCount; 30 | } 31 | 32 | return sol; 33 | }; 34 | -------------------------------------------------------------------------------- /Javascript/518_CoinChange2.js: -------------------------------------------------------------------------------- 1 | var change = function(amount, denoms) { 2 | const combs = new Array(amount + 1).fill(0); 3 | combs[0] = 1; 4 | 5 | for (denom of denoms) { 6 | for (let i = denom; i < combs.length; i++) { 7 | combs[i] += combs[i - denom]; 8 | } 9 | } 10 | 11 | return combs[amount]; 12 | }; 13 | -------------------------------------------------------------------------------- /Javascript/532_kDiffPairsInArray.js: -------------------------------------------------------------------------------- 1 | var findPairs = function(nums, k) { 2 | if (k < 0) return 0; 3 | const set = k === 0 ? new Set() : new Set(nums); 4 | const counted = new Set(); 5 | let count = 0; 6 | 7 | for (let num of nums) { 8 | if (k === 0) { 9 | if (set.has(num) && !counted.has(num)) { 10 | count++; 11 | counted.add(num) 12 | } 13 | else set.add(num) 14 | } 15 | else if (set.has(num + k) && !counted.has(num)) { 16 | count++; 17 | counted.add(num); 18 | } 19 | } 20 | return count; 21 | }; 22 | -------------------------------------------------------------------------------- /Javascript/545_BoundaryOfBinaryTree.js: -------------------------------------------------------------------------------- 1 | var boundaryOfBinaryTree = function(root) { 2 | // Edge Case 3 | if (!root) return []; 4 | 5 | const output = [root.val]; 6 | printPerimeterLeft(root.left, false, output); 7 | printPerimeterRight(root.right, false, output); 8 | return output; 9 | }; 10 | 11 | function printPerimeterLeft(root, interiorFlag, output) { 12 | // Edge Case 13 | if (!root) return; 14 | 15 | // Base Case, leaf 16 | if (!root.left && !root.right) { 17 | output.push(root.val); 18 | return; 19 | } 20 | 21 | if (!interiorFlag) output.push(root.val); 22 | 23 | // Go left and keep the flag we passed in 24 | printPerimeterLeft(root.left, interiorFlag, output); 25 | 26 | // If the left subtree doesnt exist and the interior flag is false, we need to pass in the interior flag we got 27 | if (!root.left && !interiorFlag) { 28 | printPerimeterLeft(root.right, interiorFlag, output) 29 | } 30 | else { 31 | // Go right set flag to true 32 | printPerimeterLeft(root.right, true, output); 33 | } 34 | } 35 | 36 | function printPerimeterRight(root, interiorFlag, output) { 37 | // Edge Case 38 | if (!root) return; 39 | 40 | // Base Case, leaf 41 | if (!root.left && !root.right) { 42 | output.push(root.val); 43 | return; 44 | } 45 | // If the right subtree doesnt exist and the interior flag is false, we need to pass in the interior flag we got 46 | if (!root.right && !interiorFlag) { 47 | printPerimeterRight(root.left, interiorFlag, output); 48 | } 49 | else { 50 | // Go left and set flag to true 51 | printPerimeterRight(root.left, true, output); 52 | } 53 | 54 | // Go right and keep the flag we passed in 55 | printPerimeterRight(root.right, interiorFlag, output); 56 | 57 | if (!interiorFlag) output.push(root.val); 58 | } 59 | -------------------------------------------------------------------------------- /Javascript/572_subtreeOfAnotherTree.js: -------------------------------------------------------------------------------- 1 | var isSubtree = function(s, t) { 2 | // Edge Cases 3 | if (!s && !t) return true; 4 | else if(!s || !t) return false; 5 | 6 | const queue = [s]; 7 | let cLC = 1; 8 | 9 | while (queue.length) { 10 | let nLC = 0; 11 | 12 | while(cLC--) { 13 | let cN = queue.shift(); 14 | if (cN.val === t.val && isIdentical(cN, t)) return true; 15 | 16 | if (cN.left) { 17 | nLC++; 18 | queue.push(cN.left); 19 | } 20 | 21 | if (cN.right) { 22 | nLC++; 23 | queue.push(cN.right); 24 | } 25 | } 26 | 27 | cLC = nLC; 28 | } 29 | 30 | return false; 31 | }; 32 | 33 | function isIdentical(s, t) { 34 | // Edge/Base Cases 35 | if (!s && !t) return true; 36 | else if (!s || !t) return false; 37 | 38 | if (s.val !== t.val) return false; 39 | 40 | return isIdentical(s.left, t.left) && isIdentical(s.right, t.right); 41 | } 42 | -------------------------------------------------------------------------------- /Javascript/581_shortestUnsortedContinuousSubarray.js: -------------------------------------------------------------------------------- 1 | var findUnsortedSubarray = function(arr) { 2 | let i = 0; 3 | while (arr[i] <= arr[i + 1] && i < arr.length) i++; 4 | 5 | if (i === arr.length - 1) return 0; 6 | 7 | let j = arr.length - 1; 8 | while (arr[j] >= arr[j - 1]) j--; 9 | 10 | let min = Infinity; 11 | let max = -Infinity; 12 | 13 | for (let k = i; k <= j; k++) { 14 | min = Math.min(min, arr[k]); 15 | max = Math.max(max, arr[k]); 16 | } 17 | 18 | let shifts = true; 19 | 20 | while (shifts) { 21 | shifts = false 22 | if (max > arr[j]) { 23 | j++; 24 | shifts = true; 25 | } 26 | if (min < arr[i]) { 27 | i--; 28 | shifts = true; 29 | } 30 | } 31 | return j - i - 1; 32 | }; 33 | -------------------------------------------------------------------------------- /Javascript/605_canPlaceFlowers.js: -------------------------------------------------------------------------------- 1 | var canPlaceFlowers = function(flowerbed, n) { 2 | // Edge Cases 3 | if (!flowerbed || !flowerbed.length || n > Math.round(flowerbed.length/2) ) return false; 4 | if (n === 0) return true; 5 | 6 | let i = 0; 7 | while (n && i < flowerbed.length) { 8 | const prev = flowerbed[i-1] !== undefined ? flowerbed[i-1] : 0; 9 | const cur = flowerbed[i]; 10 | const next = flowerbed[i+1] !== undefined ? flowerbed[i+1] : 0; 11 | 12 | if (prev === 0 && cur === 0 && next === 0) { 13 | flowerbed[i] = 1; 14 | n--; 15 | } 16 | i++; 17 | } 18 | 19 | return n === 0; 20 | }; 21 | -------------------------------------------------------------------------------- /Javascript/633_sumofSquareNumbers.js: -------------------------------------------------------------------------------- 1 | var judgeSquareSum = function(c) { 2 | let lo = 0; 3 | let hi = Math.floor(Math.sqrt(c)); 4 | 5 | while (lo <= hi) { 6 | let val = lo * lo + hi * hi; 7 | if (val < c) lo++; 8 | else if (val > c) hi--; 9 | else return true; 10 | } 11 | 12 | return false; 13 | }; 14 | -------------------------------------------------------------------------------- /Javascript/647_palindromicSubstrings.js: -------------------------------------------------------------------------------- 1 | var countSubstrings = function(s) { 2 | let count = 0; 3 | for (let i = 0; i < s.length; i++) { 4 | // Even 5 | count += countPalindromes(s, i, i + 1); 6 | // odd 7 | count += countPalindromes(s, i, i); 8 | } 9 | 10 | return count; 11 | }; 12 | 13 | function countPalindromes(s, leftIdx, rightIdx) { 14 | let count = 0; 15 | 16 | while (leftIdx >= 0 && rightIdx < s.length && s[leftIdx] === s[rightIdx]) { 17 | count++; 18 | leftIdx--; 19 | rightIdx++; 20 | } 21 | 22 | return count; 23 | } 24 | -------------------------------------------------------------------------------- /Javascript/653_TwoSumIV-InputIsABST.js: -------------------------------------------------------------------------------- 1 | var findTarget = function(root, target) { 2 | const nums = []; 3 | inorderTraverse(root, nums); 4 | 5 | let lo = 0; 6 | let hi = nums.length - 1; 7 | 8 | while (lo < hi) { 9 | let sum = nums[lo] + nums[hi]; 10 | 11 | if (sum === target) return true; 12 | else if (sum > target) hi--; 13 | else lo++; 14 | } 15 | 16 | return false; 17 | }; 18 | 19 | function inorderTraverse(root, nums) { 20 | // Edge Case 21 | if (!root) return 22 | 23 | // Go left 24 | inorderTraverse(root.left, nums); 25 | 26 | // Visit 27 | nums.push(root.val); 28 | 29 | // Go right 30 | inorderTraverse(root.right, nums); 31 | } 32 | -------------------------------------------------------------------------------- /Javascript/654_maximumBinaryTree.js: -------------------------------------------------------------------------------- 1 | var constructMaximumBinaryTree = function(nums) { 2 | // Edge/Base Case 3 | if (!nums.length) return null; 4 | 5 | let max = -Infinity; 6 | let mIdx = -1; 7 | 8 | for (let i = 0; i < nums.length; i++) { 9 | if (nums[i] > max) { 10 | max = nums[i]; 11 | mIdx = i; 12 | } 13 | } 14 | // Create root node 15 | let root = new TreeNode(max); 16 | 17 | // Partition left half, and right half 18 | let lPart = nums.slice(0, mIdx); 19 | let rPart = nums.slice(mIdx + 1); 20 | 21 | root.left = constructMaximumBinaryTree(lPart); 22 | root.right = constructMaximumBinaryTree(rPart); 23 | 24 | return root; 25 | }; 26 | -------------------------------------------------------------------------------- /Javascript/671_secondMinimumNodeInABT.js: -------------------------------------------------------------------------------- 1 | var findSecondMinimumValue = function(root) { 2 | let min = Infinity; 3 | let secondMin = Infinity; 4 | return findSecond(root); 5 | 6 | function findSecond(root) { 7 | // Edge/Base Case 8 | if (!root) return null; 9 | 10 | // Check if its second min 11 | if (root.val < min) { 12 | secMin = min; 13 | min = root.val; 14 | } 15 | else if (root.val < secMin && root.val > min) { 16 | secMin = root.val; 17 | } 18 | 19 | findSecond(root.left); 20 | findSecond(root.right); 21 | 22 | if (secMin === Infinity) return -1; 23 | return secMin; 24 | } 25 | 26 | }; 27 | -------------------------------------------------------------------------------- /Javascript/680_validPalindromeII.js: -------------------------------------------------------------------------------- 1 | var validPalindrome = function(str) { 2 | let i = 0, j = str.length - 1; 3 | 4 | while (i < j) { 5 | if (str[i] === str[j]) { 6 | i++; 7 | j--; 8 | } 9 | else { 10 | return isPalindrome(str.slice(i, j)) || isPalindrome(str.slice(i+1, j+1)); 11 | } 12 | } 13 | 14 | return true; 15 | }; 16 | 17 | var isPalindrome = function(s) { 18 | let i = 0, j = s.length - 1; 19 | 20 | while (i <= j) { 21 | // Move i and j until both on valid letters 22 | if (!isLetter(s[i])) { 23 | i++; 24 | continue; 25 | } 26 | if(!isLetter(s[j])) { 27 | j--; 28 | continue; 29 | } 30 | // check if they satisfy a palindrome 31 | if (s[i].toLowerCase() !== s[j].toLowerCase()) { 32 | return false; 33 | } 34 | else { 35 | i++; 36 | j--; 37 | } 38 | } 39 | return true; 40 | }; 41 | 42 | function isLetter(str) { 43 | return str.length === 1 && str.match(/[a-z]/i) || (str >= '0' && str <= '9'); 44 | } 45 | -------------------------------------------------------------------------------- /Javascript/682_baseballGame.js: -------------------------------------------------------------------------------- 1 | var calPoints = function(ops) { 2 | // Initialize a stack 3 | const stack = []; 4 | let sum = 0; 5 | 6 | for (let l of ops) { 7 | 8 | if (isNum(l)) { 9 | sum += +l; 10 | stack.push(+l); 11 | } 12 | else if (l === 'C') { 13 | let invalidNum = stack.pop(); 14 | sum -= invalidNum; 15 | } 16 | else if (l === 'D') { 17 | let newNum = stack[stack.length - 1] * 2; 18 | sum += newNum; 19 | stack.push(newNum); 20 | } 21 | else if (l === '+') { 22 | let num1 = +stack[stack.length - 1]; 23 | let num2 = +stack[stack.length - 2]; 24 | sum += num1 + num2; 25 | stack.push(num1 + num2); 26 | } 27 | } 28 | 29 | return sum; 30 | }; 31 | 32 | function isNum(letter) { 33 | return letter !== '+' && letter != 'C' && letter != 'D'; 34 | } 35 | -------------------------------------------------------------------------------- /Javascript/692_topKFrequentWords.js: -------------------------------------------------------------------------------- 1 | var topKFrequent = function(words, k) { 2 | const map = {}; 3 | 4 | for (let word of words) { 5 | if (word in map) map[word] += 1; 6 | else map[word] = 1; 7 | } 8 | 9 | const buckets = new Array(words.length); 10 | 11 | for (let i = 0; i < buckets.length; i++) { 12 | buckets[i] = []; 13 | } 14 | 15 | for (let key in map) { 16 | buckets[map[key]].push(key); 17 | } 18 | const sol = []; 19 | 20 | for (let i = buckets.length - 1; i >= 0; i--) { 21 | if (k === 0) break; 22 | 23 | if (buckets[i].length) { 24 | buckets[i].sort(); 25 | 26 | for (let j = 0; j < buckets[i].length; j++) { 27 | let word = buckets[i][j] 28 | sol.push(word); 29 | k--; 30 | if (k === 0) break; 31 | } 32 | } 33 | } 34 | 35 | return sol; 36 | }; 37 | -------------------------------------------------------------------------------- /Javascript/693_binaryNumberWithAlternatingBits.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BakeItTillYouMakeIt/LeetCodeJS/f8269e75ef6f9d88a5aa13e012e9f116c3dfddf4/Javascript/693_binaryNumberWithAlternatingBits.js -------------------------------------------------------------------------------- /Javascript/698_partitionToKEqualSumSubsets.js: -------------------------------------------------------------------------------- 1 | var canPartitionKSubsets = function(nums, k) { 2 | let n = nums.length; 3 | // The entire array can be partitioned 4 | if (k === 1) return true; 5 | 6 | // If total number of partitions are more than N, then we know its not possible 7 | if (n < k) return false; 8 | 9 | // Check to see if the sum is divisible by k 10 | let sum = 0; 11 | for (let num of nums) sum += num; 12 | if (sum % k !== 0) return false; 13 | 14 | // Each subset now should have a sum of sum/k 15 | const subset = sum / k; 16 | 17 | const subsetSum = new Array(k).fill(0); 18 | const taken = new Array(n).fill(false); 19 | 20 | // Initialize first subset sum as the last element of the array 21 | subsetSum[0] = nums[n-1]; 22 | taken[n-1] = true; 23 | 24 | return canPartitionHelper(nums, subsetSum, taken, subset, k, n, 0, n-2); 25 | 26 | }; 27 | 28 | function canPartitionHelper(nums, subsetSum, taken, subset, k, n, curIdx, limitIdx) { 29 | 30 | if (subsetSum[curIdx] === subset) { 31 | /* current index (K - 2) represents (K - 1) subsets of equal 32 | sum last partition will already remain with sum 'subset'*/ 33 | if (curIdx === k - 2) return true; 34 | 35 | // recursive call for next subsetition 36 | return canPartitionHelper(nums, subsetSum, taken, subset, k, n, curIdx + 1, n - 1); 37 | } 38 | 39 | for (let i = limitIdx; i >= 0; i--) { 40 | // If already taken, continue 41 | if (taken[i]) continue; 42 | 43 | let temp = subsetSum[curIdx] + nums[i]; 44 | if (temp <= subset) { 45 | 46 | // mark the element and include into current partition sum 47 | taken[i] = true; 48 | subsetSum[curIdx] += nums[i]; 49 | let nxt = canPartitionHelper(nums, subsetSum, taken, subset, k, n, curIdx, i - 1); 50 | 51 | // after recursive call unmark the element and remove from subset sum 52 | taken[i] = false; 53 | subsetSum[curIdx] -= nums[i]; 54 | if (nxt) return true; 55 | 56 | } 57 | } 58 | 59 | return false; 60 | } 61 | -------------------------------------------------------------------------------- /Javascript/714_BestTimeToBuyAndSellStockWithTransactionFee.js: -------------------------------------------------------------------------------- 1 | const maxProfit = (prices, fee) => { 2 | if (prices.length <= 1) return 0; 3 | let buy = new Array(prices.length).fill(0) 4 | let hold = new Array(prices.length).fill(0) 5 | let skip = new Array(prices.length).fill(0) 6 | let sell = new Array(prices.length).fill(0) 7 | // the moment we buy a stock, our balance should decrease 8 | buy[0] = 0 - prices[0]; 9 | // assume if we have stock in the first day, we are still in deficit 10 | hold[0] = 0 - prices[0]; 11 | for (let i = 1; i < prices.length; i++) { 12 | // We can only buy today if we sold stock 13 | // or skipped with empty portfolio yesterday 14 | buy[i] = Math.max(skip[i - 1], sell[i - 1]) - prices[i]; 15 | // Can only hold if we bought or already holding stock yesterday 16 | hold[i] = Math.max(buy[i - 1], hold[i - 1]); 17 | // Can skip only if we skipped, or sold stock yesterday 18 | skip[i] = Math.max(skip[i - 1], sell[i - 1]); 19 | // Can sell only if we bought, or held stock yesterday 20 | sell[i] = Math.max(buy[i - 1], hold[i - 1]) + prices[i] - fee; 21 | } 22 | // Get the max of all the 4 actions on the last day. 23 | let max = Math.max(buy[prices.length - 1], hold[prices.length - 1]); 24 | max = Math.max(skip[prices.length - 1], max); 25 | max = Math.max(sell[prices.length - 1], max); 26 | return Math.max(max, 0); 27 | } 28 | -------------------------------------------------------------------------------- /Javascript/716_MaxStack.js: -------------------------------------------------------------------------------- 1 | var MaxStack = function() { 2 | this.stack = []; 3 | this.maxStack = []; 4 | }; 5 | 6 | /** 7 | * @param {number} x 8 | * @return {void} 9 | */ 10 | MaxStack.prototype.push = function(x) { 11 | let max = this.maxStack.length === 0 ? x : this.maxStack[this.maxStack.length - 1]; 12 | this.maxStack.push(max > x ? max : x); 13 | this.stack.push(x); 14 | }; 15 | 16 | /** 17 | * @return {number} 18 | */ 19 | MaxStack.prototype.pop = function() { 20 | this.maxStack.pop(); 21 | return this.stack.pop(); 22 | }; 23 | 24 | /** 25 | * @return {number} 26 | */ 27 | MaxStack.prototype.top = function() { 28 | return this.stack[this.stack.length - 1]; 29 | }; 30 | 31 | /** 32 | * @return {number} 33 | */ 34 | MaxStack.prototype.peekMax = function() { 35 | return this.maxStack[this.maxStack.length - 1]; 36 | }; 37 | 38 | /** 39 | * @return {number} 40 | */ 41 | MaxStack.prototype.popMax = function() { 42 | let max = this.peekMax(); 43 | let buffer = []; 44 | while (this.top() != max) buffer.push(this.pop()); 45 | this.pop(); 46 | while (buffer.length) this.push(buffer.pop()); 47 | return max; 48 | }; 49 | -------------------------------------------------------------------------------- /Javascript/744_FindSmallestLetterGreaterThanTarget.js: -------------------------------------------------------------------------------- 1 | var nextGreatestLetter = function(letters, target) { 2 | // Edge Case 3 | let minTarget = ''; 4 | 5 | for (let i = 0; i < letters.length; i++) { 6 | const curLetter = letters[i]; 7 | 8 | if (curLetter > target) { 9 | if (minTarget === '') minTarget = curLetter; 10 | else if (curLetter < minTarget) minTarget = curLetter; 11 | } 12 | } 13 | 14 | if (minTarget === '') return letters[0]; 15 | return minTarget; 16 | }; 17 | -------------------------------------------------------------------------------- /Javascript/763_partitionLabels.js: -------------------------------------------------------------------------------- 1 | var partitionLabels = function(str) { 2 | const lastLetterIndex = {}; 3 | 4 | for (let i = 0; i < str.length; i++) { 5 | const letter = str[i]; 6 | lastLetterIndex[letter] = i; 7 | } 8 | 9 | let start = 0; 10 | let end = 0; 11 | const sols = []; 12 | 13 | for (let i = 0; i < str.length; i++) { 14 | // Get letter 15 | const letter = str[i]; 16 | 17 | // Get last index of this letter 18 | end = Math.max(end, lastLetterIndex[letter]); 19 | 20 | if (i === end) { 21 | sols.push(end + 1 - start); 22 | start = end + 1; 23 | } 24 | } 25 | return sols; 26 | }; 27 | -------------------------------------------------------------------------------- /Javascript/RELATIVE_PATH_HERE.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This problem has not yet been added! 4 | 5 | If you wish to add it feel free to do so :) 6 | 7 | 8 | 9 | Please use camel case, and use the name of the problem to name the file. Ex: 10 | 11 | Problem: Single Number # 136 12 | file: 136_singleNumber.js 13 | 14 | If the problem number is less than three digits please zero fill it: 15 | Problem: 1 Two Sum 16 | File: 001_twoSum.js 17 | 18 | 19 | In the read me locate the problem and make sure to update it so it links to the correct solution. 20 | 21 | Before: 22 | [Javascript](./Javascript/RELATIVE_PATH_HERE.js) Under Construction 23 | 24 | After: 25 | [Javascript](./Javascript/136_singleNumber.js) 26 | 27 | */ -------------------------------------------------------------------------------- /MySQL/average-salary-departments-vs-company.sql: -------------------------------------------------------------------------------- 1 | # Time: O(nlogn) 2 | # Space: O(n) 3 | 4 | SELECT department_salary.pay_month, department_id, 5 | CASE 6 | WHEN department_avg < company_avg THEN 'lower' 7 | WHEN department_avg > company_avg THEN 'higher' 8 | ELSE 'same' 9 | END AS comparison 10 | FROM 11 | ( 12 | SELECT department_id, AVG(amount) AS department_avg, date_format(pay_date, '%Y-%m') AS pay_month 13 | FROM salary JOIN employee ON salary.employee_id = employee.employee_id 14 | GROUP BY department_id, pay_month 15 | ) AS department_salary 16 | JOIN 17 | ( 18 | SELECT AVG(amount) AS company_avg, date_format(pay_date, '%Y-%m') AS pay_month 19 | FROM salary 20 | GROUP BY date_format(pay_date, '%Y-%m') 21 | ) AS company_salary 22 | ON department_salary.pay_month = company_salary.pay_month 23 | ; 24 | -------------------------------------------------------------------------------- /MySQL/big-countries.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | 4 | # There is a table World 5 | # +-----------------+------------+------------+--------------+---------------+ 6 | # | name | continent | area | population | gdp | 7 | # +-----------------+------------+------------+--------------+---------------+ 8 | # | Afghanistan | Asia | 652230 | 25500100 | 20343000 | 9 | # | Albania | Europe | 28748 | 2831741 | 12960000 | 10 | # | Algeria | Africa | 2381741 | 37100000 | 188681000 | 11 | # | Andorra | Europe | 468 | 78115 | 3712000 | 12 | # | Angola | Africa | 1246700 | 20609294 | 100990000 | 13 | # +-----------------+------------+------------+--------------+---------------+ 14 | # 15 | # A country is big if it has an area of bigger than 3 million square km or a population of more than 25 million. 16 | # Write a SQL solution to output big countries' name, population and area. 17 | # For example, according to the above table, we should output: 18 | # +--------------+-------------+--------------+ 19 | # | name | population | area | 20 | # +--------------+-------------+--------------+ 21 | # | Afghanistan | 25500100 | 652230 | 22 | # | Algeria | 37100000 | 2381741 | 23 | # +--------------+-------------+--------------+ 24 | 25 | SELECT name, population, area 26 | FROM World 27 | WHERE area > 3000000 OR population > 25000000; 28 | -------------------------------------------------------------------------------- /MySQL/biggest-single-number.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(n) 3 | 4 | SELECT 5 | IFNULL( 6 | (SELECT 7 | MAX(num) 8 | FROM 9 | (SELECT 10 | num 11 | FROM 12 | number 13 | GROUP BY num 14 | HAVING COUNT(num) = 1 15 | ORDER BY NULL) AS t 16 | ) 17 | , NULL 18 | ) AS num 19 | ; 20 | -------------------------------------------------------------------------------- /MySQL/classes-more-than-5-students.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(n) 3 | 4 | # There is a table courses with columns: student and class 5 | # Please list out all classes which have more than or equal to 5 students. 6 | # For example, the table: 7 | # +---------+------------+ 8 | # | student | class | 9 | # +---------+------------+ 10 | # | A | Math | 11 | # | B | English | 12 | # | C | Math | 13 | # | D | Biology | 14 | # | E | Math | 15 | # | F | Computer | 16 | # | G | Math | 17 | # | H | Math | 18 | # | I | Math | 19 | # +---------+------------+ 20 | # 21 | # Should output: 22 | # +---------+ 23 | # | class | 24 | # +---------+ 25 | # | Math | 26 | # +---------+ 27 | # 28 | # Note: 29 | # The students should not be counted duplicate in each course. 30 | 31 | SELECT class 32 | FROM courses 33 | GROUP BY class 34 | HAVING COUNT(DISTINCT student) >= 5 35 | ORDER BY NULL; 36 | -------------------------------------------------------------------------------- /MySQL/combine-two-tables.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n), n is size of Person Table 2 | # Space: O(n) 3 | # 4 | # Table: Person 5 | # 6 | # +-------------+---------+ 7 | # | Column Name | Type | 8 | # +-------------+---------+ 9 | # | PersonId | int | 10 | # | FirstName | varchar | 11 | # | LastName | varchar | 12 | # +-------------+---------+ 13 | # PersonId is the primary key column for this table. 14 | # Table: Address 15 | # 16 | # +-------------+---------+ 17 | # | Column Name | Type | 18 | # +-------------+---------+ 19 | # | AddressId | int | 20 | # | PersonId | int | 21 | # | City | varchar | 22 | # | State | varchar | 23 | # +-------------+---------+ 24 | # AddressId is the primary key column for this table. 25 | # 26 | # Write a SQL query for a report that provides the following information for each person in the Person table, regardless if there is an address for each of those people: 27 | # 28 | #FirstName, LastName, City, State 29 | # 30 | # 31 | # Write your MySQL query statement below 32 | SELECT FirstName, LastName, City, State FROM Person LEFT JOIN Address 33 | ON Person.PersonId=Address.PersonId 34 | 35 | -------------------------------------------------------------------------------- /MySQL/consecutive-available-seats.sql: -------------------------------------------------------------------------------- 1 | # Time: O(nlogn) 2 | # Space: O(n) 3 | 4 | SELECT DISTINCT c1.seat_id 5 | FROM cinema c1 JOIN cinema c2 6 | ON ((c1.seat_id = c2.seat_id - 1) OR (c1.seat_id = c2.seat_id + 1)) 7 | AND c1.free = true AND c2.free = true 8 | ORDER BY c1.seat_id 9 | ; 10 | -------------------------------------------------------------------------------- /MySQL/consecutive-numbers.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(n) 3 | # 4 | # Write a SQL query to find all numbers that appear at least three times consecutively. 5 | # 6 | # +----+-----+ 7 | # | Id | Num | 8 | # +----+-----+ 9 | # | 1 | 1 | 10 | # | 2 | 1 | 11 | # | 3 | 1 | 12 | # | 4 | 2 | 13 | # | 5 | 1 | 14 | # | 6 | 2 | 15 | # | 7 | 2 | 16 | # +----+-----+ 17 | # For example, given the above Logs table, 1 is the only number that appears consecutively for at least three times. 18 | # 19 | 20 | # Solution 1 21 | # Write your MySQL query statement below 22 | SELECT DISTINCT(Num) AS ConsecutiveNums 23 | FROM ( 24 | SELECT 25 | Num, 26 | @counter := IF(@prev = Num, @counter + 1, 1) AS how_many_cnt_in_a_row, 27 | @prev := Num 28 | FROM Logs y, (SELECT @counter:=1, @prev:=NULL) vars 29 | ) sq 30 | WHERE how_many_cnt_in_a_row >= 3 31 | 32 | # Solution 2 33 | SELECT DISTINCT l1.Num as ConsecutiveNums 34 | FROM Logs l1, Logs l2, Logs l3 35 | WHERE l1.Id + 1 = l2.Id AND l2.Id + 1 = l3.Id AND l1.Num = l2.Num AND l2.Num = l3.Num 36 | -------------------------------------------------------------------------------- /MySQL/count-student-number-in-departments.sql: -------------------------------------------------------------------------------- 1 | # Time: O(s+dlogd) 2 | # Space: O(d+s) 3 | 4 | SELECT 5 | dept_name, COUNT(student_id) AS student_number 6 | FROM 7 | department 8 | LEFT JOIN 9 | student ON department.dept_id = student.dept_id 10 | GROUP BY department.dept_name 11 | ORDER BY student_number DESC , department.dept_name 12 | ; 13 | -------------------------------------------------------------------------------- /MySQL/customer-placing-the-largest-number-of-orders.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(n) 3 | 4 | SELECT customer_number 5 | FROM orders 6 | GROUP BY customer_number 7 | HAVING COUNT(order_number) = 8 | (SELECT MAX(*) 9 | FROM 10 | (SELECT COUNT(*) AS cnt 11 | FROM 12 | orders 13 | GROUP BY customer_number 14 | ORDER BY NULL 15 | ) AS cnt_tbl 16 | ) 17 | ORDER BY NULL 18 | LIMIT 1 19 | ; 20 | -------------------------------------------------------------------------------- /MySQL/customers-who-never-order.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(1) 3 | # 4 | # Suppose that a website contains two tables, the Customers table and the Orders table. Write a SQL query to find all customers who never order anything. 5 | # 6 | # Table: Customers. 7 | # 8 | # +----+-------+ 9 | # | Id | Name | 10 | # +----+-------+ 11 | # | 1 | Joe | 12 | # | 2 | Henry | 13 | # | 3 | Sam | 14 | # | 4 | Max | 15 | # +----+-------+ 16 | # Table: Orders. 17 | # 18 | # +----+------------+ 19 | # | Id | CustomerId | 20 | # +----+------------+ 21 | # | 1 | 3 | 22 | # | 2 | 1 | 23 | # +----+------------+ 24 | # Using the above tables as example, return the following: 25 | # 26 | # +-----------+ 27 | # | Customers | 28 | # +-----------+ 29 | # | Henry | 30 | # | Max | 31 | # +-----------+ 32 | # 33 | 34 | # Time: O(n^2) 35 | # Space: O(1) 36 | # Write your MySQL query statement below 37 | SELECT Name AS Customers FROM Customers WHERE Id NOT IN (SELECT CustomerId FROM Orders) 38 | 39 | # Time: O(n^2) 40 | # Space: O(n) 41 | # Write your MySQL query statement below 42 | SELECT Customers.Name AS Customers FROM (Customers LEFT JOIN Orders ON Customers.Id = Orders.CustomerId) WHERE Orders.CustomerId IS NULL 43 | -------------------------------------------------------------------------------- /MySQL/delete-duplicate-emails.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n) 3 | # 4 | # Write a SQL query to delete all duplicate email entries in a table named Person, 5 | # keeping only unique emails based on its smallest Id. 6 | # 7 | # +----+------------------+ 8 | # | Id | Email | 9 | # +----+------------------+ 10 | # | 1 | john@example.com | 11 | # | 2 | bob@example.com | 12 | # | 3 | john@example.com | 13 | # +----+------------------+ 14 | # Id is the primary key column for this table. 15 | # For example, after running your query, the above Person table should have the following rows: 16 | # 17 | # +----+------------------+ 18 | # | Id | Email | 19 | # +----+------------------+ 20 | # | 1 | john@example.com | 21 | # | 2 | bob@example.com | 22 | # +----+------------------+ 23 | # 24 | 25 | # Write your MySQL query statement below 26 | DELETE p1 27 | FROM Person p1, Person p2 28 | WHERE p1.Email = p2.Email AND p1.Id > p2.Id 29 | -------------------------------------------------------------------------------- /MySQL/department-highest-salary.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n) 3 | # 4 | # The Employee table holds all employees. Every employee has an Id, a salary, and there is also a column for the department Id. 5 | # 6 | # +----+-------+--------+--------------+ 7 | # | Id | Name | Salary | DepartmentId | 8 | # +----+-------+--------+--------------+ 9 | # | 1 | Joe | 70000 | 1 | 10 | # | 2 | Henry | 80000 | 2 | 11 | # | 3 | Sam | 60000 | 2 | 12 | # | 4 | Max | 90000 | 1 | 13 | # +----+-------+--------+--------------+ 14 | # The Department table holds all departments of the company. 15 | # 16 | # +----+----------+ 17 | # | Id | Name | 18 | # +----+----------+ 19 | # | 1 | IT | 20 | # | 2 | Sales | 21 | # +----+----------+ 22 | # Write a SQL query to find employees who have the highest salary in each of the departments. For the above tables, Max has the highest salary in the IT department and Henry has the highest salary in the Sales department. 23 | # 24 | # +------------+----------+--------+ 25 | # | Department | Employee | Salary | 26 | # +------------+----------+--------+ 27 | # | IT | Max | 90000 | 28 | # | Sales | Henry | 80000 | 29 | # +------------+----------+--------+ 30 | # 31 | # Write your MySQL query statement below 32 | SELECT d.Department AS Department, e.Name AS Employee, d.Salary AS Salary 33 | FROM (SELECT Department.Id AS DepartmentId, Department.Name AS Department, emp.Salary AS Salary 34 | FROM Department JOIN (SELECT DepartmentId, MAX(Salary) AS Salary FROM Employee GROUP BY DepartmentId) emp 35 | ON Department.Id = emp.DepartmentId) d 36 | JOIN Employee e 37 | ON e.DepartmentId = d.DepartmentId and e.Salary = d.Salary 38 | 39 | # Write your MySQL query statement below 40 | SELECT Department.Name AS Department, Employee.Name AS Employee, Employee.Salary AS Salary 41 | FROM Department JOIN Employee ON Employee.DepartmentId = Department.Id 42 | WHERE Employee.Salary IN (SELECT MAX(e.Salary) FROM Employee e WHERE e.DepartmentId = Employee.DepartmentId) 43 | -------------------------------------------------------------------------------- /MySQL/department-top-three-salaries.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n) 3 | # 4 | # The Employee table holds all employees. Every employee has an Id, and there is also a column for the department Id. 5 | # 6 | # +----+-------+--------+--------------+ 7 | # | Id | Name | Salary | DepartmentId | 8 | # +----+-------+--------+--------------+ 9 | # | 1 | Joe | 70000 | 1 | 10 | # | 2 | Henry | 80000 | 2 | 11 | # | 3 | Sam | 60000 | 2 | 12 | # | 4 | Max | 90000 | 1 | 13 | # | 5 | Janet | 69000 | 1 | 14 | # | 6 | Randy | 85000 | 1 | 15 | # +----+-------+--------+--------------+ 16 | # The Department table holds all departments of the company. 17 | # 18 | # +----+----------+ 19 | # | Id | Name | 20 | # +----+----------+ 21 | # | 1 | IT | 22 | # | 2 | Sales | 23 | # +----+----------+ 24 | # Write a SQL query to find employees who earn the top three salaries in each of the department. For the above tables, your SQL query should return the following rows. 25 | # 26 | # +------------+----------+--------+ 27 | # | Department | Employee | Salary | 28 | # +------------+----------+--------+ 29 | # | IT | Max | 90000 | 30 | # | IT | Randy | 85000 | 31 | # | IT | Joe | 70000 | 32 | # | Sales | Henry | 80000 | 33 | # | Sales | Sam | 60000 | 34 | # +------------+----------+--------+ 35 | 36 | # Write your MySQL query statement below 37 | SELECT D.Name AS Department, E.Name AS Employee, E.Salary AS Salary 38 | FROM Employee E INNER JOIN Department D ON E.DepartmentId = D.Id 39 | WHERE (SELECT COUNT(DISTINCT(Salary)) FROM Employee 40 | WHERE DepartmentId = E.DepartmentId AND Salary > E.Salary) < 3 41 | ORDER by E.DepartmentId, E.Salary DESC; 42 | -------------------------------------------------------------------------------- /MySQL/duplicate-emails.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n) 3 | # 4 | # Write a SQL query to find all duplicate emails in a table named Person. 5 | # 6 | # +----+---------+ 7 | # | Id | Email | 8 | # +----+---------+ 9 | # | 1 | a@b.com | 10 | # | 2 | c@d.com | 11 | # | 3 | a@b.com | 12 | # +----+---------+ 13 | # For example, your query should return the following for the above table: 14 | # 15 | # +---------+ 16 | # | Email | 17 | # +---------+ 18 | # | a@b.com | 19 | # +---------+ 20 | # Note: All emails are in lowercase. 21 | # 22 | 23 | # Write your MySQL query statement below 24 | SELECT Email FROM Person GROUP BY Email HAVING COUNT(*) > 1 25 | -------------------------------------------------------------------------------- /MySQL/employee-bonus.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n) if hash join, O(nlogn) if merge join 2 | # Space: O(n) 3 | 4 | # https://www.quora.com/What-is-time-complexity-of-Join-algorithm-in-Database 5 | 6 | SELECT 7 | Employee.name, Bonus.bonus 8 | FROM 9 | Employee 10 | LEFT JOIN 11 | Bonus ON Employee.empid = Bonus.empid 12 | WHERE 13 | Bonus.bonus < 1000 OR Bonus.bonus IS NULL 14 | ; 15 | -------------------------------------------------------------------------------- /MySQL/employees-earning-more-than-their-managers.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(1) 3 | # 4 | # The Employee table holds all employees including their managers. Every employee has an Id, and there is also a column for the manager Id. 5 | # 6 | # +----+-------+--------+-----------+ 7 | # | Id | Name | Salary | ManagerId | 8 | # +----+-------+--------+-----------+ 9 | # | 1 | Joe | 70000 | 3 | 10 | # | 2 | Henry | 80000 | 4 | 11 | # | 3 | Sam | 60000 | NULL | 12 | # | 4 | Max | 90000 | NULL | 13 | # +----+-------+--------+-----------+ 14 | # Given the Employee table, write a SQL query that finds out employees who earn more than their managers. For the above table, Joe is the only employee who earns more than his manager. 15 | # 16 | # +----------+ 17 | # | Employee | 18 | # +----------+ 19 | # | Joe | 20 | # +----------+ 21 | # 22 | 23 | # Time: O(n^2) 24 | # Space: O(n) 25 | # Write your MySQL query statement below 26 | SELECT e.Name AS Employee FROM Employee e LEFT JOIN Employee b 27 | ON e.ManagerId=b.Id 28 | WHERE e.Salary > b.Salary 29 | 30 | # Time: O(n^2) 31 | # Space: O(1) 32 | # Write your MySQL query statement below 33 | SELECT Name AS Employee 34 | FROM Employee e 35 | WHERE e.ManagerId IS NOT NULL AND e.Salary > (SELECT Salary 36 | FROM Employee 37 | WHERE e.ManagerId = Id) 38 | -------------------------------------------------------------------------------- /MySQL/exchange-seats.sql: -------------------------------------------------------------------------------- 1 | # Time: O(nlogn) 2 | # Space: O(n) 3 | 4 | # Mary is a teacher in a middle school and she has a table seat storing 5 | # students' names and their corresponding seat ids. 6 | # 7 | # The column id is continuous increment. 8 | # Mary wants to change seats for the adjacent students. 9 | # Can you write a SQL query to output the result for Mary? 10 | # +---------+---------+ 11 | # | id | student | 12 | # +---------+---------+ 13 | # | 1 | Abbot | 14 | # | 2 | Doris | 15 | # | 3 | Emerson | 16 | # | 4 | Green | 17 | # | 5 | Jeames | 18 | # +---------+---------+ 19 | # 20 | # For the sample input, the output is: 21 | # +---------+---------+ 22 | # | id | student | 23 | # +---------+---------+ 24 | # | 1 | Doris | 25 | # | 2 | Abbot | 26 | # | 3 | Green | 27 | # | 4 | Emerson | 28 | # | 5 | Jeames | 29 | # +---------+---------+ 30 | # 31 | # Note: 32 | # If the number of students is odd, there is no need to change the last one's seat. 33 | 34 | SELECT 35 | s1.id, COALESCE(s2.student, s1.student) AS student 36 | FROM 37 | seat s1 38 | LEFT JOIN 39 | seat s2 ON ((s1.id + 1) ^ 1) - 1 = s2.id 40 | ORDER BY s1.id; 41 | -------------------------------------------------------------------------------- /MySQL/find-cumulative-salary-of-an-employee.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n) 3 | 4 | SELECT EA.Id, 5 | EA.Month, 6 | SUM(EB.salary) AS Salary 7 | FROM (SELECT E1.* 8 | FROM employee E1 9 | LEFT JOIN (SELECT id, 10 | MAX(month) AS month 11 | FROM employee 12 | GROUP BY id) E2 13 | ON E1.id = E2.id 14 | WHERE E1.month < E2.month) EA 15 | LEFT JOIN employee EB 16 | ON EA.id = EB.id 17 | WHERE EA.month - 2 <= EB.month 18 | AND EB.month <= EA.month 19 | GROUP BY EA.id, 20 | EA.month 21 | ORDER BY EA.id, 22 | month DESC 23 | -------------------------------------------------------------------------------- /MySQL/find-customer-referee.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | 4 | SELECT name 5 | FROM customer 6 | WHERE referee_id is NULL OR referee_id != 2; 7 | -------------------------------------------------------------------------------- /MySQL/find-median-given-frequency-of-numbers.sql: -------------------------------------------------------------------------------- 1 | # Time: O(nlogn) 2 | # Space: O(n) 3 | 4 | SELECT AVG(n.Number) AS median 5 | FROM Numbers n LEFT JOIN 6 | ( 7 | SELECT Number, @prev := @count AS prevNumber, (@count := @count + Frequency) AS countNumber 8 | FROM Numbers, 9 | (SELECT @count := 0, @prev := 0, @total := (SELECT SUM(Frequency) FROM Numbers)) temp ORDER BY Number 10 | ) n2 11 | ON n.Number = n2.Number 12 | WHERE 13 | (prevNumber < floor((@total+1)/2) AND countNumber >= floor((@total+1)/2)) 14 | OR 15 | (prevNumber < floor((@total+2)/2) AND countNumber >= floor((@total+2)/2)) 16 | -------------------------------------------------------------------------------- /MySQL/friend-requests-i-overall-acceptance-rate.sql: -------------------------------------------------------------------------------- 1 | # Time: O(rlogr + aloga) 2 | # Space: O(r + a) 3 | 4 | SELECT 5 | ROUND( 6 | IFNULL( 7 | (SELECT COUNT(*) FROM (SELECT DISTINCT requester_id, accepter_id FROM request_accepted) AS r) 8 | / 9 | (SELECT COUNT(*) FROM (SELECT DISTINCT sender_id, send_to_id FROM friend_request) AS a), 10 | 0) 11 | , 2) AS accept_rate; 12 | -------------------------------------------------------------------------------- /MySQL/friend-requests-ii-who-has-the-most-friends.sql: -------------------------------------------------------------------------------- 1 | # Time: O(nlogn) 2 | # Space: O(n) 3 | 4 | SELECT ids as id, COUNT(*) AS num 5 | FROM 6 | ( 7 | SELECT requester_id AS ids FROM request_accepted 8 | UNION ALL 9 | SELECT accepter_id FROM request_accepted 10 | ) AS tmp 11 | GROUP BY ids 12 | ORDER BY num DESC 13 | LIMIT 1 14 | ; 15 | -------------------------------------------------------------------------------- /MySQL/get-highest-answer-rate-question.sql: -------------------------------------------------------------------------------- 1 | # Time: O(nlogn) 2 | # Space: O(n) 3 | 4 | SELECT 5 | question_id AS 'survey_log' 6 | FROM 7 | survey_log 8 | GROUP BY question_id 9 | ORDER BY COUNT(answer_id) / COUNT(IF(action = 'show', 1, 0)) DESC 10 | LIMIT 1; 11 | -------------------------------------------------------------------------------- /MySQL/human-traffic-of-stadium.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n^3) 2 | # Space: O(n^3) 3 | 4 | SELECT DISTINCT s1.* 5 | FROM stadium AS s1, stadium AS s2, stadium AS s3 6 | WHERE s1.people >= 100 AND s2.people >= 100 AND s3.people >= 100 7 | AND 8 | ( 9 | (s2.id = s1.id + 1 AND s3.id = s2.id + 1 AND s3.id = s1.id + 2) -- s1, s2, s3 10 | OR 11 | (s1.id = s2.id + 1 AND s3.id = s1.id + 1 AND s3.id = s2.id + 2) -- s2, s1, s3 12 | OR 13 | (s3.id = s2.id + 1 AND s1.id = s3.id + 1 AND s1.id = s2.id + 2) -- s2, s3, s1 14 | ) 15 | ORDER BY s1.id 16 | ; 17 | -------------------------------------------------------------------------------- /MySQL/investments-in-2016.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n) 3 | 4 | SELECT 5 | SUM(insurance.TIV_2016) AS TIV_2016 6 | FROM 7 | insurance 8 | WHERE 9 | insurance.TIV_2015 IN 10 | ( 11 | SELECT 12 | TIV_2015 13 | FROM 14 | insurance 15 | GROUP BY TIV_2015 16 | HAVING COUNT(*) > 1 17 | ORDER BY NULL 18 | ) 19 | AND CONCAT(LAT, LON) IN 20 | ( 21 | SELECT 22 | CONCAT(LAT, LON) 23 | FROM 24 | insurance 25 | GROUP BY LAT , LON 26 | HAVING COUNT(*) = 1 27 | ORDER BY NULL 28 | ) 29 | ; 30 | -------------------------------------------------------------------------------- /MySQL/managers-with-at-least-5-direct-reports.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(n) 3 | 4 | SELECT 5 | Name 6 | FROM 7 | Employee AS t1 INNER JOIN 8 | (SELECT 9 | ManagerId 10 | FROM 11 | Employee 12 | GROUP BY ManagerId 13 | HAVING COUNT(ManagerId) >= 5 14 | ORDER BY NULL) AS t2 15 | ON t1.Id = t2.ManagerId 16 | ; 17 | -------------------------------------------------------------------------------- /MySQL/median-employee-salary.sql: -------------------------------------------------------------------------------- 1 | # Time: O(nlogn) 2 | # Space: O(n) 3 | 4 | SELECT Id, Company, Salary FROM 5 | ( 6 | SELECT e.Id, e.Salary, e.Company, IF (@Prev = e.Company , @Rank := @Rank + 1, @Rank := 1) AS Rank, @Prev := e.Company 7 | FROM Employee e , (SELECT @Rank := 0, @prev := 0) AS Temp ORDER BY e.Company, e.Salary, e.Id 8 | ) Ranking 9 | INNER JOIN 10 | ( 11 | SELECT COUNT(*) AS TotalCount, Company AS Name FROM Employee e2 GROUP BY e2.Company 12 | ) CompanyCount 13 | ON CompanyCount.Name = Ranking.Company 14 | WHERE Rank = floor((TotalCount+1)/2) OR Rank = floor((TotalCount+2)/2) 15 | -------------------------------------------------------------------------------- /MySQL/not-boring-movies.sql: -------------------------------------------------------------------------------- 1 | # Time: O(nlogn) 2 | # Space: O(1) 3 | 4 | # X city opened a new cinema, many people would like to go to this cinema. 5 | # The cinema also gives out a poster indicating the movies’ ratings and descriptions. 6 | # 7 | # Please write a SQL query to output movies with an odd numbered ID and 8 | # a description that is not 'boring'. Order the result by rating. 9 | # 10 | # For example, table cinema: 11 | # +---------+-----------+--------------+-----------+ 12 | # | id | movie | description | rating | 13 | # +---------+-----------+--------------+-----------+ 14 | # | 1 | War | great 3D | 8.9 | 15 | # | 2 | Science | fiction | 8.5 | 16 | # | 3 | irish | boring | 6.2 | 17 | # | 4 | Ice song | Fantacy | 8.6 | 18 | # | 5 | House card| Interesting| 9.1 | 19 | # +---------+-----------+--------------+-----------+ 20 | # 21 | # For the example above, the output should be: 22 | # +---------+-----------+--------------+-----------+ 23 | # | id | movie | description | rating | 24 | # +---------+-----------+--------------+-----------+ 25 | # | 5 | House card| Interesting| 9.1 | 26 | # | 1 | War | great 3D | 8.9 | 27 | # +---------+-----------+--------------+-----------+ 28 | 29 | SELECT * FROM cinema 30 | WHERE id % 2 != 0 and description != 'boring' 31 | ORDER BY rating DESC; 32 | -------------------------------------------------------------------------------- /MySQL/nth-highest-salary.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n) 3 | # 4 | # Write a SQL query to get the nth highest salary from the Employee table. 5 | # 6 | # +----+--------+ 7 | # | Id | Salary | 8 | # +----+--------+ 9 | # | 1 | 100 | 10 | # | 2 | 200 | 11 | # | 3 | 300 | 12 | # +----+--------+ 13 | # For example, given the above Employee table, the nth highest salary where n = 2 is 200. If there is no nth highest salary, then the query should return null. 14 | # 15 | CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT 16 | BEGIN 17 | RETURN ( 18 | # Write your MySQL query statement below. 19 | SELECT MAX(Salary) /*This is the outer query part */ 20 | FROM Employee Emp1 21 | WHERE (N-1) = ( /* Subquery starts here */ 22 | SELECT COUNT(DISTINCT(Emp2.Salary)) 23 | FROM Employee Emp2 24 | WHERE Emp2.Salary > Emp1.Salary) 25 | ); 26 | END 27 | -------------------------------------------------------------------------------- /MySQL/rank-scores.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n) 3 | # 4 | # Write a SQL query to rank scores. If there is a tie between two scores, both should have the same ranking. Note that after a tie, the next ranking number should be the next consecutive integer value. In other words, there should be no "holes" between ranks. 5 | # 6 | # +----+-------+ 7 | # | Id | Score | 8 | # +----+-------+ 9 | # | 1 | 3.50 | 10 | # | 2 | 3.65 | 11 | # | 3 | 4.00 | 12 | # | 4 | 3.85 | 13 | # | 5 | 4.00 | 14 | # | 6 | 3.65 | 15 | # +----+-------+ 16 | # For example, given the above Scores table, your query should generate the following report (order by highest score): 17 | # 18 | # +-------+------+ 19 | # | Score | Rank | 20 | # +-------+------+ 21 | # | 4.00 | 1 | 22 | # | 4.00 | 1 | 23 | # | 3.85 | 2 | 24 | # | 3.65 | 3 | 25 | # | 3.65 | 3 | 26 | # | 3.50 | 4 | 27 | # +-------+------+ 28 | # 29 | 30 | # Write your MySQL query statement below 31 | SELECT Ranks.Score, Ranks.Rank FROM Scores LEFT JOIN 32 | ( SELECT r.Score, @curRow := @curRow + 1 Rank 33 | FROM (SELECT DISTINCT(Score), (SELECT @curRow := 0) 34 | FROM Scores ORDER by Score DESC) r 35 | ) Ranks 36 | ON Scores.Score = Ranks.Score 37 | ORDER by Score DESC 38 | 39 | 40 | # Time: O(n^3) 41 | # Space: O(n) 42 | # Write your MySQL query statement below 43 | SELECT Score, (SELECT COUNT(DISTINCT(Score)) FROM Scores b WHERE b.Score > a.Score) + 1 AS Rank 44 | FROM Scores a 45 | ORDER by Score DESC 46 | -------------------------------------------------------------------------------- /MySQL/rising-temperature.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n) 3 | # 4 | # Given a Weather table, write a SQL query to find all dates' 5 | # Ids with higher temperature compared to its previous (yesterday's) dates. 6 | # 7 | # +---------+------------+------------------+ 8 | # | Id(INT) | Date(DATE) | Temperature(INT) | 9 | # +---------+------------+------------------+ 10 | # | 1 | 2015-01-01 | 10 | 11 | # | 2 | 2015-01-02 | 25 | 12 | # | 3 | 2015-01-03 | 20 | 13 | # | 4 | 2015-01-04 | 30 | 14 | # +---------+------------+------------------+ 15 | # For example, return the following Ids for the above Weather table: 16 | # +----+ 17 | # | Id | 18 | # +----+ 19 | # | 2 | 20 | # | 4 | 21 | # +----+ 22 | # 23 | 24 | # Write your MySQL query statement below 25 | SELECT wt1.Id 26 | FROM Weather wt1, Weather wt2 27 | WHERE wt1.Temperature > wt2.Temperature AND 28 | TO_DAYS(wt1.DATE)-TO_DAYS(wt2.DATE)=1; 29 | -------------------------------------------------------------------------------- /MySQL/sales-person.sql: -------------------------------------------------------------------------------- 1 | # Time: O(s * o) 2 | # Space: O(s + o) 3 | 4 | SELECT 5 | s.name 6 | FROM 7 | salesperson AS s 8 | WHERE 9 | s.sales_id NOT IN (SELECT 10 | o.sales_id 11 | FROM 12 | orders AS o 13 | LEFT JOIN 14 | company AS c ON o.com_id = c.com_id 15 | WHERE 16 | c.name = 'RED') 17 | ; 18 | -------------------------------------------------------------------------------- /MySQL/second-degree-follower.sql: -------------------------------------------------------------------------------- 1 | # Time: O(nlogn) 2 | # Space: O(n) 3 | 4 | SELECT f1.follower, COUNT(DISTINCT f2.follower) AS num 5 | FROM follow f1 6 | JOIN follow f2 ON f1.follower = f2.followee 7 | GROUP BY f1.follower 8 | -------------------------------------------------------------------------------- /MySQL/second-highest-salary.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Write a SQL query to get the second highest salary from the Employee table. Alias Salary as SecondHighestSalary. 5 | # 6 | # +----+--------+ 7 | # | Id | Salary | 8 | # +----+--------+ 9 | # | 1 | 100 | 10 | # | 2 | 200 | 11 | # | 3 | 300 | 12 | # +----+--------+ 13 | # For example, given the above Employee table, the second highest salary is 200. If there is no second highest salary, then the query should return null. 14 | # 15 | # Write your MySQL query statement below 16 | SELECT (SELECT MAX(Salary) FROM Employee WHERE Salary NOT IN (SELECT MAX(Salary) FROM Employee)) SecondHighestSalary; 17 | # or 18 | SELECT (SELECT Salary FROM Employee GROUP BY Salary ORDER BY Salary DESC LIMIT 1,1) SecondHighestSalary; 19 | -------------------------------------------------------------------------------- /MySQL/shortest-distance-in-a-line.sql: -------------------------------------------------------------------------------- 1 | # Time: O(nlogn) 2 | # Space: O(n) 3 | SET @prev := -100000000; 4 | SELECT MIN(diff) AS shortest 5 | FROM (SELECT (x - @prev) AS diff, @prev := x 6 | FROM (SELECT * 7 | FROM point 8 | ORDER BY x) AS t1 9 | ) AS t2 10 | ; 11 | 12 | # Time: O(nlogn) 13 | # Space: O(n) 14 | SELECT MIN(P1.x - P2.x) AS shortest 15 | FROM (SELECT @id1:=0, @id2:=0) AS t, 16 | (SELECT @id1:=@id1+1 AS id, x FROM point ORDER BY x) AS P1 17 | JOIN 18 | (SELECT @id2:=@id2+1 AS id, x FROM point ORDER BY x) AS P2 19 | ON P1.id = P2.id + 1 20 | WHERE P1.id > 1; 21 | 22 | # Time: O(n^2) 23 | # Space: O(n) 24 | SELECT 25 | MIN(p2.x - p1.x) AS shortest 26 | FROM 27 | point p1 28 | JOIN 29 | point p2 ON p1.x < p2.x 30 | ; 31 | -------------------------------------------------------------------------------- /MySQL/shortest-distance-in-a-plane.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n^2) 3 | 4 | SELECT 5 | ROUND(SQRT(MIN((POW(p1.x - p2.x, 2) + POW(p1.y - p2.y, 2)))),2) AS shortest 6 | FROM 7 | point_2d p1 8 | JOIN 9 | point_2d p2 ON (p1.x < p2.x) OR (p1.x = p2.x AND p1.y < p2.y) 10 | ; 11 | -------------------------------------------------------------------------------- /MySQL/students-report-by-geography.sql: -------------------------------------------------------------------------------- 1 | # Time: O(nlogn) 2 | # Space: O(n) 3 | 4 | SELECT 5 | America, Asia, Europe 6 | FROM 7 | (SELECT @as:=0, @am:=0, @eu:=0) t, 8 | (SELECT 9 | @am:=@am + 1 AS amid, name AS America 10 | FROM 11 | student 12 | WHERE 13 | continent = 'America' 14 | ORDER BY America) AS t1 15 | LEFT JOIN 16 | (SELECT 17 | @as:=@as + 1 AS asid, name AS Asia 18 | FROM 19 | student 20 | WHERE 21 | continent = 'Asia' 22 | ORDER BY Asia) AS t2 ON amid = asid 23 | LEFT JOIN 24 | (SELECT 25 | @eu:=@eu + 1 AS euid, name AS Europe 26 | FROM 27 | student 28 | WHERE 29 | continent = 'Europe' 30 | ORDER BY Europe) AS t3 ON amid = euid 31 | ; 32 | -------------------------------------------------------------------------------- /MySQL/swap-salary.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | 4 | # Given a table salary, such as the one below, that has m=male and f=female values. 5 | # Swap all f and m values (i.e., change all f values to m and vice versa) with a single update query and no intermediate temp table. 6 | # 7 | # For example: 8 | # | id | name | sex | salary | 9 | # |----|------|-----|--------| 10 | # | 1 | A | m | 2500 | 11 | # | 2 | B | f | 1500 | 12 | # | 3 | C | m | 5500 | 13 | # | 4 | D | f | 500 | 14 | # 15 | # After running your query, the above salary table should have the following rows: 16 | # | id | name | sex | salary | 17 | # |----|------|-----|--------| 18 | # | 1 | A | f | 2500 | 19 | # | 2 | B | m | 1500 | 20 | # | 3 | C | f | 5500 | 21 | # | 4 | D | m | 500 | 22 | 23 | UPDATE salary SET sex = IF(sex = 'm', 'f', 'm') 24 | -------------------------------------------------------------------------------- /MySQL/tree-node.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n) 3 | 4 | SELECT 5 | atree.id, 6 | IF(ISNULL(atree.p_id), 7 | 'Root', 8 | IF(atree.id IN (SELECT p_id FROM tree), 'Inner','Leaf')) AS Type 9 | FROM 10 | tree AS atree 11 | ORDER BY atree.id 12 | -------------------------------------------------------------------------------- /MySQL/triangle-judgement.sql: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | 4 | SELECT *, 5 | IF (x+y>z AND x+z>y AND y+z>x, "Yes","No") AS triangle 6 | FROM triangle; 7 | -------------------------------------------------------------------------------- /MySQL/trips-and-users.sql: -------------------------------------------------------------------------------- 1 | # Time: O((t * u) + tlogt) 2 | # Space: O(t) 3 | # 4 | # The Trips table holds all taxi trips. Each trip has a unique Id, while Client_Id and Driver_Id 5 | # are both foreign keys to the Users_Id at the Users table. Status is an ENUM type of 6 | # (‘completed’, ‘cancelled_by_driver’, ‘cancelled_by_client’). 7 | # 8 | # +----+-----------+-----------+---------+--------------------+----------+ 9 | # | Id | Client_Id | Driver_Id | City_Id | Status |Request_at| 10 | # +----+-----------+-----------+---------+--------------------+----------+ 11 | # | 1 | 1 | 10 | 1 | completed |2013-10-01| 12 | # | 2 | 2 | 11 | 1 | cancelled_by_driver|2013-10-01| 13 | # | 3 | 3 | 12 | 6 | completed |2013-10-01| 14 | # | 4 | 4 | 13 | 6 | cancelled_by_client|2013-10-01| 15 | # | 5 | 1 | 10 | 1 | completed |2013-10-02| 16 | # | 6 | 2 | 11 | 6 | completed |2013-10-02| 17 | # | 7 | 3 | 12 | 6 | completed |2013-10-02| 18 | # | 8 | 2 | 12 | 12 | completed |2013-10-03| 19 | # | 9 | 3 | 10 | 12 | completed |2013-10-03| 20 | # | 10 | 4 | 13 | 12 | cancelled_by_driver|2013-10-03| 21 | # +----+-----------+-----------+---------+--------------------+----------+ 22 | # The Users table holds all users. Each user has an unique Users_Id, and Role is an ENUM type of 23 | # (‘client’, ‘driver’, ‘partner’). 24 | # 25 | # +----------+--------+--------+ 26 | # | Users_Id | Banned | Role | 27 | # +----------+--------+--------+ 28 | # | 1 | No | client | 29 | # | 2 | Yes | client | 30 | # | 3 | No | client | 31 | # | 4 | No | client | 32 | # | 10 | No | driver | 33 | # | 11 | No | driver | 34 | # | 12 | No | driver | 35 | # | 13 | No | driver | 36 | # +----------+--------+--------+ 37 | # Write a SQL query to find the cancellation rate of requests made by unbanned clients between 38 | # Oct 1, 2013 and Oct 3, 2013. For the above tables, your SQL query should return the following 39 | # rows with the cancellation rate being rounded to two decimal places. 40 | # 41 | # +------------+-------------------+ 42 | # | Day | Cancellation Rate | 43 | # +------------+-------------------+ 44 | # | 2013-10-01 | 0.33 | 45 | # | 2013-10-02 | 0.00 | 46 | # | 2013-10-03 | 0.50 | 47 | # +------------+-------------------+ 48 | # 49 | select 50 | t.Request_at Day, 51 | round(sum(case when t.Status = 'completed' then 0 else 1 end) / count(*), 2) Rate 52 | from Trips t 53 | inner join Users u 54 | on t.Client_Id = u.Users_Id and u.Banned = 'No' 55 | where t.Request_at between '2013-10-01' and '2013-10-03' 56 | group by t.Request_at 57 | -------------------------------------------------------------------------------- /MySQL/winning-candidate.sql: -------------------------------------------------------------------------------- 1 | # Time: O(nlogn) 2 | # Space: O(n) 3 | 4 | SELECT 5 | name AS Name 6 | FROM 7 | Candidate 8 | JOIN 9 | (SELECT 10 | Candidateid 11 | FROM 12 | Vote 13 | GROUP BY Candidateid 14 | ORDER BY COUNT(*) DESC 15 | LIMIT 1) AS Winner 16 | WHERE 17 | Candidate.id = Winner.Candidateid 18 | ; 19 | -------------------------------------------------------------------------------- /Shell/tenth-line.sh: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # How would you print just the 10th line of a file? 5 | # 6 | # For example, assume that file.txt has the following content: 7 | # 8 | # Line 1 9 | # Line 2 10 | # Line 3 11 | # Line 4 12 | # Line 5 13 | # Line 6 14 | # Line 7 15 | # Line 8 16 | # Line 9 17 | # Line 10 18 | # Your script should output the tenth line, which is: 19 | # Line 10 20 | # 21 | # Hint: 22 | # 1. If the file contains less than 10 lines, what should you output? 23 | # 2. There's at least three different solutions. Try to explore all possibilities. 24 | # 25 | # Read from the file file.txt and output the tenth line to stdout. 26 | 27 | # Solution 1 28 | awk '{if(NR==10) print $0}' file.txt 29 | awk 'NR == 10' file.txt 30 | 31 | # Solution 2 32 | sed -n 10p file.txt 33 | 34 | # Solution 3 35 | tail -n+10 file.txt | head -1 36 | -------------------------------------------------------------------------------- /Shell/transpose-file.sh: -------------------------------------------------------------------------------- 1 | # Time: O(n^2) 2 | # Space: O(n^2) 3 | # 4 | # Given a text file file.txt, transpose its content. 5 | # 6 | # You may assume that each row has the same number of 7 | # columns and each field is separated by the ' ' character. 8 | # 9 | # For example, if file.txt has the following content: 10 | # 11 | # name age 12 | # alice 21 13 | # ryan 30 14 | # Output the following: 15 | # 16 | # name alice ryan 17 | # age 21 30 18 | # 19 | 20 | # Read from the file file.txt and print its transposed content to stdout. 21 | awk ' 22 | { 23 | for (i = 1; i <= NF; i++) { 24 | if(NR == 1) { 25 | s[i] = $i; 26 | } else { 27 | s[i] = s[i] " " $i; 28 | } 29 | } 30 | } 31 | END { 32 | for (i = 1; s[i] != ""; i++) { 33 | print s[i]; 34 | } 35 | }' file.txt 36 | -------------------------------------------------------------------------------- /Shell/valid-phone-numbers.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Time: O(n) 3 | # Space: O(1) 4 | # 5 | # Given a text file file.txt that contains list of 6 | # phone numbers (one per line), write a one liner 7 | # bash script to print all valid phone numbers. 8 | # 9 | # You may assume that a valid phone number must 10 | # appear in one of the following two formats: 11 | # (xxx) xxx-xxxx or xxx-xxx-xxxx. (x means a digit) 12 | # 13 | # You may also assume each line in the text file 14 | # must not contain leading or trailing white spaces. 15 | # 16 | # For example, assume that file.txt has the following content: 17 | # 18 | # 987-123-4567 19 | # 123 456 7890 20 | # (123) 456-7890 21 | # Your script should output the following valid phone numbers: 22 | # 987-123-4567 23 | # (123) 456-7890 24 | # 25 | # 26 | # Read from the file file.txt and output all valid phone numbers to stdout. 27 | # Using grep: 28 | grep -P '^(\d{3}-|\(\d{3}\) )\d{3}-\d{4}$' file.txt 29 | 30 | # Using sed: 31 | sed -n -E '/^([0-9]{3}-|\([0-9]{3}\) )[0-9]{3}-[0-9]{4}$/p' file.txt 32 | 33 | # Using awk: 34 | awk '/^([0-9]{3}-|\([0-9]{3}\) )[0-9]{3}-[0-9]{4}$/' file.txt 35 | -------------------------------------------------------------------------------- /Shell/word-frequency.sh: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(k), k is number of words 3 | # 4 | # Write a bash script to calculate the frequency of each word in a text file words.txt. 5 | # 6 | # For simplicity sake, you may assume: 7 | # 8 | # words.txt contains only lowercase characters and 9 | # space ' ' characters. 10 | # Each word must consist of lowercase characters only. 11 | # Words are separated by one or more whitespace characters. 12 | # For example, assume that words.txt has the following content: 13 | # 14 | # the day is sunny the the 15 | # the sunny is is 16 | # Your script should output the following, 17 | # sorted by descending frequency: 18 | # the 4 19 | # is 3 20 | # sunny 2 21 | # day 1 22 | # Note: 23 | # Don't worry about handling ties, 24 | # it is guaranteed that each word's frequency count is unique. 25 | # 26 | 27 | # Read from the file words.txt and output the word frequency list to stdout. 28 | awk '{for(i=1;i<=NF;i++) a[$i]++} END {for(k in a) print k,a[k]}' words.txt | sort -k2 -nr 29 | 30 | --------------------------------------------------------------------------------