├── .editorconfig ├── .gitignore ├── .prettierignore ├── LICENSE.md ├── README.md ├── algorithms ├── 24Game.js ├── 3Sum.js ├── AddBinary.js ├── AddOneRowToTree.js ├── AddToArrayFormOfInteger.js ├── AddTwoNumbers.js ├── AngleBetweenHandsOfAClock.js ├── ArrayPartition_I.js ├── AverageOfLevelsInBinaryTree.js ├── BackspaceStringCompare.js ├── Base7.js ├── BaseballGame.js ├── BasicCalculator_II.js ├── BestTimeToBuyAndSellStock.js ├── BestTimeToBuyAndSellStock_II.js ├── BinaryNumberWithAlternatingBits.js ├── BinarySearchTreeToGreaterSumTree.js ├── BinaryTreeInorderTraversal.js ├── BinaryTreeLevelOrderTraversal.js ├── BinaryTreeLevelOrderTraversal_II.js ├── BinaryTreePruning.js ├── BinaryTreeRightSideView.js ├── BinaryTreeTilt.js ├── BinaryTreeZigzagLevelOrderTraversal.js ├── BoatsToSavePeople.js ├── BuddyStrings.js ├── BulbSwitcher.js ├── BulbSwitcher_II.js ├── BullsAndCows.js ├── ClimbingStairs.js ├── CoinChange.js ├── CoinChange_II.js ├── CompareVersionNumbers.js ├── ComplementOfBase10Integer.js ├── ConsecutiveCharacters.js ├── ConstructBinarySearchTreeFromPreorderTraversal.js ├── ConstructStringFromBinaryTree.js ├── ContainerWithMostWater.js ├── ContainsDuplicate.II.js ├── ContainsDuplicate.js ├── ConvertANumberToHexadecimal.js ├── ConvertBinaryNumberInALinkedListToInteger.js ├── ConvertSortedArrayToBinarySearchTree.js ├── ConvertSortedListToBinarySearchTree.js ├── DetectCapital.js ├── DiameterOfBinaryTree.js ├── DuplicateZeros.js ├── ExcelSheetColumnNumber.js ├── ExcelSheetColumnTitle.js ├── FactorialTrailingZeroes.js ├── FibonacciNumber.js ├── FindACorrespondingNodeOfABinaryTreeInACloneOfThatTree.js ├── FindAllDuplicatesInAnArray.js ├── FindAllNumbersDisappearedInAnArray.js ├── FindAnagramMappings.js ├── FindAndReplacePattern.js ├── FindBottomLeftTreeValue.js ├── FindCommonCharacters.js ├── FindLargestValueInEachTreeRow.js ├── FindPivotIndex.js ├── FindSmallestLetterGreaterThanTarget.js ├── FindTheDuplicateNumber.js ├── FirstBadVersion.js ├── FirstUniqueCharacterInAString.js ├── FizzBuzz.js ├── FlattenNestedListIterator.js ├── Game24.cpp ├── GenerateParentheses.js ├── GreatestCommonDivisorOfStrings.js ├── HammingDistance.js ├── HappyNumber.js ├── ImplementMagicDict.js ├── ImplementStackUsingQueues.js ├── ImplementStrStr.js ├── ImplementTrie(PrefixTree).js ├── InsertIntoABinarySearchTree.js ├── IntegerToEnglishWords.js ├── IntegerToRoman.js ├── IntervalListIntersections.js ├── InvertBinaryTree.js ├── IsomorphicStrings.js ├── JewelsAndStones.js ├── JudgeRouteCircle.js ├── KdiffPairsInAnArray.js ├── KthLargestElementInAnArray.js ├── KthSmallestElementInBST.js ├── LRUCache.js ├── LargestNumberAtLeastTwiceOfOthers.js ├── LastStoneWeight.js ├── LengthOfLastWord.js ├── LetterCombinationsOfAPhoneNumber.js ├── LicenseKeyFormatting.js ├── LinkedListCycle.js ├── LinkedListCycle_II.js ├── LongestCommonPrefix.js ├── LongestContinuousIncreasingSubsequence.js ├── LongestPalindrome.js ├── LongestPalindromicSubstring.js ├── LongestSubstringOfAllVowelsInOrder.js ├── LongestSubstringWithoutRepeatingCharacters.js ├── LongestWordInDictionaryThroughDeleting.js ├── MajorityElement.js ├── MapSumPairs.js ├── MaximumAverageSubarray_I.js ├── MaximumBinaryTree.js ├── MaximumProductOfThreeNumbers.js ├── MaximumSubarray.js ├── MaximumSwap.js ├── MedianOfTwoSortedArrays.js ├── MergeIntervals.js ├── MergeKSortedLists.js ├── MergeTwoBinaryTrees.js ├── MergeTwoSortedArray.js ├── MergeTwoSortedList.js ├── MiddleOfTheLinkedList.js ├── MinStack.js ├── MinimumAbsoluteDifferenceInBST.js ├── MinimumDepthOfBinaryTree.js ├── MinimumDistanceToTheTargetElement.js ├── MinimumIndexSumOfTwoLists.js ├── MinimumNumberGame.js ├── MissingNumber.js ├── MostFrequentSubtreeSum.js ├── MoveZeroes.js ├── N-RepeatedElementInSize2NArray.js ├── NextGreaterElementI.js ├── NextGreaterNodeInLinkedList.js ├── NextGreaterNodeInLinkedListRecursion.js ├── NumberComplement.js ├── NumberOf1Bits.js ├── NumberOfSegmentsInAString.js ├── NumberOfStudentsDoingHomeworkAtAGivenTime.js ├── PalindromeLinkedList.js ├── PalindromeNumber.js ├── PartitionList.js ├── PascalsTriangle.js ├── PascalsTriangle_II.js ├── PathSum.js ├── PeakIndexInAMountainArray.js ├── PeopleWhoseListOfFavoriteCompaniesIsNotASubsetOfAnotherList.js ├── PerfectNumber.js ├── PlusOne.js ├── PowXN.js ├── PowerOfFour.js ├── PowerOfThree.js ├── RangeSumOfBST.js ├── RearrangeWordsInASentence.js ├── RegularExpressionMatching.js ├── Remove9.js ├── RemoveAllAdjacentDuplicatesInString.js ├── RemoveCoveredIntervals.js ├── RemoveDuplicatesFromSortedArray.js ├── RemoveDuplicatesFromSortedArray_II.js ├── RemoveElement.js ├── RemoveLinkedListElements.js ├── RemoveNthNodeFromEndOfList.js ├── RemoveOutermostParentheses.js ├── RepeatedStringMatch.js ├── ReverseBits.js ├── ReverseInteger.js ├── ReverseLinkedList.js ├── ReverseLinkedList_II.js ├── ReverseNodesInK-Group.js ├── ReverseString.js ├── ReverseString_II.js ├── ReverseVowelsOfAString.js ├── ReverseWordsInAString.js ├── ReverseWordsInAString_III.js ├── RomanToInteger.js ├── RotateString.js ├── RotatedDigits.js ├── SearchInsertPosition.js ├── SecondMinimumNodeInABinaryTree.js ├── SelfDividingNumbers.js ├── SerializeAndDeserializeBST.js ├── SerializeAndDeserializeBinaryTree.js ├── SetMismatch.js ├── ShuffleAnArray.js ├── SingleNumber.js ├── SortArrayByParity.js ├── SortArrayByParity_II.js ├── SqrtX.js ├── SquaresOfASortedArray.js ├── StringToIntegerAtoi.js ├── StudentAttendanceRecord_I.js ├── SumOfDigitsInBaseK.js ├── SumOfLeftLeaves.js ├── SumOfSquareNumbers.js ├── SwapNodesInPairs.js ├── SymmetricTree.js ├── ThirdMaximumNumber.js ├── ToLowerCase.js ├── TopKFrequentWords.js ├── TwoSum.js ├── TwoSum_II.js ├── TwoSum_IV.js ├── UglyNumber.js ├── UncommonWordsFromTwoSentences.js ├── UniqueEmailAddresses.js ├── UniqueMorseCodeWords.js ├── UnivaluedBinaryTree.js ├── ValidPalindrome_II.js ├── ValidParentheses.js ├── ValidParenthesisString.js ├── ZigZagConversion.js └── setMatrixZeros.cpp ├── package.json ├── scripts ├── README.md ├── index.js └── readme.js ├── shell ├── TenthLine.sh └── ValidPhoneNumbers.sh └── sql ├── BigCountries.sql ├── ClassesMoreThan5Students.sql ├── NotBoringMovies.sql └── SwapSalary.sql /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | 11 | # Set default charset 12 | # 4 space indentation 13 | [*.js] 14 | charset = utf-8 15 | indent_style = space 16 | 17 | # 2 space indentation 18 | [scripts/*.js] 19 | indent_size = 2 20 | 21 | # 4 space indentation 22 | [algorithms/*.js] 23 | indent_size = 4 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .AppleDouble 3 | .LSOverride 4 | 5 | # Icon must end with two \r 6 | Icon 7 | 8 | 9 | # Thumbnails 10 | ._* 11 | 12 | # Files that might appear in the root of a volume 13 | .DocumentRevisions-V100 14 | .fseventsd 15 | .Spotlight-V100 16 | .TemporaryItems 17 | .Trashes 18 | .VolumeIcon.icns 19 | 20 | # Directories potentially created on remote AFP share 21 | .AppleDB 22 | .AppleDesktop 23 | Network Trash Folder 24 | Temporary Items 25 | .apdisk 26 | 27 | # Ignore logs, backup, dist and node modules 28 | *.log 29 | *.bk 30 | dist/ 31 | node_modules/ 32 | package-lock.json 33 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | algorithms 2 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Dean Shi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /algorithms/3Sum.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/3sum 2 | // Author : Dean Shi 3 | // Date : 2017-08-02 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an array S of n integers, are there elements a, b, c in S such that a + b + c 8 | * = 0? Find all unique triplets in the array which gives the sum of zero. 9 | * 10 | * Note: The solution set must not contain duplicate triplets. 11 | * 12 | * For example, given array S = [-1, 0, 1, 2, -1, -4], 13 | * 14 | * A solution set is: 15 | * [ 16 | * [-1, 0, 1], 17 | * [-1, -1, 2] 18 | * ] 19 | * 20 | * 21 | ***************************************************************************************/ 22 | 23 | /** 24 | * @param {number[]} nums 25 | * @return {number[][]} 26 | */ 27 | var threeSum = function(nums) { 28 | let sum, right, left 29 | const result = [] 30 | nums.sort((a, b) => a - b).forEach((n, i) => { 31 | [left, right] = [i+1, nums.length-1] 32 | if (n !== nums[i-1]) while (left < right) { 33 | sum = n + nums[left] + nums[right] 34 | if (sum === 0) { 35 | result.push([n, nums[left], nums[right]]) 36 | while (left < right && nums[left] === nums[left+1]) ++left 37 | while (left < right && nums[right] === nums[right-1]) --right 38 | --right;++left 39 | } 40 | else if (sum > 0) --right 41 | else ++left 42 | } 43 | }) 44 | 45 | return result 46 | }; 47 | -------------------------------------------------------------------------------- /algorithms/AddBinary.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/add-binary 2 | // Author : Dean Shi 3 | // Date : 2017-07-11 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given two binary strings, return their sum (also a binary string). 8 | * 9 | * For example, 10 | * a = "11" 11 | * b = "1" 12 | * Return "100". 13 | * 14 | * 15 | ***************************************************************************************/ 16 | 17 | /** 18 | * @param {string} a 19 | * @param {string} b 20 | * @return {string} 21 | */ 22 | var addBinary = function(a, b) { 23 | let [i, j, c, s] = [a.length - 1, b.length - 1, 0, ''] 24 | 25 | while (i >= 0 || j >= 0 || c === 1) { 26 | c += +(a[i--] || 0) + +(b[j--] || 0) 27 | s = (c & 1) + s 28 | c = c >> 1 29 | } 30 | return s 31 | }; 32 | -------------------------------------------------------------------------------- /algorithms/AddToArrayFormOfInteger.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/add-to-array-form-of-integer/ 2 | // Author : Dean Shi 3 | // Date : 2019-03-14 4 | 5 | /*************************************************************************************** 6 | * 7 | * For a non-negative integer X, the array-form of X is an array of its digits in left 8 | * to right order.  For example, if X = 1231, then the array form is [1,2,3,1]. 9 | * 10 | * Given the array-form A of a non-negative integer X, return the array-form of the 11 | * integer X+K. 12 | * 13 | * Example 1: 14 | * 15 | * Input: A = [1,2,0,0], K = 34 16 | * Output: [1,2,3,4] 17 | * Explanation: 1200 + 34 = 1234 18 | * 19 | * Example 2: 20 | * 21 | * Input: A = [2,7,4], K = 181 22 | * Output: [4,5,5] 23 | * Explanation: 274 + 181 = 455 24 | * 25 | * Example 3: 26 | * 27 | * Input: A = [2,1,5], K = 806 28 | * Output: [1,0,2,1] 29 | * Explanation: 215 + 806 = 1021 30 | * 31 | * Example 4: 32 | * 33 | * Input: A = [9,9,9,9,9,9,9,9,9,9], K = 1 34 | * Output: [1,0,0,0,0,0,0,0,0,0,0] 35 | * Explanation: 9999999999 + 1 = 10000000000 36 | * 37 | * Note: 38 | * 39 | * 1 <= A.length <= 10000 40 | * 0 <= A[i] <= 9 41 | * 0 <= K <= 10000 42 | * If A.length > 1, then A[0] != 0 43 | * 44 | ***************************************************************************************/ 45 | 46 | /** 47 | * @param {number[]} A 48 | * @param {number} K 49 | * @return {number[]} 50 | */ 51 | var addToArrayForm = function(A, K) { 52 | return Array.from((BigInt(A.join('')) + BigInt(K)).toString()) 53 | }; 54 | -------------------------------------------------------------------------------- /algorithms/AddTwoNumbers.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/add-two-numbers/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-01 4 | 5 | /********************************************************************************** 6 | * 7 | * You are given two linked lists representing two non-negative numbers. 8 | * The digits are stored in reverse order and each of their nodes contain a single digit. 9 | * Add the two numbers and return it as a linked list. 10 | * 11 | * Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) 12 | * Output: 7 -> 0 -> 8 13 | * 14 | **********************************************************************************/ 15 | 16 | /** 17 | * Definition for singly-linked list. 18 | * function ListNode(val) { 19 | * this.val = val; 20 | * this.next = null; 21 | * } 22 | */ 23 | /** 24 | * @param {ListNode} l1 25 | * @param {ListNode} l2 26 | * @return {ListNode} 27 | */ 28 | var addTwoNumbers = function(l1, l2) { 29 | const result = new ListNode(0) 30 | let curr = result, carry = 0 31 | 32 | while (l1 || l2) { 33 | if (l1) { 34 | carry += l1.val 35 | l1 = l1.next 36 | } 37 | 38 | if (l2) { 39 | carry += l2.val 40 | l2 = l2.next 41 | } 42 | 43 | curr = curr.next = new ListNode(carry % 10) 44 | carry = ~~(carry / 10) 45 | } 46 | 47 | if (carry !== 0) curr.next = new ListNode(carry) 48 | return result.next 49 | }; 50 | -------------------------------------------------------------------------------- /algorithms/AngleBetweenHandsOfAClock.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/angle-between-hands-of-a-clock 2 | // Author : Dean Shi 3 | // Date : 2021-05-01 4 | 5 | /*************************************************************************************** 6 | * Given two numbers, hour and minutes. Return the smaller angle (in degrees) formed 7 | * between the hour and the minute hand. 8 | * 9 | * Example 1: 10 | * 11 | * Input: hour = 12, minutes = 30 12 | * Output: 165 13 | * 14 | * Example 2: 15 | * 16 | * Input: hour = 3, minutes = 30 17 | * Output: 75 18 | * 19 | * Example 3: 20 | * 21 | * Input: hour = 3, minutes = 15 22 | * Output: 7.5 23 | * 24 | * Example 4: 25 | * 26 | * Input: hour = 4, minutes = 50 27 | * Output: 155 28 | * 29 | * Example 5: 30 | * 31 | * Input: hour = 12, minutes = 0 32 | * Output: 0 33 | * 34 | * Constraints: 35 | * 36 | * 1 <= hour <= 12 37 | * 0 <= minutes <= 59 38 | * Answers within 10^-5 of the actual value will be accepted as correct. 39 | * 40 | * 41 | ***************************************************************************************/ 42 | 43 | /** 44 | * @param {number} hour 45 | * @param {number} minutes 46 | * @return {number} 47 | */ 48 | var angleClock = function (hour, minutes) { 49 | const degrees = Math.abs(hour * 30 - minutes * 5.5); 50 | return Math.min(degrees, 360 - degrees); 51 | }; 52 | -------------------------------------------------------------------------------- /algorithms/ArrayPartition_I.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/array-partition-i 2 | // Author : Dean Shi 3 | // Date : 2017-04-23 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an array of 2n integers, your task is to group these integers into n pairs of 8 | * integer, say (a1, b1), (a2, b2), ..., (an, bn) which makes sum of min(ai, bi) for 9 | * all i from 1 to n as large as possible. 10 | * 11 | * Example 1: 12 | * 13 | * Input: [1,4,3,2] 14 | * 15 | * Output: 4 16 | * Explanation: n is 2, and the maximum sum of pairs is 4. 17 | * 18 | * Note: 19 | * 20 | * n is a positive integer, which is in the range of [1, 10000]. 21 | * All the integers in the array will be in the range of [-10000, 10000]. 22 | * 23 | * 24 | ***************************************************************************************/ 25 | 26 | /** 27 | * @param {number[]} nums 28 | * @return {number} 29 | */ 30 | var arrayPairSum = function(nums) { 31 | return nums.sort((a, b) => b - a).reduce((sum, v, i) => sum + (i % 2 ? v : 0), 0) 32 | }; 33 | -------------------------------------------------------------------------------- /algorithms/AverageOfLevelsInBinaryTree.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/average-of-levels-in-binary-tree 2 | // Author : Dean Shi 3 | // Date : 2017-07-09 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a non-empty binary tree, return the average value of the nodes on each level 8 | * in the form of an array. 9 | * 10 | * Example 1: 11 | * 12 | * Input: 13 | * 3 14 | * / \ 15 | * 9 20 16 | * / \ 17 | * 15 7 18 | * Output: [3, 14.5, 11] 19 | * Explanation: 20 | * The average value of nodes on level 0 is 3, on level 1 is 14.5, and on level 2 is 21 | * 11. Hence return [3, 14.5, 11]. 22 | * 23 | * Note: 24 | * 25 | * The range of node's value is in the range of 32-bit signed integer. 26 | * 27 | * 28 | ***************************************************************************************/ 29 | 30 | /** 31 | * Definition for a binary tree node. 32 | * function TreeNode(val) { 33 | * this.val = val; 34 | * this.left = this.right = null; 35 | * } 36 | */ 37 | /** 38 | * @param {TreeNode} root 39 | * @return {number[]} 40 | */ 41 | var averageOfLevels = function(root) { 42 | const result = [] 43 | 44 | let sum, n_levels, levels = root ? [root] : [] 45 | 46 | while (levels.length) { 47 | [sum, n_levels] = [0, []] 48 | for (let l of levels) { 49 | if (l.left) n_levels.push(l.left) 50 | if (l.right) n_levels.push(l.right) 51 | sum += l.val 52 | } 53 | result.push(sum / levels.length) 54 | levels = n_levels 55 | } 56 | return result 57 | }; 58 | -------------------------------------------------------------------------------- /algorithms/BackspaceStringCompare.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/backspace-string-compare 2 | // Author : Dean Shi 3 | // Date : 2018-08-25 4 | 5 | /*************************************************************************************** 6 | * Given two strings S and T, return if they are equal when both are typed into empty 7 | * text editors. # means a backspace character. 8 | * 9 | * Example 1: 10 | * 11 | * Input: S = "ab#c", T = "ad#c" 12 | * Output: true 13 | * Explanation: Both S and T become "ac". 14 | * 15 | * Example 2: 16 | * 17 | * Input: S = "ab##", T = "c#d#" 18 | * Output: true 19 | * Explanation: Both S and T become "". 20 | * 21 | * Example 3: 22 | * 23 | * Input: S = "a##c", T = "#a#c" 24 | * Output: true 25 | * Explanation: Both S and T become "c". 26 | * 27 | * Example 4: 28 | * 29 | * Input: S = "a#c", T = "b" 30 | * Output: false 31 | * Explanation: S becomes "c" while T becomes "b". 32 | * 33 | * Note: 34 | * 35 | * 1 <= S.length <= 200 36 | * 1 <= T.length <= 200 37 | * S and T only contain lowercase letters and '#' characters. 38 | * 39 | * Follow up: 40 | * 41 | * Can you solve it in O(N) time and O(1) space? 42 | * 43 | ***************************************************************************************/ 44 | 45 | /** 46 | * @param {string} S 47 | * @param {string} T 48 | * @return {boolean} 49 | */ 50 | var backspaceCompare = function(S, T) { 51 | const sStack = [] 52 | const tStack = [] 53 | 54 | for (let c of S) c !== '#' ? sStack.push(c) : sStack.pop() 55 | for (let c of T) c !== '#' ? tStack.push(c) : tStack.pop() 56 | 57 | return sStack.join('') === tStack.join('') 58 | }; 59 | -------------------------------------------------------------------------------- /algorithms/Base7.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/base-7 2 | // Author : Dean Shi 3 | // Date : 2017-02-27 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an integer, return its base 7 string representation. 8 | * 9 | * Example 1: 10 | * 11 | * Input: 100 12 | * Output: "202" 13 | * 14 | * Example 2: 15 | * 16 | * Input: -7 17 | * Output: "-10" 18 | * 19 | * Note: 20 | * The input will be in range of [-1e7, 1e7]. 21 | * 22 | * 23 | ***************************************************************************************/ 24 | 25 | /** 26 | * @param {number} num 27 | * @return {string} 28 | */ 29 | var convertToBase7 = function(num) { 30 | return num.toString(7) 31 | }; 32 | -------------------------------------------------------------------------------- /algorithms/BasicCalculator_II.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/basic-calculator-ii 2 | // Author : Dean Shi 3 | // Date : 2017-09-25 4 | 5 | /*************************************************************************************** 6 | * 7 | * Implement a basic calculator to evaluate a simple expression string. 8 | * 9 | * The expression string contains only non-negative integers, +, -, *, / operators and 10 | * empty spaces . The integer division should truncate toward zero. 11 | * 12 | * You may assume that the given expression is always valid. 13 | * 14 | * Some examples: 15 | * "3+2*2" = 7 16 | * " 3/2 " = 1 17 | * " 3+5 / 2 " = 5 18 | * 19 | * Note: Do not use the eval built-in library function. 20 | * 21 | * Credits:Special thanks to @ts for adding this problem and creating all test cases. 22 | * 23 | ***************************************************************************************/ 24 | 25 | /** 26 | * @param {string} s 27 | * @return {number} 28 | */ 29 | var calculate = function(s) { 30 | const stack = [] 31 | const arr = s.match(/\d+|\+|\/|-|\*/g); 32 | const operators = { 33 | '+': num => stack.push(+num), 34 | '-': num => stack.push(-num), 35 | '*': num => stack.push(stack.pop() * +num), 36 | '/': num => stack.push(~~(stack.pop() / +num)), 37 | } 38 | 39 | let opt = '+' 40 | for (const c of arr) { 41 | c in operators ? opt = c : operators[opt](c) 42 | } 43 | 44 | return stack.reduce((sum, num) => sum + num) 45 | }; 46 | -------------------------------------------------------------------------------- /algorithms/BestTimeToBuyAndSellStock.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/best-time-to-buy-and-sell-stock 2 | // Author : Dean Shi 3 | // Date : 2017-07-12 4 | 5 | /*************************************************************************************** 6 | * 7 | * Say you have an array for which the ith element is the price of a given stock on day 8 | * i. 9 | * 10 | * If you were only permitted to complete at most one transaction (ie, buy one and sell 11 | * one share of the stock), design an algorithm to find the maximum profit. 12 | * 13 | * Example 1: 14 | * 15 | * Input: [7, 1, 5, 3, 6, 4] 16 | * Output: 5 17 | * 18 | * max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than 19 | * buying price) 20 | * 21 | * Example 2: 22 | * 23 | * Input: [7, 6, 4, 3, 1] 24 | * Output: 0 25 | * 26 | * In this case, no transaction is done, i.e. max profit = 0. 27 | * 28 | * 29 | ***************************************************************************************/ 30 | 31 | /** 32 | * @param {number[]} prices 33 | * @return {number} 34 | */ 35 | var maxProfit = function(prices) { 36 | let max = 0, min = prices[0] 37 | 38 | for (let p of prices) { 39 | min = Math.min(min, p) 40 | max = Math.max(max, p - min) 41 | } 42 | 43 | return max 44 | }; 45 | -------------------------------------------------------------------------------- /algorithms/BestTimeToBuyAndSellStock_II.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii 2 | // Author : Dean Shi 3 | // Date : 2018-01-20 4 | 5 | /*************************************************************************************** 6 | * 7 | * Say you have an array for which the ith element is the price of a given stock on day 8 | * i. 9 | * 10 | * Design an algorithm to find the maximum profit. You may complete as many 11 | * transactions as you like (ie, buy one and sell one share of the stock multiple times) 12 | * . However, you may not engage in multiple transactions at the same time (ie, you 13 | * must sell the stock before you buy again). 14 | * 15 | ***************************************************************************************/ 16 | 17 | /** 18 | * @param {number[]} prices 19 | * @return {number} 20 | */ 21 | var maxProfit = function(prices) { 22 | let sum = 0 23 | 24 | for (let i = 1; i < prices.length; i++) { 25 | if (prices[i] > prices[i - 1]) sum += prices[i] - prices[i - 1] 26 | } 27 | 28 | return sum 29 | }; 30 | -------------------------------------------------------------------------------- /algorithms/BinaryNumberWithAlternatingBits.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/binary-number-with-alternating-bits 2 | // Author : Dean Shi 3 | // Date : 2017-10-09 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a positive integer, check whether it has alternating bits: namely, if 8 | * two adjacent bits will always have different values. 9 | * 10 | * Example 1: 11 | * Input: 5 12 | * Output: True 13 | * Explanation: 14 | * The binary representation of 5 is: 101 15 | * 16 | * Example 2: 17 | * Input: 7 18 | * Output: False 19 | * Explanation: 20 | * The binary representation of 7 is: 111. 21 | * 22 | * Example 3: 23 | * Input: 11 24 | * Output: False 25 | * Explanation: 26 | * The binary representation of 11 is: 1011. 27 | * 28 | * Example 4: 29 | * Input: 10 30 | * Output: True 31 | * Explanation: 32 | * The binary representation of 10 is: 1010. 33 | * 34 | ***************************************************************************************/ 35 | 36 | /** 37 | * @param {number} n 38 | * @return {boolean} 39 | */ 40 | var hasAlternatingBits = function(n) { 41 | const m = n + (n >> 1) + 1 42 | return (m & (m - 1)) === 0 43 | }; -------------------------------------------------------------------------------- /algorithms/BinarySearchTreeToGreaterSumTree.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/binary-search-tree-to-greater-sum-tree 2 | // Author : Dean Shi 3 | // Date : 2019-05-26 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given the root of a binary search tree with distinct values, modify it so that every 8 | * node has a new value equal to the sum of the values of the original tree that are 9 | * greater than or equal to node.val. 10 | * 11 | * As a reminder, a binary search tree is a tree that satisfies these constraints: 12 | * 13 | * The left subtree of a node contains only nodes with keys less than the node's key. 14 | * The right subtree of a node contains only nodes with keys greater than the node's 15 | * key. 16 | * Both the left and right subtrees must also be binary search trees. 17 | * 18 | * Example 1: 19 | * 20 | * Input: [4,1,6,0,2,5,7,null,null,null,3,null,null,null,8] 21 | * Output: [30,36,21,36,35,26,15,null,null,null,33,null,null,null,8] 22 | * 23 | * Note: 24 | * 25 | * The number of nodes in the tree is between 1 and 100. 26 | * Each node will have value between 0 and 100. 27 | * The given tree is a binary search tree. 28 | * 29 | ***************************************************************************************/ 30 | 31 | /** 32 | * Definition for a binary tree node. 33 | * function TreeNode(val) { 34 | * this.val = val; 35 | * this.left = this.right = null; 36 | * } 37 | */ 38 | /** 39 | * @param {TreeNode} root 40 | * @return {TreeNode} 41 | */ 42 | var bstToGst = function(root) { 43 | gst(root) 44 | return root 45 | }; 46 | 47 | function gst(node, sum = 0) { 48 | return node 49 | ? gst(node.left, node.val += gst(node.right, sum)) 50 | : sum 51 | } 52 | -------------------------------------------------------------------------------- /algorithms/BinaryTreeInorderTraversal.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/binary-tree-inorder-traversal 2 | // Author : Dean Shi 3 | // Date : 2017-02-27 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a binary tree, return the inorder traversal of its nodes' values. 8 | * 9 | * For example: 10 | * Given binary tree [1,null,2,3], 11 | * 12 | * 1 13 | * \ 14 | * 2 15 | * / 16 | * 3 17 | * 18 | * return [1,3,2]. 19 | * 20 | * Note: Recursive solution is trivial, could you do it iteratively? 21 | * 22 | * 23 | ***************************************************************************************/ 24 | 25 | /** 26 | * Definition for a binary tree node. 27 | * function TreeNode(val) { 28 | * this.val = val; 29 | * this.left = this.right = null; 30 | * } 31 | */ 32 | /** 33 | * @param {TreeNode} root 34 | * @return {number[]} 35 | */ 36 | var inorderTraversal = function(root) { 37 | const stack = [] 38 | const result = [] 39 | while (root) { 40 | if (root.right) stack.push(root.right) 41 | stack.push(root.val) 42 | if (root.left) stack.push(root.left) 43 | 44 | root = stack.pop() 45 | while (root !== void(0) && typeof root !== 'object') { 46 | result.push(root) 47 | root = stack.pop() 48 | } 49 | } 50 | return result 51 | }; 52 | -------------------------------------------------------------------------------- /algorithms/BinaryTreeLevelOrderTraversal_II.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/binary-tree-level-order-traversal-ii 2 | // Author : Dean Shi 3 | // Date : 2017-03-02 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a binary tree, return the bottom-up level order traversal of its nodes' 8 | * values. (ie, from left to right, level by level from leaf to root). 9 | * 10 | * For example: 11 | * Given binary tree [3,9,20,null,null,15,7], 12 | * 13 | * 3 14 | * / \ 15 | * 9 20 16 | * / \ 17 | * 15 7 18 | * 19 | * return its bottom-up level order traversal as: 20 | * 21 | * [ 22 | * [15,7], 23 | * [9,20], 24 | * [3] 25 | * ] 26 | * 27 | * 28 | ***************************************************************************************/ 29 | 30 | /** 31 | * Definition for a binary tree node. 32 | * function TreeNode(val) { 33 | * this.val = val; 34 | * this.left = this.right = null; 35 | * } 36 | */ 37 | /** 38 | * @param {TreeNode} root 39 | * @return {number[][]} 40 | */ 41 | var levelOrderBottom = function(root) { 42 | const stack = [] 43 | const result = [] 44 | let index = 0 45 | while (root) { 46 | if (!result[index]) result[index] = [] 47 | result[index].push(root.val) 48 | 49 | if (root.right) stack.push([root.right, index + 1]); 50 | if (root.left) stack.push([root.left, index + 1]); 51 | [root, index] = stack.pop() || [] 52 | } 53 | return result.reverse() 54 | }; 55 | -------------------------------------------------------------------------------- /algorithms/BinaryTreePruning.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/binary-tree-pruning 2 | // Author : Dean Shi 3 | // Date : 2018-04-15 4 | 5 | /*************************************************************************************** 6 | * We are given the head node root of a binary tree, where additionally every node's 7 | * value is either a 0 or a 1. 8 | * 9 | * Return the same tree where every subtree (of the given tree) not containing a 1 has 10 | * been removed. 11 | * 12 | * (Recall that the subtree of a node X is X, plus every node that is a descendant of X. 13 | * ) 14 | * 15 | * Example 1: 16 | * Input: [1,null,0,0,1] 17 | * Output: [1,null,0,null,1] 18 | * 19 | * Explanation: 20 | * Only the red nodes satisfy the property "every subtree not containing a 1". 21 | * The diagram on the right represents the answer. 22 | * 23 | * Example 2: 24 | * Input: [1,0,1,0,0,0,1] 25 | * Output: [1,null,1,null,1] 26 | * 27 | * Example 3: 28 | * Input: [1,1,0,1,1,0,1,0] 29 | * Output: [1,1,0,1,1,null,1] 30 | * 31 | * Note: 32 | * 33 | * The binary tree will have at most 100 nodes. 34 | * The value of each node will only be 0 or 1. 35 | * 36 | ***************************************************************************************/ 37 | 38 | /** 39 | * Definition for a binary tree node. 40 | * function TreeNode(val) { 41 | * this.val = val; 42 | * this.left = this.right = null; 43 | * } 44 | */ 45 | /** 46 | * @param {TreeNode} root 47 | * @return {TreeNode} 48 | */ 49 | var pruneTree = function(root) { 50 | if (!root) return root 51 | 52 | root.left = pruneTree(root.left) 53 | root.right = pruneTree(root.right) 54 | 55 | return root.left === null && root.right === null && root.val === 0 56 | ? null 57 | : root 58 | }; 59 | -------------------------------------------------------------------------------- /algorithms/BinaryTreeTilt.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/binary-tree-tilt 2 | // Author : Dean Shi 3 | // Date : 2017-04-27 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a binary tree, return the tilt of the whole tree. 8 | * 9 | * The tilt of a tree node is defined as the absolute difference between the sum of all 10 | * left subtree node values and the sum of all right subtree node values. Null node has 11 | * tilt 0. 12 | * 13 | * The tilt of the whole tree is defined as the sum of all nodes' tilt. 14 | * 15 | * Example: 16 | * 17 | * Input: 18 | * 1 19 | * / \ 20 | * 2 3 21 | * Output: 1 22 | * Explanation: 23 | * Tilt of node 2 : 0 24 | * Tilt of node 3 : 0 25 | * Tilt of node 1 : |2-3| = 1 26 | * Tilt of binary tree : 0 + 0 + 1 = 1 27 | * 28 | * Note: 29 | * 30 | * The sum of node values in any subtree won't exceed the range of 32-bit integer. 31 | * All the tilt values won't exceed the range of 32-bit integer. 32 | * 33 | * 34 | ***************************************************************************************/ 35 | 36 | /** 37 | * Definition for a binary tree node. 38 | * function TreeNode(val) { 39 | * this.val = val; 40 | * this.left = this.right = null; 41 | * } 42 | */ 43 | /** 44 | * @param {TreeNode} root 45 | * @return {number} 46 | */ 47 | var findTilt = function(root) { 48 | return postorder(root)[1] 49 | }; 50 | 51 | function postorder(root, tilt = 0) { 52 | if (!root) return [0, tilt] 53 | let left, right 54 | [left, tilt] = postorder(root.left, tilt); 55 | [right, tilt] = postorder(root.right, tilt); 56 | 57 | tilt += Math.abs(left - right) 58 | return [left + right + root.val, tilt] 59 | } 60 | -------------------------------------------------------------------------------- /algorithms/BinaryTreeZigzagLevelOrderTraversal.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal 2 | // Author : Dean Shi 3 | // Date : 2017-08-14 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a binary tree, return the zigzag level order traversal of its nodes' values. 8 | * (ie, from left to right, then right to left for the next level and alternate 9 | * between). 10 | * 11 | * For example: 12 | * Given binary tree [3,9,20,null,null,15,7], 13 | * 14 | * 3 15 | * / \ 16 | * 9 20 17 | * / \ 18 | * 15 7 19 | * 20 | * return its zigzag level order traversal as: 21 | * 22 | * [ 23 | * [3], 24 | * [20,9], 25 | * [15,7] 26 | * ] 27 | * 28 | * 29 | ***************************************************************************************/ 30 | 31 | /** 32 | * Definition for a binary tree node. 33 | * function TreeNode(val) { 34 | * this.val = val; 35 | * this.left = this.right = null; 36 | * } 37 | */ 38 | /** 39 | * @param {TreeNode} root 40 | * @return {number[][]} 41 | */ 42 | var zigzagLevelOrder = function(root) { 43 | if (!root) return [] 44 | 45 | let stack = [root], result = [], index = 0, tmpStack, level 46 | 47 | while (stack.length) { 48 | level = [] 49 | tmpStack = [] 50 | for (let node of stack) { 51 | level.push(node.val) 52 | if (node.left) tmpStack.push(node.left) 53 | if (node.right) tmpStack.push(node.right) 54 | } 55 | result.push(index++ % 2 ? level.reverse() : level) 56 | stack = tmpStack 57 | } 58 | 59 | return result 60 | }; 61 | -------------------------------------------------------------------------------- /algorithms/BoatsToSavePeople.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/boats-to-save-people 2 | // Author : Dean Shi 3 | // Date : 2018-08-16 4 | 5 | /*************************************************************************************** 6 | * The i-th person has weight people[i], and each boat can carry a maximum weight of 7 | * limit. 8 | * 9 | * Each boat carries at most 2 people at the same time, provided the sum of the weight 10 | * of those people is at most limit. 11 | * 12 | * Return the minimum number of boats to carry every given person.  (It is guaranteed 13 | * each person can be carried by a boat.) 14 | * 15 | * Example 1: 16 | * 17 | * Input: people = [1,2], limit = 3 18 | * Output: 1 19 | * Explanation: 1 boat (1, 2) 20 | * 21 | * Example 2: 22 | * 23 | * Input: people = [3,2,2,1], limit = 3 24 | * Output: 3 25 | * Explanation: 3 boats (1, 2), (2) and (3) 26 | * 27 | * Example 3: 28 | * 29 | * Input: people = [3,5,3,4], limit = 5 30 | * Output: 4 31 | * Explanation: 4 boats (3), (3), (4), (5) 32 | * 33 | * Note: 34 | * 35 | * 1 <= people.length <= 50000 36 | * 1 <= people[i] <= limit <= 30000 37 | * 38 | ***************************************************************************************/ 39 | 40 | /** 41 | * @param {number[]} people 42 | * @param {number} limit 43 | * @return {number} 44 | */ 45 | var numRescueBoats = function(people, limit) { 46 | people.sort((a, b) => a - b) 47 | let headPt = 0 48 | let tailPt = people.length - 1 49 | let boat = 0 50 | 51 | while(headPt <= tailPt) { 52 | if (people[headPt] + people[tailPt] <= limit) headPt++ 53 | tailPt-- 54 | boat++ 55 | } 56 | 57 | return boat 58 | }; 59 | -------------------------------------------------------------------------------- /algorithms/BuddyStrings.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/buddy-strings 2 | // Author : Dean Shi 3 | // Date : 2018-08-12 4 | 5 | /*************************************************************************************** 6 | * Given two strings A and B of lowercase letters, return true if and only if we can 7 | * swap two letters in A so that the result equals B. 8 | * 9 | * Example 1: 10 | * 11 | * Input: A = "ab", B = "ba" 12 | * Output: true 13 | * 14 | * Example 2: 15 | * 16 | * Input: A = "ab", B = "ab" 17 | * Output: false 18 | * 19 | * Example 3: 20 | * 21 | * Input: A = "aa", B = "aa" 22 | * Output: true 23 | * 24 | * Example 4: 25 | * 26 | * Input: A = "aaaaaaabc", B = "aaaaaaacb" 27 | * Output: true 28 | * 29 | * Example 5: 30 | * 31 | * Input: A = "", B = "aa" 32 | * Output: false 33 | * 34 | * Note: 35 | * 36 | * 0 <= A.length <= 20000 37 | * 0 <= B.length <= 20000 38 | * A and B consist only of lowercase letters. 39 | * 40 | ***************************************************************************************/ 41 | 42 | /** 43 | * @param {string} A 44 | * @param {string} B 45 | * @return {boolean} 46 | */ 47 | var buddyStrings = function(A, B) { 48 | if (A.length !== B.length) return false 49 | if (A === B) return A.length !== new Set(A).size 50 | 51 | let countOfDiff = 0 52 | const ASet = new Set(A) 53 | for (let i = 0; i < A.length; i++) { 54 | if (A[i] !== B[i] && (++countOfDiff === 3 || !ASet.has(B[i]))) return false 55 | } 56 | 57 | return true 58 | }; 59 | -------------------------------------------------------------------------------- /algorithms/BulbSwitcher.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/bulb-switcher 2 | // Author : Dean Shi 3 | // Date : 2017-09-05 4 | 5 | /*************************************************************************************** 6 | * 7 | * There are n bulbs that are initially off. You first turn on all the bulbs. Then, you 8 | * turn off every second bulb. On the third round, you toggle every third bulb (turning 9 | * on if it's off or turning off if it's on). For the ith round, you toggle every i 10 | * bulb. For the nth round, you only toggle the last bulb. 11 | * 12 | * Find how many bulbs are on after n rounds. 13 | * 14 | * Example: 15 | * 16 | * Given n = 3. 17 | * At first, the three bulbs are [off, off, off]. 18 | * After first round, the three bulbs are [on, on, on]. 19 | * After second round, the three bulbs are [on, off, on]. 20 | * After third round, the three bulbs are [on, off, off]. 21 | * So you should return 1, because there is only one bulb is on. 22 | * 23 | * 24 | ***************************************************************************************/ 25 | 26 | /** 27 | * @param {number} n 28 | * @return {number} 29 | */ 30 | var bulbSwitch = function(n) { 31 | return ~~Math.sqrt(n) 32 | }; 33 | -------------------------------------------------------------------------------- /algorithms/BulbSwitcher_II.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/bulb-switcher-ii 2 | // Author : Dean Shi 3 | // Date : 2017-09-05 4 | 5 | /*************************************************************************************** 6 | * 7 | * There is a room with n lights which are turned on initially and 4 buttons on the 8 | * wall. After performing exactly m unknown operations towards buttons, you need to 9 | * return how many different kinds of status of the n lights could be. 10 | * 11 | * Suppose n lights are labeled as number [1, 2, 3 ..., n], function of these 4 buttons 12 | * are given below: 13 | * 14 | * Flip all the lights. 15 | * Flip lights with even numbers. 16 | * Flip lights with odd numbers. 17 | * Flip lights with (3k + 1) numbers, k = 0, 1, 2, ... 18 | * 19 | * Example 1: 20 | * 21 | * Input: n = 1, m = 1. 22 | * Output: 2 23 | * Explanation: Status can be: [on], [off] 24 | * 25 | * Example 2: 26 | * 27 | * Input: n = 2, m = 1. 28 | * Output: 3 29 | * Explanation: Status can be: [on, off], [off, on], [off, off] 30 | * 31 | * Example 3: 32 | * 33 | * Input: n = 3, m = 1. 34 | * Output: 4 35 | * Explanation: Status can be: [off, on, off], [on, off, on], [off, off, off], [off, 36 | * on, on]. 37 | * 38 | * Note: 39 | * n and m both fit in range [0, 1000]. 40 | * 41 | * 42 | ***************************************************************************************/ 43 | 44 | /** 45 | * @param {number} n 46 | * @param {number} m 47 | * @return {number} 48 | */ 49 | var flipLights = function(n, m) { 50 | if (m === 0 || n === 0) return 1 51 | if (n === 1) return 2 52 | if (n === 2) return m === 1 ? 3 : 4 53 | if (m === 1) return 4 54 | return m === 2 ? 7 : 8 55 | }; 56 | -------------------------------------------------------------------------------- /algorithms/ClimbingStairs.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/climbing-stairs 2 | // Author : Dean Shi 3 | // Date : 2017-07-10 4 | 5 | /*************************************************************************************** 6 | * 7 | * You are climbing a stair case. It takes n steps to reach to the top. 8 | * 9 | * Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb 10 | * to the top? 11 | * 12 | * Note: Given n will be a positive integer. 13 | * 14 | * 15 | ***************************************************************************************/ 16 | 17 | /** 18 | * @param {number} n 19 | * @return {number} 20 | */ 21 | var climbStairs = function(n) { 22 | let [curr, next] = [1, 2] 23 | 24 | while (--n) { 25 | [curr, next] = [next, curr + next] 26 | } 27 | 28 | return curr 29 | }; 30 | 31 | 32 | /** 33 | * Solution in DP 34 | * 35 | * @param {number} n 36 | * @return {number} 37 | */ 38 | var climbStairs = function(n) { 39 | const dp = [0, 1, 2] 40 | for(let i = 3; i <= n; ++i) { 41 | dp[i] = dp[i-1] + dp[i-2] 42 | } 43 | return dp[n] 44 | }; 45 | -------------------------------------------------------------------------------- /algorithms/CoinChange.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/coin-change 2 | // Author : Dean Shi 3 | // Date : 2017-07-15 4 | 5 | /*************************************************************************************** 6 | * 7 | * You are given coins of different denominations and a total amount of money amount. 8 | * Write a function to compute the fewest number of coins that you need to make up that 9 | * amount. If that amount of money cannot be made up by any combination of the coins, 10 | * return -1. 11 | * 12 | * Example 1: 13 | * coins = [1, 2, 5], amount = 11 14 | * return 3 (11 = 5 + 5 + 1) 15 | * 16 | * Example 2: 17 | * coins = [2], amount = 3 18 | * return -1. 19 | * 20 | * Note: 21 | * You may assume that you have an infinite number of each kind of coin. 22 | * 23 | * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating 24 | * all test cases. 25 | * 26 | * 27 | ***************************************************************************************/ 28 | 29 | /** 30 | * @param {number[]} coins 31 | * @param {number} amount 32 | * @return {number} 33 | */ 34 | var coinChange = function(coins, amount) { 35 | const dp = Array(amount + 1).fill(amount + 1) 36 | 37 | dp[0] = 0 38 | for (let i of coins) { 39 | for (let j = i; j <= amount; ++j) { 40 | dp[j] = Math.min(dp[j], dp[j - i] + 1) 41 | } 42 | } 43 | 44 | return dp[amount] > amount ? -1 : dp[amount] 45 | }; 46 | -------------------------------------------------------------------------------- /algorithms/CoinChange_II.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/coin-change-2 2 | // Author : Dean Shi 3 | // Date : 2017-07-15 4 | 5 | /*************************************************************************************** 6 | * 7 | * You are given coins of different denominations and a total amount of money. Write a 8 | * function to compute the number of combinations that make up that amount. You may 9 | * assume that you have infinite number of each kind of coin. 10 | * 11 | * Note: 12 | * You can assume that 13 | * 14 | * 0 15 | * 1 16 | * the number of coins is less than 500 17 | * the answer is guaranteed to fit into signed 32-bit integer 18 | * 19 | * Example 1: 20 | * 21 | * Input: amount = 5, coins = [1, 2, 5] 22 | * Output: 4 23 | * Explanation: there are four ways to make up the amount: 24 | * 5=5 25 | * 5=2+2+1 26 | * 5=2+1+1+1 27 | * 5=1+1+1+1+1 28 | * 29 | * Example 2: 30 | * 31 | * Input: amount = 3, coins = [2] 32 | * Output: 0 33 | * Explanation: the amount of 3 cannot be made up just with coins of 2. 34 | * 35 | * Example 3: 36 | * 37 | * Input: amount = 10, coins = [10] 38 | * Output: 1 39 | * 40 | ***************************************************************************************/ 41 | 42 | /** 43 | * @param {number} amount 44 | * @param {number[]} coins 45 | * @return {number} 46 | */ 47 | var change = function(amount, coins) { 48 | const dp = Array(amount + 1).fill(0) 49 | dp[0] = 1 50 | 51 | for (let coin of coins) { 52 | for (let i = coin; i <= amount; ++i) { 53 | dp[i] += dp[i - coin] 54 | } 55 | } 56 | return dp[amount] 57 | }; 58 | -------------------------------------------------------------------------------- /algorithms/CompareVersionNumbers.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/compare-version-numbers 2 | // Author : Dean Shi 3 | // Date : 2017-09-14 4 | 5 | /*************************************************************************************** 6 | * 7 | * Compare two version numbers version1 and version2. 8 | * If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 9 | * 0. 10 | * 11 | * You may assume that the version strings are non-empty and contain only digits and 12 | * the . character. 13 | * The . character does not represent a decimal point and is used to separate number 14 | * sequences. 15 | * For instance, 2.5 is not "two and a half" or "half way to version three", it is the 16 | * fifth second-level revision of the second first-level revision. 17 | * 18 | * Here is an example of version numbers ordering: 19 | * 0.1 < 1.1 < 1.2 < 13.37 20 | * 21 | * Credits:Special thanks to @ts for adding this problem and creating all test cases. 22 | * 23 | * 24 | ***************************************************************************************/ 25 | 26 | /** 27 | * @param {string} version1 28 | * @param {string} version2 29 | * @return {number} 30 | */ 31 | var compareVersion = function(version1, version2) { 32 | const v1 = version1.split('.') 33 | const v2 = version2.split('.') 34 | 35 | const len = Math.max(v1.length, v2.length) 36 | 37 | for (let val1, val2, i = 0; i < len; ++i) { 38 | val1 = +(v1[i] || 0) 39 | val2 = +(v2[i] || 0) 40 | if (val1 < val2) return -1 41 | if (val1 > val2) return 1 42 | } 43 | return 0 44 | }; 45 | -------------------------------------------------------------------------------- /algorithms/ComplementOfBase10Integer.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/complement-of-base-10-integer/submissions/ 2 | // Author : Dean Shi 3 | // Date : 2019-05-26 4 | 5 | /*************************************************************************************** 6 | * 7 | * Every non-negative integer N has a binary representation.  For example, 5 can be 8 | * represented as "101" in binary, 11 as "1011" in binary, and so on.  Note that except 9 | * for N = 0, there are no leading zeroes in any binary representation. 10 | * 11 | * The complement of a binary representation is the number in binary you get when 12 | * changing every 1 to a 0 and 0 to a 1.  For example, the complement of "101" in 13 | * binary is "010" in binary. 14 | * 15 | * For a given number N in base-10, return the complement of it's binary representation 16 | * as a base-10 integer. 17 | * 18 | * Example 1: 19 | * 20 | * Input: 5 21 | * Output: 2 22 | * Explanation: 5 is "101" in binary, with complement "010" in binary, which is 2 in 23 | * base-10. 24 | * 25 | * Example 2: 26 | * 27 | * Input: 7 28 | * Output: 0 29 | * Explanation: 7 is "111" in binary, with complement "000" in binary, which is 0 in 30 | * base-10. 31 | * 32 | * Example 3: 33 | * 34 | * Input: 10 35 | * Output: 5 36 | * Explanation: 10 is "1010" in binary, with complement "0101" in binary, which is 5 in 37 | * base-10. 38 | * 39 | * Note: 40 | * 41 | * 0 <= N < 10^9 42 | * 43 | ***************************************************************************************/ 44 | 45 | /** 46 | * @param {number} N 47 | * @return {number} 48 | */ 49 | var bitwiseComplement = function(N) { 50 | return Math.pow(2, N.toString(2).length) - N - 1 51 | }; 52 | -------------------------------------------------------------------------------- /algorithms/ConsecutiveCharacters.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/consecutive-characters 2 | // Author : Dean Shi 3 | // Date : 2021-12-14 4 | 5 | /*************************************************************************************** 6 | * The power of the string is the maximum length of a non-empty substring that contains 7 | * only one unique character. 8 | * 9 | * Given a string s, return the power of s. 10 | * 11 | * Example 1: 12 | * 13 | * Input: s = "leetcode" 14 | * Output: 2 15 | * Explanation: The substring "ee" is of length 2 with the character 'e' only. 16 | * 17 | * Example 2: 18 | * 19 | * Input: s = "abbcccddddeeeeedcba" 20 | * Output: 5 21 | * Explanation: The substring "eeeee" is of length 5 with the character 'e' only. 22 | * 23 | * Example 3: 24 | * 25 | * Input: s = "triplepillooooow" 26 | * Output: 5 27 | * 28 | * Example 4: 29 | * 30 | * Input: s = "hooraaaaaaaaaaay" 31 | * Output: 11 32 | * 33 | * Example 5: 34 | * 35 | * Input: s = "tourist" 36 | * Output: 1 37 | * 38 | * Constraints: 39 | * 40 | * 1 <= s.length <= 500 41 | * s consists of only lowercase English letters. 42 | * 43 | * 44 | ***************************************************************************************/ 45 | 46 | /** 47 | * @param {string} s 48 | * @return {number} 49 | */ 50 | var maxPower = function(s) { 51 | let [result, count, ch] = [0, 0, ''] 52 | for (let i = 0; i < s.length; i++) { 53 | if (s[i] === ch) { 54 | count++ 55 | } else { 56 | result = Math.max(result, count) 57 | ch = s[i] 58 | count = 1 59 | } 60 | } 61 | 62 | return Math.max(result, count) 63 | }; 64 | -------------------------------------------------------------------------------- /algorithms/ConstructBinarySearchTreeFromPreorderTraversal.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/construct-binary-search-tree-from-preorder-traversal 2 | // Author : Dean Shi 3 | // Date : 2019-06-30 4 | 5 | /*************************************************************************************** 6 | * 7 | * Return the root node of a binary search tree that matches the given preorder 8 | * traversal. 9 | * 10 | * (Recall that a binary search tree is a binary tree where for every node, any 11 | * descendant of node.left has a value < node.val, and any descendant of node.right has 12 | * a value > node.val.  Also recall that a preorder traversal displays the value of the 13 | * node first, then traverses node.left, then traverses node.right.) 14 | * 15 | * Example 1: 16 | * 17 | * Input: [8,5,1,7,10,12] 18 | * Output: [8,5,10,1,7,null,12] 19 | * 20 | * Note: 21 | * 22 | * 1 <= preorder.length <= 100 23 | * The values of preorder are distinct. 24 | * 25 | ***************************************************************************************/ 26 | 27 | /** 28 | * Definition for a binary tree node. 29 | * function TreeNode(val) { 30 | * this.val = val; 31 | * this.left = this.right = null; 32 | * } 33 | */ 34 | /** 35 | * @param {number[]} preorder 36 | * @return {TreeNode} 37 | */ 38 | var bstFromPreorder = function(preorder) { 39 | if (!preorder.length) return null 40 | 41 | const [root, ...rest] = preorder 42 | 43 | const rootNode = new TreeNode(root) 44 | rootNode.left = bstFromPreorder(rest.filter(n => n < root)) 45 | rootNode.right = bstFromPreorder(rest.filter(n => n > root)) 46 | 47 | return rootNode 48 | }; 49 | -------------------------------------------------------------------------------- /algorithms/ContainerWithMostWater.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/container-with-most-water/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-05 4 | 5 | /********************************************************************************** 6 | * 7 | * Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). 8 | * n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). 9 | * 10 | * Find two lines, which together with x-axis forms a container, such that the container contains the most water. 11 | * 12 | * Note: You may not slant the container. 13 | * 14 | * 15 | **********************************************************************************/ 16 | 17 | /** 18 | * @param {number[]} height 19 | * @return {number} 20 | */ 21 | var maxArea = function(height) { 22 | var max = 0; 23 | var left = 0; 24 | var right = height.length - 1; 25 | 26 | while (left < right) { 27 | var area = (height[left] < height[right] ? height[left] : height[right]) * (right - left); 28 | 29 | if (area > max) { 30 | max = area; 31 | } 32 | if (height[left] < height[right]) { 33 | do { 34 | ++left; 35 | } while (left < right && height[left - 1] >= height[left]); 36 | } else { 37 | do { 38 | --right; 39 | } while (left < right && height[right + 1] >= height[right]); 40 | } 41 | } 42 | return max; 43 | }; 44 | 45 | console.log(maxArea([1, 1]) === 1); // true 46 | -------------------------------------------------------------------------------- /algorithms/ContainsDuplicate.II.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/contains-duplicate-ii/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-16 4 | 5 | /********************************************************************************** 6 | * 7 | * Given an array of integers and an integer k, find out whether there there are 8 | * two distinct indices i and j in the array such that nums[i] = nums[j] and 9 | * the difference between i and j is at most k. 10 | * 11 | * 12 | **********************************************************************************/ 13 | 14 | /** 15 | * @param {number[]} nums 16 | * @param {number} k 17 | * @return {boolean} 18 | */ 19 | var containsNearbyDuplicate = function(nums, k) { 20 | var n, hash = {}; 21 | for (var i in nums) { 22 | n = nums[i]; 23 | if (i - hash[n] <= k) { 24 | return true; 25 | } 26 | hash[n] = i; 27 | } 28 | return false; 29 | }; 30 | 31 | // Test case 32 | console.log(containsNearbyDuplicate([1, 0, 1, 1], 1)); // true 33 | -------------------------------------------------------------------------------- /algorithms/ContainsDuplicate.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/contains-duplicate 2 | // Author : Dean Shi 3 | // Date : 2018-12-03 4 | 5 | /*************************************************************************************** 6 | * Given an array of integers, find if the array contains any duplicates. 7 | * 8 | * Your function should return true if any value appears at least twice in the array, 9 | * and it should return false if every element is distinct. 10 | * 11 | * Example 1: 12 | * 13 | * Input: [1,2,3,1] 14 | * Output: true 15 | * 16 | * Example 2: 17 | * 18 | * Input: [1,2,3,4] 19 | * Output: false 20 | * 21 | * Example 3: 22 | * 23 | * Input: [1,1,1,3,3,4,3,2,4,2] 24 | * Output: true 25 | * 26 | ***************************************************************************************/ 27 | 28 | /** 29 | * @param {number[]} nums 30 | * @return {boolean} 31 | */ 32 | var containsDuplicate = function(nums) { 33 | const numSet = new Set() 34 | return nums.some((n) => numSet.has(n) || !numSet.add(n)) 35 | }; 36 | -------------------------------------------------------------------------------- /algorithms/ConvertANumberToHexadecimal.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/convert-a-number-to-hexadecimal 2 | // Author : Dean Shi 3 | // Date : 2017-09-09 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an integer, write an algorithm to convert it to hexadecimal. For negative 8 | * integer, two’s complement method is used. 9 | * 10 | * Note: 11 | * 12 | * All letters in hexadecimal (a-f) must be in lowercase. 13 | * The hexadecimal string must not contain extra leading 0s. If the number is zero, it 14 | * is represented by a single zero character '0'; otherwise, the first character in the 15 | * hexadecimal string will not be the zero character. 16 | * The given number is guaranteed to fit within the range of a 32-bit signed integer. 17 | * You must not use any method provided by the library which converts/formats the 18 | * number to hex directly. 19 | * 20 | * Example 1: 21 | * 22 | * Input: 23 | * 26 24 | * 25 | * Output: 26 | * "1a" 27 | * 28 | * Example 2: 29 | * 30 | * Input: 31 | * -1 32 | * 33 | * Output: 34 | * "ffffffff" 35 | * 36 | * 37 | ***************************************************************************************/ 38 | 39 | /** 40 | * @param {number} num 41 | * @return {string} 42 | */ 43 | var toHex = function(num) { 44 | const hex = '0123456789abcdef' 45 | let rest, result = '' 46 | 47 | do { 48 | result = hex[num & 15] + result 49 | } while (num >>>= 4) 50 | 51 | return result 52 | }; 53 | -------------------------------------------------------------------------------- /algorithms/ConvertBinaryNumberInALinkedListToInteger.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/convert-binary-number-in-a-linked-list-to-integer 2 | // Author : Dean Shi 3 | // Date : 2021-12-14 4 | 5 | /*************************************************************************************** 6 | * Given head which is a reference node to a singly-linked list. The value of each node 7 | * in the linked list is either 0 or 1. The linked list holds the binary representation 8 | * of a number. 9 | * 10 | * Return the decimal value of the number in the linked list. 11 | * 12 | * Example 1: 13 | * 14 | * Input: head = [1,0,1] 15 | * Output: 5 16 | * Explanation: (101) in base 2 = (5) in base 10 17 | * 18 | * Example 2: 19 | * 20 | * Input: head = [0] 21 | * Output: 0 22 | * 23 | * Example 3: 24 | * 25 | * Input: head = [1] 26 | * Output: 1 27 | * 28 | * Example 4: 29 | * 30 | * Input: head = [1,0,0,1,0,0,1,1,1,0,0,0,0,0,0] 31 | * Output: 18880 32 | * 33 | * Example 5: 34 | * 35 | * Input: head = [0,0] 36 | * Output: 0 37 | * 38 | * Constraints: 39 | * 40 | * The Linked List is not empty. 41 | * Number of nodes will not exceed 30. 42 | * Each node's value is either 0 or 1. 43 | * 44 | ***************************************************************************************/ 45 | 46 | /** 47 | * Definition for singly-linked list. 48 | * function ListNode(val, next) { 49 | * this.val = (val===undefined ? 0 : val) 50 | * this.next = (next===undefined ? null : next) 51 | * } 52 | */ 53 | /** 54 | * @param {ListNode} head 55 | * @return {number} 56 | */ 57 | var getDecimalValue = function(head) { 58 | let result = head.val 59 | 60 | while (head = head.next) { 61 | result = result * 2 + head.val 62 | } 63 | return result 64 | }; 65 | -------------------------------------------------------------------------------- /algorithms/ConvertSortedArrayToBinarySearchTree.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree 2 | // Author : Dean Shi 3 | // Date : 2017-03-19 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an array where elements are sorted in ascending order, convert it to a height 8 | * balanced BST. 9 | * 10 | ***************************************************************************************/ 11 | 12 | /** 13 | * Definition for a binary tree node. 14 | * function TreeNode(val) { 15 | * this.val = val; 16 | * this.left = this.right = null; 17 | * } 18 | */ 19 | /** 20 | * @param {number[]} nums 21 | * @return {TreeNode} 22 | */ 23 | var sortedArrayToBST = function(nums, left = 0, right = nums.length - 1) { 24 | if (left > right) return null 25 | 26 | const mid = Math.floor((left + right) / 2) 27 | const node = new TreeNode(nums[mid]) 28 | node.left = sortedArrayToBST(nums, left, mid - 1) 29 | node.right = sortedArrayToBST(nums, mid + 1, right) 30 | return node 31 | }; 32 | -------------------------------------------------------------------------------- /algorithms/DetectCapital.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/detect-capital 2 | // Author : Dean Shi 3 | // Date : 2017-03-05 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a word, you need to judge whether the usage of capitals in it is right or not. 8 | * 9 | * We define the usage of capitals in a word to be right when one of the following 10 | * cases holds: 11 | * 12 | * All letters in this word are capitals, like "USA". 13 | * All letters in this word are not capitals, like "leetcode". 14 | * Only the first letter in this word is capital if it has more than one letter, like 15 | * "Google". 16 | * 17 | * Otherwise, we define that this word doesn't use capitals in a right way. 18 | * 19 | * Example 1: 20 | * 21 | * Input: "USA" 22 | * Output: True 23 | * 24 | * Example 2: 25 | * 26 | * Input: "FlaG" 27 | * Output: False 28 | * 29 | * Note: 30 | * The input will be a non-empty word consisting of uppercase and lowercase latin 31 | * letters. 32 | * 33 | * 34 | ***************************************************************************************/ 35 | 36 | /** 37 | * @param {string} word 38 | * @return {boolean} 39 | */ 40 | var detectCapitalUse = function(word) { 41 | return word === word.toUpperCase() 42 | || word === word.toLowerCase() 43 | || word === (word[0].toUpperCase() + word.substring(1).toLowerCase()) 44 | }; 45 | -------------------------------------------------------------------------------- /algorithms/DiameterOfBinaryTree.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/diameter-of-binary-tree 2 | // Author : Dean Shi 3 | // Date : 2017-03-30 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a binary tree, you need to compute the length of the diameter of the tree. The 8 | * diameter of a binary tree is the length of the longest path between any two nodes in 9 | * a tree. This path may or may not pass through the root. 10 | * 11 | * Example: 12 | * Given a binary tree 13 | * 14 | * 1 15 | * / \ 16 | * 2 3 17 | * / \ 18 | * 4 5 19 | * 20 | * Return 3, which is the length of the path [4,2,1,3] or [5,2,1,3]. 21 | * 22 | * Note: 23 | * The length of path between two nodes is represented by the number of edges between 24 | * them. 25 | * 26 | * 27 | ***************************************************************************************/ 28 | 29 | /** 30 | * Definition for a binary tree node. 31 | * function TreeNode(val) { 32 | * this.val = val; 33 | * this.left = this.right = null; 34 | * } 35 | */ 36 | /** 37 | * @param {TreeNode} root 38 | * @return {number} 39 | */ 40 | var diameterOfBinaryTree = function(root) { 41 | let max = 0 42 | 43 | maxDepth(root) 44 | return max 45 | 46 | function maxDepth(root) { 47 | if (!root) return 0 48 | 49 | const left = maxDepth(root.left) 50 | const right = maxDepth(root.right) 51 | max = Math.max(max, left + right) 52 | return Math.max(left, right) + 1 53 | } 54 | }; 55 | 56 | -------------------------------------------------------------------------------- /algorithms/DuplicateZeros.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/duplicate-zeros 2 | // Author : Dean Shi 3 | // Date : 2023-04-07 4 | 5 | /*************************************************************************************** 6 | * Can you solve this real interview question? Duplicate Zeros - Given a fixed-length 7 | * integer array arr, duplicate each occurrence of zero, shifting the remaining 8 | * elements to the right. 9 | * 10 | * Note that elements beyond the length of the original array are not written. Do the 11 | * above modifications to the input array in place and do not return anything. 12 | * 13 | * Example 1: 14 | * 15 | * Input: arr = [1,0,2,3,0,4,5,0] 16 | * Output: [1,0,0,2,3,0,0,4] 17 | * Explanation: After calling your function, the input array is modified to: [1,0,0,2,3, 18 | * 0,0,4] 19 | * 20 | * Example 2: 21 | * 22 | * Input: arr = [1,2,3] 23 | * Output: [1,2,3] 24 | * Explanation: After calling your function, the input array is modified to: [1,2,3] 25 | * 26 | * Constraints: 27 | * 28 | * * 1 <= arr.length <= 104 29 | * * 0 <= arr[i] <= 9 30 | ***************************************************************************************/ 31 | 32 | /** 33 | * @param {number[]} arr 34 | * @return {void} Do not return anything, modify arr in-place instead. 35 | */ 36 | var duplicateZeros = function(arr) { 37 | const result = []; 38 | arr.forEach((n) => { 39 | if (n === 0) { 40 | result.push(0); 41 | } 42 | result.push(n); 43 | }); 44 | 45 | for (let i = 0; i < arr.length; i++) { 46 | arr[i] = result[i]; 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /algorithms/ExcelSheetColumnNumber.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/excel-sheet-column-number/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-18 4 | 5 | /********************************************************************************** 6 | * 7 | * Related to question Excel Sheet Column Title 8 | * Given a column title as appear in an Excel sheet, return its corresponding column number. 9 | * 10 | * For example: 11 | * A -> 1 12 | * B -> 2 13 | * C -> 3 14 | * ... 15 | * Z -> 26 16 | * AA -> 27 17 | * AB -> 28 18 | * 19 | * Credits:Special thanks to @ts for adding this problem and creating all test cases. 20 | * 21 | **********************************************************************************/ 22 | 23 | /** 24 | * @param {string} s 25 | * @return {number} 26 | */ 27 | var titleToNumber = function(s) { 28 | var result = 0; 29 | var code = 64; //'A'.charCodeAt() - 1 30 | for (var n, i = 0, l = s.length - 1; i <= l; ++i) { 31 | // 'A'.charCodeAt() - ('A'.charCodeAt() - 1) 32 | // = 'A'.charCodeAt() - 'A'.charCodeAt() + 1 33 | // = 1 34 | // 35 | // 'Z'.charCodeAt() - ('A'.charCodeAt() - 1) 36 | // = 'Z'.charCodeAt() - 'A'.charCodeAt() + 1 37 | // = 25 + 1 = 26 38 | n = s[i].charCodeAt() - code; 39 | result = result * 26 + n; 40 | } 41 | return result; 42 | }; 43 | 44 | // Test cases 45 | console.log(titleToNumber('A') === 1); // true 46 | console.log(titleToNumber('B') === 2); // true 47 | console.log(titleToNumber('C') === 3); // true 48 | console.log(titleToNumber('Z') === 26); // true 49 | console.log(titleToNumber('AA') === 27); // true 50 | console.log(titleToNumber('AB') === 28); // true 51 | -------------------------------------------------------------------------------- /algorithms/ExcelSheetColumnTitle.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/excel-sheet-column-title/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-18 4 | 5 | /********************************************************************************** 6 | * 7 | * Given a positive integer, return its corresponding column title as appear in an Excel sheet. 8 | * 9 | * For example: 10 | * 11 | * 1 -> A 12 | * 2 -> B 13 | * 3 -> C 14 | * ... 15 | * 26 -> Z 16 | * 27 -> AA 17 | * 28 -> AB 18 | * 19 | * Credits:Special thanks to @ifanchu for adding this problem and creating all test cases. 20 | * 21 | **********************************************************************************/ 22 | 23 | /** 24 | * @param {number} n 25 | * @return {string} 26 | */ 27 | var convertToTitle = function(n) { 28 | var result = ''; 29 | var code = 65; //'A'.charCodeAt() 30 | 31 | // loop when n is greater than 0 32 | while (n) { 33 | // (n - 1) % 26 will return a num on range 0 ~ 25 34 | // 0 + A.charCodeAt() = A.charCodeAt() 35 | // 25 + A.charCodeAt() = Z.charCodeAt() 36 | result = String.fromCharCode((n - 1) % 26 + code) + result; 37 | n = ~~((n - 1) / 26); 38 | } 39 | return result; 40 | }; 41 | 42 | // Test cases 43 | console.log(convertToTitle(1) === 'A'); // true 44 | console.log(convertToTitle(2) === 'B'); // true 45 | console.log(convertToTitle(3) === 'C'); // true 46 | console.log(convertToTitle(26) === 'Z'); // true 47 | console.log(convertToTitle(27) === 'AA'); // true 48 | console.log(convertToTitle(28) === 'AB'); // true 49 | -------------------------------------------------------------------------------- /algorithms/FactorialTrailingZeroes.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/factorial-trailing-zeroes/ 2 | // Author : Dean Shi 3 | // Date : 2017-10-01 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an integer n, return the number of trailing zeroes in n!. 8 | * 9 | * Note: Your solution should be in logarithmic time complexity. 10 | * 11 | * Credits:Special thanks to @ts for adding this problem and creating all test cases. 12 | * 13 | ***************************************************************************************/ 14 | 15 | /** 16 | * @param {number} n 17 | * @return {number} 18 | */ 19 | var trailingZeroes = function(n) { 20 | return n ? (n / 5 | 0) + trailingZeroes(n / 5 | 0) : 0 21 | }; 22 | -------------------------------------------------------------------------------- /algorithms/FibonacciNumber.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/fibonacci-number/ 2 | // Author : Dean Shi 3 | // Date : 2019-01-10 4 | 5 | /*************************************************************************************** 6 | * 7 | * The Fibonacci numbers, commonly denoted F(n) form a sequence, called the Fibonacci 8 | * sequence, such that each number is the sum of the two preceding ones, starting from 9 | * 0 and 1. That is, 10 | * 11 | * F(0) = 0,   F(1) = 1 12 | * F(N) = F(N - 1) + F(N - 2), for N > 1. 13 | * 14 | * Given N, calculate F(N). 15 | * 16 | * Example 1: 17 | * 18 | * Input: 2 19 | * Output: 1 20 | * Explanation: F(2) = F(1) + F(0) = 1 + 0 = 1. 21 | * 22 | * Example 2: 23 | * 24 | * Input: 3 25 | * Output: 2 26 | * Explanation: F(3) = F(2) + F(1) = 1 + 1 = 2. 27 | * 28 | * Example 3: 29 | * 30 | * Input: 4 31 | * Output: 3 32 | * Explanation: F(4) = F(3) + F(2) = 2 + 1 = 3. 33 | * 34 | * Note: 35 | * 36 | * 0 ≤ N ≤ 30. 37 | * 38 | ***************************************************************************************/ 39 | 40 | /** 41 | * @param {number} N 42 | * @return {number} 43 | */ 44 | var fib = function(N) { 45 | let [curr, next] = [0, 1] 46 | 47 | while (N--) { 48 | [curr, next] = [next, curr + next] 49 | } 50 | return curr 51 | }; 52 | -------------------------------------------------------------------------------- /algorithms/FindAllDuplicatesInAnArray.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/find-all-duplicates-in-an-array 2 | // Author : Dean Shi 3 | // Date : 2017-03-31 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear 8 | * twice and others appear once. 9 | * 10 | * Find all the elements that appear twice in this array. 11 | * 12 | * Could you do it without extra space and in O(n) runtime? 13 | * 14 | * Example: 15 | * 16 | * Input: 17 | * [4,3,2,7,8,2,3,1] 18 | * 19 | * Output: 20 | * [2,3] 21 | * 22 | * 23 | ***************************************************************************************/ 24 | 25 | /** 26 | * Using Set - Space complexity = O(n) and Runtime complexity = O(n) 27 | * @param {number[]} nums 28 | * @return {number[]} 29 | */ 30 | var findDuplicates = function(nums) { 31 | const numsSet = new Set(), result = [] 32 | nums.forEach(n => numsSet.has(n) ? result.push(n) : numsSet.add(n)) 33 | return result 34 | }; 35 | 36 | /** 37 | * In Space - Space complexity = O(1) and Runtime complexity = O(n) 38 | * @param {number[]} nums 39 | * @return {number[]} 40 | */ 41 | var findDuplicates = function(nums) { 42 | const result = [] 43 | for (let n of nums) { 44 | n = Math.abs(n) - 1 45 | if (nums[n] < 0) result.push(Math.abs(n + 1)) 46 | nums[n] = -nums[n] 47 | } 48 | return result 49 | }; 50 | -------------------------------------------------------------------------------- /algorithms/FindAllNumbersDisappearedInAnArray.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array 2 | // Author : Dean Shi 3 | // Date : 2017-03-31 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements 8 | * appear twice and others appear once. 9 | * 10 | * Find all the elements of [1, n] inclusive that do not appear in this array. 11 | * 12 | * Could you do it without extra space and in O(n) runtime? You may assume the returned 13 | * list does not count as extra space. 14 | * 15 | * Example: 16 | * 17 | * Input: 18 | * [4,3,2,7,8,2,3,1] 19 | * 20 | * Output: 21 | * [5,6] 22 | * 23 | * 24 | ***************************************************************************************/ 25 | 26 | /** 27 | * @param {number[]} nums 28 | * @return {number[]} 29 | */ 30 | var findDisappearedNumbers = function(nums) { 31 | let i, result = [] 32 | for (let n of nums) { 33 | i = Math.abs(n) - 1 34 | nums[i] = nums[i] > 0? -nums[i] : nums[i] 35 | } 36 | for (let j = 0; j < nums.length; j++) { 37 | if (nums[j] > 0) result.push(j + 1) 38 | } 39 | return result 40 | }; 41 | -------------------------------------------------------------------------------- /algorithms/FindAnagramMappings.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/find-anagram-mappings 2 | // Author : Dean Shi 3 | // Date : 2018-01-14 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given two lists Aand B, and B is an anagram of A. B is an anagram of A means B is 8 | * made by randomizing the order of the elements in A. 9 | * 10 | * We want to find an index mapping P, from A to B. A mapping P[i] = j means the ith 11 | * element in A appears in B at index j. 12 | * 13 | * These lists A and B may contain duplicates. If there are multiple answers, output 14 | * any of them. 15 | * 16 | * For example, given 17 | * A = [12, 28, 46, 32, 50] 18 | * B = [50, 12, 32, 46, 28] 19 | * 20 | * We should return 21 | * [1, 4, 3, 2, 0] 22 | * 23 | * as P[0] = 1 because the 0th element of A appears at B[1], 24 | * and P[1] = 4 because the 1st element of A appears at B[4], 25 | * and so on. 26 | * 27 | * Note: 28 | * A, B have equal lengths in range [1, 100]. 29 | * A[i], B[i] are integers in range [0, 10^5]. 30 | * 31 | ***************************************************************************************/ 32 | 33 | /** 34 | * @param {number[]} A 35 | * @param {number[]} B 36 | * @return {number[]} 37 | */ 38 | var anagramMappings = function(A, B) { 39 | const map = new Map() 40 | B.forEach((n, i) => map.set(n, i)) 41 | 42 | return A.map(n => map.get(n)) 43 | }; 44 | -------------------------------------------------------------------------------- /algorithms/FindBottomLeftTreeValue.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/find-bottom-left-tree-value 2 | // Author : Dean Shi 3 | // Date : 2017-09-14 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a binary tree, find the leftmost value in the last row of the tree. 8 | * 9 | * Example 1: 10 | * 11 | * Input: 12 | * 13 | * 2 14 | * / \ 15 | * 1 3 16 | * 17 | * Output: 18 | * 1 19 | * 20 | * Example 2: 21 | * 22 | * Input: 23 | * 24 | * 1 25 | * / \ 26 | * 2 3 27 | * / / \ 28 | * 4 5 6 29 | * / 30 | * 7 31 | * 32 | * Output: 33 | * 7 34 | * 35 | * Note: 36 | * You may assume the tree (i.e., the given root node) is not NULL. 37 | * 38 | ***************************************************************************************/ 39 | 40 | /** 41 | * Definition for a binary tree node. 42 | * function TreeNode(val) { 43 | * this.val = val; 44 | * this.left = this.right = null; 45 | * } 46 | */ 47 | /** 48 | * @param {TreeNode} root 49 | * @return {number} 50 | */ 51 | var findBottomLeftValue = function(root) { 52 | const arr = [root] 53 | let index = 0 54 | 55 | while (index < arr.length) { 56 | root = arr[index++] 57 | if (root.right) arr.push(root.right) 58 | if (root.left) arr.push(root.left) 59 | } 60 | return root.val 61 | }; 62 | -------------------------------------------------------------------------------- /algorithms/FindCommonCharacters.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/find-common-characters/ 2 | // Author : Dean Shi 3 | // Date : 2019-03-10 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an array A of strings made only from lowercase letters, return a list of all 8 | * characters that show up in all strings within the list (including duplicates).  For 9 | * example, if a character occurs 3 times in all strings but not 4 times, you need to 10 | * include that character three times in the final answer. 11 | * 12 | * You may return the answer in any order. 13 | * 14 | * Example 1: 15 | * 16 | * Input: ["bella","label","roller"] 17 | * Output: ["e","l","l"] 18 | * 19 | * Example 2: 20 | * 21 | * Input: ["cool","lock","cook"] 22 | * Output: ["c","o"] 23 | * 24 | * Note: 25 | * 26 | * 1 <= A.length <= 100 27 | * 1 <= A[i].length <= 100 28 | * A[i][j] is a lowercase letter 29 | * 30 | ***************************************************************************************/ 31 | 32 | /** 33 | * @param {string[]} A 34 | * @return {string[]} 35 | */ 36 | var commonChars = function(A) { 37 | let result = A[0].split('') 38 | 39 | for (let i = 1; i < A.length; i++) { 40 | const map = {} 41 | for (let c of A[i]) { 42 | map[c] = (map[c] || 0) + 1 43 | } 44 | 45 | result = result.filter((c) => map[c] > 0 && map[c]--) 46 | } 47 | return result 48 | }; 49 | -------------------------------------------------------------------------------- /algorithms/FindLargestValueInEachTreeRow.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/find-largest-value-in-each-tree-row 2 | // Author : Dean Shi 3 | // Date : 2017-03-04 4 | 5 | /*************************************************************************************** 6 | * 7 | * You need to find the largest value in each row of a binary tree. 8 | * 9 | * Example: 10 | * 11 | * Input: 12 | * 13 | * 1 14 | * / \ 15 | * 3 2 16 | * / \ \ 17 | * 5 3 9 18 | * 19 | * Output: [1, 3, 9] 20 | * 21 | * 22 | ***************************************************************************************/ 23 | 24 | /** 25 | * Definition for a binary tree node. 26 | * function TreeNode(val) { 27 | * this.val = val; 28 | * this.left = this.right = null; 29 | * } 30 | */ 31 | /** 32 | * @param {TreeNode} root 33 | * @return {number[]} 34 | */ 35 | var largestValues = function(root) { 36 | if (!root) return [] 37 | 38 | const rows = [] 39 | search(root, rows, 0) 40 | 41 | return rows.map(row => Math.max(...row)) 42 | }; 43 | 44 | function search(root, rows, index) { 45 | if (!root) return 46 | 47 | rows[index] = rows[index] || [] 48 | rows[index].push(root.val) 49 | 50 | search(root.left, rows, index + 1) 51 | search(root.right, rows, index + 1) 52 | } 53 | -------------------------------------------------------------------------------- /algorithms/FindPivotIndex.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/find-pivot-index 2 | // Author : Dean Shi 3 | // Date : 2018-01-29 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an array of integers nums, write a method that returns the "pivot" index of 8 | * this array. 9 | * 10 | * We define the pivot index as the index where the sum of the numbers to the left of 11 | * the index is equal to the sum of the numbers to the right of the index. 12 | * 13 | * If no such index exists, we should return -1. If there are multiple pivot indexes, 14 | * you should return the left-most pivot index. 15 | * 16 | * Example 1: 17 | * Input: 18 | * nums = [1, 7, 3, 6, 5, 6] 19 | * Output: 3 20 | * Explanation: 21 | * The sum of the numbers to the left of index 3 (nums[3] = 6) is equal to the sum of 22 | * numbers to the right of index 3. 23 | * Also, 3 is the first index where this occurs. 24 | * 25 | * Example 2: 26 | * Input: 27 | * nums = [1, 2, 3] 28 | * Output: -1 29 | * Explanation: 30 | * There is no index that satisfies the conditions in the problem statement. 31 | * 32 | * Note: 33 | * The length of nums will be in the range [0, 10000]. 34 | * Each element nums[i] will be an integer in the range [-1000, 1000]. 35 | * 36 | ***************************************************************************************/ 37 | 38 | /** 39 | * @param {number[]} nums 40 | * @return {number} 41 | */ 42 | var pivotIndex = function(nums) { 43 | const sum = nums.reduce((s, n) => s += n, 0) 44 | 45 | for (let i = 0, leftSum = 0; i < nums.length; i++) { 46 | if (leftSum === sum - leftSum - nums[i]) return i 47 | leftSum += nums[i] 48 | } 49 | 50 | return -1 51 | }; 52 | -------------------------------------------------------------------------------- /algorithms/FindTheDuplicateNumber.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/find-the-duplicate-number 2 | // Author : Dean Shi 3 | // Date : 2020-04-16 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an array nums containing n + 1 integers where each integer is between 1 and n ( 8 | * inclusive), prove that at least one duplicate number must exist. Assume that there 9 | * is only one duplicate number, find the duplicate one. 10 | * 11 | * Example 1: 12 | * 13 | * Input: [1,3,4,2,2] 14 | * Output: 2 15 | * 16 | * Example 2: 17 | * 18 | * Input: [3,1,3,4,2] 19 | * Output: 3 20 | * 21 | * Note: 22 | * 23 | * You must not modify the array (assume the array is read only). 24 | * You must use only constant, O(1) extra space. 25 | * Your runtime complexity should be less than O(n2). 26 | * There is only one duplicate number in the array, but it could be repeated more than 27 | * once. 28 | * 29 | ***************************************************************************************/ 30 | 31 | /** 32 | * @param {number[]} nums 33 | * @return {number} 34 | */ 35 | var findDuplicate = function(nums) { 36 | let [fastPt, slowPt] = [nums[0], nums[0]] 37 | 38 | do { 39 | [fastPt, slowPt] = [nums[fastPt], nums[nums[slowPt]]] 40 | } while(fastPt !== slowPt) 41 | 42 | let [pt1, pt2] = [nums[0], fastPt] 43 | 44 | while (pt1 !== pt2) { 45 | [pt1, pt2] = [nums[pt1], nums[pt2]] 46 | } 47 | 48 | return pt1 49 | }; 50 | -------------------------------------------------------------------------------- /algorithms/FirstUniqueCharacterInAString.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/first-unique-character-in-a-string 2 | // Author : Dean Shi 3 | // Date : 2017-03-08 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a string, find the first non-repeating character in it and return it's index. 8 | * If it doesn't exist, return -1. 9 | * 10 | * Examples: 11 | * 12 | * s = "leetcode" 13 | * return 0. 14 | * 15 | * s = "loveleetcode", 16 | * return 2. 17 | * 18 | * Note: You may assume the string contain only lowercase letters. 19 | * 20 | * 21 | ***************************************************************************************/ 22 | 23 | /** 24 | * @param {string} s 25 | * @return {number} 26 | */ 27 | var firstUniqChar = function(s) { 28 | const map = new Map() 29 | 30 | for (let i = 0; i < s.length; i++) { 31 | if (map.has(s[i])) map.set(s[i], false) 32 | else map.set(s[i], i) 33 | } 34 | 35 | for (let [ch, index] of map) { 36 | if (typeof index === 'number') return index 37 | } 38 | return -1 39 | }; 40 | -------------------------------------------------------------------------------- /algorithms/FizzBuzz.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/fizz-buzz 2 | // Author : Dean Shi 3 | // Date : 2017-06-21 4 | 5 | /*************************************************************************************** 6 | * 7 | * Write a program that outputs the string representation of numbers from 1 to n. 8 | * 9 | * But for multiples of three it should output “Fizz” instead of the number and for the 10 | * multiples of five output “Buzz”. For numbers which are multiples of both three and 11 | * five output “FizzBuzz”. 12 | * 13 | * Example: 14 | * 15 | * n = 15, 16 | * 17 | * Return: 18 | * [ 19 | * "1", 20 | * "2", 21 | * "Fizz", 22 | * "4", 23 | * "Buzz", 24 | * "Fizz", 25 | * "7", 26 | * "8", 27 | * "Fizz", 28 | * "Buzz", 29 | * "11", 30 | * "Fizz", 31 | * "13", 32 | * "14", 33 | * "FizzBuzz" 34 | * ] 35 | * 36 | * 37 | ***************************************************************************************/ 38 | 39 | /** 40 | * @param {number} n 41 | * @return {string[]} 42 | */ 43 | var fizzBuzz = function(n) { 44 | const result = [] 45 | for (let str, i = 1; i <= n; i++) { 46 | str = '' 47 | if (i % 3 === 0) str += 'Fizz' 48 | if (i % 5 === 0) str += 'Buzz' 49 | if (str === '') str += `${i}` 50 | 51 | result.push(str) 52 | } 53 | return result 54 | }; 55 | -------------------------------------------------------------------------------- /algorithms/GenerateParentheses.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/generate-parentheses/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-12 4 | 5 | /********************************************************************************** 6 | * 7 | * Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. 8 | * 9 | * For example, given n = 3, a solution set is: 10 | * 11 | * "((()))", "(()())", "(())()", "()(())", "()()()" 12 | * 13 | * 14 | **********************************************************************************/ 15 | 16 | /** 17 | * @param {number} n 18 | * @return {string[]} 19 | */ 20 | var generateParenthesis = function(n) { 21 | var strArr = []; 22 | 23 | bfs('', 0, 0); 24 | return strArr; 25 | 26 | // breadth-first search algorithm 27 | function bfs(str, left, right) { 28 | if (left === n && right === n) { 29 | strArr.push(str); 30 | return; 31 | } 32 | 33 | if (left !== n) { 34 | bfs(str + '(', left + 1, right); 35 | } 36 | if (left > right) { 37 | bfs(str + ')', left, right + 1); 38 | } 39 | } 40 | }; 41 | 42 | // Test case 43 | console.log(generateParenthesis(3).toString() === '((())),(()()),(())(),()(()),()()()'); // true 44 | -------------------------------------------------------------------------------- /algorithms/GreatestCommonDivisorOfStrings.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/greatest-common-divisor-of-strings 2 | // Author : Dean Shi 3 | // Date : 2019-06-08 4 | 5 | /*************************************************************************************** 6 | * 7 | * For strings S and T, we say "T divides S" if and only if S = T + ... + T  (T 8 | * concatenated with itself 1 or more times) 9 | * 10 | * Return the largest string X such that X divides str1 and X divides str2. 11 | * 12 | * Example 1: 13 | * 14 | * Input: str1 = "ABCABC", str2 = "ABC" 15 | * Output: "ABC" 16 | * 17 | * Example 2: 18 | * 19 | * Input: str1 = "ABABAB", str2 = "ABAB" 20 | * Output: "AB" 21 | * 22 | * Example 3: 23 | * 24 | * Input: str1 = "LEET", str2 = "CODE" 25 | * Output: "" 26 | * 27 | * Note: 28 | * 29 | * 1 <= str1.length <= 1000 30 | * 1 <= str2.length <= 1000 31 | * str1[i] and str2[i] are English uppercase letters. 32 | * 33 | ***************************************************************************************/ 34 | 35 | /** 36 | * @param {string} str1 37 | * @param {string} str2 38 | * @return {string} 39 | */ 40 | var gcdOfStrings = function(str1, str2) { 41 | if ((str1 + str2) !== (str2 + str1)) return '' 42 | 43 | const gcd = (a, b) => (b === 0 ? a : gcd(b, a % b)) 44 | return str1.substring(0, gcd(str1.length, str2.length)) 45 | }; 46 | -------------------------------------------------------------------------------- /algorithms/HammingDistance.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/hamming-distance 2 | // Author : Dean Shi 3 | // Date : 2017-07-10 4 | 5 | /*************************************************************************************** 6 | * 7 | * The Hamming distance between two integers is the number of positions at which the 8 | * corresponding bits are different. 9 | * 10 | * Given two integers x and y, calculate the Hamming distance. 11 | * 12 | * Note: 13 | * 0 ≤ x, y < 231. 14 | * 15 | * Example: 16 | * 17 | * Input: x = 1, y = 4 18 | * 19 | * Output: 2 20 | * 21 | * Explanation: 22 | * 1 (0 0 0 1) 23 | * 4 (0 1 0 0) 24 | * ? ? 25 | * 26 | * The above arrows point to positions where the corresponding bits are different. 27 | * 28 | * 29 | ***************************************************************************************/ 30 | 31 | /** 32 | * @param {number} x 33 | * @param {number} y 34 | * @return {number} 35 | */ 36 | var hammingDistance = function(x, y) { 37 | let val = x ^ y, result = 0 38 | 39 | while (val) { 40 | ++result 41 | val &= val - 1 42 | } 43 | 44 | return result 45 | }; 46 | -------------------------------------------------------------------------------- /algorithms/HappyNumber.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/happy-number/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-16 4 | 5 | /********************************************************************************** 6 | * 7 | * Write an algorithm to determine if a number is "happy". 8 | * 9 | * A happy number is a number defined by the following process: Starting with any positive integer, 10 | * replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 11 | * (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this 12 | * process ends in 1 are happy numbers. 13 | * 14 | * Example: 19 is a happy number 15 | * 16 | * 12 + 92 = 82 17 | * 82 + 22 = 68 18 | * 62 + 82 = 100 19 | * 12 + 02 + 02 = 1 20 | * 21 | * Credits:Special thanks to @mithmatt and @ts for adding this problem and creating all test cases. 22 | * 23 | **********************************************************************************/ 24 | 25 | /** 26 | * @param {number} n 27 | * @return {boolean} 28 | */ 29 | var isHappy = function(n) { 30 | if (n / 10 < 1) return n === 7 || n === 1 31 | 32 | let sum = 0 33 | do { 34 | sum += Math.pow(n % 10, 2) 35 | } while(n = Math.floor(n / 10)) 36 | 37 | return isHappy(sum) 38 | }; 39 | 40 | -------------------------------------------------------------------------------- /algorithms/ImplementStrStr.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/implement-strstr 2 | // Author : Dean Shi 3 | // Date : 2017-07-10 4 | 5 | /*************************************************************************************** 6 | * 7 | * Implement strStr(). 8 | * 9 | * Returns the index of the first occurrence of needle in haystack, or -1 if needle is 10 | * not part of haystack. 11 | * 12 | ***************************************************************************************/ 13 | 14 | /** 15 | * @param {string} haystack 16 | * @param {string} needle 17 | * @return {number} 18 | */ 19 | var strStr = function(haystack, needle) { 20 | return haystack.indexOf(needle) 21 | }; 22 | -------------------------------------------------------------------------------- /algorithms/InsertIntoABinarySearchTree.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/insert-into-a-binary-search-tree 2 | // Author : Dean Shi 3 | // Date : 2019-06-08 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given the root node of a binary search tree (BST) and a value to be inserted into 8 | * the tree, insert the value into the BST. Return the root node of the BST after the 9 | * insertion. It is guaranteed that the new value does not exist in the original BST. 10 | * 11 | * Note that there may exist multiple valid ways for the insertion, as long as the tree 12 | * remains a BST after insertion. You can return any of them. 13 | * 14 | * For example, 15 | * 16 | * Given the tree: 17 | * 4 18 | * / \ 19 | * 2 7 20 | * / \ 21 | * 1 3 22 | * And the value to insert: 5 23 | * 24 | * You can return this binary search tree: 25 | * 26 | * 4 27 | * / \ 28 | * 2 7 29 | * / \ / 30 | * 1 3 5 31 | * 32 | * This tree is also valid: 33 | * 34 | * 5 35 | * / \ 36 | * 2 7 37 | * / \ 38 | * 1 3 39 | * \ 40 | * 4 41 | * 42 | ***************************************************************************************/ 43 | 44 | /** 45 | * Definition for a binary tree node. 46 | * function TreeNode(val) { 47 | * this.val = val; 48 | * this.left = this.right = null; 49 | * } 50 | */ 51 | /** 52 | * @param {TreeNode} root 53 | * @param {number} val 54 | * @return {TreeNode} 55 | */ 56 | var insertIntoBST = function(root, val) { 57 | if (!root) return new TreeNode(val) 58 | const direction = root.val < val ? 'right' : 'left' 59 | root[direction] = insertIntoBST(root[direction], val) 60 | return root 61 | }; 62 | -------------------------------------------------------------------------------- /algorithms/IntegerToRoman.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/integer-to-roman/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-10 4 | 5 | /********************************************************************************** 6 | * 7 | * Given an integer, convert it to a roman numeral. 8 | * 9 | * Input is guaranteed to be within the range from 1 to 3999. 10 | * 11 | **********************************************************************************/ 12 | 13 | /** 14 | * @param {number} num 15 | * @return {string} 16 | */ 17 | var intToRoman = function(num) { 18 | var numArr = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]; 19 | var romanArr = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I']; 20 | var result = ''; 21 | 22 | for (var i = 0; num !== 0; ++i) { 23 | while (num >= numArr[i]) { 24 | num -= numArr[i]; 25 | result += romanArr[i]; 26 | } 27 | } 28 | return result; 29 | }; 30 | 31 | // Test case 32 | console.log(intToRoman(999) === 'CMXCIX'); // true 33 | -------------------------------------------------------------------------------- /algorithms/InvertBinaryTree.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/invert-binary-tree/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-12 4 | 5 | /********************************************************************************** 6 | * 7 | * Invert a binary tree. 8 | * 4 9 | * / \ 10 | * 2 7 11 | * / \ / \ 12 | * 1 3 6 9 13 | * 14 | * to 15 | * 4 16 | * / \ 17 | * 7 2 18 | * / \ / \ 19 | * 9 6 3 1 20 | * 21 | * Trivia: 22 | * This problem was inspired by this original tweet by Max Howell: 23 | * (https://twitter.com/mxcl/status/608682016205344768) 24 | * 25 | * | Google: 90% of our engineers use the software you wrote (Homebrew), 26 | * | but you can’t invert a binary tree on a whiteboard so fuck off. 27 | * 28 | **********************************************************************************/ 29 | 30 | /** 31 | * Definition for a binary tree node. 32 | * function TreeNode(val) { 33 | * this.val = val; 34 | * this.left = this.right = null; 35 | * } 36 | */ 37 | /** 38 | * @param {TreeNode} root 39 | * @return {TreeNode} 40 | */ 41 | var invertTree = function(root) { 42 | if (root) { 43 | [root.left, root.right] = [invertTree(root.right), invertTree(root.left)] 44 | } 45 | return root 46 | }; 47 | -------------------------------------------------------------------------------- /algorithms/IsomorphicStrings.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/isomorphic-strings/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-16 4 | 5 | /********************************************************************************** 6 | * 7 | * Given two strings s and t, determine if they are isomorphic. 8 | * 9 | * Two strings are isomorphic if the characters in s can be replaced to get t. 10 | * 11 | * All occurrences of a character must be replaced with another character while preserving 12 | * the order of characters. No two characters may map to the same character but a character 13 | * may map to itself. 14 | * 15 | * For example, 16 | * 17 | * Given "egg", "add", return true. 18 | * 19 | * Given "foo", "bar", return false. 20 | * 21 | * Given "paper", "title", return true. 22 | * 23 | * Note: 24 | * You may assume both s and t have the same length. 25 | * 26 | **********************************************************************************/ 27 | 28 | /** 29 | * @param {string} s 30 | * @param {string} t 31 | * @return {boolean} 32 | */ 33 | var isIsomorphic = function(s, t) { 34 | var s_map = {}; 35 | var t_map = {}; 36 | 37 | for (var i = 0, l = s.length; i < l; ++i) { 38 | if (!s_map[s[i]] && !t_map[t[i]]) { 39 | s_map[s[i]] = t[i]; 40 | t_map[t[i]] = s[i]; 41 | } else if (s_map[s[i]] !== t[i] || t_map[t[i]] !== s[i]) { 42 | return false; 43 | } 44 | } 45 | return true; 46 | }; 47 | 48 | // Test cases 49 | console.log(isIsomorphic('egg', 'add')); // true 50 | console.log(isIsomorphic('foo', 'bar')); // false 51 | console.log(isIsomorphic('paper', 'title')); // true 52 | -------------------------------------------------------------------------------- /algorithms/JewelsAndStones.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/jewels-and-stones 2 | // Author : Dean Shi 3 | // Date : 2018-01-29 4 | 5 | /*************************************************************************************** 6 | * 7 | * You're given strings J representing the types of stones that are jewels, and S 8 | * representing the stones you have.  Each character in S is a type of stone you have. 9 | * You want to know how many of the stones you have are also jewels. 10 | * 11 | * The letters in J are guaranteed distinct, and all characters in J and S are letters. 12 | * Letters are case sensitive, so "a" is considered a different type of stone from "A". 13 | * 14 | * Example 1: 15 | * 16 | * Input: J = "aA", S = "aAAbbbb" 17 | * Output: 3 18 | * 19 | * Example 2: 20 | * 21 | * Input: J = "z", S = "ZZ" 22 | * Output: 0 23 | * 24 | * Note: 25 | * 26 | * S and J will consist of letters and have length at most 50. 27 | * The characters in J are distinct. 28 | * 29 | ***************************************************************************************/ 30 | 31 | /** 32 | * @param {string} J 33 | * @param {string} S 34 | * @return {number} 35 | */ 36 | var numJewelsInStones = function(J, S) { 37 | const jSet = new Set(J) 38 | 39 | let result = 0 40 | for (let s of S) if (jSet.has(s)) result++ 41 | 42 | return result 43 | }; 44 | -------------------------------------------------------------------------------- /algorithms/JudgeRouteCircle.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/judge-route-circle 2 | // Author : Dean Shi 3 | // Date : 2017-08-14 4 | 5 | /*************************************************************************************** 6 | * 7 | * Initially, there is a Robot at position (0, 0). Given a sequence of its moves, judge 8 | * if this robot makes a circle, which means it moves back to the original place. 9 | * 10 | * The move sequence is represented by a string. And each move is represent by a 11 | * character. The valid robot moves are R (Right), L (Left), U (Up) and D (down). The 12 | * output should be true or false representing whether the robot makes a circle. 13 | * 14 | * Example 1: 15 | * 16 | * Input: "UD" 17 | * Output: true 18 | * 19 | * Example 2: 20 | * 21 | * Input: "LL" 22 | * Output: false 23 | * 24 | * 25 | ***************************************************************************************/ 26 | 27 | /** 28 | * @param {string} moves 29 | * @return {boolean} 30 | */ 31 | var judgeCircle = function(moves) { 32 | let [h, v] = [0, 0] 33 | 34 | for (let ch of moves) { 35 | switch (ch) { 36 | case 'U': ++h; break; 37 | case 'D': --h; break; 38 | case 'L': ++v; break; 39 | case 'R': --v; break; 40 | } 41 | } 42 | 43 | return h === 0 && v === 0 44 | }; 45 | -------------------------------------------------------------------------------- /algorithms/KthLargestElementInAnArray.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/kth-largest-element-in-an-array 2 | // Author : Dean Shi 3 | // Date : 2017-03-06 4 | 5 | /*************************************************************************************** 6 | * 7 | * Find the kth largest element in an unsorted array. Note that it is the kth largest 8 | * element in the sorted order, not the kth distinct element. 9 | * 10 | * For example, 11 | * Given [3,2,1,5,6,4] and k = 2, return 5. 12 | * 13 | * Note: 14 | * You may assume k is always valid, 1 ≤ k ≤ array's length. 15 | * 16 | * 17 | ***************************************************************************************/ 18 | 19 | /** 20 | * @param {number[]} nums 21 | * @param {number} k 22 | * @return {number} 23 | */ 24 | var findKthLargest = function(nums, k) { 25 | return nums.sort((a, b) => a - b)[nums.length - k] 26 | }; 27 | -------------------------------------------------------------------------------- /algorithms/KthSmallestElementInBST.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/kth-smallest-element-in-a-bst/ 2 | // Date : 2019-10-12 3 | 4 | /** 5 | * Given a binary search tree, write a function kthSmallest to find the 6 | * kth smallest element in it. 7 | * You may assume k is always valid, 1 ≤ k ≤ BST's total elements. 8 | 9 | Example 1: 10 | 11 | Input: root = [3,1,4,null,2], k = 1 12 | 3 13 | / \ 14 | 1 4 15 | \ 16 | 2 17 | Output: 1 18 | 19 | Example 2: 20 | 21 | Input: root = [5,3,6,2,4,null,null,1], k = 3 22 | 5 23 | / \ 24 | 3 6 25 | / \ 26 | 2 4 27 | / 28 | 1 29 | Output: 3 30 | 31 | */ 32 | 33 | 34 | /** 35 | * Definition for a binary tree node. 36 | * function TreeNode(val) { 37 | * this.val = val; 38 | * this.left = this.right = null; 39 | * } 40 | */ 41 | /** 42 | * @param {TreeNode} root 43 | * @param {number} k 44 | * @return {number} 45 | */ 46 | var kthSmallest = function(root, k) { 47 | if (k == 0) { 48 | return root.val; 49 | } 50 | 51 | let count = 0; 52 | let kthElement = null; 53 | 54 | (function getKthElement(root) { 55 | if (!root) { 56 | return; 57 | } 58 | 59 | getKthElement(root.left); 60 | 61 | count++; 62 | if (count == k) { 63 | kthElement = root; 64 | return; 65 | } 66 | 67 | getKthElement(root.right); 68 | })(root); 69 | 70 | return kthElement ? kthElement.val : null; 71 | }; 72 | -------------------------------------------------------------------------------- /algorithms/LargestNumberAtLeastTwiceOfOthers.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/largest-number-at-least-twice-of-others 2 | // Author : Dean Shi 3 | // Date : 2018-01-14 4 | 5 | /*************************************************************************************** 6 | * 7 | * In a given integer array nums, there is always exactly one largest element. 8 | * 9 | * Find whether the largest element in the array is at least twice as much as every 10 | * other number in the array. 11 | * 12 | * If it is, return the index of the largest element, otherwise return -1. 13 | * 14 | * Example 1: 15 | * Input: nums = [3, 6, 1, 0] 16 | * Output: 1 17 | * Explanation: 6 is the largest integer, and for every other number in the array x, 18 | * 6 is more than twice as big as x. The index of value 6 is 1, so we return 1. 19 | * 20 | * Example 2: 21 | * Input: nums = [1, 2, 3, 4] 22 | * Output: -1 23 | * Explanation: 4 isn't at least as big as twice the value of 3, so we return -1. 24 | * 25 | * Note: 26 | * 27 | * nums will have a length in the range [1, 50]. 28 | * Every nums[i] will be an integer in the range [0, 99]. 29 | * 30 | ***************************************************************************************/ 31 | 32 | /** 33 | * @param {number[]} nums 34 | * @return {number} 35 | */ 36 | var dominantIndex = function(nums) { 37 | if (nums.length === 1) return 0 38 | 39 | const [largestNum, secondLargestNum] = nums.slice(0).sort((a, b) => b - a) 40 | return largestNum >= (secondLargestNum * 2) ? nums.indexOf(largestNum) : -1 41 | }; 42 | -------------------------------------------------------------------------------- /algorithms/LengthOfLastWord.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/length-of-last-word/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-16 4 | 5 | /********************************************************************************** 6 | * 7 | * Given a string s consists of upper/lower-case alphabets and empty space characters ' ', 8 | * return the length of last word in the string. 9 | * 10 | * If the last word does not exist, return 0. 11 | * 12 | * Note: A word is defined as a character sequence consists of non-space characters only. 13 | * 14 | * For example, 15 | * Given s = "Hello World", 16 | * return 5. 17 | * 18 | * 19 | **********************************************************************************/ 20 | 21 | /** 22 | * @param {string} s 23 | * @return {number} 24 | */ 25 | var lengthOfLastWord = function(s) { 26 | var arr = s.match(/\S+/g) || 0; 27 | return arr && arr.pop().length; 28 | }; 29 | 30 | // Test case 31 | console.log(lengthOfLastWord('Hello Wrold') === 5); // true 32 | -------------------------------------------------------------------------------- /algorithms/LetterCombinationsOfAPhoneNumber.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/letter-combinations-of-a-phone-number/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-11 4 | 5 | /********************************************************************************** 6 | * 7 | * Given a digit string, return all possible letter combinations that the number could represent. 8 | * 9 | * A mapping of digit to letters (just like on the telephone buttons) is given below. 10 | * 11 | * Input:Digit string "23" 12 | * Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. 13 | * 14 | * Note: 15 | * Although the above answer is in lexicographical order, your answer could be in any order you want. 16 | * 17 | * 18 | **********************************************************************************/ 19 | 20 | /** 21 | * @param {string} digits 22 | * @return {string[]} 23 | */ 24 | var letterCombinations = function(digits) { 25 | let result, 26 | const [first, ...rest] = digits 27 | const digitMap = { 28 | 2: ['a', 'b', 'c'], 29 | 3: ['d', 'e', 'f'], 30 | 4: ['g', 'h', 'i'], 31 | 5: ['j', 'k', 'l'], 32 | 6: ['m', 'n', 'o'], 33 | 7: ['p', 'q', 'r', 's'], 34 | 8: ['t', 'u', 'v'], 35 | 9: ['w', 'x', 'y', 'z'] 36 | } 37 | 38 | return rest.reduce((arr, d) => { 39 | result = [] 40 | arr.forEach(a => digitMap[d].forEach(b => result.push(a + b))) 41 | return result 42 | }, digitMap[first] || []) 43 | }; 44 | -------------------------------------------------------------------------------- /algorithms/LinkedListCycle.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/linked-list-cycle 2 | // Author : Dean Shi 3 | // Date : 2018-01-25 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a linked list, determine if it has a cycle in it. 8 | * 9 | * Follow up: 10 | * Can you solve it without using extra space? 11 | * 12 | ***************************************************************************************/ 13 | 14 | /** 15 | * Definition for singly-linked list. 16 | * function ListNode(val) { 17 | * this.val = val; 18 | * this.next = null; 19 | * } 20 | */ 21 | 22 | /** 23 | * @param {ListNode} head 24 | * @return {boolean} 25 | */ 26 | var hasCycle = function(head) { 27 | if (!head) return false 28 | 29 | let slowerPointer = head 30 | let fasterPointer = head.next 31 | 32 | while (slowerPointer && fasterPointer && fasterPointer.next) { 33 | if (slowerPointer === fasterPointer) return true 34 | 35 | slowerPointer = slowerPointer.next 36 | fasterPointer = fasterPointer.next.next 37 | } 38 | 39 | return false 40 | }; 41 | -------------------------------------------------------------------------------- /algorithms/LinkedListCycle_II.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/linked-list-cycle-ii/ 2 | // Author : Dean Shi 3 | // Date : 2018-01-30 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a linked list, return the node where the cycle begins. If there is no cycle, 8 | * return null. 9 | * 10 | * Note: Do not modify the linked list. 11 | * 12 | * Follow up: 13 | * Can you solve it without using extra space? 14 | * 15 | ***************************************************************************************/ 16 | 17 | /** 18 | * Definition for singly-linked list. 19 | * function ListNode(val) { 20 | * this.val = val; 21 | * this.next = null; 22 | * } 23 | */ 24 | 25 | /** 26 | * @param {ListNode} head 27 | * @return {ListNode} 28 | */ 29 | var detectCycle = function(head) { 30 | const hash = new Set() 31 | 32 | while (head) { 33 | if (hash.has(head)) return head 34 | hash.add(head) 35 | head = head.next 36 | } 37 | return null 38 | }; 39 | -------------------------------------------------------------------------------- /algorithms/LongestCommonPrefix.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/longest-common-prefix 2 | // Author : Dean Shi 3 | // Date : 2015-06-08 4 | 5 | /*************************************************************************************** 6 | * 7 | * Write a function to find the longest common prefix string amongst an array of 8 | * strings. 9 | * 10 | * If there is no common prefix, return an empty string "". 11 | * 12 | * Example 1: 13 | * 14 | * Input: ["flower","flow","flight"] 15 | * Output: "fl" 16 | * 17 | * Example 2: 18 | * 19 | * Input: ["dog","racecar","car"] 20 | * Output: "" 21 | * Explanation: There is no common prefix among the input strings. 22 | * 23 | * Note: 24 | * 25 | * All given inputs are in lowercase letters a-z. 26 | * 27 | ***************************************************************************************/ 28 | 29 | /** 30 | * @param {string[]} strs 31 | * @return {string} 32 | */ 33 | var longestCommonPrefix = function(strs) { 34 | if (!strs || strs.length === 0) return '' 35 | 36 | let prefix = strs[0] 37 | for (let curr of strs) { 38 | for (let i = 0; i < prefix.length; i++) { 39 | if (curr[i] !== prefix[i]) { 40 | prefix = curr.slice(0, i) 41 | break 42 | } 43 | } 44 | } 45 | return prefix 46 | }; 47 | -------------------------------------------------------------------------------- /algorithms/LongestPalindrome.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/longest-palindrome 2 | // Author : Dean Shi 3 | // Date : 2017-04-01 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a string which consists of lowercase or uppercase letters, find the length of 8 | * the longest palindromes that can be built with those letters. 9 | * 10 | * This is case sensitive, for example "Aa" is not considered a palindrome here. 11 | * 12 | * Note: 13 | * Assume the length of given string will not exceed 1,010. 14 | * 15 | * Example: 16 | * 17 | * Input: 18 | * "abccccdd" 19 | * 20 | * Output: 21 | * 7 22 | * 23 | * Explanation: 24 | * One longest palindrome that can be built is "dccaccd", whose length is 7. 25 | * 26 | * 27 | ***************************************************************************************/ 28 | 29 | /** 30 | * @param {string} s 31 | * @return {number} 32 | */ 33 | var longestPalindrome = function(s) { 34 | const map = new Map() 35 | let hasOdd = false, length = 0 36 | 37 | for (let ch of s) { 38 | map.set(ch, ~~(map.get(ch)) + 1) 39 | } 40 | 41 | for (let n of map.values()) { 42 | length += n >> 1 << 1 43 | hasOdd = hasOdd || n % 2 === 1 44 | } 45 | return length + (hasOdd ? 1 : 0) 46 | }; 47 | -------------------------------------------------------------------------------- /algorithms/LongestSubstringWithoutRepeatingCharacters.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/longest-substring-without-repeating-characters/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-01 4 | 5 | /********************************************************************************** 6 | * 7 | * Given a string, find the length of the longest substring without repeating characters. 8 | * For example, the longest substring without repeating letters for "abcabcbb" is "abc", 9 | * which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1. 10 | * 11 | **********************************************************************************/ 12 | 13 | /** 14 | * @param {string} s 15 | * @return {number} 16 | */ 17 | var lengthOfLongestSubstring = function(s) { 18 | var max = 0; 19 | var last = -1; 20 | var map = {}; 21 | 22 | for (var i = 0, l = s.length; i < l; ++i) { 23 | if (map[s[i]] >= 0 && last < map[s[i]]) { 24 | last = map[s[i]]; 25 | } 26 | 27 | if (i - last > max) { 28 | max = i - last; 29 | } 30 | 31 | map[s[i]] = i; 32 | } 33 | return max; 34 | }; 35 | 36 | var testCase1 = 'abcabcbb'; 37 | var testCase2 = 'bbbbb'; 38 | 39 | console.log(lengthOfLongestSubstring(testCase1) === 3); // true 40 | console.log(lengthOfLongestSubstring(testCase2) === 1); // true 41 | -------------------------------------------------------------------------------- /algorithms/MajorityElement.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/majority-element/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-18 4 | 5 | /********************************************************************************** 6 | * 7 | * Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. 8 | * 9 | * You may assume that the array is non-empty and the majority element always exist in the array. 10 | * 11 | * Credits:Special thanks to @ts for adding this problem and creating all test cases. 12 | * 13 | **********************************************************************************/ 14 | 15 | /** 16 | * @param {number[]} nums 17 | * @return {number} 18 | */ 19 | var majorityElement = function(nums) { 20 | // Moore Voting Algorithm 21 | var majority, count = 0; 22 | nums.forEach(function(n) { 23 | if (count === 0) { 24 | majority = n; 25 | count = 1; 26 | } else { 27 | n === majority ? ++count : --count; 28 | } 29 | }); 30 | return majority; 31 | }; 32 | 33 | // Test case 34 | console.log(majorityElement([1, 2, 1, 1, 1, 2, 3, 1, 3, 1]) === 1); 35 | -------------------------------------------------------------------------------- /algorithms/MaximumAverageSubarray_I.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/maximum-average-subarray-i 2 | // Author : Dean Shi 3 | // Date : 2017-07-15 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an array consisting of n integers, find the contiguous subarray of given 8 | * length k that has the maximum average value. And you need to output the maximum 9 | * average value. 10 | * 11 | * Example 1: 12 | * 13 | * Input: [1,12,-5,-6,50,3], k = 4 14 | * Output: 12.75 15 | * Explanation: Maximum average is (12-5-6+50)/4 = 51/4 = 12.75 16 | * 17 | * Note: 18 | * 19 | * 1. 1 <= k <= n <= 30,000. 20 | * 2. Elements of the given array will be in the range [-10,000, 10,000]. 21 | * 22 | * 23 | ***************************************************************************************/ 24 | 25 | /** 26 | * @param {number[]} nums 27 | * @param {number} k 28 | * @return {number} 29 | */ 30 | var findMaxAverage = function(nums, k) { 31 | let sum = 0, max 32 | 33 | for (let i = 0; i < k; ++i) { 34 | sum += nums[i] 35 | } 36 | max = sum 37 | 38 | for (let i = k; i < nums.length; ++i) { 39 | sum += nums[i] - nums[i - k] 40 | max = Math.max(max, sum) 41 | } 42 | return max / k 43 | }; 44 | -------------------------------------------------------------------------------- /algorithms/MaximumProductOfThreeNumbers.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/maximum-product-of-three-numbers/ 2 | // Author : Dean Shi 3 | // Date : 2017-07-05 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an integer array, find three numbers whose product is maximum and output the 8 | * maximum product. 9 | * 10 | * Example 1: 11 | * 12 | * Input: [1,2,3] 13 | * Output: 6 14 | * 15 | * Example 2: 16 | * 17 | * Input: [1,2,3,4] 18 | * Output: 24 19 | * 20 | * Note: 21 | * 22 | * The length of the given array will be in range [3,104] and all elements are in the 23 | * range [-1000, 1000]. 24 | * Multiplication of any three numbers in the input won't exceed the range of 32-bit 25 | * signed integer. 26 | * 27 | * 28 | ***************************************************************************************/ 29 | 30 | /** 31 | * @param {number[]} nums 32 | * @return {number} 33 | */ 34 | var maximumProduct = function(nums) { 35 | nums.sort((a, b) => a - b) 36 | return Math.max( 37 | nums[0] * nums[1] * nums[nums.length - 1], 38 | nums[nums.length - 1] * nums[nums.length - 2] * nums[nums.length - 3] 39 | ) 40 | }; 41 | -------------------------------------------------------------------------------- /algorithms/MaximumSubarray.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/maximum-subarray 2 | // Author : Dean Shi 3 | // Date : 2017-03-02 4 | 5 | /*************************************************************************************** 6 | * 7 | * Find the contiguous subarray within an array (containing at least one number) which 8 | * has the largest sum. 9 | * 10 | * For example, given the array [-2,1,-3,4,-1,2,1,-5,4], 11 | * the contiguous subarray [4,-1,2,1] has the largest sum = 6. 12 | * 13 | * click to show more practice. 14 | * 15 | * More practice: 16 | * 17 | * If you have figured out the O(n) solution, try coding another solution using the 18 | * divide and conquer approach, which is more subtle. 19 | * 20 | * 21 | ***************************************************************************************/ 22 | 23 | /** 24 | * @param {number[]} nums 25 | * @return {number} 26 | */ 27 | var maxSubArray = function(nums) { 28 | let max = nums[0] 29 | 30 | nums.reduce((sum, num) => { 31 | sum = Math.max(sum + num, num) 32 | max = Math.max(max, sum) 33 | return sum 34 | }) 35 | return max 36 | }; 37 | -------------------------------------------------------------------------------- /algorithms/MaximumSwap.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/maximum-swap 2 | // Author : Dean Shi 3 | // Date : 2017-09-05 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a non-negative integer, you could swap two digits at most once to get the 8 | * maximum valued number. Return the maximum valued number you could get. 9 | * 10 | * Example 1: 11 | * 12 | * Input: 2736 13 | * Output: 7236 14 | * Explanation: Swap the number 2 and the number 7. 15 | * 16 | * Example 2: 17 | * 18 | * Input: 9973 19 | * Output: 9973 20 | * Explanation: No swap. 21 | * 22 | * Note: 23 | * 24 | * The given number is in the range [0, 108] 25 | * 26 | * 27 | ***************************************************************************************/ 28 | 29 | /** 30 | * @param {number} num 31 | * @return {number} 32 | */ 33 | var maximumSwap = function(num) { 34 | const numArr = [...String(num)].map(ch => +ch) 35 | const sortedArr = numArr.slice().sort((a, b) => b - a) 36 | 37 | for (let i = 0; i < numArr.length; ++i) { 38 | if (numArr[i] !== sortedArr[i]) { 39 | const index = numArr.lastIndexOf(sortedArr[i]); 40 | [numArr[index], numArr[i]] = [numArr[i], sortedArr[i]] 41 | return +numArr.join('') 42 | } 43 | } 44 | return num 45 | }; 46 | -------------------------------------------------------------------------------- /algorithms/MedianOfTwoSortedArrays.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/median-of-two-sorted-arrays/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-04 4 | 5 | /********************************************************************************** 6 | * 7 | * There are two sorted arrays A and B of size m and n respectively. 8 | * Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). 9 | * 10 | **********************************************************************************/ 11 | 12 | /** 13 | * @param {number[]} nums1 14 | * @param {number[]} nums2 15 | * @return {number} 16 | */ 17 | var findMedianSortedArrays = function(nums1, nums2) { 18 | // Merge nums2 into nums1 19 | for (var n1Index = 0, n2Index = 0, l = nums2.length; n2Index < l; ++n2Index) { 20 | while (nums2[n2Index] > nums1[n1Index]) { 21 | n1Index++; 22 | } 23 | nums1.splice(n1Index, 0, nums2[n2Index]); 24 | } 25 | 26 | var n = nums1.length / 2; 27 | return (nums1.length % 2 === 0) ? (nums1[n] + nums1[n - 1]) / 2 : nums1[n - 0.5]; 28 | }; 29 | 30 | console.log(findMedianSortedArrays([], [1, 2, 3, 4]) === 2.5); // true 31 | console.log(findMedianSortedArrays([2], []) === 2); // true 32 | console.log(findMedianSortedArrays([1, 2], [1, 2]) === 1.5); // true 33 | console.log(findMedianSortedArrays([1, 2, 3], [1, 2]) === 2); // true 34 | console.log(findMedianSortedArrays([4, 5, 6, 8, 9], []) === 6); // true 35 | -------------------------------------------------------------------------------- /algorithms/MergeIntervals.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/merge-intervals 2 | // Author : Dean Shi 3 | // Date : 2021-11-12 4 | 5 | /*************************************************************************************** 6 | * Given an array of intervals where intervals[i] = [starti, endi], merge all 7 | * overlapping intervals, and return an array of the non-overlapping intervals that 8 | * cover all the intervals in the input. 9 | * 10 | * Example 1: 11 | * 12 | * Input: intervals = [[1,3],[2,6],[8,10],[15,18]] 13 | * Output: [[1,6],[8,10],[15,18]] 14 | * Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6]. 15 | * 16 | * Example 2: 17 | * 18 | * Input: intervals = [[1,4],[4,5]] 19 | * Output: [[1,5]] 20 | * Explanation: Intervals [1,4] and [4,5] are considered overlapping. 21 | * 22 | * Constraints: 23 | * 24 | * 1 <= intervals.length <= 104 25 | * intervals[i].length == 2 26 | * 0 <= starti <= endi <= 104 27 | * 28 | * 29 | ***************************************************************************************/ 30 | 31 | /** 32 | * @param {number[][]} intervals 33 | * @return {number[][]} 34 | */ 35 | var merge = function(intervals) { 36 | const sortedIntervals = intervals 37 | .slice() 38 | .sort((a, b) => a[0] - b[0]) 39 | 40 | const result = [sortedIntervals[0]] 41 | for (let i = 1; i < sortedIntervals.length; i++) { 42 | const mergedInterval = result[result.length - 1] 43 | const prevEnd = mergedInterval[1] 44 | const [currStart, currEnd] = sortedIntervals[i] 45 | 46 | if (prevEnd >= currStart) { 47 | mergedInterval[1] = Math.max(prevEnd, currEnd) 48 | } else { 49 | result.push(sortedIntervals[i]) 50 | } 51 | } 52 | return result 53 | }; 54 | -------------------------------------------------------------------------------- /algorithms/MergeKSortedLists.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/merge-k-sorted-lists/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-12 4 | 5 | /********************************************************************************** 6 | * 7 | * Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 8 | * 9 | * 10 | **********************************************************************************/ 11 | 12 | /** 13 | * Definition for singly-linked list. 14 | * function ListNode(val) { 15 | * this.val = val; 16 | * this.next = null; 17 | * } 18 | */ 19 | /** 20 | * @param {ListNode[]} lists 21 | * @return {ListNode} 22 | */ 23 | var mergeKLists = function(lists) { 24 | var i, tmp; 25 | while (lists.length >= 2) { 26 | tmp = []; 27 | for (i = lists.length - 1; i > 0; i -= 2) { 28 | tmp.push(mergeTwoLists(lists[i], lists[i - 1])); 29 | } 30 | if (i === 0) { 31 | tmp.push(lists[0]); 32 | } 33 | lists = tmp; 34 | } 35 | return lists[0] || []; 36 | }; 37 | 38 | function mergeTwoLists(l1, l2) { 39 | var result, node; 40 | result = node = new ListNode(); 41 | 42 | while (l1 && l2) { 43 | if (l1.val > l2.val) { 44 | node.next = l2; 45 | l2 = l2.next; 46 | } else { 47 | node.next = l1; 48 | l1 = l1.next; 49 | } 50 | node = node.next; 51 | } 52 | node.next = l1 ? l1 : l2; 53 | return result.next; 54 | } 55 | -------------------------------------------------------------------------------- /algorithms/MergeTwoBinaryTrees.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/merge-two-binary-trees 2 | // Author : Dean Shi 3 | // Date : 2017-06-14 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given two binary trees and imagine that when you put one of them to cover the other, 8 | * some nodes of the two trees are overlapped while the others are not. 9 | * 10 | * You need to merge them into a new binary tree. The merge rule is that if two nodes 11 | * overlap, then sum node values up as the new value of the merged node. Otherwise, the 12 | * NOT null node will be used as the node of new tree. 13 | * 14 | * Example 1: 15 | * 16 | * Input: 17 | * Output: 18 | * Merged tree: 19 | * 3 20 | * / \ 21 | * 4 5 22 | * / \ \ 23 | * 5 4 7 24 | * 25 | * Note: 26 | * The merging process must start from the root nodes of both trees. 27 | * 28 | ***************************************************************************************/ 29 | 30 | /** 31 | * Definition for a binary tree node. 32 | * function TreeNode(val) { 33 | * this.val = val; 34 | * this.left = this.right = null; 35 | * } 36 | */ 37 | /** 38 | * @param {TreeNode} t1 39 | * @param {TreeNode} t2 40 | * @return {TreeNode} 41 | */ 42 | var mergeTrees = function(t1, t2) { 43 | if (!t1) return t2 44 | if (!t2) return t1 45 | 46 | t1.val += t2.val 47 | t1.left = mergeTrees(t1.left, t2.left) 48 | t1.right = mergeTrees(t1.right, t2.right) 49 | return t1 50 | }; 51 | -------------------------------------------------------------------------------- /algorithms/MergeTwoSortedArray.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/merge-sorted-array/ 2 | // Author : Dean Shi 3 | // Date : 2015-05-29 4 | 5 | /********************************************************************************** 6 | * 7 | * Given two sorted integer arrays A and B, merge B into A as one sorted array. 8 | * 9 | * Note: 10 | * You may assume that A has enough space (size that is greater or equal to m + n) 11 | * to hold additional elements from B. The number of elements initialized in A and B 12 | * are m and n respectively. 13 | * 14 | **********************************************************************************/ 15 | 16 | /** 17 | * @param {number[]} nums1 18 | * @param {number} m 19 | * @param {number[]} nums2 20 | * @param {number} n 21 | * @return {void} Do not return anything, modify nums1 in-place instead. 22 | */ 23 | var merge = function(nums1, m, nums2, n) { 24 | let i = m - 1, j = n - 1, k = m + n - 1 25 | 26 | while(i >= 0 && j >= 0) { 27 | nums1[k--] = nums1[i] > nums2[j] ? nums1[i--] : nums2[j--] 28 | } 29 | while(j >= 0) { 30 | nums1[k--] = nums2[j--] 31 | } 32 | }; 33 | 34 | // Test case 35 | var m = [4, 5, 6, 0, 0, 0]; 36 | var n = [1, 2, 3]; 37 | merge(m, 3, n, 3); 38 | 39 | console.log(m.toString() === '1,2,3,4,5,6'); // true 40 | -------------------------------------------------------------------------------- /algorithms/MergeTwoSortedList.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/merge-two-sorted-lists/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-11 4 | 5 | /********************************************************************************** 6 | * 7 | * Merge two sorted linked lists and return it as a new list. The new list should be 8 | * made by splicing together the nodes of the first two lists. 9 | * 10 | **********************************************************************************/ 11 | 12 | /** 13 | * Definition for singly-linked list. 14 | * function ListNode(val) { 15 | * this.val = val; 16 | * this.next = null; 17 | * } 18 | */ 19 | /** 20 | * @param {ListNode} l1 21 | * @param {ListNode} l2 22 | * @return {ListNode} 23 | */ 24 | var mergeTwoLists = function(l1, l2) { 25 | if (!l1) return l2 26 | if (!l2) return l1 27 | 28 | if (l1.val > l2.val) { 29 | l2.next = mergeTwoLists(l1, l2.next) 30 | return l2 31 | } else { 32 | l1.next = mergeTwoLists(l1.next, l2) 33 | return l1 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /algorithms/MiddleOfTheLinkedList.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/middle-of-the-linked-list 2 | // Author : Dean Shi 3 | // Date : 2018-08-10 4 | 5 | /*************************************************************************************** 6 | * Given a non-empty, singly linked list with head node head, return a middle node of 7 | * linked list. 8 | * 9 | * If there are two middle nodes, return the second middle node. 10 | * 11 | * Example 1: 12 | * 13 | * Input: [1,2,3,4,5] 14 | * Output: Node 3 from this list (Serialization: [3,4,5]) 15 | * The returned node has value 3. (The judge's serialization of this node is [3,4,5]). 16 | * Note that we returned a ListNode object ans, such that: 17 | * ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, and ans.next.next.next = NULL. 18 | * 19 | * Example 2: 20 | * 21 | * Input: [1,2,3,4,5,6] 22 | * Output: Node 4 from this list (Serialization: [4,5,6]) 23 | * Since the list has two middle nodes with values 3 and 4, we return the second one. 24 | * 25 | * Note: 26 | * 27 | * The number of nodes in the given list will be between 1 and 100. 28 | * 29 | ***************************************************************************************/ 30 | 31 | /** 32 | * Definition for singly-linked list. 33 | * function ListNode(val) { 34 | * this.val = val; 35 | * this.next = null; 36 | * } 37 | */ 38 | /** 39 | * @param {ListNode} head 40 | * @return {ListNode} 41 | */ 42 | var middleNode = function(head) { 43 | let fastPt = head 44 | let slowPt = head 45 | 46 | while (fastPt && fastPt.next) { 47 | fastPt = fastPt.next.next 48 | slowPt = slowPt.next 49 | } 50 | return slowPt 51 | }; 52 | -------------------------------------------------------------------------------- /algorithms/MinimumAbsoluteDifferenceInBST.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/minimum-absolute-difference-in-bst 2 | // Author : Dean Shi 3 | // Date : 2017-03-11 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a binary search tree with non-negative values, find the minimum absolute 8 | * difference between values of any two nodes. 9 | * 10 | * Example: 11 | * 12 | * Input: 13 | * 14 | * 1 15 | * \ 16 | * 3 17 | * / 18 | * 2 19 | * 20 | * Output: 21 | * 1 22 | * 23 | * Explanation: 24 | * The minimum absolute difference is 1, which is the difference between 2 and 1 (or 25 | * between 2 and 3). 26 | * 27 | * Note: 28 | * There are at least two nodes in this BST. 29 | * 30 | * 31 | ***************************************************************************************/ 32 | 33 | /** 34 | * Definition for a binary tree node. 35 | * function TreeNode(val) { 36 | * this.val = val; 37 | * this.left = this.right = null; 38 | * } 39 | */ 40 | /** 41 | * @param {TreeNode} root 42 | * @return {number} 43 | */ 44 | var getMinimumDifference = function(root) { 45 | const hash = [] 46 | let result = Number.MAX_SAFE_INTEGER 47 | helper(root, hash) 48 | 49 | hash.sort((a,b) => a - b) 50 | 51 | let curr, diff, prev = hash[0] 52 | for (let i = 1; i < hash.length; i++) { 53 | curr = hash[i] 54 | diff = curr - prev 55 | if (diff < result) result = diff 56 | prev = curr 57 | } 58 | 59 | return result 60 | }; 61 | 62 | function helper(root, hash) { 63 | if (!root) return 64 | 65 | hash.push(root.val) 66 | 67 | helper(root.left, hash) 68 | helper(root.right, hash) 69 | } 70 | -------------------------------------------------------------------------------- /algorithms/MinimumDepthOfBinaryTree.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/minimum-depth-of-binary-tree 2 | // Author : Dean Shi 3 | // Date : 2017-03-11 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a binary tree, find its minimum depth. 8 | * 9 | * The minimum depth is the number of nodes along the shortest path from the root node 10 | * down to the nearest leaf node. 11 | * 12 | * 13 | ***************************************************************************************/ 14 | 15 | /** 16 | * Definition for a binary tree node. 17 | * function TreeNode(val) { 18 | * this.val = val; 19 | * this.left = this.right = null; 20 | * } 21 | */ 22 | /** 23 | * @param {TreeNode} root 24 | * @return {number} 25 | */ 26 | var minDepth = function(root) { 27 | if (!root) return 0 28 | if (!root.left) return minDepth(root.right) + 1 29 | if (!root.right) return minDepth(root.left) + 1 30 | return Math.min(minDepth(root.left), minDepth(root.right)) + 1 31 | }; 32 | -------------------------------------------------------------------------------- /algorithms/MissingNumber.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/missing-number 2 | // Author : Dean Shi 3 | // Date : 2017-09-06 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the 8 | * one that is missing from the array. 9 | * 10 | * For example, 11 | * Given nums = [0, 1, 3] return 2. 12 | * 13 | * Note: 14 | * Your algorithm should run in linear runtime complexity. Could you implement it using 15 | * only constant extra space complexity? 16 | * 17 | * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating 18 | * all test cases. 19 | * 20 | * 21 | ***************************************************************************************/ 22 | 23 | /** 24 | * @param {number[]} nums 25 | * @return {number} 26 | */ 27 | var missingNumber = function(nums) { 28 | let sum = nums.length * (nums.length + 1) / 2 29 | return nums.reduce((sum, num) => sum -= num, sum) 30 | }; 31 | -------------------------------------------------------------------------------- /algorithms/MoveZeroes.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/move-zeroes 2 | // Author : Dean Shi 3 | // Date : 2020-04-04 4 | 5 | /*************************************************************************************** 6 | * Given an array nums, write a function to move all 0's to the end of it while 7 | * maintaining the relative order of the non-zero elements. 8 | * 9 | * Example: 10 | * 11 | * Input: [0,1,0,3,12] 12 | * Output: [1,3,12,0,0] 13 | * 14 | * Note: 15 | * 16 | * You must do this in-place without making a copy of the array. 17 | * Minimize the total number of operations. 18 | * 19 | ***************************************************************************************/ 20 | 21 | /** 22 | * @param {number[]} nums 23 | * @return {void} Do not return anything, modify nums in-place instead. 24 | */ 25 | var moveZeroes = function(nums) { 26 | let pt = 0 27 | for (let i = 0; i < nums.length; i++) { 28 | if (nums[i] !== 0) { 29 | [nums[i], nums[pt++]] = [0, nums[i]] 30 | } 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /algorithms/N-RepeatedElementInSize2NArray.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/n-repeated-element-in-size-2n-array/ 2 | // Author : Dean Shi 3 | // Date : 2019-01-13 4 | 5 | /*************************************************************************************** 6 | * 7 | * In a array A of size 2N, there are N+1 unique elements, and exactly one of these 8 | * elements is repeated N times. 9 | * 10 | * Return the element repeated N times. 11 | * 12 | * Example 1: 13 | * 14 | * Input: [1,2,3,3] 15 | * Output: 3 16 | * 17 | * Example 2: 18 | * 19 | * Input: [2,1,2,5,3,2] 20 | * Output: 2 21 | * 22 | * Example 3: 23 | * 24 | * Input: [5,1,5,2,5,3,5,4] 25 | * Output: 5 26 | * 27 | * Note: 28 | * 29 | * 4 <= A.length <= 10000 30 | * 0 <= A[i] < 10000 31 | * A.length is even 32 | * 33 | ***************************************************************************************/ 34 | 35 | /** 36 | * @param {number[]} A 37 | * @return {number} 38 | */ 39 | var repeatedNTimes = function(A) { 40 | const map = new Set() 41 | 42 | for (const n of A) { 43 | if (map.has(n)) return n 44 | map.add(n) 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /algorithms/NextGreaterNodeInLinkedList.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * function ListNode(val, next) { 4 | * this.val = (val===undefined ? 0 : val) 5 | * this.next = (next===undefined ? null : next) 6 | * } 7 | */ 8 | /** 9 | * @param {ListNode} head 10 | * @return {number[]} 11 | */ 12 | var nextLargerNodes = function (head) { 13 | let stack = []; 14 | let sol = []; 15 | let ptr = head; 16 | while (ptr) { 17 | while (stack.length > 0 && getTopVal(stack) < ptr.val) { 18 | let e = stack.pop(); 19 | e.val = ptr.val; 20 | } 21 | stack.push(ptr); 22 | ptr = ptr.next; 23 | } 24 | while (stack.length > 0) { 25 | let e = stack.pop(); 26 | e.val = 0; 27 | } 28 | ptr = head; 29 | while (ptr) { 30 | sol.push(ptr.val); 31 | ptr = ptr.next; 32 | } 33 | return sol; 34 | }; 35 | 36 | var getTopVal = function (stack) { 37 | return stack[stack.length - 1].val; 38 | } -------------------------------------------------------------------------------- /algorithms/NumberComplement.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/number-complement 2 | // Author : Dean Shi 3 | // Date : 2017-07-10 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a positive integer, output its complement number. The complement strategy is 8 | * to flip the bits of its binary representation. 9 | * 10 | * Note: 11 | * 12 | * The given integer is guaranteed to fit within the range of a 32-bit signed integer. 13 | * You could assume no leading zero bit in the integer’s binary representation. 14 | * 15 | * Example 1: 16 | * 17 | * Input: 5 18 | * Output: 2 19 | * Explanation: The binary representation of 5 is 101 (no leading zero bits), and its 20 | * complement is 010. So you need to output 2. 21 | * 22 | * Example 2: 23 | * 24 | * Input: 1 25 | * Output: 0 26 | * Explanation: The binary representation of 1 is 1 (no leading zero bits), and its 27 | * complement is 0. So you need to output 0. 28 | * 29 | * 30 | ***************************************************************************************/ 31 | 32 | /** 33 | * @param {number} num 34 | * @return {number} 35 | */ 36 | var findComplement = function(num) { 37 | const i = 1 << num.toString(2).length 38 | return (i - 1) ^ num 39 | }; 40 | -------------------------------------------------------------------------------- /algorithms/NumberOf1Bits.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/number-of-1-bits/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-16 4 | 5 | /********************************************************************************** 6 | * 7 | * Write a function that takes an unsigned integer and returns the number of ’1' bits it has 8 | * (also known as the Hamming weight). 9 | * 10 | * For example, the 32-bit integer ’11' has binary representation 00000000000000000000000000001011, 11 | * so the function should return 3. 12 | * 13 | * Credits:Special thanks to @ts for adding this problem and creating all test cases. 14 | * 15 | **********************************************************************************/ 16 | 17 | /** 18 | * @param {number} n - a positive integer 19 | * @return {number} 20 | */ 21 | var hammingWeight = function(n) { 22 | let result = 0 23 | do { 24 | result += n & 1 25 | } while (n >>>= 1) 26 | return result 27 | }; 28 | -------------------------------------------------------------------------------- /algorithms/NumberOfSegmentsInAString.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/number-of-segments-in-a-string 2 | // Author : Dean Shi 3 | // Date : 2017-03-31 4 | 5 | /*************************************************************************************** 6 | * 7 | * Count the number of segments in a string, where a segment is defined to be a 8 | * contiguous sequence of non-space characters. 9 | * 10 | * Please note that the string does not contain any non-printable characters. 11 | * 12 | * Example: 13 | * 14 | * Input: "Hello, my name is John" 15 | * Output: 5 16 | * 17 | * 18 | ***************************************************************************************/ 19 | 20 | /** 21 | * @param {string} s 22 | * @return {number} 23 | */ 24 | var countSegments = function(s) { 25 | s = s.trim() 26 | if (s.length === 0) return 0 27 | 28 | return s.split(/ +/).length 29 | }; 30 | -------------------------------------------------------------------------------- /algorithms/PalindromeLinkedList.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/palindrome-linked-list 2 | // Author : Dean Shi 3 | // Date : 2017-10-21 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a singly linked list, determine if it is a palindrome. 8 | * 9 | * Follow up: 10 | * Could you do it in O(n) time and O(1) space? 11 | * 12 | ***************************************************************************************/ 13 | 14 | /** 15 | * Definition for singly-linked list. 16 | * function ListNode(val) { 17 | * this.val = val; 18 | * this.next = null; 19 | * } 20 | */ 21 | /** 22 | * @param {ListNode} head 23 | * @return {boolean} 24 | */ 25 | var isPalindrome = function(head) { 26 | const stack = [] 27 | 28 | while (head) { 29 | stack.push(head.val) 30 | head = head.next 31 | } 32 | 33 | return stack.join('') === stack.reverse().join('') 34 | }; -------------------------------------------------------------------------------- /algorithms/PartitionList.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/partition-list 2 | // Author : Dean Shi 3 | // Date : 2017-09-01 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a linked list and a value x, partition it such that all nodes less than x come 8 | * before nodes greater than or equal to x. 9 | * 10 | * You should preserve the original relative order of the nodes in each of the two 11 | * partitions. 12 | * 13 | * For example, 14 | * Given 1->4->3->2->5->2 and x = 3, 15 | * return 1->2->2->4->3->5. 16 | * 17 | * 18 | ***************************************************************************************/ 19 | 20 | /** 21 | * Definition for singly-linked list. 22 | * function ListNode(val) { 23 | * this.val = val; 24 | * this.next = null; 25 | * } 26 | */ 27 | /** 28 | * @param {ListNode} head 29 | * @param {number} x 30 | * @return {ListNode} 31 | */ 32 | var partition = function(head, x) { 33 | let headNode, headpt, tailNode, tailpt 34 | 35 | headNode = headpt = new ListNode() 36 | tailNode = tailpt = new ListNode() 37 | 38 | while (head) { 39 | if (head.val < x) { 40 | headpt = headpt.next = head 41 | } else { 42 | tailpt = tailpt.next = head 43 | } 44 | head = head.next 45 | } 46 | 47 | [headpt.next, tailpt.next ] = [tailNode.next, null] 48 | 49 | return headNode.next 50 | }; 51 | -------------------------------------------------------------------------------- /algorithms/PascalsTriangle.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/pascals-triangle 2 | // Author : Dean Shi 3 | // Date : 2017-07-12 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given numRows, generate the first numRows of Pascal's triangle. 8 | * 9 | * For example, given numRows = 5, 10 | * Return 11 | * 12 | * [ 13 | * [1], 14 | * [1,1], 15 | * [1,2,1], 16 | * [1,3,3,1], 17 | * [1,4,6,4,1] 18 | * ] 19 | * 20 | * 21 | ***************************************************************************************/ 22 | 23 | /** 24 | * @param {number} numRows 25 | * @return {number[][]} 26 | */ 27 | var generate = function(numRows) { 28 | const result = [] 29 | 30 | for (let row, prevRow, i = 0; i < numRows; ++i) { 31 | [row, prevRow] = [[1], result[i - 1] || []] 32 | prevRow.forEach((n, j) => row.push(n + (prevRow[j + 1] || 0))) 33 | result.push(row) 34 | } 35 | return result 36 | }; 37 | 38 | 39 | /** 40 | * @param {number} numRows 41 | * @return {number[][]} 42 | */ 43 | var generate = function(numRows) { 44 | const result = [] 45 | 46 | for (let row = [], i = 0; i < numRows; ++i) { 47 | row.push(1) 48 | for (let j = i - 1; j > 0; --j) { 49 | row[j] = row[j - 1] + row[j] 50 | } 51 | result.push(row.slice()) 52 | } 53 | return result 54 | }; 55 | -------------------------------------------------------------------------------- /algorithms/PascalsTriangle_II.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/pascals-triangle-ii 2 | // Author : Dean Shi 3 | // Date : 2017-07-12 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an index k, return the kth row of the Pascal's triangle. 8 | * 9 | * For example, given k = 3, 10 | * Return [1,3,3,1]. 11 | * 12 | * Note: 13 | * Could you optimize your algorithm to use only O(k) extra space? 14 | * 15 | * 16 | ***************************************************************************************/ 17 | 18 | /** 19 | * @param {number} rowIndex 20 | * @return {number[]} 21 | */ 22 | var getRow = function(rowIndex) { 23 | const result = [] 24 | 25 | for (let i = 0; i <= rowIndex; ++i) { 26 | result.push(1) 27 | for (let j = i - 1; j > 0; --j) { 28 | result[j] = result[j - 1] + result[j] 29 | } 30 | } 31 | return result 32 | }; 33 | -------------------------------------------------------------------------------- /algorithms/PeakIndexInAMountainArray.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/peak-index-in-a-mountain-array 2 | // Author : Dean Shi 3 | // Date : 2018-08-13 4 | 5 | /*************************************************************************************** 6 | * Let's call an array A a mountain if the following properties hold: 7 | * 8 | * A.length >= 3 9 | * There exists some 0 < i < A.length - 1 such that A[0] < A[1] < ... A[i-1] < A[i] > 10 | * A[i+1] > ... > A[A.length - 1] 11 | * 12 | * Given an array that is definitely a mountain, return any i such that A[0] < A[1] < .. 13 | * . A[i-1] < A[i] > A[i+1] > ... > A[A.length - 1]. 14 | * 15 | * Example 1: 16 | * 17 | * Input: [0,1,0] 18 | * Output: 1 19 | * 20 | * Example 2: 21 | * 22 | * Input: [0,2,1,0] 23 | * Output: 1 24 | * 25 | * Note: 26 | * 27 | * 3 <= A.length <= 10000 28 | * 0 <= A[i] <= 10^6 29 | * A is a mountain, as defined above. 30 | * 31 | ***************************************************************************************/ 32 | 33 | /** 34 | * @param {number[]} A 35 | * @return {number} 36 | */ 37 | var peakIndexInMountainArray = function(A) { 38 | let i = 0 39 | while (A[i] < A[i+1]) i++ 40 | return i 41 | }; 42 | -------------------------------------------------------------------------------- /algorithms/PerfectNumber.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/perfect-number 2 | // Author : Dean Shi 3 | // Date : 2017-03-30 4 | 5 | /*************************************************************************************** 6 | * 7 | * We define the Perfect Number is a positive integer that is equal to the sum of all 8 | * its positive divisors except itself. 9 | * 10 | * Now, given an integer n, write a function that returns true when it is a perfect 11 | * number and false when it is not. 12 | * 13 | * Example: 14 | * 15 | * Input: 28 16 | * Output: True 17 | * Explanation: 28 = 1 + 2 + 4 + 7 + 14 18 | * 19 | * Note: 20 | * The input number n will not exceed 100,000,000. (1e8) 21 | * 22 | * 23 | ***************************************************************************************/ 24 | 25 | /** 26 | * @param {number} num 27 | * @return {boolean} 28 | */ 29 | var checkPerfectNumber = function(num) { 30 | if (num === 1) return false 31 | 32 | let sum = 1 33 | const length = Math.floor(Math.sqrt(num)) 34 | 35 | for (let i = 2; i <= length; i++) { 36 | if (num % i === 0) { 37 | sum += num / i + i 38 | } 39 | } 40 | return sum === num 41 | }; 42 | -------------------------------------------------------------------------------- /algorithms/PlusOne.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/plus-one/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-16 4 | 5 | /********************************************************************************** 6 | * 7 | * Given a non-negative number represented as an array of digits, plus one to the number. 8 | * 9 | * The digits are stored such that the most significant digit is at the head of the list. 10 | * 11 | **********************************************************************************/ 12 | 13 | /** 14 | * @param {number[]} digits 15 | * @return {number[]} 16 | */ 17 | var plusOne = function(digits) { 18 | var i = digits.length - 1; 19 | while (i >= 0) { 20 | if (++digits[i] < 10) { 21 | return digits; 22 | } 23 | digits[i--] = 0; 24 | } 25 | digits.unshift(1); 26 | return digits; 27 | }; 28 | 29 | // Test cases 30 | console.log(plusOne([9]).toString() === '1,0'); // true 31 | console.log(plusOne([1, 0]).toString() === '1,1'); // true 32 | console.log(plusOne([1, 2, 3]).toString() === '1,2,4'); // true 33 | -------------------------------------------------------------------------------- /algorithms/PowXN.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/powx-n 2 | // Author : Dean Shi 3 | // Date : 2017-07-10 4 | 5 | /*************************************************************************************** 6 | * 7 | * Implement pow(x, n). 8 | * 9 | ***************************************************************************************/ 10 | 11 | /** 12 | * @param {number} x 13 | * @param {number} n 14 | * @return {number} 15 | */ 16 | var myPow = function(x, n) { 17 | if (x === 1 || n === 0) return 1 18 | if (x === x + 1) return 0 19 | 20 | if (n < 0) { 21 | n = -n 22 | x = 1 / x 23 | } 24 | return n & 1 ? x * myPow(x * x, n >> 1) : myPow(x * x, n >> 1) 25 | }; 26 | -------------------------------------------------------------------------------- /algorithms/PowerOfFour.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/power-of-four 2 | // Author : Dean Shi 3 | // Date : 2017-09-14 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an integer (signed 32 bits), write a function to check whether it is a power 8 | * of 4. 9 | * 10 | * Example: 11 | * Given num = 16, return true. 12 | * Given num = 5, return false. 13 | * 14 | * Follow up: Could you solve it without loops/recursion? 15 | * 16 | * Credits:Special thanks to @yukuairoy for adding this problem and creating all test 17 | * cases. 18 | * 19 | ***************************************************************************************/ 20 | 21 | /** 22 | * Recursion 23 | * @param {number} num 24 | * @return {boolean} 25 | */ 26 | var isPowerOfFour = function(num) { 27 | if (num === 1) return true 28 | if (num % 4 !== 0 || num === 0) return false 29 | 30 | return isPowerOfFour(num / 4) 31 | }; 32 | 33 | /** 34 | * Iteration 35 | * @param {number} num 36 | * @return {boolean} 37 | */ 38 | var isPowerOfFour = function(num) { 39 | if (num < 1) return false 40 | while (num % 4 === 0) num /= 4 41 | 42 | return num === 1 43 | }; 44 | -------------------------------------------------------------------------------- /algorithms/PowerOfThree.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/power-of-three 2 | // Author : Dean Shi 3 | // Date : 2017-09-14 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an integer, write a function to determine if it is a power of three. 8 | * 9 | * Follow up: 10 | * Could you do it without using any loop / recursion? 11 | * 12 | * Credits:Special thanks to @dietpepsi for adding this problem and creating all test 13 | * cases. 14 | * 15 | ***************************************************************************************/ 16 | 17 | /** 18 | * Recursion 19 | * @param {number} n 20 | * @return {boolean} 21 | */ 22 | var isPowerOfThree = function(n) { 23 | if (n === 1) return true 24 | if (n % 3 !== 0 || n === 0) return false 25 | 26 | return isPowerOfThree(n / 3) 27 | }; 28 | 29 | /** 30 | * Iteration 31 | * @param {number} n 32 | * @return {boolean} 33 | */ 34 | var isPowerOfThree = function(n) { 35 | if (n < 1) return false 36 | while (n % 3 === 0) n /= 3 37 | 38 | return n === 1 39 | }; 40 | -------------------------------------------------------------------------------- /algorithms/RangeSumOfBST.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/range-sum-of-bst/ 2 | // Author : Dean Shi 3 | // Date : 2019-01-10 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given the root node of a binary search tree, return the sum of values of all nodes 8 | * with value between L and R (inclusive). 9 | * 10 | * The binary search tree is guaranteed to have unique values. 11 | * 12 | * Example 1: 13 | * 14 | * Input: root = [10,5,15,3,7,null,18], L = 7, R = 15 15 | * Output: 32 16 | * 17 | * Example 2: 18 | * 19 | * Input: root = [10,5,15,3,7,13,18,1,null,6], L = 6, R = 10 20 | * Output: 23 21 | * 22 | * Note: 23 | * 24 | * The number of nodes in the tree is at most 10000. 25 | * The final answer is guaranteed to be less than 2^31. 26 | * 27 | ***************************************************************************************/ 28 | 29 | /** 30 | * Definition for a binary tree node. 31 | * function TreeNode(val) { 32 | * this.val = val; 33 | * this.left = this.right = null; 34 | * } 35 | */ 36 | /** 37 | * @param {TreeNode} root 38 | * @param {number} L 39 | * @param {number} R 40 | * @return {number} 41 | */ 42 | var rangeSumBST = function(root, L, R) { 43 | let result = 0 44 | const stack = [root] 45 | 46 | while (stack.length) { 47 | const node = stack.pop() 48 | 49 | if (node) { 50 | if (L <= node.val && node.val <= R) { 51 | result += node.val 52 | } 53 | if (L < node.val) { 54 | stack.push(node.left) 55 | } 56 | if (node.val < R) { 57 | stack.push(node.right) 58 | } 59 | } 60 | } 61 | return result 62 | }; 63 | -------------------------------------------------------------------------------- /algorithms/RegularExpressionMatching.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/regular-expression-matching/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-03 4 | 5 | /********************************************************************************** 6 | * 7 | * Implement regular expression matching with support for '.' and '*'. 8 | * 9 | * '.' Matches any single character. 10 | * '*' Matches zero or more of the preceding element. 11 | * 12 | * The matching should cover the entire input string (not partial). 13 | * 14 | * The function prototype should be: 15 | * bool isMatch(const char *s, const char *p) 16 | * 17 | * Some examples: 18 | * isMatch("aa","a") → false 19 | * isMatch("aa","aa") → true 20 | * isMatch("aaa","aa") → false 21 | * isMatch("aa", "a*") → true 22 | * isMatch("aa", ".*") → true 23 | * isMatch("ab", ".*") → true 24 | * isMatch("aab", "c*a*b") → true 25 | * 26 | * 27 | **********************************************************************************/ 28 | 29 | /** 30 | * @param {string} s 31 | * @param {string} p 32 | * @return {boolean} 33 | */ 34 | var isMatch = function(s, p) { 35 | if (p.length === 0) { 36 | return !s.length 37 | } 38 | let firstLetterMatched = s.length > 0 && (s[0] === p[0] || p[0] === '.') 39 | 40 | if (p[1] === '*') { 41 | return isMatch(s, p.substring(2)) || (firstLetterMatched && isMatch(s.substring(1), p)) 42 | } 43 | return firstLetterMatched && isMatch(s.substring(1), p.substring(1)) 44 | }; 45 | -------------------------------------------------------------------------------- /algorithms/Remove9.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/remove-9 2 | // Author : Dean Shi 3 | // Date : 2017-08-14 4 | 5 | /*************************************************************************************** 6 | * 7 | * Start from integer 1, remove any integer that contains 9 such as 9, 19, 29... 8 | * 9 | * So now, you will have a new integer sequence: 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, ... 10 | * 11 | * Given a positive integer n, you need to return the n-th integer after removing. Note 12 | * that 1 will be the first integer. 13 | * 14 | * Example 1: 15 | * 16 | * Input: 9 17 | * Output: 10 18 | * 19 | * Hint: n will not exceed 9 x 10^8. 20 | * 21 | * 22 | ***************************************************************************************/ 23 | 24 | /** 25 | * @param {number} n 26 | * @return {number} 27 | */ 28 | var newInteger = function(n) { 29 | return +(n.toString(9)) 30 | }; 31 | -------------------------------------------------------------------------------- /algorithms/RemoveAllAdjacentDuplicatesInString.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/remove-all-adjacent-duplicates-in-string/ 2 | // Author : Dean Shi 3 | // Date : 2019-05-24 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a string S of lowercase letters, a duplicate removal consists of choosing two 8 | * adjacent and equal letters, and removing them. 9 | * 10 | * We repeatedly make duplicate removals on S until we no longer can. 11 | * 12 | * Return the final string after all such duplicate removals have been made.  It is 13 | * guaranteed the answer is unique. 14 | * 15 | * Example 1: 16 | * 17 | * Input: "abbaca" 18 | * Output: "ca" 19 | * Explanation: 20 | * For example, in "abbaca" we could remove "bb" since the letters are adjacent and 21 | * equal, and this is the only possible move.  The result of this move is that the 22 | * string is "aaca", of which only "aa" is possible, so the final string is "ca". 23 | * 24 | * Note: 25 | * 26 | * 1 <= S.length <= 20000 27 | * S consists only of English lowercase letters. 28 | * 29 | ***************************************************************************************/ 30 | 31 | /** 32 | * @param {string} S 33 | * @return {string} 34 | */ 35 | var removeDuplicates = function(S) { 36 | const stack = [S[0]] 37 | for (let i = 1; i < S.length; i++) { 38 | const char = stack.pop() 39 | if (char !== S[i]) { 40 | stack.push(char, S[i]) 41 | } 42 | } 43 | return stack.join('') 44 | }; 45 | -------------------------------------------------------------------------------- /algorithms/RemoveDuplicatesFromSortedArray.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/remove-duplicates-from-sorted-array 2 | // Author : Dean Shi 3 | // Date : 2017-03-04 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a sorted array, remove the duplicates in place such that each element appear 8 | * only once and return the new length. 9 | * 10 | * Do not allocate extra space for another array, you must do this in place with 11 | * constant memory. 12 | * 13 | * For example, 14 | * Given input array nums = [1,1,2], 15 | * 16 | * Your function should return length = 2, with the first two elements of nums being 1 17 | * and 2 respectively. It doesn't matter what you leave beyond the new length. 18 | * 19 | * 20 | ***************************************************************************************/ 21 | 22 | /** 23 | * @param {number[]} nums 24 | * @return {number} 25 | */ 26 | var removeDuplicates = function(nums) { 27 | let pointer = 0 28 | 29 | for (let i = 1; i < nums.length; i++) { 30 | if (nums[pointer] !== nums[i]) { 31 | nums[++pointer] = nums[i] 32 | } 33 | } 34 | return nums.length ? pointer + 1 : 0 35 | }; 36 | -------------------------------------------------------------------------------- /algorithms/RemoveDuplicatesFromSortedArray_II.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii 2 | // Author : Dean Shi 3 | // Date : 2017-03-04 4 | 5 | /*************************************************************************************** 6 | * 7 | * Follow up for "Remove Duplicates": 8 | * What if duplicates are allowed at most twice? 9 | * 10 | * For example, 11 | * Given sorted array nums = [1,1,1,2,2,3], 12 | * 13 | * Your function should return length = 5, with the first five elements of nums being 14 | * 1, 1, 2, 2 and 3. It doesn't matter what you leave beyond the new length. 15 | * 16 | * 17 | ***************************************************************************************/ 18 | 19 | /** 20 | * @param {number[]} nums 21 | * @return {number} 22 | */ 23 | var removeDuplicates = function(nums) { 24 | let pointer = 0 25 | for (let i = 1, isRepeated = false; i < nums.length; i++) { 26 | if (nums[pointer] !== nums[i]) { 27 | nums[++pointer] = nums[i] 28 | isRepeated = false 29 | } else if (!isRepeated) { 30 | nums[++pointer] = nums[i] 31 | isRepeated = true 32 | } 33 | } 34 | return nums.length ? pointer + 1 : 0 35 | }; 36 | -------------------------------------------------------------------------------- /algorithms/RemoveElement.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/remove-element 2 | // Author : Dean Shi 3 | // Date : 2017-07-10 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an array and a value, remove all instances of that value in place and return 8 | * the new length. 9 | * 10 | * Do not allocate extra space for another array, you must do this in place with 11 | * constant memory. 12 | * 13 | * The order of elements can be changed. It doesn't matter what you leave beyond the 14 | * new length. 15 | * 16 | * Example: 17 | * Given input array nums = [3,2,2,3], val = 3 18 | * 19 | * Your function should return length = 2, with the first two elements of nums being 2. 20 | * 21 | * 22 | ***************************************************************************************/ 23 | 24 | /** 25 | * @param {number[]} nums 26 | * @param {number} val 27 | * @return {number} 28 | */ 29 | var removeElement = function(nums, val) { 30 | let pointer = 0 31 | for (let n of nums) if (n !== val) nums[pointer++] = n 32 | 33 | return pointer 34 | }; 35 | -------------------------------------------------------------------------------- /algorithms/RemoveLinkedListElements.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/remove-linked-list-elements/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-16 4 | 5 | /********************************************************************************** 6 | * 7 | * Remove all elements from a linked list of integers that have value val. 8 | * 9 | * Example 10 | * Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6 11 | * Return: 1 --> 2 --> 3 --> 4 --> 5 12 | * 13 | * Credits:Special thanks to @mithmatt for adding this problem and creating all test cases. 14 | * 15 | **********************************************************************************/ 16 | 17 | /** 18 | * Definition for singly-linked list. 19 | * function ListNode(val) { 20 | * this.val = val; 21 | * this.next = null; 22 | * } 23 | */ 24 | /** 25 | * Recursion 26 | * @param {ListNode} head 27 | * @param {number} val 28 | * @return {ListNode} 29 | */ 30 | var removeElements = function(head, val) { 31 | if (!head) return head; 32 | 33 | head.next = removeElements(head.next, val); 34 | return head.val === val ? head.next : head; 35 | }; 36 | 37 | /** 38 | * Iteration 39 | * @param {ListNode} head 40 | * @param {number} val 41 | * @return {ListNode} 42 | */ 43 | var removeElements = function(head, val) { 44 | let headNode, prevNode, currNode 45 | headNode = prevNode = new ListNode() 46 | prevNode.next = currNode = head 47 | 48 | while (currNode) { 49 | if (currNode.val !== val) { 50 | prevNode = prevNode.next 51 | } else { 52 | prevNode.next = currNode.next 53 | } 54 | currNode = currNode.next 55 | } 56 | return headNode.next 57 | }; 58 | -------------------------------------------------------------------------------- /algorithms/RemoveNthNodeFromEndOfList.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/remove-nth-node-from-end-of-list/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-11 4 | 5 | /********************************************************************************** 6 | * 7 | * Given a linked list, remove the nth node from the end of list and return its head. 8 | * 9 | * For example, 10 | * 11 | * Given linked list: 1->2->3->4->5, and n = 2. 12 | * 13 | * After removing the second node from the end, the linked list becomes 1->2->3->5. 14 | * 15 | * Note: 16 | * Given n will always be valid. 17 | * Try to do this in one pass. 18 | * 19 | * 20 | **********************************************************************************/ 21 | 22 | /** 23 | * Definition for singly-linked list. 24 | * function ListNode(val) { 25 | * this.val = val; 26 | * this.next = null; 27 | * } 28 | */ 29 | /** 30 | * @param {ListNode} head 31 | * @param {number} n 32 | * @return {ListNode} 33 | */ 34 | var removeNthFromEnd = function(head, n) { 35 | var node, prevNth; 36 | node = prevNth = head; 37 | 38 | for (var i = 0; i < n; ++i) { 39 | node = node.next; 40 | } 41 | if (!node) { 42 | return head.next; 43 | } 44 | 45 | while (node.next) { 46 | node = node.next; 47 | prevNth = prevNth.next; 48 | } 49 | prevNth.next = prevNth.next.next; 50 | return head; 51 | }; 52 | -------------------------------------------------------------------------------- /algorithms/RepeatedStringMatch.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/repeated-string-match 2 | // Author : Dean Shi 3 | // Date : 2017-10-09 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given two strings A and B, find the minimum number of times A has to be 8 | * repeated such that B is a substring of it. If no such solution, return -1. 9 | * 10 | * For example, with A = "abcd" and B = "cdabcdab". 11 | * 12 | * Return 3, because by repeating A three times (“abcdabcdabcd”), B is a substring of 13 | * it; and B is not a substring of A repeated two times ("abcdabcd"). 14 | * 15 | * Note: 16 | * The length of A and B will be between 1 and 10000. 17 | * 18 | ***************************************************************************************/ 19 | 20 | /** 21 | * @param {string} A 22 | * @param {string} B 23 | * @return {number} 24 | */ 25 | var repeatedStringMatch = function(A, B) { 26 | let result = Math.ceil(B.length / A.length) 27 | const [str1, str2] = [A.repeat(result), A.repeat(result + 1)] 28 | 29 | if (str1.includes(B)) return result 30 | if (str2.includes(B)) return result + 1 31 | 32 | return -1 33 | }; -------------------------------------------------------------------------------- /algorithms/ReverseBits.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/reverse-bits/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-16 4 | 5 | /********************************************************************************** 6 | * 7 | * Reverse bits of a given 32 bits unsigned integer. 8 | * 9 | * For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), 10 | * return 964176192 (represented in binary as 00111001011110000010100101000000). 11 | * 12 | * Follow up: 13 | * If this function is called many times, how would you optimize it? 14 | * 15 | * Related problem: Reverse Integer 16 | * 17 | * Credits:Special thanks to @ts for adding this problem and creating all test cases. 18 | * 19 | **********************************************************************************/ 20 | 21 | /** 22 | * @param {number} n - a positive integer 23 | * @return {number} - a positive integer 24 | */ 25 | var reverseBits = function(n) { 26 | var bits = n.toString(2).split('').reverse(); 27 | var l = bits.length; 28 | while (32 - l > 0) { 29 | bits.push('0'); 30 | ++l; 31 | } 32 | return parseInt(bits.join(''), 2); 33 | }; 34 | 35 | // Test case 36 | console.log(reverseBits(43261596) === 964176192); // true 37 | -------------------------------------------------------------------------------- /algorithms/ReverseInteger.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/reverse-integer/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-03 4 | 5 | /********************************************************************************** 6 | * 7 | * Reverse digits of an integer. 8 | * 9 | * Example1: x = 123, return 321 10 | * Example2: x = -123, return -321 11 | * 12 | * 13 | * Have you thought about this? 14 | * 15 | * Here are some good questions to ask before coding. Bonus points for you if you have already thought through this! 16 | * 17 | * > If the integer's last digit is 0, what should the output be? ie, cases such as 10, 100. 18 | * 19 | * > Did you notice that the reversed integer might overflow? Assume the input is a 32-bit integer, 20 | * then the reverse of 1000000003 overflows. How should you handle such cases? 21 | * 22 | * > Throw an exception? Good, but what if throwing an exception is not an option? 23 | * You would then have to re-design the function (ie, add an extra parameter). 24 | * 25 | * 26 | **********************************************************************************/ 27 | 28 | /** 29 | * @param {number} x 30 | * @return {number} 31 | */ 32 | var reverse = function(x) { 33 | let result = 0 34 | while(x) { 35 | result = result * 10 + x % 10 36 | x = ~~(x / 10) 37 | } 38 | if (result > 2147483648 || result < -2147483649) result = 0 39 | 40 | return result 41 | }; 42 | 43 | // Test cases 44 | console.log(reverse(1563847412) === 0); // true 45 | console.log(reverse(-2147483648) === 0); // true 46 | console.log(reverse(32768) === 86723); // true 47 | -------------------------------------------------------------------------------- /algorithms/ReverseLinkedList.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/reverse-linked-list/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-12 4 | 5 | /********************************************************************************** 6 | * 7 | * Reverse a singly linked list. 8 | * 9 | * click to show more hints. 10 | * 11 | * Hint: 12 | * A linked list can be reversed either iteratively or recursively. Could you implement both? 13 | * 14 | * 15 | **********************************************************************************/ 16 | 17 | /** 18 | * Definition for singly-linked list. 19 | * function ListNode(val) { 20 | * this.val = val; 21 | * this.next = null; 22 | * } 23 | */ 24 | /** 25 | * Recursion 26 | * 27 | * @param {ListNode} head 28 | * @return {ListNode} 29 | */ 30 | var reverseList = function(head) { 31 | if (!head || !head.next) return head 32 | 33 | let node = reverseList(head.next) 34 | 35 | head.next.next = head 36 | head.next = null 37 | 38 | return node 39 | }; 40 | 41 | /** 42 | * Iteration 43 | * 44 | * @param {ListNode} head 45 | * @return {ListNode} 46 | */ 47 | var reverseList = function(head) { 48 | let next, prev = null 49 | 50 | while (head) { 51 | [next, head.next] = [head.next, prev]; 52 | [prev, head] = [head, next] 53 | } 54 | 55 | return prev 56 | }; 57 | -------------------------------------------------------------------------------- /algorithms/ReverseLinkedList_II.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/reverse-linked-list-ii 2 | // Author : Dean Shi 3 | // Date : 2017-03-27 4 | 5 | /*************************************************************************************** 6 | * 7 | * Reverse a linked list from position m to n. Do it in-place and in one-pass. 8 | * 9 | * For example: 10 | * Given 1->2->3->4->5->NULL, m = 2 and n = 4, 11 | * 12 | * return 1->4->3->2->5->NULL. 13 | * 14 | * Note: 15 | * Given m, n satisfy the following condition: 16 | * 1 ≤ m ≤ n ≤ length of list. 17 | * 18 | * 19 | ***************************************************************************************/ 20 | 21 | /** 22 | * Definition for singly-linked list. 23 | * function ListNode(val) { 24 | * this.val = val; 25 | * this.next = null; 26 | * } 27 | */ 28 | /** 29 | * @param {ListNode} head 30 | * @param {number} m 31 | * @param {number} n 32 | * @return {ListNode} 33 | */ 34 | var reverseBetween = function(head, m, n) { 35 | if (m === 1) { 36 | return reverse(head, n - 1)[0] 37 | } 38 | head.next = reverseBetween(head.next, m - 1, n - 1) 39 | return head 40 | }; 41 | 42 | function reverse(head, n) { 43 | if (!n) return [head, head.next] 44 | 45 | const [node, nodeNext] = reverse(head.next, n - 1) 46 | const next = head.next 47 | next.next = head 48 | head.next = nodeNext 49 | 50 | return [node, nodeNext] 51 | 52 | } 53 | -------------------------------------------------------------------------------- /algorithms/ReverseString.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/reverse-string 2 | // Author : Dean Shi 3 | // Date : 2020-04-04 4 | 5 | /*************************************************************************************** 6 | * Write a function that reverses a string. The input string is given as an array of 7 | * characters char[]. 8 | * 9 | * Do not allocate extra space for another array, you must do this by modifying the 10 | * input array in-place with O(1) extra memory. 11 | * 12 | * You may assume all the characters consist of printable ascii characters. 13 | * 14 | * Example 1: 15 | * 16 | * Input: ["h","e","l","l","o"] 17 | * Output: ["o","l","l","e","h"] 18 | * 19 | * Example 2: 20 | * 21 | * Input: ["H","a","n","n","a","h"] 22 | * Output: ["h","a","n","n","a","H"] 23 | * 24 | * 25 | ***************************************************************************************/ 26 | 27 | /** 28 | * @param {character[]} s 29 | * @return {void} Do not return anything, modify s in-place instead. 30 | */ 31 | var reverseString = function(s) { 32 | const end = s.length / 2 33 | for (let i = 0; i < end; i++) { 34 | [s[i], s[s.length - i - 1]] = [s[s.length - i - 1], s[i]] 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /algorithms/ReverseString_II.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/reverse-string-ii 2 | // Author : Dean Shi 3 | // Date : 2017-03-11 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a string and an integer k, you need to reverse the first k characters for 8 | * every 2k characters counting from the start of the string. If there are less than k 9 | * characters left, reverse all of them. If there are less than 2k but greater than or 10 | * equal to k characters, then reverse the first k characters and left the other as 11 | * original. 12 | * 13 | * Example: 14 | * 15 | * Input: s = "abcdefg", k = 2 16 | * Output: "bacdfeg" 17 | * 18 | * Restrictions: 19 | * 20 | * The string consists of lower English letters only. 21 | * Length of the given string and k will in the range [1, 10000] 22 | * 23 | * 24 | ***************************************************************************************/ 25 | 26 | /** 27 | * @param {string} s 28 | * @param {number} k 29 | * @return {string} 30 | */ 31 | var reverseStr = function(s, k) { 32 | return s.length <= k 33 | ? s.split('').reverse().join('') 34 | : reverseStr(s.substring(0, k), k) + s.substring(k, 2 * k) + reverseStr(s.substring(2 * k), k) 35 | }; 36 | -------------------------------------------------------------------------------- /algorithms/ReverseVowelsOfAString.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/reverse-vowels-of-a-string 2 | // Author : Dean Shi 3 | // Date : 2017-09-14 4 | 5 | /*************************************************************************************** 6 | * 7 | * Write a function that takes a string as input and reverse only the vowels of a 8 | * string. 9 | * 10 | * Example 1: 11 | * Given s = "hello", return "holle". 12 | * 13 | * Example 2: 14 | * Given s = "leetcode", return "leotcede". 15 | * 16 | * Note: 17 | * The vowels does not include the letter "y". 18 | * 19 | ***************************************************************************************/ 20 | 21 | /** 22 | * @param {string} s 23 | * @return {string} 24 | */ 25 | var reverseVowels = function(s) { 26 | let [lpt, rpt] = [0, s.length - 1] 27 | let vowels = new Set('aeiouAEIOU') 28 | const result = [...s] 29 | 30 | while (lpt < rpt) { 31 | while (lpt < rpt && !vowels.has(s[lpt])) ++lpt 32 | while (lpt < rpt && !vowels.has(s[rpt])) --rpt 33 | 34 | ;[result[lpt++], result[rpt--]] = [result[rpt], result[lpt]] 35 | } 36 | return result.join('') 37 | }; 38 | -------------------------------------------------------------------------------- /algorithms/ReverseWordsInAString.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/reverse-words-in-a-string/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-13 4 | 5 | /********************************************************************************** 6 | * 7 | * Given an input string, reverse the string word by word. 8 | * 9 | * For example, 10 | * Given s = "the sky is blue", 11 | * return "blue is sky the". 12 | * 13 | * 14 | * Clarification: 15 | * 16 | * What constitutes a word? 17 | * A sequence of non-space characters constitutes a word. 18 | * Could the input string contain leading or trailing spaces? 19 | * Yes. However, your reversed string should not contain leading or trailing spaces. 20 | * How about multiple spaces between two words? 21 | * Reduce them to a single space in the reversed string. 22 | * 23 | * 24 | **********************************************************************************/ 25 | 26 | /** 27 | * @param {string} str 28 | * @returns {string} 29 | */ 30 | var reverseWords = function(str) { 31 | return str.trim().split(/ +/).reverse().join(' ') 32 | }; 33 | 34 | // Test case 35 | console.log(reverseWords('the sky is blue') === 'blue is sky the'); // true 36 | -------------------------------------------------------------------------------- /algorithms/ReverseWordsInAString_III.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/reverse-words-in-a-string-iii 2 | // Author : Dean Shi 3 | // Date : 2017-04-09 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a string, you need to reverse the order of characters in each word within a 8 | * sentence while still preserving whitespace and initial word order. 9 | * 10 | * Example 1: 11 | * 12 | * Input: "Let's take LeetCode contest" 13 | * Output: "s'teL ekat edoCteeL tsetnoc" 14 | * 15 | * Note: 16 | * In the string, each word is separated by single space and there will not be any 17 | * extra space in the string. 18 | * 19 | * 20 | ***************************************************************************************/ 21 | 22 | /** 23 | * @param {string} s 24 | * @return {string} 25 | */ 26 | var reverseWords = function(s) { 27 | return s.split('').reverse().join('').split(' ').reverse().join(' ') 28 | }; 29 | -------------------------------------------------------------------------------- /algorithms/RomanToInteger.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/roman-to-integer/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-10 4 | 5 | /********************************************************************************** 6 | * 7 | * Given a roman numeral, convert it to an integer. 8 | * 9 | * Input is guaranteed to be within the range from 1 to 3999. 10 | * 11 | **********************************************************************************/ 12 | 13 | /** 14 | * @param {string} s 15 | * @return {number} 16 | */ 17 | var romanToInt = function(s) { 18 | var romanTable = { 19 | 'M': 1000, 20 | 'D': 500, 21 | 'C': 100, 22 | 'L': 50, 23 | 'X': 10, 24 | 'V': 5, 25 | 'I': 1 26 | }; 27 | 28 | var result, prev, curr; 29 | result = prev = romanTable[s[0]]; 30 | 31 | for (var i = 1, l = s.length; i < l; ++i) { 32 | curr = romanTable[s[i]]; 33 | result += curr - (prev < curr ? prev * 2 : 0); 34 | prev = curr; 35 | } 36 | 37 | return result; 38 | }; 39 | 40 | // Test case 41 | console.log(romanToInt('CMXCIX') === 999); // true 42 | -------------------------------------------------------------------------------- /algorithms/RotateString.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/rotate-string 2 | // Author : Dean Shi 3 | // Date : 2018-03-27 4 | 5 | /*************************************************************************************** 6 | * We are given two strings, A and B. 7 | * 8 | * A shift on A consists of taking string A and moving the leftmost character to the 9 | * rightmost position. For example, if A = 'abcde', then it will be 'bcdea' after one 10 | * shift on A. Return True if and only if A can become B after some number of shifts on 11 | * A. 12 | * 13 | * Example 1: 14 | * Input: A = 'abcde', B = 'cdeab' 15 | * Output: true 16 | * 17 | * Example 2: 18 | * Input: A = 'abcde', B = 'abced' 19 | * Output: false 20 | * 21 | * Note: 22 | * 23 | * A and B will have length at most 100. 24 | ***************************************************************************************/ 25 | 26 | /** 27 | * @param {string} A 28 | * @param {string} B 29 | * @return {boolean} 30 | */ 31 | var rotateString = function(A, B) { 32 | return A.length === B.length && (A + A).includes(B) 33 | }; 34 | -------------------------------------------------------------------------------- /algorithms/RotatedDigits.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/rotated-digits 2 | // Author : Dean Shi 3 | // Date : 2018-03-10 4 | 5 | /*************************************************************************************** 6 | * X is a good number if after rotating each digit individually by 180 degrees, we get 7 | * a valid number that is different from X.  Each digit must be rotated - we cannot 8 | * choose to leave it alone. 9 | * 10 | * A number is valid if each digit remains a digit after rotation. 0, 1, and 8 rotate 11 | * to themselves; 2 and 5 rotate to each other; 6 and 9 rotate to each other, and the 12 | * rest of the numbers do not rotate to any other number and become invalid. 13 | * 14 | * Now given a positive number N, how many numbers X from 1 to N are good? 15 | * 16 | * Example: 17 | * Input: 10 18 | * Output: 4 19 | * Explanation: 20 | * There are four good numbers in the range [1, 10] : 2, 5, 6, 9. 21 | * Note that 1 and 10 are not good numbers, since they remain unchanged after rotating. 22 | * 23 | * Note: 24 | * 25 | * N  will be in range [1, 10000]. 26 | * 27 | ***************************************************************************************/ 28 | 29 | /** 30 | * @param {number} N 31 | * @return {number} 32 | */ 33 | var rotatedDigits = function(N) { 34 | const validNumArr = ['2', '5', '6', '9'] 35 | const invalidNumArr = ['3', '4', '7'] 36 | let sum = 0 37 | 38 | for (let i = 1; i <= N; i++) { 39 | const strNum = String(i) 40 | if ( 41 | !invalidNumArr.some((n) => strNum.includes(n)) && 42 | validNumArr.some((n) => strNum.includes(n)) 43 | ) sum++ 44 | } 45 | return sum 46 | }; 47 | -------------------------------------------------------------------------------- /algorithms/SearchInsertPosition.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/search-insert-position/ 2 | // Author : Dean Shi 3 | // Date : 2017-02-25 4 | 5 | /********************************************************************************** 6 | * 7 | * Given a sorted array and a target value, return the index if the target is found. 8 | * If not, return the index where it would be if it were inserted in order. 9 | * 10 | * You may assume no duplicates in the array. 11 | * 12 | * Here are few examples. 13 | * [1,3,5,6], 5 → 2 14 | * [1,3,5,6], 2 → 1 15 | * [1,3,5,6], 7 → 4 16 | * [1,3,5,6], 0 → 0 17 | * 18 | * 19 | **********************************************************************************/ 20 | 21 | /** 22 | * Iteration 23 | * @param {number[]} nums 24 | * @param {number} target 25 | * @return {number} 26 | */ 27 | var searchInsert = function(nums, target) { 28 | let mid, head = 0, tail = nums.length - 1 29 | while (head <= tail) { 30 | mid = (head + tail) >> 1 31 | 32 | if (nums[mid] === target) return mid 33 | if (nums[mid] < target) head = mid + 1 34 | if (nums[mid] > target) tail = mid - 1 35 | } 36 | return head 37 | }; 38 | 39 | /** 40 | * Recursion 41 | * @param {number[]} nums 42 | * @param {number} target 43 | * @return {number} 44 | */ 45 | var searchInsert = function(nums, target) { 46 | return helper(nums, target, 0, nums.length - 1) 47 | }; 48 | 49 | function helper(arr, target, head, tail) { 50 | if (head > tail) return head 51 | 52 | let mid = (head + tail) >> 1 53 | 54 | if (arr[mid] === target) return mid 55 | if (arr[mid] < target) return helper(arr, target, mid + 1, tail) 56 | if (arr[mid] > target) return helper(arr, target, head, mid - 1) 57 | } 58 | 59 | -------------------------------------------------------------------------------- /algorithms/SetMismatch.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/set-mismatch 2 | // Author : Dean Shi 3 | // Date : 2017-07-25 4 | 5 | /*************************************************************************************** 6 | * 7 | * The set S originally contains numbers from 1 to n. But unfortunately, due to the 8 | * data error, one of the numbers in the set got duplicated to another number in the 9 | * set, which results in repetition of one number and loss of another number. 10 | * 11 | * Given an array nums representing the data status of this set after the error. Your 12 | * task is to firstly find the number occurs twice and then find the number that is 13 | * missing. Return them in the form of an array. 14 | * 15 | * Example 1: 16 | * 17 | * Input: nums = [1,2,2,4] 18 | * Output: [2,3] 19 | * 20 | * Note: 21 | * 22 | * The given array size will in the range [2, 10000]. 23 | * The given array's numbers won't have any order. 24 | * 25 | * 26 | ***************************************************************************************/ 27 | 28 | /** 29 | * @param {number[]} nums 30 | * @return {number[]} 31 | */ 32 | var findErrorNums = function(nums) { 33 | const set = new Set() 34 | let duplicate, sum = (nums.length * (nums.length + 1)) / 2 35 | for (let n of nums) { 36 | if (set.has(n)) duplicate = n 37 | else { 38 | sum -= n 39 | set.add(n) 40 | } 41 | } 42 | return [duplicate, sum] 43 | }; 44 | -------------------------------------------------------------------------------- /algorithms/SingleNumber.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/single-number/ 2 | // Author : Dean Shi 3 | // Date : 2015-05-29 4 | 5 | /********************************************************************************** 6 | * 7 | * Given an array of integers, every element appears twice except for one. Find that single one. 8 | * 9 | * Note: 10 | * Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 11 | * 12 | * 13 | **********************************************************************************/ 14 | 15 | /** 16 | * @param {number[]} nums 17 | * @return {number} 18 | */ 19 | var singleNumber = function(nums) { 20 | // Solution 1: 21 | // Runtime: 164 ms 22 | return nums.reduce(function(pre, cur) { 23 | return pre ^ cur; 24 | }); 25 | 26 | // Solution 2: 27 | // Runtime: 140 ms 28 | // var res; 29 | // for (var i in nums) { 30 | // res ^= nums[i]; 31 | // } 32 | // return res; 33 | 34 | // Solution 3: 35 | // Runtime: 128 ms 36 | // var res = nums[0]; 37 | // for (var i = 1, l = nums.length; i < l; ++i) { 38 | // res ^= nums[i]; 39 | // } 40 | // return res; 41 | }; 42 | 43 | var testCase = [1, 1, 2, 2, 3]; 44 | 45 | console.log(singleNumber(testCase) === 3); // true 46 | -------------------------------------------------------------------------------- /algorithms/SortArrayByParity.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/sort-array-by-parity 2 | // Author : Dean Shi 3 | // Date : 2019-06-30 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an array A of non-negative integers, return an array consisting of all the 8 | * even elements of A, followed by all the odd elements of A. 9 | * 10 | * You may return any answer array that satisfies this condition. 11 | * 12 | * Example 1: 13 | * 14 | * Input: [3,1,2,4] 15 | * Output: [2,4,3,1] 16 | * The outputs [4,2,3,1], [2,4,1,3], and [4,2,1,3] would also be accepted. 17 | * 18 | * Note: 19 | * 20 | * 1 <= A.length <= 5000 21 | * 0 <= A[i] <= 5000 22 | * 23 | ***************************************************************************************/ 24 | 25 | /** 26 | * @param {number[]} A 27 | * @return {number[]} 28 | */ 29 | var sortArrayByParity = function(A) { 30 | return [...A.filter(n => !(n % 2)), ...A.filter(n => n % 2)] 31 | }; 32 | -------------------------------------------------------------------------------- /algorithms/SortArrayByParity_II.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/sort-array-by-parity-ii 2 | // Author : Dean Shi 3 | // Date : 2018-11-12 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an array A of non-negative integers, half of the integers in A are odd, and 8 | * half of the integers are even. 9 | * 10 | * Sort the array so that whenever A[i] is odd, i is odd; and whenever A[i] is even, i 11 | * is even. 12 | * 13 | * You may return any answer array that satisfies this condition. 14 | * 15 | * Example 1: 16 | * 17 | * Input: [4,2,5,7] 18 | * Output: [4,5,2,7] 19 | * Explanation: [4,7,2,5], [2,5,4,7], [2,7,4,5] would also have been accepted. 20 | * 21 | * Note: 22 | * 23 | * 2 <= A.length <= 20000 24 | * A.length % 2 == 0 25 | * 0 <= A[i] <= 1000 26 | * 27 | * 28 | ***************************************************************************************/ 29 | 30 | /** 31 | * @param {number[]} A 32 | * @return {number[]} 33 | */ 34 | var sortArrayByParityII = function(A) { 35 | const oddList = A.filter(n => n % 2 === 1) 36 | const evenList = A.filter(n => n % 2 === 0) 37 | 38 | const result = [] 39 | let len = oddList.length 40 | 41 | while (len--) { 42 | result.push( 43 | evenList.pop(), 44 | oddList.pop() 45 | ) 46 | } 47 | return result 48 | }; 49 | -------------------------------------------------------------------------------- /algorithms/SqrtX.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/sqrtx 2 | // Author : Dean Shi 3 | // Date : 2017-07-10 4 | 5 | /*************************************************************************************** 6 | * 7 | * Implement int sqrt(int x). 8 | * 9 | * Compute and return the square root of x. 10 | * 11 | * 12 | ***************************************************************************************/ 13 | 14 | /** 15 | * @param {number} x 16 | * @return {number} 17 | */ 18 | var mySqrt = function(x) { 19 | let r = x 20 | while (r * r > x) r = ((r + x / r) / 2) | 0 21 | return r 22 | }; 23 | -------------------------------------------------------------------------------- /algorithms/SquaresOfASortedArray.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/squares-of-a-sorted-array 2 | // Author : Dean Shi 3 | // Date : 2019-06-30 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an array of integers A sorted in non-decreasing order, return an array of the 8 | * squares of each number, also in sorted non-decreasing order. 9 | * 10 | * Example 1: 11 | * 12 | * Input: [-4,-1,0,3,10] 13 | * Output: [0,1,9,16,100] 14 | * 15 | * Example 2: 16 | * 17 | * Input: [-7,-3,2,3,11] 18 | * Output: [4,9,9,49,121] 19 | * 20 | * Note: 21 | * 22 | * 1 <= A.length <= 10000 23 | * -10000 <= A[i] <= 10000 24 | * A is sorted in non-decreasing order. 25 | * 26 | ***************************************************************************************/ 27 | 28 | /** 29 | * @param {number[]} A 30 | * @return {number[]} 31 | */ 32 | var sortedSquares = function(A) { 33 | return A.map(n => n * n).sort((a, b) => a - b) 34 | }; 35 | -------------------------------------------------------------------------------- /algorithms/StudentAttendanceRecord_I.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/student-attendance-record-i 2 | // Author : Dean Shi 3 | // Date : 2017-04-17 4 | 5 | /*************************************************************************************** 6 | * 7 | * You are given a string representing an attendance record for a student. The record 8 | * only contains the following three characters: 9 | * 10 | * 'A' : Absent. 11 | * 'L' : Late. 12 | * 'P' : Present. 13 | * 14 | * A student could be rewarded if his attendance record doesn't contain more than one 15 | * 'A' (absent) or more than two continuous 'L' (late). 16 | * 17 | * You need to return whether the student could be rewarded according to his attendance 18 | * record. 19 | * 20 | * Example 1: 21 | * 22 | * Input: "PPALLP" 23 | * Output: True 24 | * 25 | * Example 2: 26 | * 27 | * Input: "PPALLL" 28 | * Output: False 29 | * 30 | * 31 | ***************************************************************************************/ 32 | 33 | /** 34 | * @param {string} s 35 | * @return {boolean} 36 | */ 37 | var checkRecord = function(s) { 38 | return s.split('A').length <= 2 && s.indexOf('LLL') === -1 39 | }; 40 | -------------------------------------------------------------------------------- /algorithms/SumOfDigitsInBaseK.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/sum-of-digits-in-base-k 2 | // Author : Dean Shi 3 | // Date : 2021-05-01 4 | 5 | /*************************************************************************************** 6 | * Given an integer n (in base 10) and a base k, return the sum of the digits of n 7 | * after converting n from base 10 to base k. 8 | * 9 | * After converting, each digit should be interpreted as a base 10 number, and the sum 10 | * should be returned in base 10. 11 | * 12 | * Example 1: 13 | * 14 | * Input: n = 34, k = 6 15 | * Output: 9 16 | * Explanation: 34 (base 10) expressed in base 6 is 54. 5 + 4 = 9. 17 | * 18 | * Example 2: 19 | * 20 | * Input: n = 10, k = 10 21 | * Output: 1 22 | * Explanation: n is already in base 10. 1 + 0 = 1. 23 | * 24 | * Constraints: 25 | * 26 | * 1 <= n <= 100 27 | * 2 <= k <= 10 28 | * 29 | * 30 | ***************************************************************************************/ 31 | 32 | /** 33 | * @param {number} n 34 | * @param {number} k 35 | * @return {number} 36 | */ 37 | var sumBase = function(n, k) { 38 | return n.toString(k).split('').reduce((sum, n) => +n + sum, 0) 39 | }; 40 | -------------------------------------------------------------------------------- /algorithms/SumOfLeftLeaves.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/sum-of-left-leaves 2 | // Author : Dean Shi 3 | // Date : 2017-09-09 4 | 5 | /*************************************************************************************** 6 | * 7 | * Find the sum of all left leaves in a given binary tree. 8 | * 9 | * Example: 10 | * 11 | * 3 12 | * / \ 13 | * 9 20 14 | * / \ 15 | * 15 7 16 | * 17 | * There are two left leaves in the binary tree, with values 9 and 15 respectively. 18 | * Return 24. 19 | * 20 | * 21 | ***************************************************************************************/ 22 | 23 | /** 24 | * Definition for a binary tree node. 25 | * function TreeNode(val) { 26 | * this.val = val; 27 | * this.left = this.right = null; 28 | * } 29 | */ 30 | /** 31 | * @param {TreeNode} root 32 | * @return {number} 33 | */ 34 | var sumOfLeftLeaves = function(root) { 35 | let sum = 0 36 | const stack = [root] 37 | 38 | while (node = stack.pop()) { 39 | if (node.left) { 40 | if (!node.left.left && !node.left.right) { 41 | sum += node.left.val 42 | } 43 | stack.push(node.left) 44 | } 45 | if (node.right) { 46 | stack.push(node.right) 47 | } 48 | } 49 | return sum 50 | }; 51 | -------------------------------------------------------------------------------- /algorithms/SumOfSquareNumbers.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/sum-of-square-numbers 2 | // Author : Dean Shi 3 | // Date : 2017-07-09 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a non-negative integer c, your task is to decide whether there're two integers 8 | * a and b such that a2 + b2 = c. 9 | * 10 | * Example 1: 11 | * 12 | * Input: 5 13 | * Output: True 14 | * Explanation: 1 * 1 + 2 * 2 = 5 15 | * 16 | * Example 2: 17 | * 18 | * Input: 3 19 | * Output: False 20 | * 21 | * 22 | ***************************************************************************************/ 23 | 24 | /** 25 | * @param {number} c 26 | * @return {boolean} 27 | */ 28 | var judgeSquareSum = function(c) { 29 | const limit = Math.sqrt(c) 30 | 31 | for (let i = 0; i <= limit; i++) { 32 | if (Number.isInteger(Math.sqrt(c - i ** 2))) return true 33 | } 34 | return false 35 | }; 36 | -------------------------------------------------------------------------------- /algorithms/SwapNodesInPairs.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/swap-nodes-in-pairs/ 2 | // Author : Dean Shi 3 | // Date : 2017-07-05 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a linked list, swap every two adjacent nodes and return its head. 8 | * 9 | * For example, 10 | * Given 1->2->3->4, you should return the list as 2->1->4->3. 11 | * 12 | * Your algorithm should use only constant space. You may not modify the values in the 13 | * list, only nodes itself can be changed. 14 | * 15 | * 16 | ***************************************************************************************/ 17 | 18 | /** 19 | * Definition for singly-linked list. 20 | * function ListNode(val) { 21 | * this.val = val; 22 | * this.next = null; 23 | * } 24 | */ 25 | /** 26 | * @param {ListNode} head 27 | * @return {ListNode} 28 | */ 29 | var swapPairs = function(head) { 30 | if (head && head.next) { 31 | const next = head.next 32 | 33 | head.next = swapPairs(next.next) 34 | next.next = head 35 | return next 36 | } 37 | return head 38 | }; 39 | -------------------------------------------------------------------------------- /algorithms/SymmetricTree.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/symmetric-tree 2 | // Author : Dean Shi 3 | // Date : 2017-03-17 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a binary tree, check whether it is a mirror of itself (ie, symmetric around 8 | * its center). 9 | * 10 | * For example, this binary tree [1,2,2,3,4,4,3] is symmetric: 11 | * 12 | * 1 13 | * / \ 14 | * 2 2 15 | * / \ / \ 16 | * 3 4 4 3 17 | * 18 | * But the following [1,2,2,null,3,null,3] is not: 19 | * 20 | * 1 21 | * / \ 22 | * 2 2 23 | * \ \ 24 | * 3 3 25 | * 26 | * Note: 27 | * Bonus points if you could solve it both recursively and iteratively. 28 | * 29 | * 30 | ***************************************************************************************/ 31 | 32 | /** 33 | * Definition for a binary tree node. 34 | * function TreeNode(val) { 35 | * this.val = val; 36 | * this.left = this.right = null; 37 | * } 38 | */ 39 | /** 40 | * @param {TreeNode} root 41 | * @return {boolean} 42 | */ 43 | var isSymmetric = function(root) { 44 | if (!root) return true 45 | return JSON.stringify(helper(root.left)) === JSON.stringify(helper(root.right).reverse()) 46 | && (root.left && root.left.val) === (root.right && root.right.val) 47 | }; 48 | 49 | function helper(root, arr = []) { 50 | if (root) { 51 | helper(root.left, arr) 52 | arr.push(root.val) 53 | helper(root.right, arr) 54 | } 55 | return arr 56 | } 57 | -------------------------------------------------------------------------------- /algorithms/ThirdMaximumNumber.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/third-maximum-number 2 | // Author : Dean Shi 3 | // Date : 2020-04-17 4 | 5 | /*************************************************************************************** 6 | * Given a non-empty array of integers, return the third maximum number in this array. 7 | * If it does not exist, return the maximum number. The time complexity must be in O(n). 8 | * 9 | * Example 1: 10 | * Input: [3, 2, 1] 11 | * 12 | * Output: 1 13 | * 14 | * Explanation: The third maximum is 1. 15 | * 16 | * Example 2: 17 | * Input: [1, 2] 18 | * 19 | * Output: 2 20 | * 21 | * Explanation: The third maximum does not exist, so the maximum (2) is returned 22 | * instead. 23 | * 24 | * Example 3: 25 | * Input: [2, 2, 3, 1] 26 | * 27 | * Output: 1 28 | * 29 | * Explanation: Note that the third maximum here means the third maximum distinct 30 | * number. 31 | * Both numbers with value 2 are both considered as second maximum. 32 | * 33 | * 34 | ***************************************************************************************/ 35 | 36 | /** 37 | * @param {number[]} nums 38 | * @return {number} 39 | */ 40 | var thirdMax = function(nums) { 41 | const list = [] 42 | 43 | for (let num of new Set(nums)) { 44 | list.push(num) 45 | list.sort((a, b) => b - a) 46 | 47 | if (list.length > 3) { 48 | list.pop() 49 | } 50 | } 51 | 52 | return list.length === 3 ? list.pop() : list.shift() 53 | }; 54 | -------------------------------------------------------------------------------- /algorithms/ToLowerCase.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/to-lower-case 2 | // Author : Dean Shi 3 | // Date : 2018-08-27 4 | 5 | /*************************************************************************************** 6 | * Implement function ToLowerCase() that has a string parameter str, and returns the 7 | * same string in lowercase. 8 | * 9 | * Example 1: 10 | * 11 | * Input: "Hello" 12 | * Output: "hello" 13 | * 14 | * Example 2: 15 | * 16 | * Input: "here" 17 | * Output: "here" 18 | * 19 | * Example 3: 20 | * 21 | * Input: "LOVELY" 22 | * Output: "lovely" 23 | * 24 | ***************************************************************************************/ 25 | 26 | /** 27 | * @param {string} str 28 | * @return {string} 29 | */ 30 | var toLowerCase = function(str) { 31 | const result = [] 32 | 33 | for (let i = 0; i < str.length; i++) { 34 | result.push( 35 | 'A' <= str[i] && str[i] <= 'Z' 36 | ? String.fromCharCode(str.charCodeAt(i) + 32) 37 | : str[i] 38 | ) 39 | } 40 | return result.join('') 41 | }; 42 | -------------------------------------------------------------------------------- /algorithms/TwoSum.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/two-sum/ 2 | // Author : Dean Shi 3 | // Date : 2015-05-30 4 | 5 | /********************************************************************************** 6 | * 7 | * Given an array of integers, find two numbers such that they add up to a specific target number. 8 | * 9 | * The function twoSum should return indices of the two numbers such that they add up to the target, 10 | * where index1 must be less than index2. Please note that your returned answers (both index1 and index2) 11 | * are not zero-based. 12 | * 13 | * You may assume that each input would have exactly one solution. 14 | * 15 | * Input: numbers={2, 7, 11, 15}, target=9 16 | * Output: index1=1, index2=2 17 | * 18 | **********************************************************************************/ 19 | 20 | /** 21 | * @param {number[]} nums 22 | * @param {number} target 23 | * @return {number[]} 24 | */ 25 | var twoSum = function(nums, target) { 26 | const hash = {} 27 | 28 | for (let [i, n] of nums.entries()) { 29 | if (hash[n] >= 0) { 30 | return [hash[n], i] 31 | } 32 | hash[target - n] = i 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /algorithms/TwoSum_II.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/two-sum-ii-input-array-is-sorted 2 | // Author : Dean Shi 3 | // Date : 2017-07-11 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given an array of integers that is already sorted in ascending order, find two 8 | * numbers such that they add up to a specific target number. 9 | * 10 | * The function twoSum should return indices of the two numbers such that they add up 11 | * to the target, where index1 must be less than index2. Please note that your returned 12 | * answers (both index1 and index2) are not zero-based. 13 | * 14 | * You may assume that each input would have exactly one solution and you may not use 15 | * the same element twice. 16 | * 17 | * Input: numbers={2, 7, 11, 15}, target=9 18 | * Output: index1=1, index2=2 19 | * 20 | * 21 | ***************************************************************************************/ 22 | 23 | /** 24 | * @param {number[]} numbers 25 | * @param {number} target 26 | * @return {number[]} 27 | */ 28 | var twoSum = function(numbers, target) { 29 | let sum, p1 = 0, p2 = numbers.length - 1 30 | 31 | while ((sum = numbers[p1] + numbers[p2]) !== target) sum < target ? ++p1 : --p2 32 | 33 | return [p1 + 1, p2 + 1] 34 | }; 35 | -------------------------------------------------------------------------------- /algorithms/TwoSum_IV.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/two-sum-iv-input-is-a-bst 2 | // Author : Dean Shi 3 | // Date : 2017-08-09 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a Binary Search Tree and a target number, return true if there exist two 8 | * elements in the BST such that their sum is equal to the given target. 9 | * 10 | * Example 1: 11 | * 12 | * Input: 13 | * 5 14 | * / \ 15 | * 3 6 16 | * / \ \ 17 | * 2 4 7 18 | * 19 | * Target = 9 20 | * 21 | * Output: True 22 | * 23 | * Example 2: 24 | * 25 | * Input: 26 | * 5 27 | * / \ 28 | * 3 6 29 | * / \ \ 30 | * 2 4 7 31 | * 32 | * Target = 28 33 | * 34 | * Output: False 35 | * 36 | * 37 | ***************************************************************************************/ 38 | 39 | /** 40 | * Definition for a binary tree node. 41 | * function TreeNode(val) { 42 | * this.val = val; 43 | * this.left = this.right = null; 44 | * } 45 | */ 46 | /** 47 | * @param {TreeNode} root 48 | * @param {number} k 49 | * @return {boolean} 50 | */ 51 | var findTarget = function(root, k, map = new Set()) { 52 | if (!root) return false 53 | if (map.has(root.val)) return true 54 | 55 | map.add(k - root.val) 56 | return findTarget(root.left, k, map) || findTarget(root.right, k, map) 57 | }; 58 | -------------------------------------------------------------------------------- /algorithms/UglyNumber.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/ugly-number 2 | // Author : Dean Shi 3 | // Date : 2017-10-20 4 | 5 | /*************************************************************************************** 6 | * 7 | * Write a program to check whether a given number is an ugly number. 8 | * 9 | * Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For 10 | * example, 6, 8 are ugly while 14 is not ugly since it includes another prime factor 7. 11 | * 12 | * Note that 1 is typically treated as an ugly number. 13 | * 14 | * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating 15 | * all test cases. 16 | * 17 | ***************************************************************************************/ 18 | 19 | /** 20 | * @param {number} num 21 | * @return {boolean} 22 | */ 23 | var isUgly = function(num) { 24 | for (const p of [2, 3, 5]) { 25 | while (num && num % p === 0) num /= p 26 | } 27 | return num === 1 28 | }; 29 | -------------------------------------------------------------------------------- /algorithms/UncommonWordsFromTwoSentences.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/uncommon-words-from-two-sentences 2 | // Author : Dean Shi 3 | // Date : 2018-08-13 4 | 5 | /*************************************************************************************** 6 | * We are given two sentences A and B.  (A sentence is a string of space separated 7 | * words.  Each word consists only of lowercase letters.) 8 | * 9 | * A word is uncommon if it appears exactly once in one of the sentences, and does not 10 | * appear in the other sentence. 11 | * 12 | * Return a list of all uncommon words. 13 | * 14 | * You may return the list in any order. 15 | * 16 | * Example 1: 17 | * 18 | * Input: A = "this apple is sweet", B = "this apple is sour" 19 | * Output: ["sweet","sour"] 20 | * 21 | * Example 2: 22 | * 23 | * Input: A = "apple apple", B = "banana" 24 | * Output: ["banana"] 25 | * 26 | * Note: 27 | * 28 | * 0 <= A.length <= 200 29 | * 0 <= B.length <= 200 30 | * A and B both contain only spaces and lowercase letters. 31 | * 32 | ***************************************************************************************/ 33 | 34 | /** 35 | * @param {string} A 36 | * @param {string} B 37 | * @return {string[]} 38 | */ 39 | var uncommonFromSentences = function(A, B) { 40 | const wordList = A.split(' ').concat(B.split(' ')) 41 | const table = {} 42 | 43 | wordList.forEach((word) => { 44 | if (table[word]) ++table[word] 45 | else table[word] = 1 46 | }) 47 | 48 | return Object 49 | .entries(table) 50 | .filter(([word, count]) => count === 1 && word !== '') 51 | .map(([word]) => word) 52 | }; 53 | -------------------------------------------------------------------------------- /algorithms/UnivaluedBinaryTree.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/univalued-binary-tree/ 2 | // Author : Dean Shi 3 | // Date : 2019-01-10 4 | 5 | /*************************************************************************************** 6 | * 7 | * A binary tree is univalued if every node in the tree has the same value. 8 | * 9 | * Return true if and only if the given tree is univalued. 10 | * 11 | * Example 1: 12 | * 13 | * Input: [1,1,1,1,1,null,1] 14 | * Output: true 15 | * 16 | * Example 2: 17 | * 18 | * Input: [2,2,2,5,2] 19 | * Output: false 20 | * 21 | * Note: 22 | * 23 | * The number of nodes in the given tree will be in the range [1, 100]. 24 | * Each node's value will be an integer in the range [0, 99]. 25 | * 26 | ***************************************************************************************/ 27 | 28 | /** 29 | * Definition for a binary tree node. 30 | * function TreeNode(val) { 31 | * this.val = val; 32 | * this.left = this.right = null; 33 | * } 34 | */ 35 | /** 36 | * @param {TreeNode} root 37 | * @return {boolean} 38 | */ 39 | var isUnivalTree = function(root) { 40 | const valSet = new Set([root.val]) 41 | 42 | const stack = [root] 43 | while (stack.length) { 44 | const node = stack.pop() 45 | 46 | if (!valSet.has(node.val)) { 47 | return false 48 | } 49 | if (node.left) { 50 | stack.push(node.left) 51 | } 52 | if (node.right) { 53 | stack.push(node.right) 54 | } 55 | } 56 | return true 57 | }; 58 | -------------------------------------------------------------------------------- /algorithms/ValidPalindrome_II.js: -------------------------------------------------------------------------------- 1 | // Source : https://leetcode.com/problems/valid-palindrome-ii 2 | // Author : Dean Shi 3 | // Date : 2017-09-21 4 | 5 | /*************************************************************************************** 6 | * 7 | * Given a non-empty string s, you may delete at most one character. Judge whether you 8 | * can make it a palindrome 9 | * 10 | * Example 1 11 | * Input: "aba 12 | * Output: True 13 | * 14 | * Example 2 15 | * Input: "abca 16 | * Output: True 17 | * Explanation: You could delete the character 'c 18 | * 19 | * Note 20 | * 21 | * The string will only contain lowercase characters a-z 22 | * The maximum length of the string is 50000 23 | * 24 | ***************************************************************************************/ 25 | 26 | /** 27 | * @param {string} s 28 | * @return {boolean} 29 | */ 30 | var validPalindrome = function(s) { 31 | let left = 0, right = s.length - 1 32 | 33 | while (left < right) { 34 | if (s[left] !== s[right]) { 35 | return removeCharAndCheck(s, left, right - 1) 36 | || removeCharAndCheck(s, left + 1, right) 37 | } 38 | ++left 39 | --right 40 | } 41 | return true 42 | }; 43 | 44 | function removeCharAndCheck(s, left, right) { 45 | while (left < right) { 46 | if (s[left++] !== s[right--]) return false 47 | } 48 | return true 49 | } 50 | -------------------------------------------------------------------------------- /algorithms/ValidParentheses.js: -------------------------------------------------------------------------------- 1 | // Source : https://oj.leetcode.com/problems/valid-parentheses/ 2 | // Author : Dean Shi 3 | // Date : 2015-06-11 4 | 5 | /********************************************************************************** 6 | * 7 | * Given a string containing just the characters '(', ')', '{', '}', '[' and ']', 8 | * determine if the input string is valid. 9 | * 10 | * The brackets must close in the correct order, "()" and "()[]{}" are all valid 11 | * but "(]" and "([)]" are not. 12 | * 13 | * 14 | **********************************************************************************/ 15 | 16 | /** 17 | * @param {string} s 18 | * @return {boolean} 19 | */ 20 | var isValid = function(s) { 21 | const stack = [] 22 | const openChars = new Set('({['); 23 | const closeChars = { 24 | '(': ')', 25 | '{': '}', 26 | '[': ']', 27 | } 28 | 29 | for (let ch of s) { 30 | if (openChars.has(ch)) { 31 | stack.push(ch) 32 | } else if (closeChars[stack.pop()] !== ch) { 33 | return false 34 | } 35 | } 36 | 37 | return stack.length === 0 38 | }; 39 | 40 | // Test cases 41 | console.log(isValid('()[]{}')); // true 42 | console.log(isValid('(]')); // false 43 | console.log(isValid('([)]')); // false 44 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leetcode", 3 | "version": "1.0.0", 4 | "type": "module", 5 | "description": "LeetCode Solutions", 6 | "main": "./scripts/index.js", 7 | "repository": "git@github.com:dnshi/Leetcode.git", 8 | "author": "Dean Shi", 9 | "email": "dean.xiaoshi@gmail.com", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "eslint": "^8.56.0", 13 | "prettier": "^3.1.1", 14 | "puppeteer": "^21.6.1" 15 | }, 16 | "engines": { 17 | "node": ">=18.0.0" 18 | }, 19 | "scripts": { 20 | "start": "node ./scripts $(git status --short | grep -oE \"[^ ]*(algorithms|shell|sql).*$\")" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /scripts/README.md: -------------------------------------------------------------------------------- 1 | # Comment & Readme Generator 2 | 3 | The Node.js script is to generate: 4 | - comment header in your target source file 5 | - a table row in your README.md 6 | 7 | ### Commands 8 | 9 | 1) Install Node packages 10 | ``` 11 | npm install 12 | ``` 13 | 14 | 2) Add Leetcode url to the **FIRST** line of your source file. The format should be same as the following one: 15 | ```js 16 | https://leetcode.com/problems/two-sum/description/ 17 | 18 | /** 19 | * @param {number[]} nums 20 | * @param {number} target 21 | * @return {number[]} 22 | */ 23 | var twoSum = function(nums, target) { 24 | }; 25 | ``` 26 | 27 | 3) Run the following command in your terminal 28 | ``` 29 | npm start 30 | ``` 31 | -------------------------------------------------------------------------------- /shell/TenthLine.sh: -------------------------------------------------------------------------------- 1 | # Source : https://leetcode.com/problems/tenth-line/ 2 | # Author : Dean Shi 3 | # Date : 2015-05-29 4 | 5 | ################################################################################## 6 | # 7 | # How would you print just the 10th line of a file? 8 | # 9 | # For example, assume that file.txt has the following content: 10 | # 11 | # Line 1 12 | # Line 2 13 | # Line 3 14 | # Line 4 15 | # Line 5 16 | # Line 6 17 | # Line 7 18 | # Line 8 19 | # Line 9 20 | # Line 10 21 | # 22 | # Your script should output the tenth line, which is: 23 | # 24 | # Line 10 25 | # 26 | # [show hint] 27 | # Hint: 28 | # 1. If the file contains less than 10 lines, what should you output? 29 | # 2. There's at least three different solutions. Try to explore all possibilities. 30 | # 31 | ################################################################################## 32 | 33 | #!/bin/sh 34 | 35 | 36 | # Read from the file file.txt and output the tenth line to stdout. 37 | cat file.txt | sed -n 10p 38 | 39 | # or 40 | 41 | sed -n 10p file.txt 42 | 43 | -------------------------------------------------------------------------------- /shell/ValidPhoneNumbers.sh: -------------------------------------------------------------------------------- 1 | # Source : https://leetcode.com/problems/valid-phone-numbers 2 | # Author : Dean Shi 3 | # Date : 2017-09-05 4 | 5 | ################################################################################## 6 | # 7 | # Given a text file file.txt that contains list of phone numbers (one per line), write 8 | # a one liner bash script to print all valid phone numbers. 9 | # 10 | # You may assume that a valid phone number must appear in one of the following two 11 | # formats: (xxx) xxx-xxxx or xxx-xxx-xxxx. (x means a digit) 12 | # 13 | # You may also assume each line in the text file must not contain leading or trailing 14 | # 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 | # 22 | # Your script should output the following valid phone numbers: 23 | # 24 | # 987-123-4567 25 | # (123) 456-7890 26 | # 27 | ################################################################################## 28 | 29 | #!/bin/sh 30 | 31 | 32 | # Read from the file file.txt and output all valid phone numbers to stdout. 33 | grep -P '^(\(\d{3}\) |\d{3}-)\d{3}-\d{4}$' file.txt 34 | -------------------------------------------------------------------------------- /sql/BigCountries.sql: -------------------------------------------------------------------------------- 1 | # Source : https://leetcode.com/problems/big-countries 2 | # Author : Dean Shi 3 | # Date : 2017-08-16 4 | 5 | ################################################################################## 6 | # 7 | # There is a table World 8 | # 9 | # +-----------------+------------+------------+--------------+---------------+ 10 | # | name | continent | area | population | gdp | 11 | # +-----------------+------------+------------+--------------+---------------+ 12 | # | Afghanistan | Asia | 652230 | 25500100 | 20343000 | 13 | # | Albania | Europe | 28748 | 2831741 | 12960000 | 14 | # | Algeria | Africa | 2381741 | 37100000 | 188681000 | 15 | # | Andorra | Europe | 468 | 78115 | 3712000 | 16 | # | Angola | Africa | 1246700 | 20609294 | 100990000 | 17 | # +-----------------+------------+------------+--------------+---------------+ 18 | # 19 | # A country is big if it has an area of bigger than 3 million square km or a 20 | # population of more than 25 million. 21 | # 22 | # Write a SQL solution to output big countries' name, population and area. 23 | # 24 | # For example, according to the above table, we should output: 25 | # 26 | # +--------------+-------------+--------------+ 27 | # | name | population | area | 28 | # +--------------+-------------+--------------+ 29 | # | Afghanistan | 25500100 | 652230 | 30 | # | Algeria | 37100000 | 2381741 | 31 | # +--------------+-------------+--------------+ 32 | # 33 | ################################################################################## 34 | 35 | SELECT name, population, area FROM World WHERE area > 3000000 OR population > 25000000 36 | -------------------------------------------------------------------------------- /sql/ClassesMoreThan5Students.sql: -------------------------------------------------------------------------------- 1 | # Source : https://leetcode.com/problems/classes-more-than-5-students 2 | # Author : Dean Shi 3 | # Date : 2017-08-16 4 | 5 | ################################################################################## 6 | # 7 | # There is a table courses with columns: student and class 8 | # 9 | # Please list out all classes which have more than or equal to 5 students. 10 | # 11 | # For example, the table: 12 | # 13 | # +---------+------------+ 14 | # | student | class | 15 | # +---------+------------+ 16 | # | A | Math | 17 | # | B | English | 18 | # | C | Math | 19 | # | D | Biology | 20 | # | E | Math | 21 | # | F | Computer | 22 | # | G | Math | 23 | # | H | Math | 24 | # | I | Math | 25 | # +---------+------------+ 26 | # 27 | # Should output: 28 | # 29 | # +---------+ 30 | # | class | 31 | # +---------+ 32 | # | Math | 33 | # +---------+ 34 | # 35 | # Note: 36 | # The students should not be counted duplicate in each course. 37 | # 38 | ################################################################################## 39 | 40 | SELECT class FROM courses GROUP BY class HAVING COUNT(DISTINCT student) >= 5 41 | -------------------------------------------------------------------------------- /sql/NotBoringMovies.sql: -------------------------------------------------------------------------------- 1 | # Source : https://leetcode.com/problems/not-boring-movies 2 | # Author : Dean Shi 3 | # Date : 2017-08-15 4 | 5 | ################################################################################## 6 | # 7 | # X city opened a new cinema, many people would like to go to this cinema. 8 | # The cinema also gives out a poster indicating the movies’ ratings and descriptions. 9 | # 10 | # Please write a SQL query to output movies with an odd numbered ID and a description 11 | # that is not 'boring'. Order the result by rating. 12 | # 13 | # For example, table cinema: 14 | # 15 | # +---------+-----------+--------------+-----------+ 16 | # | id | movie | description | rating | 17 | # +---------+-----------+--------------+-----------+ 18 | # | 1 | War | great 3D | 8.9 | 19 | # | 2 | Science | fiction | 8.5 | 20 | # | 3 | irish | boring | 6.2 | 21 | # | 4 | Ice song | Fantacy | 8.6 | 22 | # | 5 | House card| Interesting| 9.1 | 23 | # +---------+-----------+--------------+-----------+ 24 | # 25 | # For the example above, the output should be: 26 | # 27 | # +---------+-----------+--------------+-----------+ 28 | # | id | movie | description | rating | 29 | # +---------+-----------+--------------+-----------+ 30 | # | 5 | House card| Interesting| 9.1 | 31 | # | 1 | War | great 3D | 8.9 | 32 | # +---------+-----------+--------------+-----------+ 33 | # 34 | ################################################################################## 35 | 36 | SELECT * From cinema WHERE mod(id, 2) = 1 AND description <> 'boring' ORDER BY rating DESC 37 | -------------------------------------------------------------------------------- /sql/SwapSalary.sql: -------------------------------------------------------------------------------- 1 | # Source : https://leetcode.com/problems/swap-salary 2 | # Author : Dean Shi 3 | # Date : 2017-08-15 4 | 5 | ################################################################################## 6 | # 7 | # Given a table salary, such as the one below, that has m=male and f=female values. 8 | # Swap all f and m values (i.e., change all f values to m and vice versa) with a 9 | # single update query and no intermediate temp table. 10 | # 11 | # For example: 12 | # 13 | # 14 | # | id | name | sex | salary | 15 | # |----|------|-----|--------| 16 | # | 1 | A | m | 2500 | 17 | # | 2 | B | f | 1500 | 18 | # | 3 | C | m | 5500 | 19 | # | 4 | D | f | 500 | 20 | # 21 | # After running your query, the above salary table should have the following rows: 22 | # 23 | # | id | name | sex | salary | 24 | # |----|------|-----|--------| 25 | # | 1 | A | f | 2500 | 26 | # | 2 | B | m | 1500 | 27 | # | 3 | C | f | 5500 | 28 | # | 4 | D | m | 500 | 29 | # 30 | ################################################################################## 31 | 32 | UPDATE salary SET sex = CHAR(ASCII(sex) ^ 11) 33 | --------------------------------------------------------------------------------