diff --git a/.gitconfig b/.gitconfig new file mode 100644 index 000000000..f7b78e2ba --- /dev/null +++ b/.gitconfig @@ -0,0 +1,5 @@ +[alias] + lg0 = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit -- + lg1 = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all + lg2 = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)' --all + lg = !"git lg0" diff --git a/.gitignore b/.gitignore index 1f1c65c40..25a4d2a65 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .idea algorithms-java/out +*.class diff --git a/README.md b/README.md index 3f71fe9be..863b572d2 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,158 @@ LeetCode ======== -###LeetCode Algorithm +### LeetCode Algorithm (Notes: "♥" means you need to buy a book from Leetcode) | # | Title | Solution | Difficulty | |---| ----- | -------- | ---------- | +|1170|[Compare Strings by Frequency of the Smallest Character](https://leetcode.com/problems/compare-strings-by-frequency-of-the-smallest-character/) | [C++](./algorithms/cpp/compareStringsByFrequencyOfTheSmallestCharacter/CompareStringsByFrequencyOfTheSmallestCharacter.cpp)|Easy| +|1030|[Matrix Cells in Distance Order](https://leetcode.com/problems/matrix-cells-in-distance-order/) | [C++](./algorithms/cpp/matrixCellsInDistanceOrder/MatrixCellsInDistanceOrder.cpp)|Easy| +|1029|[Two City Scheduling](https://leetcode.com/problems/two-city-scheduling/) | [C++](./algorithms/cpp/twoCityScheduling/TwoCityScheduling.cpp)|Easy| +|1028|[Recover a Tree From Preorder Traversal](https://leetcode.com/problems/recover-a-tree-from-preorder-traversal/) | [C++](./algorithms/cpp/recoverATreeFromPreorderTraversal/recoverATreeFromPreorderTraversal.cpp)|Hard| +|1024|[Video Stitching](https://leetcode.com/problems/video-stitching/) | [C++](./algorithms/cpp/videoStitching/VideoStitching.cpp)|Medium| +|993|[Cousins in Binary Tree](https://leetcode.com/problems/cousins-in-binary-tree/) | [C++](./algorithms/cpp/cousinsInBinaryTree/CousinsInBinaryTree.cpp)|Easy| +|991|[Broken Calculator](https://leetcode.com/problems/broken-calculator/) | [C++](./algorithms/cpp/brokenCalculator/BrokenCalculator.cpp)|Medium| +|990|[Satisfiability of Equality Equations](https://leetcode.com/problems/satisfiability-of-equality-equations/) | [C++](./algorithms/cpp/satisfiabilityOfEqualityEquations/SatisfiabilityOfEqualityEquations.cpp)|Medium| +|989|[Add to Array-Form of Integer](https://leetcode.com/problems/add-to-array-form-of-integer/) | [C++](./algorithms/cpp/addToArrayFormOfInteger/AddToArrayFormOfInteger.cpp)|Easy| +|988|[Smallest String Starting From Leaf](https://leetcode.com/problems/smallest-string-starting-from-leaf/) | [C++](./algorithms/cpp/smallestStringStartingFromLeaf/SmallestStringStartingFromLeaf.cpp)|Medium| +|987|[Vertical Order Traversal of a Binary Tree](https://leetcode.com/problems/vertical-order-traversal-of-a-binary-tree/) | [C++](./algorithms/cpp/verticalOrderTraversalOfABinaryTree/VerticalOrderTraversalOfABinaryTree.cpp)|Medium| +|986|[Interval List Intersections](https://leetcode.com/problems/interval-list-intersections/) | [C++](./algorithms/cpp/intervalListIntersectons/IntervalListIntersections.cpp)|Medium| +|985|[Sum of Even Numbers After Queries](https://leetcode.com/problems/sum-of-even-numbers-after-queries/) | [C++](./algorithms/cpp/sumOfEvenNumbersAfterQueries/SumOfEvenNumbersAfterQueries.cpp)|Easy| +|984|[String Without AAA or BBB](https://leetcode.com/problems/string-without-aaa-or-bbb/) | [C++](./algorithms/cpp/stringWithoutAAAOrBBB/StringWithoutAAAOrBBB.cpp)|Easy| +|983|[Minimum Cost For Tickets](https://leetcode.com/problems/minimum-cost-for-tickets/) | [C++](./algorithms/cpp/minimumCostForTickets/MinimumCostForTickets.cpp)|Medium| +|981|[Time Based Key-Value Store](https://leetcode.com/problems/time-based-key-value-store/) | [C++](./algorithms/cpp/timeBasedKeyValueStore/TimeBasedKeyValueStore.cpp)|Medium| +|980|[Unique Paths III](https://leetcode.com/problems/unique-paths-iii/) | [C++](./algorithms/cpp/uniquePaths/UniquePaths.III.cpp)|Hard| +|979|[Distribute Coins in Binary Tree](https://leetcode.com/problems/distribute-coins-in-binary-tree/) | [C++](./algorithms/cpp/distributeCoinsInBinaryTree/DistributeCoinsInBinaryTree.cpp)|Medium| +|978|[Longest Turbulent Subarray](https://leetcode.com/problems/longest-turbulent-subarray/) | [C++](./algorithms/cpp/longestTurbulentSubarray/LongestTurbulentSubarray.cpp),[Python](./algorithms/python/LongestTurbulentSubarray/maxTurbulenceSize.py)|Medium| +|977|[Squares of a Sorted Array](https://leetcode.com/problems/squares-of-a-sorted-array/) | [C++](./algorithms/cpp/squaresOfASortedArray/SquaresOfASortedArray.cpp), [Python](./algorithms/python/SquaresOfSortedArray/sortedSquares.py)|Easy| +|976|[Largest Perimeter Triangle](https://leetcode.com/problems/largest-perimeter-triangle/) | [C++](./algorithms/cpp/largestPerimeterTriangle/largestPerimeterTriangle.cpp), [Python](./algorithms/python/LargestPerimeterTriangle/largestPerimeter.py)|Easy| +|971|[Flip Binary Tree To Match Preorder Traversal](https://leetcode.com/problems/flip-binary-tree-to-match-preorder-traversal/) | [Python](./algorithms/python/FlipBinaryTreeToMatchPreorderTraversal/flipMatchVoyage.py)|Medium| +|969|[Pancake Sorting](https://leetcode.com/problems/pancake-sorting/) | [Python](./algorithms/python/PancakeSorting/pancakeSort.py)|Medium| +|958|[Check Completeness of a Binary Tree](https://leetcode.com/problems/check-completeness-of-a-binary-tree/) | [Python](./algorithms/python/CheckCompletenessOfABinaryTree/isCompleteTree.py)|Medium| +|951|[Flip Equivalent Binary Trees](https://leetcode.com/problems/flip-equivalent-binary-trees/) | [Python](./algorithms/python/FlipEquivalentBinaryTrees/flipEquiv.py)|Medium| +|950|[Reveal Cards In Increasing Order](https://leetcode.com/problems/reveal-cards-in-increasing-order/) | [Python](./algorithms/python/RevealCardsInIncreasingOrder/deckRevealedIncreasing.py)|Medium| +|941|[Valid Mountain Array](https://leetcode.com/problems/valid-mountain-array/) | [Python](./algorithms/python/ValidMountainArray/validMountainArray.py)|Easy| +|931|[Minimum Falling Path Sum](https://leetcode.com/problems/minimum-falling-path-sum/) | [C++](./algorithms/cpp/minimumFallingPathSum/MinimumFallingPathSum.cpp)|Medium| +|922|[Sort Array By Parity II](https://leetcode.com/problems/sort-array-by-parity-ii/) | [C++](./algorithms/cpp/sortArrayByParity/SortArrayByParity.II.cpp)|Easy| +|914|[X of a Kind in a Deck of Cards](https://leetcode.com/problems/x-of-a-kind-in-a-deck-of-cards/) | [Python](./algorithms/python/XOfAKindInADeckOfCards/hasGroupsSizeX.py)|Easy| +|905|[Sort Array By Parity](https://leetcode.com/problems/sort-array-by-parity/) | [C++](./algorithms/cpp/sortArrayByParity/SortArrayByParity.cpp)|Easy| +|859|[Buddy Strings](https://leetcode.com/problems/buddy-strings/description/) | [C++](./algorithms/cpp/buddyStrings/BuddyStrings.cpp)|Easy| +|858|[Mirror Reflection](https://leetcode.com/problems/mirror-reflection/description/) | [C++](./algorithms/cpp/mirrorReflection/MirrorReflection.cpp)|Medium| +|852|[Peak Index in a Mountain Array](https://leetcode.com/problems/peak-index-in-a-mountain-array/description/) | [C++](./algorithms/cpp/peakIndexInAMountainArray/PeakIndexInAMountainArray.cpp)|Easy| +|849|[Maximize Distance to Closest Person](https://leetcode.com/problems/maximize-distance-to-closest-person/) | [Python](./algorithms/python/MaximizeDistanceToClosestPerson/maxDistToClosest.py)|Easy| +|844|[Backspace String Compare](https://leetcode.com/problems/backspace-string-compare/description/) | [C++](./algorithms/cpp/backspaceStringCompare/BackspaceStringCompare.cpp)|Easy| +|837|[Most Common Word](https://leetcode.com/problems/most-common-word/) | [C++](./algorithms/cpp/mostCommonWord/MostCommonWord.cpp)|Easy| +|830|[Positions of Large Groups](https://leetcode.com/problems/positions-of-large-groups/) | [Python](./algorithms/python/PositionsOfLargeGroups/largeGroupPositions.py)|Easy| +|804|[Unique Morse Code Words](https://leetcode.com/problems/unique-morse-code-words/description/) | [C++](./algorithms/cpp/uniqueMorseCodeWords/UniqueMorseCodeWords.cpp)|Easy| +|771|[Jewels and Stones](https://leetcode.com/problems/jewels-and-stones/description) | [C++](./algorithms/cpp/jewelsAndStones/JewelsAndStones.cpp)|Easy| +|747|[Largest Number At Least Twice of Others](https://leetcode.com/problems/largest-number-at-least-twice-of-others/) | [Python](./algorithms/python/LargestNumberAtLeastTwiceOfOthers/dominantIndex.py)|Easy| +|746|[Min Cost Climbing Stairs](https://leetcode.com/problems/min-cost-climbing-stairs/) | [C++](./algorithms/cpp/minCostClimbingStairs/MinCostClimbingStairs.cpp), [Python](./algorithms/python/MinCostClimbingStairs/minCostClimbingStairs.py)|Easy| +|721|[Accounts Merge](https://leetcode.com/problems/accounts-merge/) | [C++](./algorithms/cpp/accountsMerge/AccountsMerge.cpp)|Medium| +|717|[1-bit and 2-bit Characters](https://leetcode.com/problems/1-bit-and-2-bit-characters/) | [Python](./algorithms/python/1-bitAnd2-bitCharacters/isOneBitCharacter.py)|Easy| +|714|[Best Time to Buy and Sell Stock with Transaction Fee](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee) | [C++](./algorithms/cpp/bestTimeToBuyAndSellStock/BestTimeToBuyAndSellStockWithTransactionFee.cpp)|Medium| +|712|[Minimum ASCII Delete Sum for Two Strings](https://leetcode.com/problems/minimum-ascii-delete-sum-for-two-strings/) | [C++](./algorithms/cpp/minimumASCIIDeleteSumForTwoStrings/MinimumAsciiDeleteSumForTwoStrings.cpp)|Medium| +|695|[Max Area of Island](https://leetcode.com/problems/max-area-of-island/) | [C++](./algorithms/cpp/maxAreaOfIsland/MaxAreaOfIsland.cpp)|Medium| +|687|[Longest Univalue Path](https://leetcode.com/problems/longest-univalue-path/) | [Python](./algorithms/python/LongestUnivaluePath/longestUnivaluePath.py)|Easy| +|684|[Redundant Connection](https://leetcode.com/problems/redundant-connection/) | [Python](./algorithms/python/RedundantConnection/findRedundantConnection.py)|Medium| +|674|[Longest Continuous Increasing Subsequence](https://leetcode.com/problems/longest-continuous-increasing-subsequence/) | [Python](./algorithms/python/LongestContinuousIncreasingSubsequence/findLengthOfLCIS.py)|Easy| +|671|[Second Minimum Node In a Binary Tree](https://leetcode.com/problems/second-minimum-node-in-a-binary-tree/) | [Python](./algorithms/python/SecondMinimumNodeInABinaryTree/findSecondMinimumValue.py)|Easy| +|665|[Non-decreasing Array](https://leetcode.com/problems/non-decreasing-array/) | [Python](./algorithms/python/Non-decreasingArray/checkPossibility.py)|Easy| +|662|[Maximum Width of Binary Tree](https://leetcode.com/problems/maximum-width-of-binary-tree/) | [Python](./algorithms/python/MaximumWidthOfBinaryTree/widthOfBinaryTree.py)|Medium| +|661|[Image Smoother](https://leetcode.com/problems/image-smoother/) | [Python](./algorithms/python/ImageSmoother/imageSmoother.py)|Easy| +|655|[Print Binary Tree](https://leetcode.com/problems/print-binary-tree/) | [Python](./algorithms/python/PrintBinaryTree/printTree.py)|Medium| +|652|[Find Duplicate Subtrees](https://leetcode.com/problems/find-duplicate-subtrees/) | [Python](./algorithms/python/FindDuplicateSubtrees/findDuplicateSubtrees.py)|Medium| +|647|[Palindromic Substrings](https://leetcode.com/problems/palindromic-substrings/) | [C++](./algorithms/cpp/palindromicSubstrings/PalindromicSubstrings.cpp)|Medium| +|643|[Maximum Average Subarray I](https://leetcode.com/problems/maximum-average-subarray-i/description/) | [C++](./algorithms/cpp/maximumAverageSubarray/MaximumAverageSubarray.I.cpp), [Python](./algorithms/python/MaximumAverageSubarrayI/findMaxAverage.py)|Easy| +|628|[Maximum Product of Three Numbers](https://leetcode.com/problems/maximum-product-of-three-numbers/) | [Python](./algorithms/python/MaximumProductOfThreeNumbers/maximumProduct.py)|Easy| +|623|[Add One Row to Tree](https://leetcode.com/problems/add-one-row-to-tree/) | [Python](./algorithms/python/AddOneRowToTree/addOneRow.py)|Medium| +|581|[Shortest Unsorted Continuous Subarray](https://leetcode.com/problems/shortest-unsorted-continuous-subarray/) | [Python](./algorithms/python/ShortestUnsortedContinuousSubarray/findUnsortedSubarray.py)|Easy| +|572|[Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree/) | [Python](./algorithms/python/SubtreeOfAnotherTree/isSubtree.py)|Easy| +|563|[Binary Tree Tilt](https://leetcode.com/problems/binary-tree-tilt/) | [Python](./algorithms/python/BinaryTreeTilt/findTilt.py)|Easy| +|547|[Friend Circles](https://leetcode.com/problems/friend-circles/) | [C++](./algorithms/cpp/friendCircles/FriendCircles.cpp)|Medium| +|543|[Diameter of Binary Tree](https://leetcode.com/problems/diameter-of-binary-tree/) | [Python](./algorithms/python/DiameterOfBinaryTree/diameterOfBinaryTree.py)|Easy| +|538|[Convert BST to Greater Tree](https://leetcode.com/problems/convert-bst-to-greater-tree/) | [Python](./algorithms/python/ConvertBSTtoGreaterTree/convertBST.py)|Easy| +|532|[K-diff Pairs in an Array](https://leetcode.com/problems/k-diff-pairs-in-an-array/) | [Python](./algorithms/python/K-diffPairsInAnArray/findPairs.py)|Easy| +|520|[Detect Capital](https://leetcode.com/problems/detect-capital/) | [C++](./algorithms/cpp/detectCapital/DetectCapital.cpp)|Easy| +|518|[Coin Change 2](https://leetcode.com/problems/coin-change-2/) | [C++](./algorithms/cpp/coinChange/CoinChange2.cpp)|Medium| +|509|[Fibonacci Number](https://leetcode.com/problems/fibonacci-number/) | [C++](./algorithms/cpp/fibonacciNumber/FibonacciNumber.cpp), [Python](./algorithms/python/FibonacciNumber/fib.py)|Easy| +|477|[Total Hamming Distance](https://leetcode.com/problems/total-hamming-distance/) | [C++](./algorithms/cpp/totalHammingDistance/totalHammingDistance.cpp)|Medium| +|463|[Island Perimeter](https://leetcode.com/problems/island-perimeter/) | [C++](./algorithms/cpp/islandPerimeter/IslandPerimeter.cpp)|Easy| +|450|[DeleteNodeInABST](https://leetcode.com/problems/delete-node-in-a-bst/) | [Python](./algorithms/python/DeleteNodeInABST/deleteNode.py)|Medium| +|449|[Serialize and Deserialize BST](https://leetcode.com/problems/serialize-and-deserialize-bst/) | [Python](./algorithms/python/SerializeAndDeserializeBST/serialize.py)|Medium| +|437|[Path Sum III](https://leetcode.com/problems/path-sum-iii/) | [Python](./algorithms/python/PathSumIII/pathSum.py)|Medium| +|418|[SentenceScreenFitting](https://leetcode.com/problems/sentence-screen-fitting/) ♥ | [C++](./algorithms/cpp/sentenceScreenFitting/sentenceScreenFitting.cpp)|Easy| +|416|[Partition Equal Subset Sum](https://leetcode.com/problems/partition-equal-subset-sum/description/) | [C++](./algorithms/cpp/partitionEqualSubsetSum/PartitionEqualSubsetSum.cpp)|Medium| +|415|[Add Strings](https://leetcode.com/problems/add-strings/) | [C++](./algorithms/cpp/addStrings/AddStrings.cpp)|Easy| +|414|[Third Maximum Number](https://leetcode.com/problems/third-maximum-number/) | [C++](./algorithms/cpp/thirdMaximumNumber/ThirdMaximumNumber.cpp), [Python](./algorithms/python/ThirdMaximumNumber/thirdMax.py)|Easy| +|413|[Arithmetic Slices](https://leetcode.com/problems/arithmetic-slices/) | [C++](./algorithms/cpp/arithmeticSlices/ArithmeticSlices.cpp)|Medium| +|412|[Fizz Buzz](https://leetcode.com/problems/fizz-buzz/) | [C++](./algorithms/cpp/fizzBuzz/FizzBuzz.cpp)|Easy| +|410|[Split Array Largest Sum](https://leetcode.com/problems/split-array-largest-sum/) | [C++](./algorithms/cpp/splitArrayLargestSum/SplitArrayLargestSum.cpp)|Hard| +|409|[Longest Palindrome](https://leetcode.com/problems/longest-palindrome/) | [C++](./algorithms/cpp/longestPalindrome/LongestPalindrome.cpp)|Easy| +|406|[Queue Reconstruction by Height](https://leetcode.com/problems/queue-reconstruction-by-height/) | [C++](./algorithms/cpp/queueReconstructionByHeight/QueueReconstructionByHeight.cpp)|Medium| +|405|[Convert a Number to Hexadecimal](https://leetcode.com/problems/convert-a-number-to-hexadecimal/) | [C++](./algorithms/cpp/convertANumberToHexadecimal/ConvertANumberToHexadecimal.cpp)|Easy| +|404|[Sum of Left Leaves](https://leetcode.com/problems/sum-of-left-leaves/) | [C++](./algorithms/cpp/sumOfLeftLeaves/SumOfLeftLeaves.cpp), [Python](./algorithms/python/SumOfLeftLeaves/sumOfLeftLeaves.py)|Easy| +|403|[Frog Jump](https://leetcode.com/problems/frog-jump/) | [C++](./algorithms/cpp/frogJump/FrogJump.cpp)|Hard| +|402|[Remove K Digits](https://leetcode.com/problems/remove-k-digits/) | [C++](./algorithms/cpp/removeKDigits/RemoveKDigits.cpp)|Medium| +|401|[Binary Watch](https://leetcode.com/problems/binary-watch/) | [C++](./algorithms/cpp/binaryWatch/BinaryWatch.cpp)|Easy| +|400|[Nth Digit](https://leetcode.com/problems/nth-digit/) | [C++](./algorithms/cpp/nthDigit/NthDigit.cpp)|Easy| +|399|[Evaluate Division](https://leetcode.com/problems/evaluate-division/) | [C++](./algorithms/cpp/evaluateDivision/EvaluateDivision.cpp)|Medium| +|398|[Random Pick Index](https://leetcode.com/problems/random-pick-index/) | [C++](./algorithms/cpp/randomPickIndex/RandomPickIndex.cpp)|Medium| +|397|[Integer Replacement](https://leetcode.com/problems/integer-replacement/) | [C++](./algorithms/cpp/integerReplacement/IntegerReplacement.cpp)|Medium| +|396|[Rotate Function](https://leetcode.com/problems/rotate-function/) | [C++](./algorithms/cpp/rotateFunction/RotateFunction.cpp)|Easy| +|395|[Longest Substring with At Least K Repeating Characters](https://leetcode.com/problems/longest-substring-with-at-least-k-repeating-characters/) | [C++](./algorithms/cpp/longestSubstringWithAtLeastKRepeatingCharacters/LongestSubstringWithAtLeastKRepeatingCharacters.cpp)|Medium| +|394|[Decode String](https://leetcode.com/problems/decode-string/) | [C++](./algorithms/cpp/decodeString/DecodeString.cpp)|Medium| +|393|[UTF-8 Validation](https://leetcode.com/problems/utf-8-validation/) | [C++](./algorithms/cpp/UTF8Validation/UTF8Validation.cpp)|Medium| +|392|[Is Subsequence](https://leetcode.com/problems/is-subsequence/) | [C++](./algorithms/cpp/isSubsequence/IsSubsequence.cpp)|Medium| +|391|[Perfect Rectangle](https://leetcode.com/problems/perfect-rectangle/) | [C++](./algorithms/cpp/perfectRectangle/PerfectRectangle.cpp)|Hard| +|390|[Elimination Game](https://leetcode.com/problems/elimination-game/) | [C++](./algorithms/cpp/eliminationGame/EliminationGame.cpp)|Medium| +|389|[Find the Difference](https://leetcode.com/problems/find-the-difference/) | [C++](./algorithms/cpp/findTheDifference/FindTheDifference.cpp)|Easy| +|388|[Longest Absolute File Path](https://leetcode.com/problems/longest-absolute-file-path/) | [C++](./algorithms/cpp/longestAbsoluteFilePath/LongestAbsoluteFilePath.cpp)|Medium| +|387|[First Unique Character in a String](https://leetcode.com/problems/first-unique-character-in-a-string/) | [C++](./algorithms/cpp/firstUniqueCharacterInAString/FirstUniqueCharacterInAString.cpp)|Easy| +|386|[Lexicographical Numbers](https://leetcode.com/problems/lexicographical-numbers/) | [C++](./algorithms/cpp/lexicographicalNumbers/LexicographicalNumbers.cpp)|Medium| +|385|[Mini Parser](https://leetcode.com/problems/mini-parser/) | [C++](./algorithms/cpp/miniParser/MiniParser.cpp)|Medium| +|384|[Shuffle an Array](https://leetcode.com/problems/shuffle-an-array/) | [C++](./algorithms/cpp/shuffleAnArray/ShuffleAnArray.cpp)|Medium| +|383|[Ransom Note](https://leetcode.com/problems/ransom-note/) | [C++](./algorithms/cpp/ransomNote/RansomNote.cpp)|Easy| +|382|[Linked List Random Node](https://leetcode.com/problems/linked-list-random-node/) | [C++](./algorithms/cpp/linkedListRandomNode/LinkedListRandomNode.cpp)|Medium| +|381|[Insert Delete GetRandom O(1) - Duplicates allowed](https://leetcode.com/problems/insert-delete-getrandom-o1-duplicates-allowed/) | [C++](./algorithms/cpp/insertDeleteGetRandom/InsertDeleteGetrandomO1DuplicatesAllowed.cpp)|Hard| +|380|[Insert Delete GetRandom O(1)](https://leetcode.com/problems/insert-delete-getrandom-o1/) | [C++](./algorithms/cpp/insertDeleteGetRandom/InsertDeleteGetrandomO1.cpp)|Hard| +|377|[Combination Sum IV](https://leetcode.com/problems/combination-sum-iv/) | [C++](./algorithms/cpp/combinationSumIV/combinationSumIV.cpp)|Medium| +|376|[Wiggle Subsequence](https://leetcode.com/problems/wiggle-subsequence/) | [C++](./algorithms/cpp/wiggleSubsequence/wiggleSubsequence.cpp)|Medium| +|371|[Sum of Two Integers](https://leetcode.com/problems/sum-of-two-integers/description/) | [C++](./algorithms/cpp/sumOfTwoIntegers/SumOfTwoIntegers.cpp)|Easy| +|367|[Valid Perfect Square](https://leetcode.com/problems/valid-perfect-square/description/) | [C++](./algorithms/cpp/validPerfectSquare/ValidPerfectSquare.cpp)|Easy| +|357|[Count Numbers with Unique Digits](https://leetcode.com/problems/count-numbers-with-unique-digits/) | [C++](./algorithms/cpp/countNumbersWithUniqueDigits/CountNumbersWithUniqueDigits.cpp)|Medium| +|350|[Intersection of Two Arrays II](https://leetcode.com/problems/intersection-of-two-arrays-ii/) | [C++](./algorithms/cpp/intersectionOfTwoArrays/intersectionOfTwoArraysII.cpp)|Easy| +|349|[Intersection of Two Arrays](https://leetcode.com/problems/intersection-of-two-arrays/) | [C++](./algorithms/cpp/intersectionOfTwoArrays/intersectionOfTwoArrays.cpp)|Easy| +|347|[Top K Frequent Elements](https://leetcode.com/problems/top-k-frequent-elements/) | [C++](./algorithms/cpp/topKFrequentElements/topKFrequentElements.cpp)|Medium| +|345|[Reverse Vowels of a String](https://leetcode.com/problems/reverse-vowels-of-a-string/) | [C++](./algorithms/cpp/reverseVowelsOfAString/reverseVowelsOfAString.cpp)|Easy| +|344|[Reverse String](https://leetcode.com/problems/reverse-string/) | [C++](./algorithms/cpp/reverseString/ReverseString.cpp)|Easy| +|343|[Integer Break](https://leetcode.com/problems/integer-break/) | [C++](./algorithms/cpp/integerBreak/IntegerBreak.cpp)|Medium| +|342|[Power of Four](https://leetcode.com/problems/power-of-four/) | [C++](./algorithms/cpp/powerOfFour/PowerOfFour.cpp)|Easy| +|341|[Flatten Nested List Iterator](https://leetcode.com/problems/flatten-nested-list-iterator/) | [C++](./algorithms/cpp/flattenNestedListIterator/FlattenNestedListIterator.cpp)|Medium| +|338|[Counting Bits](https://leetcode.com/problems/counting-bits/) | [C++](./algorithms/cpp/countingBits/CountingBits.cpp)|Medium| +|337|[House Robber III](https://leetcode.com/problems/house-robber-iii/) | [C++](./algorithms/cpp/houseRobber/houseRobberIII.cpp), [Python](./algorithms/python/HouseRobberIII/rob.py)|Medium| +|336|[Palindrome Pairs](https://leetcode.com/problems/palindrome-pairs/) | [C++](./algorithms/cpp/palindromePairs/PalindromePairs.cpp)|Hard| +|334|[Increasing Triplet Subsequence](https://leetcode.com/problems/increasing-triplet-subsequence/) | [C++](./algorithms/cpp/increasingTripletSubsequence/increasingTripletSubsequence.cpp)|Medium| +|332|[Reconstruct Itinerary](https://leetcode.com/problems/reconstruct-itinerary/) | [C++](./algorithms/cpp/reconstructItinerary/ReconstructItinerary.cpp)|Medium| +|331|[Verify Preorder Serialization of a Binary Tree](https://leetcode.com/problems/verify-preorder-serialization-of-a-binary-tree/) | [C++](./algorithms/cpp/verifyPreorderSerializationOfABinaryTree/VerifyPreorderSerializationOfABinaryTree.cpp)|Medium| +|330|[Patching Array](https://leetcode.com/problems/patching-array/) | [C++](./algorithms/cpp/patchingArray/PatchingArray.cpp)|Medium| +|329|[Longest Increasing Path in a Matrix](https://leetcode.com/problems/longest-increasing-path-in-a-matrix/) | [C++](./algorithms/cpp/longestIncreasingPathInAMatrix/LongestIncreasingPathInAMatrix.cpp)|Medium| +|328|[Odd Even Linked List](https://leetcode.com/problems/odd-even-linked-list/) | [C++](./algorithms/cpp/oddEvenLinkedList/OddEvenLinkedList.cpp)|Easy| +|327|[Count of Range Sum](https://leetcode.com/problems/count-of-range-sum/) | [C++](./algorithms/cpp/countOfRangeSum/CountOfRangeSum.cpp)|Hard| +|326|[Power of Three](https://leetcode.com/problems/power-of-three/) | [C++](./algorithms/cpp/powerOfThree/PowerOfThree.cpp)|Easy| +|324|[Wiggle Sort II](https://leetcode.com/problems/wiggle-sort-ii/) | [C++](./algorithms/cpp/wiggleSort/WiggleSort.II.cpp)|Medium| +|322|[Coin Change](https://leetcode.com/problems/coin-change/) | [C++](./algorithms/cpp/coinChange/coinChange.cpp)|Medium| +|321|[Create Maximum Number](https://leetcode.com/problems/create-maximum-number/) | [C++](./algorithms/cpp/createMaximumNumber/CreateMaximumNumber.cpp)|Hard| +|319|[Bulb Switcher](https://leetcode.com/problems/bulb-switcher/) | [C++](./algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp)|Medium| +|318|[Maximum Product of Word Lengths](https://leetcode.com/problems/maximum-product-of-word-lengths/) | [C++](./algorithms/cpp/maximumProductOfWordLengths/MaximumProductOfWordLengths.cpp)|Medium| +|316|[Remove Duplicate Letters](https://leetcode.com/problems/remove-duplicate-letters/) | [C++](./algorithms/cpp/removeDuplicateLetters/RemoveDuplicateLetters.cpp)|Hard| |315|[Count of Smaller Numbers After Self](https://leetcode.com/problems/count-of-smaller-numbers-after-self/) | [C++](./algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp)|Hard| +|313|[Super Ugly Number](https://leetcode.com/problems/super-ugly-number/) | [C++](./algorithms/cpp/superUglyNumber/SuperUglyNumber.cpp)|Medium| +|312|[Burst Balloons](https://leetcode.com/problems/burst-balloons/) | [C++](./algorithms/cpp/burstBalloons/BurstBalloons.cpp)|Hard| +|310|[Minimum Height Trees](https://leetcode.com/problems/minimum-height-trees/) | [C++](./algorithms/cpp/minimumHeightTrees/MinimumHeightTrees.cpp)|Medium| +|309|[Best Time to Buy and Sell Stock with Cooldown](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/) | [C++](./algorithms/cpp/bestTimeToBuyAndSellStock/BestTimeToBuyAndSellStockWithCooldown.cpp)|Medium| |307|[Range Sum Query - Mutable](https://leetcode.com/problems/range-sum-query-mutable/) | [C++](./algorithms/cpp/rangeSumQuery-Immutable/rangeSumQuery-Mutable/RangeSumQueryMutable.cpp)|Medium| |306|[Additive Number](https://leetcode.com/problems/additive-number/) | [C++](./algorithms/cpp/additiveNumber/AdditiveNumber.cpp)|Medium| |304|[Range Sum Query 2D - Immutable](https://leetcode.com/problems/range-sum-query-2d-immutable/) | [C++](./algorithms/cpp/rangeSumQuery2D-Immutable/RangeSumQuery2dImmutable.cpp)|Medium| @@ -20,10 +164,12 @@ LeetCode |295|[Find Median from Data Stream](https://leetcode.com/problems/find-median-from-data-stream/) | [C++](./algorithms/cpp/findMedianFromDataStream/FindMedianFromDataStream.cpp)|Hard| |292|[Nim Game](https://leetcode.com/problems/nim-game/) | [C++](./algorithms/cpp/nimGame/nimGame.cpp)|Easy| |290|[Word Pattern](https://leetcode.com/problems/word-pattern/) | [C++](./algorithms/cpp/wordPattern/WordPattern.cpp)|Easy| -|287|[Find the Duplicate Number](https://leetcode.com/problems/find-the-duplicate-number/) | [C++](./algorithms/cpp/findTheDuplicateNumber/findTheDuplicateNumber.cpp)|Hard| +|289|[Game of Life](https://leetcode.com/problems/game-of-life/) | [C++](./algorithms/cpp/gameOfLife/GameOfLife.cpp)|Medium| +|287|[Find the Duplicate Number](https://leetcode.com/problems/find-the-duplicate-number/) | [C++](./algorithms/cpp/findTheDuplicateNumber/findTheDuplicateNumber.cpp), [Python](./algorithms/python/FindTheDuplicateNumber/findDuplicate.py)|Hard| |285|[Inorder Successor in BST](https://leetcode.com/problems/inorder-successor-in-bst/) ♥ | [Java](./algorithms/java/src/inorderSuccessorInBST/inorderSuccessorInBST.java)|Medium| |284|[Peeking Iterator](https://leetcode.com/problems/peeking-iterator/) | [C++](./algorithms/cpp/peekingIterator/PeekingIterator.cpp)|Medium| |283|[Move Zeroes](https://leetcode.com/problems/move-zeroes/) | [C++](./algorithms/cpp/moveZeroes/moveZeroes.cpp)|Easy| +|282|[Expression Add Operators](https://leetcode.com/problems/expression-add-operators/) | [C++](./algorithms/cpp/expressionAddOperators/ExpressionAddOperators.cpp)|Hard| |279|[Perfect Squares](https://leetcode.com/problems/perfect-squares/) | [C++](./algorithms/cpp/perfectSquares/PerfectSquares.cpp)|Medium| |278|[First Bad Version](https://leetcode.com/problems/first-bad-version/)| [C++](./algorithms/cpp/firstBadVersion/FirstBadVersion.cpp), [Java](./algorithms/java/src/firstBadVersion/firstBadVersion.java)|Easy| |275|[H-Index II](https://leetcode.com/problems/h-index-ii/)| [C++](./algorithms/cpp/h-Index/h-Index.II.cpp)|Medium| @@ -32,32 +178,33 @@ LeetCode |268|[Missing Number](https://leetcode.com/problems/missing-number/)| [C++](./algorithms/cpp/missingNumber/MissingNumber.cpp)|Medium| |264|[Ugly Number II](https://leetcode.com/problems/ugly-number-ii/)| [C++](./algorithms/cpp/uglyNumber/UglyNumber.II.cpp)|Medium| |263|[Ugly Number](https://leetcode.com/problems/ugly-number/)| [C++](./algorithms/cpp/uglyNumber/UglyNumber.cpp)|Easy| +|260|[Single Number III](https://leetcode.com/problems/single-number-iii/)| [C++](./algorithms/cpp/singleNumber/singleNumber.III.cpp)|Medium| |258|[Add Digits](https://leetcode.com/problems/add-digits/)| [C++](./algorithms/cpp/addDigits/addDigits.cpp)|Easy| |257|[Binary Tree Paths](https://leetcode.com/problems/binary-tree-paths/)| [C++](./algorithms/cpp/binaryTreePaths/binaryTreePaths.cpp)|Easy| -|242|[Valid Anagram](https://leetcode.com/problems/valid-anagram/)| [C++](./algorithms/cpp/anagrams/ValidAnagram.cpp)|Easy| -|241|[Different Ways to Add Parentheses](https://leetcode.com/problems/different-ways-to-add-parentheses/)|[C++](./algorithms/cpp/differentWaysToAddParentheses/DifferentWaysToAddParentheses.cpp)|Medium| -|240|[Search a 2D Matrix II](https://leetcode.com/problems/search-a-2d-matrix-ii/)|[C++](./algorithms/cpp/search2DMatrix/search2DMatrix.II.cpp)|Medium| +|242|[Valid Anagram](https://leetcode.com/problems/valid-anagram/)| [C++](./algorithms/cpp/anagrams/ValidAnagram.cpp), [Java](./algorithms/java/src/validAnagram/ValidAnagram.java)|Easy| +|241|[Different Ways to Add Parentheses](https://leetcode.com/problems/different-ways-to-add-parentheses/)|[C++](./algorithms/cpp/differentWaysToAddParentheses/DifferentWaysToAddParentheses.cpp), [Python](./algorithms/python/DifferentWaysToAddParentheses/diffWaysToCompute.py)|Medium| +|240|[Search a 2D Matrix II](https://leetcode.com/problems/search-a-2d-matrix-ii/)|[C++](./algorithms/cpp/search2DMatrix/search2DMatrix.II.cpp), [Java](./algorithms/java/src/searchA2DMatrixII/SearchA2DMatrixII.java), [Python](./algorithms/python/SearchA2DMatrixII/searchMatrix.py)|Medium| |239|[Sliding Window Maximum](https://leetcode.com/problems/sliding-window-maximum/)| [C++](./algorithms/cpp/slidingWindowMaximum/SlidingWindowMaximum.cpp)|Hard| |238|[Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/)| [C++](./algorithms/cpp/productOfArrayExceptSelf/ProductOfArrayExceptSelf.cpp)|Medium| |237|[Delete Node in a Linked List](https://leetcode.com/problems/delete-node-in-a-linked-list/)| [C++](./algorithms/cpp/deleteNodeInALinkedList/DeleteNodeInALinkedList.cpp)|Easy| -|236|[Lowest Common Ancestor of a Binary Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/)| [C++](./algorithms/cpp/lowestCommonAncestorOfABinaryTree/LowestCommonAncestorOfABinaryTree.cpp), [Java](./algorithms/java/src/lowestCommonAncestorOfABinaryTree/lowestCommonAncestorOfABinaryTree.java)|Medium| -|235|[Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/)| [C++](./algorithms/cpp/lowestCommonAncestorOfABinarySearchTree/LowestCommonAncestorOfABinarySearchTree.cpp)|Easy| +|236|[Lowest Common Ancestor of a Binary Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/)| [C++](./algorithms/cpp/lowestCommonAncestorOfABinaryTree/LowestCommonAncestorOfABinaryTree.cpp), [Java](./algorithms/java/src/lowestCommonAncestorOfABinaryTree/lowestCommonAncestorOfABinaryTree.java), [Python](./algorithms/python/LowestCommonAncestorOfABinaryTree/lowestCommonAncestor.py)|Medium| +|235|[Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/)| [C++](./algorithms/cpp/lowestCommonAncestorOfABinarySearchTree/LowestCommonAncestorOfABinarySearchTree.cpp), [Python](./algorithms/python/LowestCommonAncestorOfABinarySearchTree/lowestCommonAncestor.py)|Easy| |234|[Palindrome Linked List](https://leetcode.com/problems/palindrome-linked-list/)| [C++](./algorithms/cpp/palindromeLinkedList/PalindromeLinkedList.cpp)|Easy| |233|[Number of Digit One](https://leetcode.com/problems/number-of-digit-one/)| [C++](./algorithms/cpp/numberOfDigitOne/NumberOfDigitOne.cpp)|Medium| -|232|[Implement Queue using Stacks](https://leetcode.com/problems/implement-queue-using-stacks/)| [C++](./algorithms/cpp/implementQueueUsingStacks/ImplementQueueUsingStacks.cpp)|Easy| +|232|[Implement Queue using Stacks](https://leetcode.com/problems/implement-queue-using-stacks/)| [C++](./algorithms/cpp/implementQueueUsingStacks/ImplementQueueUsingStacks.cpp), [Java](./algorithms/java/src/myQueue/MyQueue.java)|Easy| |231|[Power of Two](https://leetcode.com/problems/power-of-two/)| [C++](./algorithms/cpp/powerOfTwo/PowerOfTwo.cpp)|Easy| -|230|[Kth Smallest Element in a BST](https://leetcode.com/problems/kth-smallest-element-in-a-bst/)| [C++](./algorithms/cpp/kthSmallestElementInaBST/KthSmallestElementInABst.cpp)|Medium| -|229|[Majority Element II](https://oj.leetcode.com/problems/majority-element-ii/) | [C++](./algorithms/cpp/majorityElement/majorityElement.II.cpp)|Medium| +|230|[Kth Smallest Element in a BST](https://leetcode.com/problems/kth-smallest-element-in-a-bst/)| [C++](./algorithms/cpp/kthSmallestElementInaBST/KthSmallestElementInABst.cpp), [Python](./algorithms/python/KthSmallestElementInABST/kthSmallest.py)|Medium| +|229|[Majority Element II](https://leetcode.com/problems/majority-element-ii/) | [C++](./algorithms/cpp/majorityElement/majorityElement.II.cpp)|Medium| |228|[Summary Ranges](https://leetcode.com/problems/summary-ranges/)| [C++](./algorithms/cpp/summaryRanges/SummaryRanges.cpp)|Easy| |227|[Basic Calculator II](https://leetcode.com/problems/basic-calculator-ii/)| [C++](./algorithms/cpp/basicCalculator/BasicCalculator.II.cpp)|Medium| |226|[Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/)| [C++](./algorithms/cpp/invertBinaryTree/InvertBinaryTree.cpp)|Easy| -|225|[Implement Stack using Queues](https://leetcode.com/problems/implement-stack-using-queues/)| [C++](./algorithms/cpp/implementStackUsingQueues/ImplementStackUsingQueues.cpp)|Medium| +|225|[Implement Stack using Queues](https://leetcode.com/problems/implement-stack-using-queues/)| [C++](./algorithms/cpp/implementStackUsingQueues/ImplementStackUsingQueues.cpp), [Java](./algorithms/java/src/myStack/MyStack.java)|Medium| |224|[Basic Calculator](https://leetcode.com/problems/basic-calculator/)| [C++](./algorithms/cpp/basicCalculator/BasicCalculator.cpp)|Medium| |223|[Rectangle Area](https://leetcode.com/problems/rectangle-area/)| [C++](./algorithms/cpp/rectangleArea/RectangleArea.cpp)|Easy| -|222|[Count Complete Tree Nodes](https://leetcode.com/problems/count-complete-tree-nodes/)| [C++](./algorithms/cpp/countCompleteTreeNodes/CountCompleteTreeNodes.cpp)|Medium| +|222|[Count Complete Tree Nodes](https://leetcode.com/problems/count-complete-tree-nodes/)| [C++](./algorithms/cpp/countCompleteTreeNodes/CountCompleteTreeNodes.cpp), [Python](./algorithms/python/CountCompleteTreeNodes/countNodes.py)|Medium| |221|[Maximal Square](https://leetcode.com/problems/maximal-square/)| [C++](./algorithms/cpp/maximalSquare/MaximalSquare.cpp)|Medium| -|220|[Contains Duplicate III](https://leetcode.com/problems/contains-duplicate-iii/)| [C++](./algorithms/cpp/containsDuplicate/ContainsDuplicate.III.cpp)|Medium| -|219|[Contains Duplicate II](https://leetcode.com/problems/contains-duplicate-ii/)| [C++](./algorithms/cpp/containsDuplicate/ContainsDuplicate.II.cpp)|Easy| +|220|[Contains Duplicate III](https://leetcode.com/problems/contains-duplicate-iii/)| [C++](./algorithms/cpp/containsDuplicate/ContainsDuplicate.III.cpp), [Python](./algorithms/python/ContainsDuplicateIII/containsNearbyAlmostDuplicate.py)|Medium| +|219|[Contains Duplicate II](https://leetcode.com/problems/contains-duplicate-ii/)| [C++](./algorithms/cpp/containsDuplicate/ContainsDuplicate.II.cpp), [Python](./algorithms/python/ContainsDuplicateII/containsNearbyDuplicate.py)|Easy| |218|[The Skyline Problem](https://leetcode.com/problems/the-skyline-problem/)| [C++](./algorithms/cpp/theSkylineProblem/TheSkylineProblem.cpp)|Hard| |217|[Contains Duplicate](https://leetcode.com/problems/contains-duplicate/)| [C++](./algorithms/cpp/containsDuplicate/ContainsDuplicate.cpp)|Easy| |216|[Combination Sum III](https://leetcode.com/problems/combination-sum-iii/)| [C++](./algorithms/cpp/combinationSum/combinationSum.III.cpp)|Medium| @@ -70,199 +217,199 @@ LeetCode |209|[Minimum Size Subarray Sum](https://leetcode.com/problems/minimum-size-subarray-sum/)| [C++](./algorithms/cpp/minimumSizeSubarraySum/MinimumSizeSubarraySum.cpp)|Medium| |208|[Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree/)| [C++](./algorithms/cpp/implementTriePrefixTree/ImplementTriePrefixTree.cpp)|Medium| |207|[Course Schedule](https://leetcode.com/problems/course-schedule/)| [C++](./algorithms/cpp/courseSchedule/CourseSchedule.cpp)|Medium| -|206|[Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/)| [C++](./algorithms/cpp/reverseLinkedList/reverseLinkedList.cpp)|Easy| +|206|[Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/)| [C++](./algorithms/cpp/reverseLinkedList/reverseLinkedList.cpp), [Java](./algorithms/java/src/reverseLinkedList/ReverseLinkedList.java)|Easy| |205|[Isomorphic Strings](https://leetcode.com/problems/isomorphic-strings/)| [C++](./algorithms/cpp/isomorphicStrings/IsomorphicStrings.cpp)|Easy| |204|[Count Primes](https://leetcode.com/problems/count-primes/)| [C++](./algorithms/cpp/countPrimes/CountPrimes.cpp)|Easy| |203|[Remove Linked List Elements](https://leetcode.com/problems/remove-linked-list-elements/)| [C++](./algorithms/cpp/removeLinkedListElements/RemoveLinkedListElements.cpp)|Easy| -|202|[Happy Number](https://leetcode.com/problems/happy-number/)| [C++](./algorithms/cpp/happyNumber/HappyNumber.cpp)|Easy| +|202|[Happy Number](https://leetcode.com/problems/happy-number/)| [C++](./algorithms/cpp/happyNumber/HappyNumber.cpp), [Python](./algorithms/python/HappyNumber/isHappy.py)|Easy| |201|[Bitwise AND of Numbers Range](https://leetcode.com/problems/bitwise-and-of-numbers-range/)| [C++](./algorithms/cpp/bitwiseANDOfNumbersRange/BitwiseAndOfNumbersRange.cpp)|Medium| -|200|[Number of Islands](https://leetcode.com/problems/number-of-islands/)| [C++](./algorithms/cpp/numberOfIslands/NumberOfIslands.cpp)|Medium| +|200|[Number of Islands](https://leetcode.com/problems/number-of-islands/)| [C++](./algorithms/cpp/numberOfIslands/NumberOfIslands.cpp), [Python](./algorithms/python/NumberOfIslands/numIslands.py)|Medium| |199|[Binary Tree Right Side View](https://leetcode.com/problems/binary-tree-right-side-view/)| [C++](./algorithms/cpp/binaryTreeRightSideView/binaryTreeRightSideView.cpp)|Medium| -|198|[House Robber](https://leetcode.com/problems/house-robber/)| [C++](./algorithms/cpp/houseRobber/houseRobber.cpp)|Easy| -|191|[Number of 1 Bits](https://oj.leetcode.com/problems/number-of-1-bits/)| [C++](./algorithms/cpp/numberOf1Bits/numberOf1Bits.cpp)|Easy| -|190|[Reverse Bits](https://oj.leetcode.com/problems/reverse-bits/)| [C++](./algorithms/cpp/reverseBits/reverseBits.cpp)|Easy| -|189|[Rotate Array](https://oj.leetcode.com/problems/rotate-array/)| [C++](./algorithms/cpp/rotateArray/rotateArray.cpp)|Easy| -|188|[Best Time to Buy and Sell Stock IV](https://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/)| [C++](./algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.IV.cpp)|Hard| -|187|[Repeated DNA Sequences](https://oj.leetcode.com/problems/repeated-dna-sequences/)| [C++](./algorithms/cpp/repeatedDNASequences/repeatedDNASequences.cpp)|Medium| -|186|[Reverse Words in a String II](https://oj.leetcode.com/problems/reverse-words-in-a-string-ii/) ♥ | [C++](./algorithms/cpp/reverseWordsInAString/reverseWordsInAString.II.cpp)|Medium| -|179|[Largest Number](https://oj.leetcode.com/problems/largest-number/) | [C++](./algorithms/cpp/largestNumber/largestNumber.cpp)|Medium| -|174|[Dungeon Game](https://oj.leetcode.com/problems/dungeon-game/) | [C++](./algorithms/cpp/dungeonGame/dungeonGame.cpp)|Hard| -|173|[Binary Search Tree Iterator](https://oj.leetcode.com/problems/binary-search-tree-iterator/) | [C++](./algorithms/cpp/binarySearchTreeIterator/binarySearchTreeIterator.cpp), [Java](./algorithms/java/src/binarySearchTreeIterator/binarySearchTreeIterator.java)|Medium| -|172|[Factorial Trailing Zeroes](https://oj.leetcode.com/problems/factorial-trailing-zeroes/) | [C++](./algorithms/cpp/factorialTrailingZeroes/factorialTrailingZeroes.cpp)|Easy| -|171|[Excel Sheet Column Number](https://oj.leetcode.com/problems/excel-sheet-column-number/) | [C++](./algorithms/cpp/excelSheetColumnNumber/excelSheetColumnNumber.cpp)|Easy| -|170|[Two Sum III - Data structure design](https://oj.leetcode.com/problems/two-sum-iii-data-structure-design/) ♥ | [C++](./algorithms/cpp/twoSum/twoSum.III.cpp)|Easy| -|169|[Majority Element](https://oj.leetcode.com/problems/majority-element/) | [C++](./algorithms/cpp/majorityElement/majorityElement.cpp)|Easy| -|168|[Excel Sheet Column Title](https://oj.leetcode.com/problems/excel-sheet-column-title/) | [C++](./algorithms/cpp/excelSheetColumnTitle/excelSheetColumnTitle.cpp)|Easy| -|167|[Two Sum II - Input array is sorted](https://oj.leetcode.com/problems/two-sum-ii-input-array-is-sorted/) ♥ | [C++](./algorithms/cpp/twoSum/twoSum.II.cpp)|Medium| -|166|[Fraction to Recurring Decimal](https://oj.leetcode.com/problems/fraction-to-recurring-decimal/) | [C++](./algorithms/cpp/fractionToRecurringDecimal/fractionToRecurringDecimal.cpp)|Medium| -|165|[Compare Version Numbers](https://oj.leetcode.com/problems/compare-version-numbers/) | [C++](./algorithms/cpp/compareVersionNumbers/compareVersionNumbers.cpp)|Easy| -|164|[Maximum Gap](https://oj.leetcode.com/problems/maximum-gap/) | [C++](./algorithms/cpp/maximumGap/maximumGap.cpp)|Hard| -|163|[Missing Ranges](https://oj.leetcode.com/problems/missing-ranges/) ♥ | [C++](./algorithms/cpp/missingRanges/missingRanges.cpp)|Medium| -|162|[Find Peak Element](https://oj.leetcode.com/problems/find-peak-element/) | [C++](./algorithms/cpp/findPeakElement/findPeakElement.cpp), [Java](./algorithms/java/src/findPeakElement/findPeakElement.java)|Medium| -|161|[One Edit Distance](https://oj.leetcode.com/problems/one-edit-distance/)♥ | [C++](./algorithms/cpp/oneEditDistance/oneEditDistance.cpp)|Medium| -|160|[Intersection of Two Linked Lists](https://oj.leetcode.com/problems/intersection-of-two-linked-lists/) | [C++](./algorithms/cpp/intersectionOfTwoLinkedLists/intersectionOfTwoLinkedLists.cpp)|Easy| -|159|[Longest Substring with At Most Two Distinct Characters](https://oj.leetcode.com/problems/longest-substring-with-at-most-two-distinct-characters/) ♥ | [C++](./algorithms/cpp/longestSubstringWithAtMostTwoDistinctCharacters/longestSubstringWithAtMostTwoDistinctCharacters.cpp)|Hard| -|158|[Read N Characters Given Read4 II - Call multiple times](https://oj.leetcode.com/problems/read-n-characters-given-read4-ii-call-multiple-times/) ♥ | [C++](./algorithms/cpp/readNCharactersGivenRead4/readNCharactersGivenRead4.II.cpp)|Hard| -|157|[Read N Characters Given Read4](https://oj.leetcode.com/problems/read-n-characters-given-read4/) ♥ | [C++](./algorithms/cpp/readNCharactersGivenRead4/readNCharactersGivenRead4.cpp)|Easy| -|156|[Binary Tree Upside Down](https://oj.leetcode.com/problems/binary-tree-upside-down/) ♥ | [C++](./algorithms/cpp/binaryTreeUpsideDown/binaryTreeUpsideDown.cpp)|Medium| -|155|[Min Stack](https://oj.leetcode.com/problems/min-stack/)| [C++](./algorithms/cpp/minStack/minStack.cpp)|Easy| -|154|[Find Minimum in Rotated Sorted Array II](https://oj.leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/)| [C++](./algorithms/cpp/findMinimumInRotatedSortedArray/findMinimumInRotatedSortedArray.II.cpp)|Hard| -|153|[Find Minimum in Rotated Sorted Array](https://oj.leetcode.com/problems/find-minimum-in-rotated-sorted-array/)| [C++](./algorithms/cpp/findMinimumInRotatedSortedArray/findMinimumInRotatedSortedArray.cpp), [Java](./algorithms/java/src/findMinimumInRotatedSortedArray/findMinimumInRotatedSortedArray.java)|Medium| -|152|[Maximum Product Subarray](https://oj.leetcode.com/problems/maximum-product-subarray/)| [C++](./algorithms/cpp/maximumProductSubarray/maximumProductSubarray.cpp)|Medium| -|151|[Reverse Words in a String](https://oj.leetcode.com/problems/reverse-words-in-a-string/)| [C++](./algorithms/cpp/reverseWordsInAString/reverseWordsInAString.cpp)|Medium| -|150|[Evaluate Reverse Polish Notation](https://oj.leetcode.com/problems/evaluate-reverse-polish-notation/)| [C++](./algorithms/cpp/evaluateReversePolishNotation/evaluateReversePolishNotation.cpp)|Medium| -|149|[Max Points on a Line](https://oj.leetcode.com/problems/max-points-on-a-line/)| [C++](./algorithms/cpp/maxPointsOnALine/maxPointsOnALine.cpp)|Hard| -|148|[Sort List](https://oj.leetcode.com/problems/sort-list/)| [C++](./algorithms/cpp/sortList/sortList.cpp)|Medium| -|147|[Insertion Sort List](https://oj.leetcode.com/problems/insertion-sort-list/)| [C++](./algorithms/cpp/insertionSortList/insertionSortList.cpp)|Medium| -|146|[LRU Cache](https://oj.leetcode.com/problems/lru-cache/)| [C++](./algorithms/cpp/LRUCache/LRUCache.cpp)|Hard| -|145|[Binary Tree Postorder Traversal](https://oj.leetcode.com/problems/binary-tree-postorder-traversal/)| [C++](./algorithms/cpp/binaryTreePostorderTraversal/binaryTreePostorderTraversal.cpp)|Hard| -|144|[Binary Tree Preorder Traversal](https://oj.leetcode.com/problems/binary-tree-preorder-traversal/)| [C++](./algorithms/cpp/binaryTreePreorderTraversal/binaryTreePreorderTraversal.cpp), [Java](./algorithms/java/src/binaryTreePreorderTraversal/binaryTreePreorderTraversal.java)|Medium| -|143|[Reorder List](https://oj.leetcode.com/problems/reorder-list/)| [C++](./algorithms/cpp/reorderList/reorderList.cpp)|Medium| -|142|[Linked List Cycle II](https://oj.leetcode.com/problems/linked-list-cycle-ii/)| [C++](./algorithms/cpp/linkedListCycle/linkedListCycle.II.cpp)|Medium| -|141|[Linked List Cycle](https://oj.leetcode.com/problems/linked-list-cycle/)| [C++](./algorithms/cpp/linkedListCycle/linkedListCycle.cpp)|Medium| -|140|[Word Break II](https://oj.leetcode.com/problems/word-break-ii/)| [C++](./algorithms/cpp/wordBreak/wordBreak.II.cpp)|Hard| -|139|[Word Break](https://oj.leetcode.com/problems/word-break/)| [C++](./algorithms/cpp/wordBreak/wordBreak.cpp)|Medium| -|138|[Copy List with Random Pointer](https://oj.leetcode.com/problems/copy-list-with-random-pointer/)| [C++](./algorithms/cpp/copyListWithRandomPointer/copyListWithRandomPointer.cpp)|Hard| -|137|[Single Number II](https://oj.leetcode.com/problems/single-number-ii/)| [C++](./algorithms/cpp/singleNumber/singleNumber.II.cpp)|Medium| -|136|[Single Number](https://oj.leetcode.com/problems/single-number/)| [C++](./algorithms/cpp/singleNumber/singleNumber.cpp)|Medium| -|135|[Candy](https://oj.leetcode.com/problems/candy/)| [C++](./algorithms/cpp/candy/candy.cpp)|Hard| -|134|[Gas Station](https://oj.leetcode.com/problems/gas-station/)| [C++](./algorithms/cpp/gasStation/gasStation.cpp)|Medium| -|133|[Clone Graph](https://oj.leetcode.com/problems/clone-graph/)| [C++](./algorithms/cpp/cloneGraph/cloneGraph.cpp)|Medium| -|132|[Palindrome Partitioning II](https://oj.leetcode.com/problems/palindrome-partitioning-ii/)| [C++](./algorithms/cpp/palindromePartitioning/palindromePartitioning.II.cpp)|Hard| -|131|[Palindrome Partitioning](https://oj.leetcode.com/problems/palindrome-partitioning/)| [C++](./algorithms/cpp/palindromePartitioning/palindromePartitioning.cpp)|Medium| -|130|[Surrounded Regions](https://oj.leetcode.com/problems/surrounded-regions/)| [C++](./algorithms/cpp/surroundedRegions/surroundedRegions.cpp)|Medium| -|129|[Sum Root to Leaf Numbers](https://oj.leetcode.com/problems/sum-root-to-leaf-numbers/)| [C++](./algorithms/cpp/sumRootToLeafNumber/sumRootToLeafNumber.cpp)|Medium| -|128|[Longest Consecutive Sequence](https://oj.leetcode.com/problems/longest-consecutive-sequence/)| [C++](./algorithms/cpp/longestConsecutiveSequence/longestConsecutiveSequence.cpp)|Hard| -|127|[Word Ladder](https://oj.leetcode.com/problems/word-ladder/)| [C++](./algorithms/cpp/wordLadder/wordLadder.cpp)|Medium| -|126|[Word Ladder II](https://oj.leetcode.com/problems/word-ladder-ii/)| [C++](./algorithms/cpp/wordLadder/wordLadder.II.cpp)|Hard| -|125|[Valid Palindrome](https://oj.leetcode.com/problems/valid-palindrome/)| [C++](./algorithms/cpp/validPalindrome/validPalindrome.cpp)|Easy| -|124|[Binary Tree Maximum Path Sum](https://oj.leetcode.com/problems/binary-tree-maximum-path-sum/)| [C++](./algorithms/cpp/binaryTreeMaximumPathSum/binaryTreeMaximumPathSum.cpp), [Java](./algorithms/java/src/binaryTreeMaximumPathSum/binaryTreeMaximumPathSum.java)|Hard| -|123|[Best Time to Buy and Sell Stock III](https://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/)| [C++](./algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.III.cpp)|Hard| -|122|[Best Time to Buy and Sell Stock II](https://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/)| [C++](./algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.II.cpp)|Medium| -|121|[Best Time to Buy and Sell Stock](https://oj.leetcode.com/problems/best-time-to-buy-and-sell-stock/)| [C++](./algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.cpp)|Medium| -|120|[Triangle](https://oj.leetcode.com/problems/triangle/)| [C++](./algorithms/cpp/triangle/triangle.cpp), [Java](./algorithms/java/src/dynamicProgramming/triangle/triangle.java)|Medium| -|119|[Pascal's Triangle II](https://oj.leetcode.com/problems/pascals-triangle-ii/)| [C++](./algorithms/cpp/pascalTriangle/pascalTriangle.II.cpp)|Easy| -|118|[Pascal's Triangle](https://oj.leetcode.com/problems/pascals-triangle/)| [C++](./algorithms/cpp/pascalTriangle/pascalTriangle.cpp)|Easy| -|117|[Populating Next Right Pointers in Each Node II](https://oj.leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/)| [C++](./algorithms/cpp/populatingNextRightPointersInEachNode/populatingNextRightPointersInEachNode.II.cpp)|Hard| -|116|[Populating Next Right Pointers in Each Node](https://oj.leetcode.com/problems/populating-next-right-pointers-in-each-node/)| [C++](./algorithms/cpp/populatingNextRightPointersInEachNode/populatingNextRightPointersInEachNode.cpp)|Medium| -|115|[Distinct Subsequences](https://oj.leetcode.com/problems/distinct-subsequences/)| [C++](./algorithms/cpp/distinctSubsequences/distinctSubsequences.cpp)|Hard| -|114|[Flatten Binary Tree to Linked List](https://oj.leetcode.com/problems/flatten-binary-tree-to-linked-list/)| [C++](./algorithms/cpp/flattenBinaryTreeToLinkedList/flattenBinaryTreeToLinkedList.cpp)|Medium| -|113|[Path Sum II](https://oj.leetcode.com/problems/path-sum-ii/)| [C++](./algorithms/cpp/pathSum/pathSum.II.cpp)|Medium| -|112|[Path Sum](https://oj.leetcode.com/problems/path-sum/)| [C++](./algorithms/cpp/pathSum/pathSum.cpp)|Easy| -|111|[Minimum Depth of Binary Tree](https://oj.leetcode.com/problems/minimum-depth-of-binary-tree/)| [C++](./algorithms/cpp/minimumDepthOfBinaryTree/minimumDepthOfBinaryTree.cpp)|Easy| -|110|[Balanced Binary Tree](https://oj.leetcode.com/problems/balanced-binary-tree/)| [C++](./algorithms/cpp/balancedBinaryTree/balancedBinaryTree.cpp), [Java](./algorithms/java/src/balancedBinaryTree/balancedBinaryTree.java)|Easy| -|109|[Convert Sorted List to Binary Search Tree](https://oj.leetcode.com/problems/convert-sorted-list-to-binary-search-tree/)| [C++](./algorithms/cpp/convertSortedListToBinarySearchTree/convertSortedListToBinarySearchTree.cpp)|Medium| -|108|[Convert Sorted Array to Binary Search Tree](https://oj.leetcode.com/problems/convert-sorted-array-to-binary-search-tree/)| [C++](./algorithms/cpp/convertSortedArrayToBinarySearchTree/convertSortedArrayToBinarySearchTree.cpp)|Medium| -|107|[Binary Tree Level Order Traversal II](https://oj.leetcode.com/problems/binary-tree-level-order-traversal-ii/)| [C++](./algorithms/cpp/binaryTreeLevelOrderTraversal/binaryTreeLevelOrderTraversal.II.cpp)|Easy| -|106|[Construct Binary Tree from Inorder and Postorder Traversal](https://oj.leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/)| [C++](./algorithms/cpp/constructBinaryTreeFromInorderAndPostorderTraversal/constructBinaryTreeFromInorderAndPostorderTraversal.cpp)|Medium| -|105|[Construct Binary Tree from Preorder and Inorder Traversal](https://oj.leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/)| [C++](./algorithms/cpp/constructBinaryTreeFromPreorderAndInorderTraversal/constructBinaryTreeFromPreorderAndInorderTraversal.cpp)|Medium| -|104|[Maximum Depth of Binary Tree](https://oj.leetcode.com/problems/maximum-depth-of-binary-tree/)| [C++](./algorithms/cpp/maximumDepthOfBinaryTree/maximumDepthOfBinaryTree.cpp), [Java](./algorithms/java/src/maximumDepthOfBinaryTree/maximumDepthOfBinaryTree.java)|Easy| -|103|[Binary Tree Zigzag Level Order Traversal](https://oj.leetcode.com/problems/binary-tree-zigzag-level-order-traversal/)| [C++](./algorithms/cpp/binaryTreeZigzagLevelOrderTraversal/binaryTreeZigzagLevelOrderTraversal.cpp)|Medium| -|102|[Binary Tree Level Order Traversal](https://oj.leetcode.com/problems/binary-tree-level-order-traversal/)| [C++](./algorithms/cpp/binaryTreeLevelOrderTraversal/binaryTreeLevelOrderTraversal.cpp), [Java](./algorithms/java/src/binaryTreeLevelOrderTraversal/binaryTreeLevelOrderTraversal.java)|Easy| -|101|[Symmetric Tree](https://oj.leetcode.com/problems/symmetric-tree/)| [C++](./algorithms/cpp/symmetricTree/symmetricTree.cpp)|Easy| -|100|[Same Tree](https://oj.leetcode.com/problems/same-tree/)| [C++](./algorithms/cpp/sameTree/sameTree.cpp)|Easy| -|99|[Recover Binary Search Tree](https://oj.leetcode.com/problems/recover-binary-search-tree/)| [C++](./algorithms/cpp/recoverBinarySearchTree/recoverBinarySearchTree.cpp)|Hard| -|98|[Validate Binary Search Tree](https://oj.leetcode.com/problems/validate-binary-search-tree/)| [C++](./algorithms/cpp/validateBinarySearchTree/validateBinarySearchTree.cpp), [Java](./algorithms/java/src/validateBinarySearchTree/validateBinarySearchTree.java)|Medium| -|97|[Interleaving String](https://oj.leetcode.com/problems/interleaving-string/)| [C++](./algorithms/cpp/interleavingString/interleavingString.cpp)|Hard| -|96|[Unique Binary Search Trees](https://oj.leetcode.com/problems/unique-binary-search-trees/)| [C++](./algorithms/cpp/uniqueBinarySearchTrees/uniqueBinarySearchTrees.cpp)|Medium| -|95|[Unique Binary Search Trees II](https://oj.leetcode.com/problems/unique-binary-search-trees-ii/)| [C++](./algorithms/cpp/uniqueBinarySearchTrees/uniqueBinarySearchTrees.II.cpp)|Medium| -|94|[Binary Tree Inorder Traversal](https://oj.leetcode.com/problems/binary-tree-inorder-traversal/)| [C++](./algorithms/cpp/binaryTreeInorderTraversal/binaryTreeInorderTraversal.cpp)|Medium| -|93|[Restore IP Addresses](https://oj.leetcode.com/problems/restore-ip-addresses/)| [C++](./algorithms/cpp/restoreIPAddresses/restoreIPAddresses.cpp)|Medium| -|92|[Reverse Linked List II](https://oj.leetcode.com/problems/reverse-linked-list-ii/)| [C++](./algorithms/cpp/reverseLinkedList/reverseLinkedList.II.cpp)|Medium| -|91|[Decode Ways](https://oj.leetcode.com/problems/decode-ways/)| [C++](./algorithms/cpp/decodeWays/decodeWays.cpp)|Medium| -|90|[Subsets II](https://oj.leetcode.com/problems/subsets-ii/)| [C++](./algorithms/cpp/subsets/subsets.II.cpp), [Java](./algorithms/java/src/subsets/subsetsII.java)|Medium| -|89|[Gray Code](https://oj.leetcode.com/problems/gray-code/)| [C++](./algorithms/cpp/grayCode/grayCode.cpp)|Medium| -|88|[Merge Sorted Array](https://oj.leetcode.com/problems/merge-sorted-array/)| [C++](./algorithms/cpp/mergeTwoSortedArray/mergeTwoSortedArray.cpp)|Easy| -|87|[Scramble String](https://oj.leetcode.com/problems/scramble-string/)| [C++](./algorithms/cpp/scrambleString/scrambleString.cpp)|Hard| -|86|[Partition List](https://oj.leetcode.com/problems/partition-list/)| [C++](./algorithms/cpp/partitionList/partitionList.cpp)|Medium| -|85|[Maximal Rectangle](https://oj.leetcode.com/problems/maximal-rectangle/)| [C++](./algorithms/cpp/maximalRectangle/maximalRectangle.cpp)|Hard| -|84|[Largest Rectangle in Histogram](https://oj.leetcode.com/problems/largest-rectangle-in-histogram/)| [C++](./algorithms/cpp/largestRectangleInHistogram/largestRectangleInHistogram.cpp)|Hard| -|83|[Remove Duplicates from Sorted List](https://oj.leetcode.com/problems/remove-duplicates-from-sorted-list/)| [C++](./algorithms/cpp/removeDuplicatesFromSortedList/removeDuplicatesFromSortedList.cpp)|Easy| -|82|[Remove Duplicates from Sorted List II](https://oj.leetcode.com/problems/remove-duplicates-from-sorted-list-ii/)| [C++](./algorithms/cpp/removeDuplicatesFromSortedList/removeDuplicatesFromSortedList.II.cpp)|Medium| -|81|[Search in Rotated Sorted Array II](https://oj.leetcode.com/problems/search-in-rotated-sorted-array-ii/)| [C++](./algorithms/cpp/searchInRotatedSortedArray/searchInRotatedSortedArray.II.cpp)|Medium| -|80|[Remove Duplicates from Sorted Array II](https://oj.leetcode.com/problems/remove-duplicates-from-sorted-array-ii/)| [C++](./algorithms/cpp/removeDuplicatesFromSortedArray/removeDuplicatesFromSortedArray.II.cpp)|Medium| -|79|[Word Search](https://oj.leetcode.com/problems/word-search/)| [C++](./algorithms/cpp/wordSearch/wordSearch.cpp)|Medium| -|78|[Subsets](https://oj.leetcode.com/problems/subsets/)| [C++](./algorithms/cpp/subsets/subsets.cpp), [Java](./algorithms/java/src/subsets/subsets.java)|Medium| -|77|[Combinations](https://oj.leetcode.com/problems/combinations/)| [C++](./algorithms/cpp/combinations/combinations.cpp)|Medium| -|76|[Minimum Window Substring](https://oj.leetcode.com/problems/minimum-window-substring/)| [C++](./algorithms/cpp/minimumWindowSubstring/minimumWindowSubstring.cpp)|Hard| -|75|[Sort Colors](https://oj.leetcode.com/problems/sort-colors/)| [C++](./algorithms/cpp/sortColors/sortColors.cpp)|Medium| -|74|[Search a 2D Matrix](https://oj.leetcode.com/problems/search-a-2d-matrix/)| [C++](./algorithms/cpp/search2DMatrix/search2DMatrix.cpp), [Java](./algorithms/java/src/search2DMatrix/search2DMatrix.java)|Medium| -|73|[Set Matrix Zeroes](https://oj.leetcode.com/problems/set-matrix-zeroes/)| [C++](./algorithms/cpp/setMatrixZeroes/setMatrixZeroes.cpp)|Medium| -|72|[Edit Distance](https://oj.leetcode.com/problems/edit-distance/)| [C++](./algorithms/cpp/editDistance/editDistance.cpp)|Hard| -|71|[Simplify Path](https://oj.leetcode.com/problems/simplify-path/)| [C++](./algorithms/cpp/simplifyPath/simplifyPath.cpp)|Medium| -|70|[Climbing Stairs](https://oj.leetcode.com/problems/climbing-stairs/)| [C++](./algorithms/cpp/climbStairs/climbStairs.cpp), [Java](./algorithms/java/src/dynamicProgramming/climbStairs/climbStairs.java)|Easy| -|69|[Sqrt(x)](https://oj.leetcode.com/problems/sqrtx/)| [C++](./algorithms/cpp/sqrt/sqrt.cpp)|Medium| -|68|[Text Justification](https://oj.leetcode.com/problems/text-justification/)| [C++](./algorithms/cpp/textJustification/textJustification.cpp)|Hard| -|67|[Add Binary](https://oj.leetcode.com/problems/add-binary/)| [C++](./algorithms/cpp/addBinary/addBinary.cpp)|Easy| -|66|[Plus One](https://oj.leetcode.com/problems/plus-one/)| [C++](./algorithms/cpp/plusOne/plusOne.cpp)|Easy| -|65|[Valid Number](https://oj.leetcode.com/problems/valid-number/)| [C++](./algorithms/cpp/validNumber/validNumber.cpp)|Easy| -|64|[Minimum Path Sum](https://oj.leetcode.com/problems/minimum-path-sum/)| [C++](./algorithms/cpp/minimumPathSum/minimumPathSum.cpp), [Java](./algorithms/java/src/dynamicProgramming/minimumPathSum/minimumPathSum.java)|Medium| -|63|[Unique Paths II](https://oj.leetcode.com/problems/unique-paths-ii/)| [C++](./algorithms/cpp/uniquePaths/uniquePaths.II.cpp), [Java](./algorithms/java/src/dynamicProgramming/uniquePaths/uniquePathsII.java)|Medium| -|62|[Unique Paths](https://oj.leetcode.com/problems/unique-paths/)| [C++](./algorithms/cpp/uniquePaths/uniquePaths.cpp), [Java](./algorithms/java/src/dynamicProgramming/uniquePaths/uniquePaths.java)|Medium| -|61|[Rotate List](https://oj.leetcode.com/problems/rotate-list/)| [C++](./algorithms/cpp/rotateList/rotateList.cpp)|Medium| -|60|[Permutation Sequence](https://oj.leetcode.com/problems/permutation-sequence/)| [C++](./algorithms/cpp/permutationSequence/permutationSequence.cpp)|Medium| -|59|[Spiral Matrix II](https://oj.leetcode.com/problems/spiral-matrix-ii/)| [C++](./algorithms/cpp/spiralMatrix/spiralMatrix.II.cpp)|Medium| -|58|[Length of Last Word](https://oj.leetcode.com/problems/length-of-last-word/)| [C++](./algorithms/cpp/lengthOfLastWord/lengthOfLastWord.cpp)|Easy| -|57|[Insert Interval](https://oj.leetcode.com/problems/insert-interval/)| [C++](./algorithms/cpp/insertInterval/insertInterval.cpp)|Hard| -|56|[Merge Intervals](https://oj.leetcode.com/problems/merge-intervals/)| [C++](./algorithms/cpp/mergeIntervals/mergeIntervals.cpp)|Hard| -|55|[Jump Game](https://oj.leetcode.com/problems/jump-game/)| [C++](./algorithms/cpp/jumpGame/jumpGame.cpp)|Medium| -|54|[Spiral Matrix](https://oj.leetcode.com/problems/spiral-matrix/)| [C++](./algorithms/cpp/spiralMatrix/spiralMatrix.cpp)|Medium| -|53|[Maximum Subarray](https://oj.leetcode.com/problems/maximum-subarray/)| [C++](./algorithms/cpp/maximumSubArray/maximumSubArray.cpp)|Medium| -|52|[N-Queens II](https://oj.leetcode.com/problems/n-queens-ii/)| [C++](./algorithms/cpp/nQueens/nQueuens.II.cpp)|Hard| -|51|[N-Queens](https://oj.leetcode.com/problems/n-queens/)| [C++](./algorithms/cpp/nQueens/nQueuens.cpp)|Hard| -|50|["Pow(x, n)"](https://oj.leetcode.com/problems/powx-n/)| [C++](./algorithms/cpp/pow/pow.cpp)|Medium| -|49|[Group Anagrams](https://oj.leetcode.com/problems/anagrams/)| [C++](./algorithms/cpp/anagrams/GroupAnagrams.cpp)|Medium| -|48|[Rotate Image](https://oj.leetcode.com/problems/rotate-image/)| [C++](./algorithms/cpp/rotateImage/rotateImage.cpp)|Medium| -|47|[Permutations II](https://oj.leetcode.com/problems/permutations-ii/)| [C++](./algorithms/cpp/permutations/permutations.II.cpp)|Hard| -|46|[Permutations](https://oj.leetcode.com/problems/permutations/)| [C++](./algorithms/cpp/permutations/permutations.cpp)|Medium| -|45|[Jump Game II](https://oj.leetcode.com/problems/jump-game-ii/)| [C++](./algorithms/cpp/jumpGame/jumpGame.II.cpp)|Hard| -|44|[Wildcard Matching](https://oj.leetcode.com/problems/wildcard-matching/)| [C++](./algorithms/cpp/wildcardMatching/wildcardMatching.cpp)|Hard| -|43|[Multiply Strings](https://oj.leetcode.com/problems/multiply-strings/)| [C++](./algorithms/cpp/multiplyStrings/multiplyStrings.cpp)|Medium| -|42|[Trapping Rain Water](https://oj.leetcode.com/problems/trapping-rain-water/)| [C++](./algorithms/cpp/trappingRainWater/trappingRainWater.cpp)|Hard| -|41|[First Missing Positive](https://oj.leetcode.com/problems/first-missing-positive/)| [C++](./algorithms/cpp/firstMissingPositive/firstMissingPositive.cpp)|Hard| -|40|[Combination Sum II](https://oj.leetcode.com/problems/combination-sum-ii/)| [C++](./algorithms/cpp/combinationSum/combinationSum.II.cpp)|Medium| -|39|[Combination Sum](https://oj.leetcode.com/problems/combination-sum/)| [C++](./algorithms/cpp/combinationSum/combinationSum.cpp)|Medium| -|38|[Count and Say](https://oj.leetcode.com/problems/count-and-say/)| [C++](./algorithms/cpp/countAndSay/countAndSay.cpp)|Easy| -|37|[Sudoku Solver](https://oj.leetcode.com/problems/sudoku-solver/)| [C++](./algorithms/cpp/sudokuSolver/sudokuSolver.cpp)|Hard| -|36|[Valid Sudoku](https://oj.leetcode.com/problems/valid-sudoku/)| [C++](./algorithms/cpp/validSudoku/validSudoku.cpp)|Easy| -|35|[Search Insert Position](https://oj.leetcode.com/problems/search-insert-position/)| [C++](./algorithms/cpp/searchInsertPosition/searchInsertPosition.cpp), [Java](./algorithms/java/src/searchInsertPosition/searchInsertPosition.java)|Medium| -|34|[Search for a Range](https://oj.leetcode.com/problems/search-for-a-range/)| [C++](./algorithms/cpp/searchForRange/searchForRange.cpp), [Java](./algorithms/java/src/searchForRange/searchForRange.java)|Medium| -|33|[Search in Rotated Sorted Array](https://oj.leetcode.com/problems/search-in-rotated-sorted-array/)| [C++](./algorithms/cpp/searchInRotatedSortedArray/searchInRotatedSortedArray.cpp), [Java](./algorithms/java/src/searchInRotatedSortedArray/searchInRotatedSortedArray.java)|Hard| -|32|[Longest Valid Parentheses](https://oj.leetcode.com/problems/longest-valid-parentheses/)| [C++](./algorithms/cpp/longestValidParentheses/longestValidParentheses.cpp)|Hard| -|31|[Next Permutation](https://oj.leetcode.com/problems/next-permutation/)| [C++](./algorithms/cpp/nextPermutation/nextPermutation.cpp)|Medium| -|30|[Substring with Concatenation of All Words](https://oj.leetcode.com/problems/substring-with-concatenation-of-all-words/)| [C++](./algorithms/cpp/substringWithConcatenationOfAllWords/substringWithConcatenationOfAllWords.cpp)|Hard| -|29|[Divide Two Integers](https://oj.leetcode.com/problems/divide-two-integers/)| [C++](./algorithms/cpp/divideTwoInt/divideTwoInt.cpp)|Medium| -|28|[Implement strStr()](https://oj.leetcode.com/problems/implement-strstr/)| [C++](./algorithms/cpp/strStr/strStr.cpp), [Java](./algorithms/java/src/strStr/strStr.java)|Easy| -|27|[Remove Element](https://oj.leetcode.com/problems/remove-element/)| [C++](./algorithms/cpp/removeElement/removeElement.cpp)|Easy| -|26|[Remove Duplicates from Sorted Array](https://oj.leetcode.com/problems/remove-duplicates-from-sorted-array/)| [C++](./algorithms/cpp/removeDuplicatesFromSortedArray/removeDuplicatesFromSortedArray.cpp)|Easy| -|25|[Reverse Nodes in k-Group](https://oj.leetcode.com/problems/reverse-nodes-in-k-group/)| [C++](./algorithms/cpp/reverseNodesInKGroup/reverseNodesInKGroup.cpp)|Hard| -|24|[Swap Nodes in Pairs](https://oj.leetcode.com/problems/swap-nodes-in-pairs/)| [C++](./algorithms/cpp/swapNodesInPairs/swapNodesInPairs.cpp)|Medium| -|23|[Merge k Sorted Lists](https://oj.leetcode.com/problems/merge-k-sorted-lists/)| [C++](./algorithms/cpp/mergeKSortedLists/mergeKSortedLists.cpp)|Hard| -|22|[Generate Parentheses](https://oj.leetcode.com/problems/generate-parentheses/)| [C++](./algorithms/cpp/generateParentheses/generateParentheses.cpp)|Medium| -|21|[Merge Two Sorted Lists](https://oj.leetcode.com/problems/merge-two-sorted-lists/)| [C++](./algorithms/cpp/mergeTwoSortedList/mergeTwoSortedList.cpp)|Easy| -|20|[Valid Parentheses](https://oj.leetcode.com/problems/valid-parentheses/)| [C++](./algorithms/cpp/validParentheses/validParentheses.cpp)|Easy| -|19|[Remove Nth Node From End of List](https://oj.leetcode.com/problems/remove-nth-node-from-end-of-list/)| [C++](./algorithms/cpp/removeNthNodeFromEndOfList/removeNthNodeFromEndOfList.cpp)|Easy| -|18|[4Sum](https://oj.leetcode.com/problems/4sum/)| [C++](./algorithms/cpp/4Sum/4Sum.cpp)|Medium| -|17|[Letter Combinations of a Phone Number](https://oj.leetcode.com/problems/letter-combinations-of-a-phone-number/)| [C++](./algorithms/cpp/letterCombinationsOfAPhoneNumber/letterCombinationsOfAPhoneNumber.cpp)|Medium| -|16|[3Sum Closest](https://oj.leetcode.com/problems/3sum-closest/)| [C++](./algorithms/cpp/3SumClosest/3SumClosest.cpp)|Medium| -|15|[3Sum](https://oj.leetcode.com/problems/3sum/)| [C++](./algorithms/cpp/3Sum/3Sum.cpp)|Medium| -|14|[Longest Common Prefix](https://oj.leetcode.com/problems/longest-common-prefix/)| [C++](./algorithms/cpp/longestCommonPrefix/longestCommonPrefix.cpp)|Easy| -|13|[Roman to Integer](https://oj.leetcode.com/problems/roman-to-integer/)| [C++](./algorithms/cpp/romanToInteger/romanToInteger.cpp)|Easy| -|12|[Integer to Roman](https://oj.leetcode.com/problems/integer-to-roman/)| [C++](./algorithms/cpp/integerToRoman/integerToRoman.cpp)|Medium| -|11|[Container With Most Water](https://oj.leetcode.com/problems/container-with-most-water/)| [C++](./algorithms/cpp/containerWithMostWater/containerWithMostWater.cpp)|Medium| -|10|[Regular Expression Matching](https://oj.leetcode.com/problems/regular-expression-matching/)| [C++](./algorithms/cpp/regularExpressionMatching/regularExpressionMatching.cpp)|Hard| -|9|[Palindrome Number](https://oj.leetcode.com/problems/palindrome-number/)| [C++](./algorithms/cpp/palindromeNumber/palindromeNumber.cpp)|Easy| -|8|[String to Integer (atoi)](https://oj.leetcode.com/problems/string-to-integer-atoi/)| [C++](./algorithms/cpp/stringToIntegerAtoi/stringToIntegerAtoi.cpp)|Easy| -|7|[Reverse Integer](https://oj.leetcode.com/problems/reverse-integer/)| [C++](./algorithms/cpp/reverseInteger/reverseInteger.cpp)|Easy| -|6|[ZigZag Conversion](https://oj.leetcode.com/problems/zigzag-conversion/)| [C++](./algorithms/cpp/zigZagConversion/zigZagConversion.cpp)|Easy| -|5|[Longest Palindromic Substring](https://oj.leetcode.com/problems/longest-palindromic-substring/)| [C++](./algorithms/cpp/longestPalindromicSubstring/longestPalindromicSubstring.cpp)|Medium| -|4|[Median of Two Sorted Arrays](https://oj.leetcode.com/problems/median-of-two-sorted-arrays/)| [C++](./algorithms/cpp/medianOfTwoSortedArrays/medianOfTwoSortedArrays.cpp)|Hard| -|3|[Longest Substring Without Repeating Characters](https://oj.leetcode.com/problems/longest-substring-without-repeating-characters/)| [C++](./algorithms/cpp/longestSubstringWithoutRepeatingCharacters/longestSubstringWithoutRepeatingCharacters.cpp)|Medium| -|2|[Add Two Numbers](https://oj.leetcode.com/problems/add-two-numbers/)| [C++](./algorithms/cpp/addTwoNumbers/addTwoNumbers.cpp)|Medium| -|1|[Two Sum](https://oj.leetcode.com/problems/two-sum/)| [C++](./algorithms/cpp/twoSum/twoSum.cpp)|Medium| +|198|[House Robber](https://leetcode.com/problems/house-robber/)| [C++](./algorithms/cpp/houseRobber/houseRobber.cpp), [Python](./algorithms/python/HouseRobber/rob.py)|Easy| +|191|[Number of 1 Bits](https://leetcode.com/problems/number-of-1-bits/)| [C++](./algorithms/cpp/numberOf1Bits/numberOf1Bits.cpp)|Easy| +|190|[Reverse Bits](https://leetcode.com/problems/reverse-bits/)| [C++](./algorithms/cpp/reverseBits/reverseBits.cpp)|Easy| +|189|[Rotate Array](https://leetcode.com/problems/rotate-array/)| [C++](./algorithms/cpp/rotateArray/rotateArray.cpp), [Java](./algorithms/java/src/rotateArray/RotateArray.java)|Easy| +|188|[Best Time to Buy and Sell Stock IV](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/)| [C++](./algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.IV.cpp)|Hard| +|187|[Repeated DNA Sequences](https://leetcode.com/problems/repeated-dna-sequences/)| [C++](./algorithms/cpp/repeatedDNASequences/repeatedDNASequences.cpp)|Medium| +|186|[Reverse Words in a String II](https://leetcode.com/problems/reverse-words-in-a-string-ii/) ♥ | [C++](./algorithms/cpp/reverseWordsInAString/reverseWordsInAString.II.cpp)|Medium| +|179|[Largest Number](https://leetcode.com/problems/largest-number/) | [C++](./algorithms/cpp/largestNumber/largestNumber.cpp)|Medium| +|174|[Dungeon Game](https://leetcode.com/problems/dungeon-game/) | [C++](./algorithms/cpp/dungeonGame/dungeonGame.cpp)|Hard| +|173|[Binary Search Tree Iterator](https://leetcode.com/problems/binary-search-tree-iterator/) | [C++](./algorithms/cpp/binarySearchTreeIterator/binarySearchTreeIterator.cpp), [Java](./algorithms/java/src/binarySearchTreeIterator/binarySearchTreeIterator.java), [Python](./algorithms/python/BinarySearchTreeIterator/BSTIterator.py)|Medium| +|172|[Factorial Trailing Zeroes](https://leetcode.com/problems/factorial-trailing-zeroes/) | [C++](./algorithms/cpp/factorialTrailingZeroes/factorialTrailingZeroes.cpp)|Easy| +|171|[Excel Sheet Column Number](https://leetcode.com/problems/excel-sheet-column-number/) | [C++](./algorithms/cpp/excelSheetColumnNumber/excelSheetColumnNumber.cpp)|Easy| +|170|[Two Sum III - Data structure design](https://leetcode.com/problems/two-sum-iii-data-structure-design/) ♥ | [C++](./algorithms/cpp/twoSum/twoSum.III.cpp)|Easy| +|169|[Majority Element](https://leetcode.com/problems/majority-element/) | [C++](./algorithms/cpp/majorityElement/majorityElement.cpp)|Easy| +|168|[Excel Sheet Column Title](https://leetcode.com/problems/excel-sheet-column-title/) | [C++](./algorithms/cpp/excelSheetColumnTitle/excelSheetColumnTitle.cpp)|Easy| +|167|[Two Sum II - Input array is sorted](https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/) ♥ | [C++](./algorithms/cpp/twoSum/twoSum.II.cpp)|Medium| +|166|[Fraction to Recurring Decimal](https://leetcode.com/problems/fraction-to-recurring-decimal/) | [C++](./algorithms/cpp/fractionToRecurringDecimal/fractionToRecurringDecimal.cpp)|Medium| +|165|[Compare Version Numbers](https://leetcode.com/problems/compare-version-numbers/) | [C++](./algorithms/cpp/compareVersionNumbers/compareVersionNumbers.cpp)|Easy| +|164|[Maximum Gap](https://leetcode.com/problems/maximum-gap/) | [C++](./algorithms/cpp/maximumGap/maximumGap.cpp)|Hard| +|163|[Missing Ranges](https://leetcode.com/problems/missing-ranges/) ♥ | [C++](./algorithms/cpp/missingRanges/missingRanges.cpp)|Medium| +|162|[Find Peak Element](https://leetcode.com/problems/find-peak-element/) | [C++](./algorithms/cpp/findPeakElement/findPeakElement.cpp), [Java](./algorithms/java/src/findPeakElement/findPeakElement.java)|Medium| +|161|[One Edit Distance](https://leetcode.com/problems/one-edit-distance/)♥ | [C++](./algorithms/cpp/oneEditDistance/oneEditDistance.cpp)|Medium| +|160|[Intersection of Two Linked Lists](https://leetcode.com/problems/intersection-of-two-linked-lists/) | [C++](./algorithms/cpp/intersectionOfTwoLinkedLists/intersectionOfTwoLinkedLists.cpp)|Easy| +|159|[Longest Substring with At Most Two Distinct Characters](https://leetcode.com/problems/longest-substring-with-at-most-two-distinct-characters/) ♥ | [C++](./algorithms/cpp/longestSubstringWithAtMostTwoDistinctCharacters/longestSubstringWithAtMostTwoDistinctCharacters.cpp)|Hard| +|158|[Read N Characters Given Read4 II - Call multiple times](https://leetcode.com/problems/read-n-characters-given-read4-ii-call-multiple-times/) ♥ | [C++](./algorithms/cpp/readNCharactersGivenRead4/readNCharactersGivenRead4.II.cpp)|Hard| +|157|[Read N Characters Given Read4](https://leetcode.com/problems/read-n-characters-given-read4/) ♥ | [C++](./algorithms/cpp/readNCharactersGivenRead4/readNCharactersGivenRead4.cpp)|Easy| +|156|[Binary Tree Upside Down](https://leetcode.com/problems/binary-tree-upside-down/) ♥ | [C++](./algorithms/cpp/binaryTreeUpsideDown/binaryTreeUpsideDown.cpp)|Medium| +|155|[Min Stack](https://leetcode.com/problems/min-stack/)| [C++](./algorithms/cpp/minStack/minStack.cpp), [Java](./algorithms/java/src/minStack/MinStack.java)|Easy| +|154|[Find Minimum in Rotated Sorted Array II](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/)| [C++](./algorithms/cpp/findMinimumInRotatedSortedArray/findMinimumInRotatedSortedArray.II.cpp)|Hard| +|153|[Find Minimum in Rotated Sorted Array](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/)| [C++](./algorithms/cpp/findMinimumInRotatedSortedArray/findMinimumInRotatedSortedArray.cpp), [Java](./algorithms/java/src/findMinimumInRotatedSortedArray/findMinimumInRotatedSortedArray.java)|Medium| +|152|[Maximum Product Subarray](https://leetcode.com/problems/maximum-product-subarray/)| [C++](./algorithms/cpp/maximumProductSubarray/maximumProductSubarray.cpp)|Medium| +|151|[Reverse Words in a String](https://leetcode.com/problems/reverse-words-in-a-string/)| [C++](./algorithms/cpp/reverseWordsInAString/reverseWordsInAString.cpp), [Java](./algorithms/java/src/reverseWordsInAString/ReverseWordsInAString.java)|Medium| +|150|[Evaluate Reverse Polish Notation](https://leetcode.com/problems/evaluate-reverse-polish-notation/)| [C++](./algorithms/cpp/evaluateReversePolishNotation/evaluateReversePolishNotation.cpp)|Medium| +|149|[Max Points on a Line](https://leetcode.com/problems/max-points-on-a-line/)| [C++](./algorithms/cpp/maxPointsOnALine/maxPointsOnALine.cpp)|Hard| +|148|[Sort List](https://leetcode.com/problems/sort-list/)| [C++](./algorithms/cpp/sortList/sortList.cpp), [Python](./algorithms/python/SortList/sortList.py)|Medium| +|147|[Insertion Sort List](https://leetcode.com/problems/insertion-sort-list/)| [C++](./algorithms/cpp/insertionSortList/insertionSortList.cpp), [Python](./algorithms/python/InsertionSortList/insertionSortList.py)|Medium| +|146|[LRU Cache](https://leetcode.com/problems/lru-cache/)| [C++](./algorithms/cpp/LRUCache/LRUCache.cpp), [Java](./algorithms/java/src/lruCache/LRUCache.java)|Hard| +|145|[Binary Tree Postorder Traversal](https://leetcode.com/problems/binary-tree-postorder-traversal/)| [C++](./algorithms/cpp/binaryTreePostorderTraversal/binaryTreePostorderTraversal.cpp), [Python](./algorithms/python/BinaryTreePostorderTraversal/postorderTraversal.py)|Hard| +|144|[Binary Tree Preorder Traversal](https://leetcode.com/problems/binary-tree-preorder-traversal/)| [C++](./algorithms/cpp/binaryTreePreorderTraversal/binaryTreePreorderTraversal.cpp), [Java](./algorithms/java/src/binaryTreePreorderTraversal/binaryTreePreorderTraversal.java)|Medium| +|143|[Reorder List](https://leetcode.com/problems/reorder-list/)| [C++](./algorithms/cpp/reorderList/reorderList.cpp), [Python](./algorithms/python/ReorderList/reorderList.py)|Medium| +|142|[Linked List Cycle II](https://leetcode.com/problems/linked-list-cycle-ii/)| [C++](./algorithms/cpp/linkedListCycle/linkedListCycle.II.cpp), [Python](./algorithms/python/LinkedListCycleII/detectCycle.py)|Medium| +|141|[Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/)| [C++](./algorithms/cpp/linkedListCycle/linkedListCycle.cpp)|Medium| +|140|[Word Break II](https://leetcode.com/problems/word-break-ii/)| [C++](./algorithms/cpp/wordBreak/wordBreak.II.cpp)|Hard| +|139|[Word Break](https://leetcode.com/problems/word-break/)| [C++](./algorithms/cpp/wordBreak/wordBreak.cpp)|Medium| +|138|[Copy List with Random Pointer](https://leetcode.com/problems/copy-list-with-random-pointer/)| [C++](./algorithms/cpp/copyListWithRandomPointer/copyListWithRandomPointer.cpp), [Python](./algorithms/python/CopyListWithRandomPointer/copyRandomList.py)|Hard| +|137|[Single Number II](https://leetcode.com/problems/single-number-ii/)| [C++](./algorithms/cpp/singleNumber/singleNumber.II.cpp)|Medium| +|136|[Single Number](https://leetcode.com/problems/single-number/)| [C++](./algorithms/cpp/singleNumber/singleNumber.cpp)|Medium| +|135|[Candy](https://leetcode.com/problems/candy/)| [C++](./algorithms/cpp/candy/candy.cpp)|Hard| +|134|[Gas Station](https://leetcode.com/problems/gas-station/)| [C++](./algorithms/cpp/gasStation/gasStation.cpp)|Medium| +|133|[Clone Graph](https://leetcode.com/problems/clone-graph/)| [C++](./algorithms/cpp/cloneGraph/cloneGraph.cpp)|Medium| +|132|[Palindrome Partitioning II](https://leetcode.com/problems/palindrome-partitioning-ii/)| [C++](./algorithms/cpp/palindromePartitioning/palindromePartitioning.II.cpp)|Hard| +|131|[Palindrome Partitioning](https://leetcode.com/problems/palindrome-partitioning/)| [C++](./algorithms/cpp/palindromePartitioning/palindromePartitioning.cpp)|Medium| +|130|[Surrounded Regions](https://leetcode.com/problems/surrounded-regions/)| [C++](./algorithms/cpp/surroundedRegions/surroundedRegions.cpp)|Medium| +|129|[Sum Root to Leaf Numbers](https://leetcode.com/problems/sum-root-to-leaf-numbers/)| [C++](./algorithms/cpp/sumRootToLeafNumber/sumRootToLeafNumber.cpp), [Python](./algorithms/python/SumRootToLeafNumbers/sumNumbers.py)|Medium| +|128|[Longest Consecutive Sequence](https://leetcode.com/problems/longest-consecutive-sequence/)| [C++](./algorithms/cpp/longestConsecutiveSequence/longestConsecutiveSequence.cpp)|Hard| +|127|[Word Ladder](https://leetcode.com/problems/word-ladder/)| [C++](./algorithms/cpp/wordLadder/wordLadder.cpp)|Medium| +|126|[Word Ladder II](https://leetcode.com/problems/word-ladder-ii/)| [C++](./algorithms/cpp/wordLadder/wordLadder.II.cpp)|Hard| +|125|[Valid Palindrome](https://leetcode.com/problems/valid-palindrome/)| [C++](./algorithms/cpp/validPalindrome/validPalindrome.cpp), [Java](./algorithms/java/src/validPalindrome/ValidPalindrome.java)|Easy| +|124|[Binary Tree Maximum Path Sum](https://leetcode.com/problems/binary-tree-maximum-path-sum/)| [C++](./algorithms/cpp/binaryTreeMaximumPathSum/binaryTreeMaximumPathSum.cpp), [Java](./algorithms/java/src/binaryTreeMaximumPathSum/binaryTreeMaximumPathSum.java)|Hard| +|123|[Best Time to Buy and Sell Stock III](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/)| [C++](./algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.III.cpp)|Hard| +|122|[Best Time to Buy and Sell Stock II](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/)| [C++](./algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.II.cpp)|Medium| +|121|[Best Time to Buy and Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/)| [C++](./algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.cpp)|Medium| +|120|[Triangle](https://leetcode.com/problems/triangle/)| [C++](./algorithms/cpp/triangle/triangle.cpp), [Java](./algorithms/java/src/dynamicProgramming/triangle/triangle.java)|Medium| +|119|[Pascal's Triangle II](https://leetcode.com/problems/pascals-triangle-ii/)| [C++](./algorithms/cpp/pascalTriangle/pascalTriangle.II.cpp)|Easy| +|118|[Pascal's Triangle](https://leetcode.com/problems/pascals-triangle/)| [C++](./algorithms/cpp/pascalTriangle/pascalTriangle.cpp)|Easy| +|117|[Populating Next Right Pointers in Each Node II](https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/)| [C++](./algorithms/cpp/populatingNextRightPointersInEachNode/populatingNextRightPointersInEachNode.II.cpp), [Python](./algorithms/python/PopulatingNextRightPointersInEachNodeII/connect.py)|Hard| +|116|[Populating Next Right Pointers in Each Node](https://leetcode.com/problems/populating-next-right-pointers-in-each-node/)| [C++](./algorithms/cpp/populatingNextRightPointersInEachNode/populatingNextRightPointersInEachNode.cpp), [Python](./algorithms/python/PopulatingNextRightPointersInEachNode/connect.py)|Medium| +|115|[Distinct Subsequences](https://leetcode.com/problems/distinct-subsequences/)| [C++](./algorithms/cpp/distinctSubsequences/distinctSubsequences.cpp)|Hard| +|114|[Flatten Binary Tree to Linked List](https://leetcode.com/problems/flatten-binary-tree-to-linked-list/)| [C++](./algorithms/cpp/flattenBinaryTreeToLinkedList/flattenBinaryTreeToLinkedList.cpp), [Python](./algorithms/python/FlattenBinaryTreeToLinkedList/flatten.py)|Medium| +|113|[Path Sum II](https://leetcode.com/problems/path-sum-ii/)| [C++](./algorithms/cpp/pathSum/pathSum.II.cpp), [Python](./algorithms/python/PathSumII/pathSum.py)|Medium| +|112|[Path Sum](https://leetcode.com/problems/path-sum/)| [C++](./algorithms/cpp/pathSum/pathSum.cpp)|Easy| +|111|[Minimum Depth of Binary Tree](https://leetcode.com/problems/minimum-depth-of-binary-tree/)| [C++](./algorithms/cpp/minimumDepthOfBinaryTree/minimumDepthOfBinaryTree.cpp)|Easy| +|110|[Balanced Binary Tree](https://leetcode.com/problems/balanced-binary-tree/)| [C++](./algorithms/cpp/balancedBinaryTree/balancedBinaryTree.cpp), [Java](./algorithms/java/src/balancedBinaryTree/balancedBinaryTree.java)|Easy| +|109|[Convert Sorted List to Binary Search Tree](https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/)| [C++](./algorithms/cpp/convertSortedListToBinarySearchTree/convertSortedListToBinarySearchTree.cpp)|Medium| +|108|[Convert Sorted Array to Binary Search Tree](https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/)| [C++](./algorithms/cpp/convertSortedArrayToBinarySearchTree/convertSortedArrayToBinarySearchTree.cpp)|Medium| +|107|[Binary Tree Level Order Traversal II](https://leetcode.com/problems/binary-tree-level-order-traversal-ii/)| [C++](./algorithms/cpp/binaryTreeLevelOrderTraversal/binaryTreeLevelOrderTraversal.II.cpp)|Easy| +|106|[Construct Binary Tree from Inorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/)| [C++](./algorithms/cpp/constructBinaryTreeFromInorderAndPostorderTraversal/constructBinaryTreeFromInorderAndPostorderTraversal.cpp), [Python](./algorithms/python/ConstructBinaryTreeFromInorderAndPostorderTraversal/buildTree.py)|Medium| +|105|[Construct Binary Tree from Preorder and Inorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/)| [C++](./algorithms/cpp/constructBinaryTreeFromPreorderAndInorderTraversal/constructBinaryTreeFromPreorderAndInorderTraversal.cpp), [Python](./algorithms/python/ConstructBinaryTreeFromPreorderAndInorderTraversal/buildTree.py)|Medium| +|104|[Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/)| [C++](./algorithms/cpp/maximumDepthOfBinaryTree/maximumDepthOfBinaryTree.cpp), [Java](./algorithms/java/src/maximumDepthOfBinaryTree/maximumDepthOfBinaryTree.java)|Easy| +|103|[Binary Tree Zigzag Level Order Traversal](https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/)| [C++](./algorithms/cpp/binaryTreeZigzagLevelOrderTraversal/binaryTreeZigzagLevelOrderTraversal.cpp), [Python](./algorithms/python/BinaryTreeZigzagLevelOrderTraversal/zigzagLevelOrder.py)|Medium| +|102|[Binary Tree Level Order Traversal](https://leetcode.com/problems/binary-tree-level-order-traversal/)| [C++](./algorithms/cpp/binaryTreeLevelOrderTraversal/binaryTreeLevelOrderTraversal.cpp), [Java](./algorithms/java/src/binaryTreeLevelOrderTraversal/binaryTreeLevelOrderTraversal.java)|Easy| +|101|[Symmetric Tree](https://leetcode.com/problems/symmetric-tree/)| [C++](./algorithms/cpp/symmetricTree/symmetricTree.cpp)|Easy| +|100|[Same Tree](https://leetcode.com/problems/same-tree/)| [C++](./algorithms/cpp/sameTree/sameTree.cpp)|Easy| +|99|[Recover Binary Search Tree](https://leetcode.com/problems/recover-binary-search-tree/)| [C++](./algorithms/cpp/recoverBinarySearchTree/recoverBinarySearchTree.cpp)|Hard| +|98|[Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree/)| [C++](./algorithms/cpp/validateBinarySearchTree/validateBinarySearchTree.cpp), [Java](./algorithms/java/src/validateBinarySearchTree/validateBinarySearchTree.java), [Python](./algorithms/python/ValidateBinarySearchTree/isValidBST.py)|Medium| +|97|[Interleaving String](https://leetcode.com/problems/interleaving-string/)| [C++](./algorithms/cpp/interleavingString/interleavingString.cpp)|Hard| +|96|[Unique Binary Search Trees](https://leetcode.com/problems/unique-binary-search-trees/)| [C++](./algorithms/cpp/uniqueBinarySearchTrees/uniqueBinarySearchTrees.cpp), [Python](./algorithms/python/UniqueBinarySearchTrees/numTrees.py)|Medium| +|95|[Unique Binary Search Trees II](https://leetcode.com/problems/unique-binary-search-trees-ii/)| [C++](./algorithms/cpp/uniqueBinarySearchTrees/uniqueBinarySearchTrees.II.cpp), [Python](./algorithms/python/UniqueBinarySearchTreesII/generateTrees.py)|Medium| +|94|[Binary Tree Inorder Traversal](https://leetcode.com/problems/binary-tree-inorder-traversal/)| [C++](./algorithms/cpp/binaryTreeInorderTraversal/binaryTreeInorderTraversal.cpp)|Medium| +|93|[Restore IP Addresses](https://leetcode.com/problems/restore-ip-addresses/)| [C++](./algorithms/cpp/restoreIPAddresses/restoreIPAddresses.cpp)|Medium| +|92|[Reverse Linked List II](https://leetcode.com/problems/reverse-linked-list-ii/)| [C++](./algorithms/cpp/reverseLinkedList/reverseLinkedList.II.cpp), [Java](./algorithms/java/src/reverseLinkedListII/ReverseLinkedListII.java), [Python](./algorithms/python/ReverseLinkedListII/reverseBetween.py)|Medium| +|91|[Decode Ways](https://leetcode.com/problems/decode-ways/)| [C++](./algorithms/cpp/decodeWays/decodeWays.cpp)|Medium| +|90|[Subsets II](https://leetcode.com/problems/subsets-ii/)| [C++](./algorithms/cpp/subsets/subsets.II.cpp), [Java](./algorithms/java/src/subsets/subsetsII.java)|Medium| +|89|[Gray Code](https://leetcode.com/problems/gray-code/)| [C++](./algorithms/cpp/grayCode/grayCode.cpp)|Medium| +|88|[Merge Sorted Array](https://leetcode.com/problems/merge-sorted-array/)| [C++](./algorithms/cpp/mergeTwoSortedArray/mergeTwoSortedArray.cpp)|Easy| +|87|[Scramble String](https://leetcode.com/problems/scramble-string/)| [C++](./algorithms/cpp/scrambleString/scrambleString.cpp)|Hard| +|86|[Partition List](https://leetcode.com/problems/partition-list/)| [C++](./algorithms/cpp/partitionList/partitionList.cpp), [Python](./algorithms/python/PartitionList/partition.py)|Medium| +|85|[Maximal Rectangle](https://leetcode.com/problems/maximal-rectangle/)| [C++](./algorithms/cpp/maximalRectangle/maximalRectangle.cpp)|Hard| +|84|[Largest Rectangle in Histogram](https://leetcode.com/problems/largest-rectangle-in-histogram/)| [C++](./algorithms/cpp/largestRectangleInHistogram/largestRectangleInHistogram.cpp)|Hard| +|83|[Remove Duplicates from Sorted List](https://leetcode.com/problems/remove-duplicates-from-sorted-list/)| [C++](./algorithms/cpp/removeDuplicatesFromSortedList/removeDuplicatesFromSortedList.cpp)|Easy| +|82|[Remove Duplicates from Sorted List II](https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/)| [C++](./algorithms/cpp/removeDuplicatesFromSortedList/removeDuplicatesFromSortedList.II.cpp), [Python](./algorithms/python/RemoveDuplicatesFromSortedListII/deleteDuplicates.py)|Medium| +|81|[Search in Rotated Sorted Array II](https://leetcode.com/problems/search-in-rotated-sorted-array-ii/)| [C++](./algorithms/cpp/searchInRotatedSortedArray/searchInRotatedSortedArray.II.cpp)|Medium| +|80|[Remove Duplicates from Sorted Array II](https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii/)| [C++](./algorithms/cpp/removeDuplicatesFromSortedArray/removeDuplicatesFromSortedArray.II.cpp)|Medium| +|79|[Word Search](https://leetcode.com/problems/word-search/)| [C++](./algorithms/cpp/wordSearch/wordSearch.cpp)|Medium| +|78|[Subsets](https://leetcode.com/problems/subsets/)| [C++](./algorithms/cpp/subsets/subsets.cpp), [Java](./algorithms/java/src/subsets/subsets.java), [Python](./algorithms/python/Subsets/subsets.py)|Medium| +|77|[Combinations](https://leetcode.com/problems/combinations/)| [C++](./algorithms/cpp/combinations/combinations.cpp)|Medium| +|76|[Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/)| [C++](./algorithms/cpp/minimumWindowSubstring/minimumWindowSubstring.cpp)|Hard| +|75|[Sort Colors](https://leetcode.com/problems/sort-colors/)| [C++](./algorithms/cpp/sortColors/sortColors.cpp)|Medium| +|74|[Search a 2D Matrix](https://leetcode.com/problems/search-a-2d-matrix/)| [C++](./algorithms/cpp/search2DMatrix/search2DMatrix.cpp), [Java](./algorithms/java/src/search2DMatrix/search2DMatrix.java)|Medium| +|73|[Set Matrix Zeroes](https://leetcode.com/problems/set-matrix-zeroes/)| [C++](./algorithms/cpp/setMatrixZeroes/setMatrixZeroes.cpp)|Medium| +|72|[Edit Distance](https://leetcode.com/problems/edit-distance/)| [C++](./algorithms/cpp/editDistance/editDistance.cpp)|Hard| +|71|[Simplify Path](https://leetcode.com/problems/simplify-path/)| [C++](./algorithms/cpp/simplifyPath/simplifyPath.cpp)|Medium| +|70|[Climbing Stairs](https://leetcode.com/problems/climbing-stairs/)| [C++](./algorithms/cpp/climbStairs/climbStairs.cpp), [Java](./algorithms/java/src/dynamicProgramming/climbStairs/climbStairs.java)|Easy| +|69|[Sqrt(x)](https://leetcode.com/problems/sqrtx/)| [C++](./algorithms/cpp/sqrt/sqrt.cpp)|Medium| +|68|[Text Justification](https://leetcode.com/problems/text-justification/)| [C++](./algorithms/cpp/textJustification/textJustification.cpp)|Hard| +|67|[Add Binary](https://leetcode.com/problems/add-binary/)| [C++](./algorithms/cpp/addBinary/addBinary.cpp)|Easy| +|66|[Plus One](https://leetcode.com/problems/plus-one/)| [C++](./algorithms/cpp/plusOne/plusOne.cpp)|Easy| +|65|[Valid Number](https://leetcode.com/problems/valid-number/)| [C++](./algorithms/cpp/validNumber/validNumber.cpp)|Easy| +|64|[Minimum Path Sum](https://leetcode.com/problems/minimum-path-sum/)| [C++](./algorithms/cpp/minimumPathSum/minimumPathSum.cpp), [Java](./algorithms/java/src/dynamicProgramming/minimumPathSum/minimumPathSum.java)|Medium| +|63|[Unique Paths II](https://leetcode.com/problems/unique-paths-ii/)| [C++](./algorithms/cpp/uniquePaths/uniquePaths.II.cpp), [Java](./algorithms/java/src/dynamicProgramming/uniquePaths/uniquePathsII.java)|Medium| +|62|[Unique Paths](https://leetcode.com/problems/unique-paths/)| [C++](./algorithms/cpp/uniquePaths/uniquePaths.cpp), [Java](./algorithms/java/src/dynamicProgramming/uniquePaths/uniquePaths.java)|Medium| +|61|[Rotate List](https://leetcode.com/problems/rotate-list/)| [C++](./algorithms/cpp/rotateList/rotateList.cpp)|Medium| +|60|[Permutation Sequence](https://leetcode.com/problems/permutation-sequence/)| [C++](./algorithms/cpp/permutationSequence/permutationSequence.cpp)|Medium| +|59|[Spiral Matrix II](https://leetcode.com/problems/spiral-matrix-ii/)| [C++](./algorithms/cpp/spiralMatrix/spiralMatrix.II.cpp)|Medium| +|58|[Length of Last Word](https://leetcode.com/problems/length-of-last-word/)| [C++](./algorithms/cpp/lengthOfLastWord/lengthOfLastWord.cpp), [Java](./algorithms/java/src/lengthOfLastWord/LengthOfLastWord.java)|Easy| +|57|[Insert Interval](https://leetcode.com/problems/insert-interval/)| [C++](./algorithms/cpp/insertInterval/insertInterval.cpp)|Hard| +|56|[Merge Intervals](https://leetcode.com/problems/merge-intervals/)| [C++](./algorithms/cpp/mergeIntervals/mergeIntervals.cpp)|Hard| +|55|[Jump Game](https://leetcode.com/problems/jump-game/)| [C++](./algorithms/cpp/jumpGame/jumpGame.cpp)|Medium| +|54|[Spiral Matrix](https://leetcode.com/problems/spiral-matrix/)| [C++](./algorithms/cpp/spiralMatrix/spiralMatrix.cpp)|Medium| +|53|[Maximum Subarray](https://leetcode.com/problems/maximum-subarray/)| [C++](./algorithms/cpp/maximumSubArray/maximumSubArray.cpp)|Medium| +|52|[N-Queens II](https://leetcode.com/problems/n-queens-ii/)| [C++](./algorithms/cpp/nQueens/nQueuens.II.cpp)|Hard| +|51|[N-Queens](https://leetcode.com/problems/n-queens/)| [C++](./algorithms/cpp/nQueens/nQueuens.cpp)|Hard| +|50|["Pow(x, n)"](https://leetcode.com/problems/powx-n/)| [C++](./algorithms/cpp/pow/pow.cpp), [Java](./algorithms/java/src/powXn/PowXn.java)|Medium| +|49|[Group Anagrams](https://leetcode.com/problems/anagrams/)| [C++](./algorithms/cpp/anagrams/GroupAnagrams.cpp)|Medium| +|48|[Rotate Image](https://leetcode.com/problems/rotate-image/)| [C++](./algorithms/cpp/rotateImage/rotateImage.cpp)|Medium| +|47|[Permutations II](https://leetcode.com/problems/permutations-ii/)| [C++](./algorithms/cpp/permutations/permutations.II.cpp)|Hard| +|46|[Permutations](https://leetcode.com/problems/permutations/)| [C++](./algorithms/cpp/permutations/permutations.cpp)|Medium| +|45|[Jump Game II](https://leetcode.com/problems/jump-game-ii/)| [C++](./algorithms/cpp/jumpGame/jumpGame.II.cpp)|Hard| +|44|[Wildcard Matching](https://leetcode.com/problems/wildcard-matching/)| [C++](./algorithms/cpp/wildcardMatching/wildcardMatching.cpp)|Hard| +|43|[Multiply Strings](https://leetcode.com/problems/multiply-strings/)| [C++](./algorithms/cpp/multiplyStrings/multiplyStrings.cpp)|Medium| +|42|[Trapping Rain Water](https://leetcode.com/problems/trapping-rain-water/)| [C++](./algorithms/cpp/trappingRainWater/trappingRainWater.cpp)|Hard| +|41|[First Missing Positive](https://leetcode.com/problems/first-missing-positive/)| [C++](./algorithms/cpp/firstMissingPositive/firstMissingPositive.cpp)|Hard| +|40|[Combination Sum II](https://leetcode.com/problems/combination-sum-ii/)| [C++](./algorithms/cpp/combinationSum/combinationSum.II.cpp)|Medium| +|39|[Combination Sum](https://leetcode.com/problems/combination-sum/)| [C++](./algorithms/cpp/combinationSum/combinationSum.cpp)|Medium| +|38|[Count and Say](https://leetcode.com/problems/count-and-say/)| [C++](./algorithms/cpp/countAndSay/countAndSay.cpp), [Java](./algorithms/java/src/countAndSay/CountAndSay.java)|Easy| +|37|[Sudoku Solver](https://leetcode.com/problems/sudoku-solver/)| [C++](./algorithms/cpp/sudokuSolver/sudokuSolver.cpp)|Hard| +|36|[Valid Sudoku](https://leetcode.com/problems/valid-sudoku/)| [C++](./algorithms/cpp/validSudoku/validSudoku.cpp)|Easy| +|35|[Search Insert Position](https://leetcode.com/problems/search-insert-position/)| [C++](./algorithms/cpp/searchInsertPosition/searchInsertPosition.cpp), [Java](./algorithms/java/src/searchInsertPosition/searchInsertPosition.java)|Medium| +|34|[Search for a Range](https://leetcode.com/problems/search-for-a-range/)| [C++](./algorithms/cpp/searchForRange/searchForRange.cpp), [Java](./algorithms/java/src/searchForRange/searchForRange.java)|Medium| +|33|[Search in Rotated Sorted Array](https://leetcode.com/problems/search-in-rotated-sorted-array/)| [C++](./algorithms/cpp/searchInRotatedSortedArray/searchInRotatedSortedArray.cpp), [Java](./algorithms/java/src/searchInRotatedSortedArray/searchInRotatedSortedArray.java)|Hard| +|32|[Longest Valid Parentheses](https://leetcode.com/problems/longest-valid-parentheses/)| [C++](./algorithms/cpp/longestValidParentheses/longestValidParentheses.cpp)|Hard| +|31|[Next Permutation](https://leetcode.com/problems/next-permutation/)| [C++](./algorithms/cpp/nextPermutation/nextPermutation.cpp)|Medium| +|30|[Substring with Concatenation of All Words](https://leetcode.com/problems/substring-with-concatenation-of-all-words/)| [C++](./algorithms/cpp/substringWithConcatenationOfAllWords/substringWithConcatenationOfAllWords.cpp)|Hard| +|29|[Divide Two Integers](https://leetcode.com/problems/divide-two-integers/)| [C++](./algorithms/cpp/divideTwoInt/divideTwoInt.cpp)|Medium| +|28|[Implement strStr()](https://leetcode.com/problems/implement-strstr/)| [C++](./algorithms/cpp/strStr/strStr.cpp), [Java](./algorithms/java/src/strStr/strStr.java)|Easy| +|27|[Remove Element](https://leetcode.com/problems/remove-element/)| [C++](./algorithms/cpp/removeElement/removeElement.cpp)|Easy| +|26|[Remove Duplicates from Sorted Array](https://leetcode.com/problems/remove-duplicates-from-sorted-array/)| [C++](./algorithms/cpp/removeDuplicatesFromSortedArray/removeDuplicatesFromSortedArray.cpp), [Java](./algorithms/java/src/removeDuplicatesFromSortedArray/RemoveDuplicatesFromSortedArray.java)|Easy| +|25|[Reverse Nodes in k-Group](https://leetcode.com/problems/reverse-nodes-in-k-group/)| [C++](./algorithms/cpp/reverseNodesInKGroup/reverseNodesInKGroup.cpp)|Hard| +|24|[Swap Nodes in Pairs](https://leetcode.com/problems/swap-nodes-in-pairs/)| [C++](./algorithms/cpp/swapNodesInPairs/swapNodesInPairs.cpp)|Medium| +|23|[Merge k Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/)| [C++](./algorithms/cpp/mergeKSortedLists/mergeKSortedLists.cpp)|Hard| +|22|[Generate Parentheses](https://leetcode.com/problems/generate-parentheses/)| [C++](./algorithms/cpp/generateParentheses/generateParentheses.cpp)|Medium| +|21|[Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/)| [C++](./algorithms/cpp/mergeTwoSortedList/mergeTwoSortedList.cpp)|Easy| +|20|[Valid Parentheses](https://leetcode.com/problems/valid-parentheses/)| [C++](./algorithms/cpp/validParentheses/validParentheses.cpp)|Easy| +|19|[Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/)| [C++](./algorithms/cpp/removeNthNodeFromEndOfList/removeNthNodeFromEndOfList.cpp), [Python](./algorithms/python/RemoveNthNodeFromEndOfList/removeNthFromEnd.py)|Easy| +|18|[4Sum](https://leetcode.com/problems/4sum/)| [C++](./algorithms/cpp/4Sum/4Sum.cpp)|Medium| +|17|[Letter Combinations of a Phone Number](https://leetcode.com/problems/letter-combinations-of-a-phone-number/)| [C++](./algorithms/cpp/letterCombinationsOfAPhoneNumber/letterCombinationsOfAPhoneNumber.cpp)|Medium| +|16|[3Sum Closest](https://leetcode.com/problems/3sum-closest/)| [C++](./algorithms/cpp/3SumClosest/3SumClosest.cpp)|Medium| +|15|[3Sum](https://leetcode.com/problems/3sum/)| [C++](./algorithms/cpp/3Sum/3Sum.cpp)|Medium| +|14|[Longest Common Prefix](https://leetcode.com/problems/longest-common-prefix/)| [C++](./algorithms/cpp/longestCommonPrefix/longestCommonPrefix.cpp)|Easy| +|13|[Roman to Integer](https://leetcode.com/problems/roman-to-integer/)| [C++](./algorithms/cpp/romanToInteger/romanToInteger.cpp)|Easy| +|12|[Integer to Roman](https://leetcode.com/problems/integer-to-roman/)| [C++](./algorithms/cpp/integerToRoman/integerToRoman.cpp)|Medium| +|11|[Container With Most Water](https://leetcode.com/problems/container-with-most-water/)| [C++](./algorithms/cpp/containerWithMostWater/containerWithMostWater.cpp)|Medium| +|10|[Regular Expression Matching](https://leetcode.com/problems/regular-expression-matching/)| [C++](./algorithms/cpp/regularExpressionMatching/regularExpressionMatching.cpp)|Hard| +|9|[Palindrome Number](https://leetcode.com/problems/palindrome-number/)| [C++](./algorithms/cpp/palindromeNumber/palindromeNumber.cpp), [Java](./algorithms/java/src/palindromeNumber/PalindromeNumber.java)|Easy| +|8|[String to Integer (atoi)](https://leetcode.com/problems/string-to-integer-atoi/)| [C++](./algorithms/cpp/stringToIntegerAtoi/stringToIntegerAtoi.cpp)|Easy| +|7|[Reverse Integer](https://leetcode.com/problems/reverse-integer/)| [C++](./algorithms/cpp/reverseInteger/reverseInteger.cpp)|Easy| +|6|[ZigZag Conversion](https://leetcode.com/problems/zigzag-conversion/)| [C++](./algorithms/cpp/zigZagConversion/zigZagConversion.cpp)|Easy| +|5|[Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/)| [C++](./algorithms/cpp/longestPalindromicSubstring/longestPalindromicSubstring.cpp)|Medium| +|4|[Median of Two Sorted Arrays](https://leetcode.com/problems/median-of-two-sorted-arrays/)| [C++](./algorithms/cpp/medianOfTwoSortedArrays/medianOfTwoSortedArrays.cpp)|Hard| +|3|[Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/)| [C++](./algorithms/cpp/longestSubstringWithoutRepeatingCharacters/longestSubstringWithoutRepeatingCharacters.cpp)|Medium| +|2|[Add Two Numbers](https://leetcode.com/problems/add-two-numbers/)| [C++](./algorithms/cpp/addTwoNumbers/addTwoNumbers.cpp)|Medium| +|1|[Two Sum](https://leetcode.com/problems/two-sum/)| [C++](./algorithms/cpp/twoSum/twoSum.cpp), [Go](./algorithms/golang/twoSum/twoSum.go)|Easy| -###LeetCode Shell +### LeetCode Shell | # | Title | Solution | Difficulty | @@ -272,8 +419,10 @@ LeetCode |2|[Valid Phone Numbers](https://leetcode.com/problems/valid-phone-numbers/)| [Bash](./shell/ValidPhoneNumbers.sh)|Easy| |1|[Word Frequency](https://leetcode.com/problems/word-frequency/)| [Bash](./shell/WordFrequency.sh)|Medium| -###LintCode +### LintCode + | # | Title | Solution | Difficulty | |---| ----- | -------- | ---------- | |1|[Search in a big sorted array](http://www.lintcode.com/en/problem/search-in-a-big-sorted-array/)|[Java](./algorithms/java/src/searchInABigSortedArray/searchInABigSortedArray.java)|Medium| |2|[Search Range in Binary Search Tree](http://www.lintcode.com/en/problem/search-range-in-binary-search-tree/) | [Java](./algorithms/java/src/searchRangeInBinarySearchTree/searchRangeInBinarySearchTree.java)|Medium| + diff --git a/algorithms/cpp/3Sum/3Sum.cpp b/algorithms/cpp/3Sum/3Sum.cpp index 0b38716e4..ada7dba86 100644 --- a/algorithms/cpp/3Sum/3Sum.cpp +++ b/algorithms/cpp/3Sum/3Sum.cpp @@ -30,7 +30,7 @@ using namespace std; /* - * Simlar like "Two Number" problem, we can have the simlar solution. + * Similar like "Two Number" problem, we can have the simlar solution. * * Suppose the input array is S[0..n-1], 3SUM can be solved in O(n^2) time on average by * inserting each number S[i] into a hash table, and then for each index i and j, @@ -47,6 +47,7 @@ using namespace std; vector > threeSum(vector &num) { vector< vector > result; + if(num.size()==0 || num.size()==1 || num.size() == 2) return result; //sort the array, this is the key sort(num.begin(), num.end()); @@ -71,7 +72,7 @@ vector > threeSum(vector &num) { result.push_back(v); // Continue search for all triplet combinations summing to zero. //skip the duplication - while(low0 && num[high]==num[high-1]) high--; low++; high--; @@ -81,7 +82,7 @@ vector > threeSum(vector &num) { high--; } else{ //skip the duplication - while(low& data) { + int i = 0; + while ( i < data.size() ) { + if ( (data[i] & 0x80) == 0 ){ + i++; + continue; + } + + int len = 0; + if ( (data[i] & 0xE0) == 0xC0 ) { // checking 110xxxxx + len = 2; + }else if ( (data[i] & 0xF0) == 0xE0) { // checking 1110xxxx + len = 3; + }else if ( (data[i] & 0xF8) == 0xF0) { // checking 11110xxx + len = 4; + }else { + return false; + } + + + for (int j=i+1; j < i+len; j++) { //checking 10xxxxxx + if ( (data[j] & 0xC0) != 0x80 ) { + return false; + } + } + + i += len ; + + if (i > data.size()) { + return false; + } + + } + return true; + } +}; diff --git a/algorithms/cpp/accountsMerge/AccountsMerge.cpp b/algorithms/cpp/accountsMerge/AccountsMerge.cpp new file mode 100644 index 000000000..a8fab40a0 --- /dev/null +++ b/algorithms/cpp/accountsMerge/AccountsMerge.cpp @@ -0,0 +1,174 @@ +// Source : https://leetcode.com/problems/accounts-merge/ +// Author : Hao Chen +// Date : 2019-03-29 + +/***************************************************************************************************** + * + * Given a list accounts, each element accounts[i] is a list of strings, where the first element + * accounts[i][0] is a name, and the rest of the elements are emails representing emails of the + * account. + * + * Now, we would like to merge these accounts. Two accounts definitely belong to the same person if + * there is some email that is common to both accounts. Note that even if two accounts have the same + * name, they may belong to different people as people could have the same name. A person can have + * any number of accounts initially, but all of their accounts definitely have the same name. + * + * After merging the accounts, return the accounts in the following format: the first element of each + * account is the name, and the rest of the elements are emails in sorted order. The accounts + * themselves can be returned in any order. + * + * Example 1: + * + * Input: + * accounts = [["John", "johnsmith@mail.com", "john00@mail.com"], ["John", "johnnybravo@mail.com"], + * ["John", "johnsmith@mail.com", "john_newyork@mail.com"], ["Mary", "mary@mail.com"]] + * Output: [["John", 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com'], ["John", + * "johnnybravo@mail.com"], ["Mary", "mary@mail.com"]] + * + * Explanation: + * The first and third John's are the same person as they have the common email "johnsmith@mail.com". + * The second John and Mary are different people as none of their email addresses are used by other + * accounts. + * + * We could return these lists in any order, for example the answer [['Mary', 'mary@mail.com'], + * ['John', 'johnnybravo@mail.com'], + * ['John', 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com']] would still be accepted. + * + * Note: + * The length of accounts will be in the range [1, 1000]. + * The length of accounts[i] will be in the range [1, 10]. + * The length of accounts[i][j] will be in the range [1, 30]. + ******************************************************************************************************/ + + +//Bad Performance Solution +class Solution_Time_Limit_Exceeded { +public: + // We can orginze all relevant emails to a chain, + // then we can use Union Find algorithm + // Besides, we also need to map the relationship between name and email. + vector> accountsMerge(vector>& accounts) { + unordered_map emails_chains; // email chains + unordered_map names; // names to email chains' head + + //initialization + for(int i = 0 ; i> res; + for( auto& acc : accounts ) { + string e = find(emails_chains, acc[1]); + res[e].insert(acc.begin()+1, acc.end()); + } + + //output the result + vector> result; + for (auto pair : res) { + vector emails(pair.second.begin(), pair.second.end()); + emails.insert(emails.begin(), names[pair.first]); + result.push_back(emails); + } + return result; + } + + string find(unordered_map& emails_chains, + string email) { + while( email != emails_chains[email] ){ + email = emails_chains[email]; + } + return email; + } + + bool join(unordered_map& emails_chains, + string& email1, string& email2) { + string e1 = find(emails_chains, email1); + string e2 = find(emails_chains, email2); + if ( e1 != e2 ) emails_chains[e1] = email2; + return e1 == e2; + } +}; + +// +// Performance Tunning +// ----------------- +// +// The above algorithm need to do string comparison, it causes lots of efforts +// So, we allocated the ID for each email, and compare the ID would save the time. +// +// Furthermore, we can use the Group-Email-ID instead of email ID, +// this would save more time. +// +class Solution { +public: + // We can orginze all relevant emails to a chain, + // then we can use Union Find algorithm + // Besides, we also need to map the relationship between name and email. + vector> accountsMerge(vector>& accounts) { + unordered_map emails_id; //using email ID for union find + unordered_map emails_chains; // email chains + unordered_map names; // email id & name + + //initialization & join + for(int i = 0 ; i> res; + for(int i=0; i> result; + for (auto pair : res) { + vector emails( pair.second.begin(), pair.second.end() ); + emails.insert(emails.begin(), names[pair.first]); + result.push_back(emails); + } + return result; + } + + int find(unordered_map& emails_chains, int id) { + while( id != emails_chains[id] ){ + id = emails_chains[id]; + } + return id; + } + + bool join(unordered_map& emails_chains, int id1, int id2) { + int e1 = find(emails_chains, id1); + int e2 = find(emails_chains, id2); + if ( e1 != e2 ) emails_chains[e1] = e2; + return e1 == e2; + } +}; diff --git a/algorithms/cpp/addStrings/AddStrings.cpp b/algorithms/cpp/addStrings/AddStrings.cpp new file mode 100644 index 000000000..32b6734bb --- /dev/null +++ b/algorithms/cpp/addStrings/AddStrings.cpp @@ -0,0 +1,48 @@ +// Source : https://leetcode.com/problems/add-strings/ +// Author : Hao Chen +// Date : 2016-11-12 + +/*************************************************************************************** + * + * Given two non-negative numbers num1 and num2 represented as string, return the sum + * of num1 and num2. + * + * Note: + * + * The length of both num1 and num2 is + * Both num1 and num2 contains only digits 0-9. + * Both num1 and num2 does not contain any leading zero. + * You must not use any built-in BigInteger library or convert the inputs to integer + * directly. + ***************************************************************************************/ + +class Solution { +public: + string addStrings(string num1, string num2) { + string& longstr = ( num1.size() >= num2.size() ? num1 : num2 ); + string& shortstr = ( num1.size() < num2.size() ? num1 : num2 ); + + int longlen = longstr.size(); + int shortlen = shortstr.size(); + + char carry = 0; + int i, j; + + string result; + for (i = longlen-1, j=shortlen-1; i>=0; i--, j--) { + int add = 0; + if (j>=0) { + add = longstr[i] + shortstr[j] - 2 * '0' + carry; + }else{ + add = longstr[i] - '0' + carry; + } + carry = add/10; + result = char('0' + add % 10) + result; + } + + if (carry) { + result = '1' + result; + } + return result; + } +}; diff --git a/algorithms/cpp/addToArrayFormOfInteger/AddToArrayFormOfInteger.cpp b/algorithms/cpp/addToArrayFormOfInteger/AddToArrayFormOfInteger.cpp new file mode 100644 index 000000000..652a5d0e6 --- /dev/null +++ b/algorithms/cpp/addToArrayFormOfInteger/AddToArrayFormOfInteger.cpp @@ -0,0 +1,62 @@ +// Source : https://leetcode.com/problems/add-to-array-form-of-integer/ +// Author : Hao Chen +// Date : 2019-03-25 + +/***************************************************************************************************** + * + * For a non-negative integer X, the array-form of X is an array of its digits in left to right order. + * For example, if X = 1231, then the array form is [1,2,3,1]. + * + * Given the array-form A of a non-negative integer X, return the array-form of the integer X+K. + * + * Example 1: + * + * Input: A = [1,2,0,0], K = 34 + * Output: [1,2,3,4] + * Explanation: 1200 + 34 = 1234 + * + * Example 2: + * + * Input: A = [2,7,4], K = 181 + * Output: [4,5,5] + * Explanation: 274 + 181 = 455 + * + * Example 3: + * + * Input: A = [2,1,5], K = 806 + * Output: [1,0,2,1] + * Explanation: 215 + 806 = 1021 + * + * Example 4: + * + * Input: A = [9,9,9,9,9,9,9,9,9,9], K = 1 + * Output: [1,0,0,0,0,0,0,0,0,0,0] + * Explanation: 9999999999 + 1 = 10000000000 + * + * Note: + * + * 1 <= A.length <= 10000 + * 0 <= A[i] <= 9 + * 0 <= K <= 10000 + * If A.length > 1, then A[0] != 0 + * + ******************************************************************************************************/ + +class Solution { +public: + vector addToArrayForm(vector& A, int K) { + int carry = K; + for (int i = A.size() - 1; i >= 0 && carry > 0; i--) { + int a = A[i] + carry; + A[i] = a % 10 ; + carry = a / 10; + } + + while ( carry > 0 ) { + A.insert(A.begin(), carry%10); + carry /= 10; + } + + return A; + } +}; diff --git a/algorithms/cpp/arithmeticSlices/ArithmeticSlices.cpp b/algorithms/cpp/arithmeticSlices/ArithmeticSlices.cpp new file mode 100644 index 000000000..dc7c9fa05 --- /dev/null +++ b/algorithms/cpp/arithmeticSlices/ArithmeticSlices.cpp @@ -0,0 +1,72 @@ +// Source : https://leetcode.com/problems/arithmetic-slices/ +// Author : Hao Chen +// Date : 2016-11-13 + +/*************************************************************************************** + * + * A sequence of number is called arithmetic if it consists of at least three elements + * and if the difference between any two consecutive elements is the same. + * + * For example, these are arithmetic sequence: + * 1, 3, 5, 7, 9 + * 7, 7, 7, 7 + * 3, -1, -5, -9 + * + * The following sequence is not arithmetic. 1, 1, 2, 5, 7 + * + * A zero-indexed array A consisting of N numbers is given. A slice of that array is + * any pair of integers (P, Q) such that 0 + * + * A slice (P, Q) of array A is called arithmetic if the sequence: + * A[P], A[p + 1], ..., A[Q - 1], A[Q] is arithmetic. In particular, this means + * that P + 1 + * + * The function should return the number of arithmetic slices in the array A. + * + * Example: + * + * A = [1, 2, 3, 4] + * + * return: 3, for 3 arithmetic slices in A: [1, 2, 3], [2, 3, 4] and [1, 2, 3, 4] + * itself. + ***************************************************************************************/ + +class Solution { +public: + // + // It's easy to find out how many 3-length slices in an arithmetic array with N length. + // + // len = 3, then 1 slices, sum(1) + // len = 4, then 3 slices, sum(1,2) - TWO 3-length slices + ONE 4-length slice + // len = 5, then 6 slices, sum(1,2,3) - THREE 3-length slices + TWO 4-length slices + ONE 5-length slice + // len = 6, then 10 slices, sum(1,2,3,4) - ... + // len = 7, then 15 slices, sum(1,2,3,4,5) - .. + // + // So, with N length arithmetic array, there are Sum[1, N-3+1] 3-length slices + // + // And, we know the formula sum from 1 to n is: + // + // n * ( n + 1 ) + // sum [1, n] = --------------- + // 2 + // Then, we could have the solution - O(n) Time with O(1) Space + // + + int sum1toN(int n) { + return n * (n+1) / 2; + } + + int numberOfArithmeticSlices(vector& A) { + int result = 0; + int len = 0; // the current length of arithmetic + for (int i=2; i0 ? 2 : 1; + s.erase(i-backSteps + 1, backSteps); + i -= backSteps; + } + } + } + +public: + bool backspaceCompare(string S, string T) { + removeBackspaces(S); + removeBackspaces(T); + return S == T; + } +}; diff --git a/algorithms/cpp/bestTimeToBuyAndSellStock/BestTimeToBuyAndSellStockWithCooldown.cpp b/algorithms/cpp/bestTimeToBuyAndSellStock/BestTimeToBuyAndSellStockWithCooldown.cpp new file mode 100644 index 000000000..be3e38e5f --- /dev/null +++ b/algorithms/cpp/bestTimeToBuyAndSellStock/BestTimeToBuyAndSellStockWithCooldown.cpp @@ -0,0 +1,63 @@ +// Source : https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/ +// Author : Hao Chen +// Date : 2019-02-01 + +/***************************************************************************************************** + * + * Say you have an array for which the ith element is the price of a given stock on day i. + * + * Design an algorithm to find the maximum profit. You may complete as many transactions as you like + * (ie, buy one and sell one share of the stock multiple times) with the following restrictions: + * + * You may not engage in multiple transactions at the same time (ie, you must sell the stock + * before you buy again). + * After you sell your stock, you cannot buy stock on next day. (ie, cooldown 1 day) + * + * Example: + * + * Input: [1,2,3,0,2] + * Output: 3 + * Explanation: transactions = [buy, sell, cooldown, buy, sell] + ******************************************************************************************************/ +class Solution { +public: + // + //Define + // + // - buy[i] as the max profit when you buy the stock at day i. + // - sell[i] as the max profit when you sell the stock at day i. + // + // Therefore set buy[0] = -prices[0], because spend the money, the profit is -prices[0]. + // Also set sell[0] = 0, that you do nothing in the first day. + // + // So, + // buy[i] = max(buy[i-1], // do nothing - keep holding + // sell[i-2] - prices[i] ) // sell previous day, buy today + // // i-1 is cooldown day + // sell[i] = max(sell[i-1], // do nothing + // buy[i-1] + prices[i] ) // buy previous day, sell today. + // + + int maxProfit(vector& prices) { + int len = prices.size(); + if ( len < 2 ) return 0; + + vector buy(len, 0); + vector sell(len, 0); + + //day 0 + buy[0] = -prices[0]; + sell[0] = 0; + + //day 1 + buy[1] = max(buy[0], 0 - prices[1]); + sell[1] = max(sell[0], buy[0] + prices[1]); + + for (int i=2; i y ? x: y; + } + int max(int x, int y, int z) { + return max(x, max(y,z)); + } + +public: + + int maxProfit(vector& prices, int fee) { + return maxProfit_dp03(prices, fee); // 100ms + return maxProfit_dp02(prices, fee); // 100ms + return maxProfit_dp01(prices, fee); // 2700ms + } + + // find the [buy-low, sell-high] prices pairs, + // and remove the unnecessary prices. + void genPricesPairs(vector &prices, vector< pair > &prices_pairs, int fee){ + + int low = -1; + for (int i=0; i prices[i+1] && low >= 0) { + prices_pairs.push_back( make_pair( prices[low], prices[i]) ); + low = -1; // reset the `low` & `high` + } + } + + // edge case + if ( low >= 0 ) { + prices_pairs.push_back( make_pair( prices[low], prices[prices.size()-1] ) ); + } + + } + + int maxProfit_dp01(vector &prices, int &fee) { + + vector< pair > prices_pairs; + genPricesPairs(prices, prices_pairs, fee); + + vector dp(prices_pairs.size()+1, 0); + + for (int i=0; i &prices, int &fee) { + + vector< pair > prices_pairs; + genPricesPairs(prices, prices_pairs, fee); + + if ( prices_pairs.size() < 1 ) return 0; + + + // first - represent the max profit if we buy. + // second - represent the max profit if we sell. + vector< pair > dp(prices_pairs.size() , make_pair(0,0) ); + + //buy profit - if we buy it in day 0, then we got negtive profit. + dp[0].first = - prices_pairs[0].first; + + //sell profit - if we sell it in day 0, then we have the profits + // if the profit is negtive, then won't sell it. + dp[0].second = max(0, prices_pairs[0].second - prices_pairs[0].first - fee); + + for (int i=1; i &prices, int &fee) { + int buy=-prices[0], sell=0; + int pre_buy=0, pre_sell=0; + + for(auto price: prices) { + pre_buy = buy; + buy = max (sell - price, pre_buy); + + pre_sell = sell; + sell = max( pre_buy + price - fee, pre_sell); + } + + return sell; + } +}; diff --git a/algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.II.cpp b/algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.II.cpp index 353989372..67665bb01 100644 --- a/algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.II.cpp +++ b/algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.II.cpp @@ -2,46 +2,80 @@ // Author : Hao Chen // Date : 2014-06-18 -/********************************************************************************** -* -* Say you have an array for which the ith element is the price of a given stock on day i. -* -* Design an algorithm to find the maximum profit. You may complete as many transactions -* as you like (ie, buy one and sell one share of the stock multiple times). However, -* you may not engage in multiple transactions at the same time (ie, you must sell the -* stock before you buy again). -* -**********************************************************************************/ +/***************************************************************************************************** + * + * Say you have an array for which the ith element is the price of a given stock on day i. + * + * Design an algorithm to find the maximum profit. You may complete as many transactions as you like + * (i.e., buy one and sell one share of the stock multiple times). + * + * Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock + * before you buy again). + * + * Example 1: + * + * Input: [7,1,5,3,6,4] + * Output: 7 + * Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4. + * Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3. + * + * Example 2: + * + * Input: [1,2,3,4,5] + * Output: 4 + * Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4. + * Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are + * engaging multiple transactions at the same time. You must sell before buying again. + * + * Example 3: + * + * Input: [7,6,4,3,1] + * Output: 0 + * Explanation: In this case, no transaction is done, i.e. max profit = 0. + ******************************************************************************************************/ class Solution { public: - // + int maxProfit(vector& prices) { + return maxProfit02(prices); + return maxProfit01(prices); + } + // Solution 1 // find all of ranges: which start a valley with the nearest peak after // add their delta together // - int maxProfit(vector &prices) { - int max=0, begin=0, end=0; - bool up=false, down=false; - for (int i=1; i prices[i-1] && up==false){ // goes up - begin = i-1; - up = true; - down = false; + int maxProfit01(vector &prices) { + + int max = 0; + int low = -1; + int len = prices.size(); + for (int i=0; i < len - 1; i++){ + //meet the valley, then goes up + if (prices[i] < prices[i+1] && low < 0 ) { + low = i; } - - if (prices[i] < prices[i-1] && down==false) { // goes down - end = i-1; - down = true; - up = false; - max += (prices[end] - prices[begin]); + //meet the peak, then goes down + if (prices[i] > prices[i+1] && low >= 0) { + max += ( prices[i] - prices[low] ) ; + low = -1; // reset the `low` } } - // edge case - if (begin < prices.size() && up==true){ - end = prices.size() - 1; - max += (prices[end] - prices[begin]); + + // edge case + if ( low >= 0 ) { + max += ( prices[prices.size()-1] - prices[low] ); } - + return max; } + + // Solution 2 + // if we find we can earn money, we just sell + int maxProfit02(vector& prices) { + int profit = 0 ; + for(int i=1; i< prices.size(); i++) { + profit += max(0, prices[i] - prices[i-1]); + } + return profit; + } }; diff --git a/algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.III.cpp b/algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.III.cpp index 72240c234..c8ab3f9c1 100644 --- a/algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.III.cpp +++ b/algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.III.cpp @@ -2,16 +2,36 @@ // Author : Hao Chen // Date : 2014-08-22 -/********************************************************************************** -* -* Say you have an array for which the ith element is the price of a given stock on day i. -* -* Design an algorithm to find the maximum profit. You may complete at most two transactions. -* -* Note: -* You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again). -* -**********************************************************************************/ +/***************************************************************************************************** + * + * Say you have an array for which the ith element is the price of a given stock on day i. + * + * Design an algorithm to find the maximum profit. You may complete at most two transactions. + * + * Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock + * before you buy again). + * + * Example 1: + * + * Input: [3,3,5,0,0,3,1,4] + * Output: 6 + * Explanation: Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3. + * Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 = 3. + * + * Example 2: + * + * Input: [1,2,3,4,5] + * Output: 4 + * Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4. + * Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are + * engaging multiple transactions at the same time. You must sell before buying again. + * + * Example 3: + * + * Input: [7,6,4,3,1] + * Output: 0 + * Explanation: In this case, no transaction is done, i.e. max profit = 0. + ******************************************************************************************************/ class Solution { diff --git a/algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.IV.cpp b/algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.IV.cpp index 96bab7f3a..c7e0a7fcb 100644 --- a/algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.IV.cpp +++ b/algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.IV.cpp @@ -2,75 +2,134 @@ // Author : Hao Chen // Date : 2015-03-31 -/********************************************************************************** -* -* Say you have an array for which the ith element is the price of a given stock on day i. -* -* Design an algorithm to find the maximum profit. You may complete at most k transactions. -* -* Note: -* You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again). -* -* Credits:Special thanks to @Freezen for adding this problem and creating all test cases. -* -**********************************************************************************/ +/***************************************************************************************************** + * + * Say you have an array for which the ith element is the price of a given stock on day i. + * + * Design an algorithm to find the maximum profit. You may complete at most k transactions. + * + * Note: + * You may not engage in multiple transactions at the same time (ie, you must sell the stock before + * you buy again). + * + * Example 1: + * + * Input: [2,4,1], k = 2 + * Output: 2 + * Explanation: Buy on day 1 (price = 2) and sell on day 2 (price = 4), profit = 4-2 = 2. + * + * Example 2: + * + * Input: [3,2,6,5,0,3], k = 2 + * Output: 7 + * Explanation: Buy on day 2 (price = 2) and sell on day 3 (price = 6), profit = 6-2 = 4. + * Then buy on day 5 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3. + ******************************************************************************************************/ class Solution { -public: - /* - * dp[i, j] - * - `i` represents the number of transactions we've done so far. ( 0 <= i <= k ) - * - `j` represents the number of days so far. ( 0 <= j <= prices.size() ) - * - * So, we have the initialization as below: - * - * dp[0, j] = 0; // 0 <= j <= prices.size() - * dp[i, 0] = 0; // 0 <= i <= k - * - * And the iteration logic as below: - * - * dp[i, j] = max ( - * dp[i, j-1], // same times transactions, but one days before. - * dp[i-1, t] + prices[j] - prices[t+1] // for all of (0 <= t < j ) - * // this means find max profit from previous any of days - * ) - * - */ - - int maxProfit(int k, vector &prices) { - int ndays = prices.size(); - - // error case - if (ndays<=1) return 0; - - // Edge case - // --------- - // if the number of transactions is too many, it means we can make - // as many transactions as we can, that brings us the problem back to - // Best-Time-To-Buy-And-Sell-Stock-II which can be simply solve in O(n) - // by using a greedy approach. - if(k > ndays/2){ - int sum = 0; - for (int i=1; i &prices) { + int ndays = prices.size(); + + // error case + if (ndays<=1) return 0; + + // Edge case + // --------- + // if the number of transactions is too many, it means we can make + // as many transactions as we can, that brings us the problem back to + // Best-Time-To-Buy-And-Sell-Stock-II which can be simply solve in O(n) + // by using a greedy approach. + if(k > ndays/2){ + int sum = 0; + for (int i=1; i &prices) { + int ndays = prices.size(); + vector< vector > profits(k+1, vector( ndays+1, 0)); + for(int trans=1; trans<=k; trans++) { + for (int day=1; day<=ndays; day++) { + int m=0; + for (int i=1; i<=day; i++) { + m = max(m, profits[trans-1][i-1]+ prices[day-1] - prices[i-1]); + } + profits[trans][day] = max( profits[trans][day-1], m); + } + } + return profits[k][ndays]; + } + + //DP solution - O(kn) complexity + //Actually, we could save the loop in above- for(int i=1; i<=day; i++) + //Becasue there are so many dupliations + + int maxProfit_DP02 (int k, vector &prices) { + + int ndays = prices.size(); + + vector< vector > profits(k+1, vector( ndays+1, 0)); + vector m(ndays+1, 0); // tracking the max profits of previous days + + for(int trans=1; trans<=k; trans++) { + m[0] = profits[trans-1][0] - prices[0]; + for (int day=1; day<=ndays; day++) { + profits[trans][day] = max( profits[trans][day-1], m[day-1]+prices[day-1]); + if (day < ndays) { + m[day] = max(m[day-1], profits[trans-1][day] - prices[day]); + } + } } - return sum; + return profits[k][ndays]; } - - //DP solution - O(kn) complexity - vector< vector > dp (k+1, vector( ndays+1, 0)); - - for(int i=1; i<=k; i++) { - int t = dp[i-1][0] - prices[0]; - for (int j=1; j <= ndays; j++) { - dp[i][j] = max(dp[i][j-1], t + prices[j-1]); - if ( j < ndays ) { - t = max(t, dp[i-1][j] - prices[j]); + + + // save the memory, remove the m[ ] array + int maxProfit_DP03 (int k, vector &prices) { + int ndays = prices.size(); + vector< vector > profits(k+1, vector( ndays+1, 0)); + + for(int trans=1; trans<=k; trans++) { + int m = profits[trans-1][0] - prices[0]; + for (int day=1; day <= ndays; day++) { + profits[trans][day] = max(profits[trans][day-1], m + prices[day-1]); + if ( day < ndays ) { + m = max(m, profits[trans-1][day] - prices[day]); + } } } + + return profits[k][ndays]; } - - return dp[k][ndays]; - - } }; diff --git a/algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.cpp b/algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.cpp index e6bc986b1..b7b90a649 100644 --- a/algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.cpp +++ b/algorithms/cpp/bestTimeToBuyAndSellStock/bestTimeToBuyAndSellStock.cpp @@ -2,14 +2,29 @@ // Author : Hao Chen // Date : 2014-06-18 -/********************************************************************************** -* -* Say you have an array for which the ith element is the price of a given stock on day i. -* -* If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), -* design an algorithm to find the maximum profit. -* -**********************************************************************************/ +/***************************************************************************************************** + * + * Say you have an array for which the ith element is the price of a given stock on day i. + * + * If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of + * the stock), design an algorithm to find the maximum profit. + * + * Note that you cannot sell a stock before you buy one. + * + * Example 1: + * + * Input: [7,1,5,3,6,4] + * Output: 5 + * Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5. + * Not 7-1 = 6, as selling price needs to be larger than buying price. + * + * Example 2: + * + * Input: [7,6,4,3,1] + * Output: 0 + * Explanation: In this case, no transaction is done, i.e. max profit = 0. + * + ******************************************************************************************************/ class Solution { public: @@ -50,3 +65,19 @@ class Solution { } }; + + +class Solution { +public: + int maxProfit(vector& prices) { + int buy = INT_MAX; + int profit = 0; + for (auto p : prices) { + // Keep tracking the previous lowest price + buy = min (buy, p); + // Keep tacking the current max profit + profit = max(profit, p - buy); + } + return profit; + } +}; diff --git a/algorithms/cpp/binaryWatch/BinaryWatch.cpp b/algorithms/cpp/binaryWatch/BinaryWatch.cpp new file mode 100644 index 000000000..26c59425c --- /dev/null +++ b/algorithms/cpp/binaryWatch/BinaryWatch.cpp @@ -0,0 +1,111 @@ +// Source : https://leetcode.com/problems/binary-watch/ +// Author : Hao Chen +// Date : 2016-11-05 + +/*************************************************************************************** + * + * A binary watch has 4 LEDs on the top which represent the hours (0-11), and the 6 + * LEDs on the bottom represent the minutes (0-59). + * Each LED represents a zero or one, with the least significant bit on the right. + * + * For example, the above binary watch reads "3:25". + * + * Given a non-negative integer n which represents the number of LEDs that are + * currently on, return all possible times the watch could represent. + * + * Example: + * Input: n = 1Return: ["1:00", "2:00", "4:00", "8:00", "0:01", "0:02", "0:04", "0:08", + * "0:16", "0:32"] + * + * Note: + * + * The order of output does not matter. + * The hour must not contain a leading zero, for example "01:00" is not valid, it + * should be "1:00". + * The minute must be consist of two digits and may contain a leading zero, for example + * "10:2" is not valid, it should be "10:02". + ***************************************************************************************/ + +class Solution { +private: + void combination(int nLED, int nLight, int max, bool zero, + int start, int k, int solution, + vector>& result) { + if (solution > max){ + return; + } + if (k == 0) { + char tmp[5] = ""; + if (zero) { + sprintf(tmp, "%02d", solution); + }else{ + sprintf(tmp, "%d", solution); + } + result[nLight].push_back(tmp); + return; + } + for (int i=start; i<=nLED-k; i++) { + solution += pow(2, i); + combination(nLED, nLight, max, zero, i+1, k-1, solution, result); + solution -= pow(2, i); + } + } + + void generate_combination(int nLED, int max, bool zero, vector>& result) { + for (int i=0; i>& vv) { + for(auto v : vv) { + cout << "[ "; + for (auto i : v) { + cout << i << " "; + } + cout << "]" << endl; + } + } + +private: + vector> hour; + vector> mins; + +public: + + Solution():hour(4, vector()), mins(6, vector()){ + generate_combination(4, 11, false, hour); + //print(hour); + //[ 0 ] + //[ 1 2 4 8 ] + //[ 3 5 9 6 10 ] + //[ 7 11 ] + + + generate_combination(6, 59, true, mins); + //print(mins); + //[ 00 ] + //[ 01 02 04 08 16 32 ] + //[ 03 05 09 17 33 06 10 18 34 12 20 36 24 40 48 ] + //[ 07 11 19 35 13 21 37 25 41 49 14 22 38 26 42 50 28 44 52 56 ] + //[ 15 23 39 27 43 51 29 45 53 57 30 46 54 58 ] + //[ 31 47 55 59 ] + } + + vector readBinaryWatch(int num) { + + vector result; + for (int i = 0; i <= 3 && i <= num; i++) { + if (num - i > 5) { + continue; + } + for (auto h : hour[i]) { + for (auto m : mins[num - i]) { + result.push_back( h + ":" + m ); + } + } + + } + return result; + } +}; diff --git a/algorithms/cpp/brokenCalculator/BrokenCalculator.cpp b/algorithms/cpp/brokenCalculator/BrokenCalculator.cpp new file mode 100644 index 000000000..b0fa97996 --- /dev/null +++ b/algorithms/cpp/brokenCalculator/BrokenCalculator.cpp @@ -0,0 +1,54 @@ +// Source : https://leetcode.com/problems/broken-calculator/ +// Author : Hao Chen +// Date : 2019-05-01 + +/***************************************************************************************************** + * + * On a broken calculator that has a number showing on its display, we can perform two operations: + * + * Double: Multiply the number on the display by 2, or; + * Decrement: Subtract 1 from the number on the display. + * + * Initially, the calculator is displaying the number X. + * + * Return the minimum number of operations needed to display the number Y. + * + * Example 1: + * + * Input: X = 2, Y = 3 + * Output: 2 + * Explanation: Use double operation and then decrement operation {2 -> 4 -> 3}. + * + * Example 2: + * + * Input: X = 5, Y = 8 + * Output: 2 + * Explanation: Use decrement and then double {5 -> 4 -> 8}. + * + * Example 3: + * + * Input: X = 3, Y = 10 + * Output: 3 + * Explanation: Use double, decrement and double {3 -> 6 -> 5 -> 10}. + * + * Example 4: + * + * Input: X = 1024, Y = 1 + * Output: 1023 + * Explanation: Use decrement operations 1023 times. + * + * Note: + * + * 1 <= X <= 10^9 + * 1 <= Y <= 10^9 + ******************************************************************************************************/ + + +class Solution { +public: + int brokenCalc(int X, int Y) { + if (X >= Y) return X-Y ; + if ( Y%2 ==0 ) return brokenCalc(X, Y/2) + 1; + return brokenCalc(X, Y+1) + 1; + } +}; diff --git a/algorithms/cpp/buddyStrings/BuddyStrings.cpp b/algorithms/cpp/buddyStrings/BuddyStrings.cpp new file mode 100644 index 000000000..41b0b5ea9 --- /dev/null +++ b/algorithms/cpp/buddyStrings/BuddyStrings.cpp @@ -0,0 +1,94 @@ +// Source : https://leetcode.com/problems/buddy-strings/description/ +// Author : Hao Chen +// Date : 2018-06-27 + +/*************************************************************************************** + * + * Given two strings A and B of lowercase letters, return true if and only if we can + * swap two letters in A so that the result equals B. + * + * + * + * Example 1: + * + * + * + * Input: A = "ab", B = "ba" + * Output: true + * + * + * + * Example 2: + * + * + * Input: A = "ab", B = "ab" + * Output: false + * + * + * + * Example 3: + * + * + * Input: A = "aa", B = "aa" + * Output: true + * + * + * + * Example 4: + * + * + * Input: A = "aaaaaaabc", B = "aaaaaaacb" + * Output: true + * + * + * + * Example 5: + * + * + * Input: A = "", B = "aa" + * Output: false + * + * + * + * + * Note: + * + * + * 0 <= A.length <= 20000 + * 0 <= B.length <= 20000 + * A and B consist only of lowercase letters. + * + * + * + * + * + ***************************************************************************************/ + + + +class Solution { +public: + bool buddyStrings(string A, string B) { + if (A.size() != B.size()) return false; + if (A.size()<2) return false; + + bool bRepeat = false; + bool map[26] = {false}; + int idx[2], diffCnt=0; + + for (int i=0; i=2) return false; + idx[diffCnt++] = i; + + } + } + //if A == B and there has repeated chars , then return true + if (diffCnt==0 && bRepeat) return true; + + return (A[idx[0]] == B[idx[1]] && A[idx[1]] == B[idx[0]]); + + } +}; diff --git a/algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp b/algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp new file mode 100644 index 000000000..d4f51736b --- /dev/null +++ b/algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp @@ -0,0 +1,80 @@ +// Source : https://leetcode.com/problems/bulb-switcher/ +// Author : Calinescu Valentin, Hao Chen +// Date : 2015-12-28 + +/*************************************************************************************** + * + * There are n bulbs that are initially off. You first turn on all the bulbs. Then, you + * turn off every second bulb. On the third round, you toggle every third bulb (turning + * on if it's off or turning off if it's on). For the nth round, you only toggle the + * last bulb. Find how many bulbs are on after n rounds. + * + * Example: + * + * Given n = 3. + * + * At first, the three bulbs are [off, off, off]. + * After first round, the three bulbs are [on, on, on]. + * After second round, the three bulbs are [on, off, on]. + * After third round, the three bulbs are [on, off, off]. + * + * So you should return 1, because there is only one bulb is on. + * + ***************************************************************************************/ + + /* Solution + * -------- + * + * We know, + * - if a bulb can be switched to ON eventually, it must be switched by ODD times + * - Otherwise, if a bulb has been switched by EVEN times, it will be OFF eventually. + * So, + * - If bulb `i` ends up ON if and only if `i` has an ODD numbers of divisors. + * And we know, + * - the divisors come in pairs. for example: + * 12 - [1,12] [2,6] [3,4] [6,2] [12,1] (the 12th bulb would be switched by 1,2,3,4,6,12) + * - the pairs means almost all of the numbers are switched by EVEN times. + * + * But we have a special case - square numbers + * - A square number must have a divisors pair with same number. such as 4 - [2,2], 9 - [3,3] + * - So, a square number has a ODD numbers of divisors. + * + * At last, we figure out the solution is: + * + * Count the number of the squre numbers!! + */ + +class Solution { +public: + int bulbSwitch(int n) { + int cnt = 0; + for (int i=1; i*i<=n; i++) { + cnt++; + } + return cnt; + } +}; + + + + /* + * Solution 1 - O(1) + * ========= + * + * We notice that for every light bulb on position i there will be one toggle for every + * one of its divisors, given that you toggle all of the multiples of one number. The + * total number of toggles is irrelevant, because there are only 2 possible positions(on, + * off). We quickly find that 2 toggles cancel each other so given that the start position + * is always off a light bulb will be in if it has been toggled an odd number of times. + * The only integers with an odd number of divisors are perfect squares(because the square + * root only appears once, not like the other divisors that form pairs). The problem comes + * down to finding the number of perfect squares <= n. That number is the integer part of + * the square root of n. + * + */ +class Solution { +public: + int bulbSwitch(int n) { + return (int)sqrt(n); + } +}; diff --git a/algorithms/cpp/bullsAndCows/bullsAndCows.cpp b/algorithms/cpp/bullsAndCows/bullsAndCows.cpp index f91550532..feeb1bb89 100644 --- a/algorithms/cpp/bullsAndCows/bullsAndCows.cpp +++ b/algorithms/cpp/bullsAndCows/bullsAndCows.cpp @@ -42,8 +42,8 @@ class Solution { } string getHint01(string secret, string guess) { - int appears_in_secret[10], appears_in_guess[10], bulls[10]; - int total_bulls, total_cows; + int appears_in_secret[10] = {0}, appears_in_guess[10] = {0}, bulls[10] = {0}; + int total_bulls = 0, total_cows = 0; for(int i = 0; i < secret.size(); i++) appears_in_secret[secret[i] - '0']++; for(int i = 0; i < guess.size(); i++) diff --git a/algorithms/cpp/burstBalloons/BurstBalloons.cpp b/algorithms/cpp/burstBalloons/BurstBalloons.cpp new file mode 100644 index 000000000..901f2e8eb --- /dev/null +++ b/algorithms/cpp/burstBalloons/BurstBalloons.cpp @@ -0,0 +1,104 @@ +// Source : https://leetcode.com/problems/burst-balloons/ +// Author : Hao Chen +// Date : 2016-01-17 + +/*************************************************************************************** + * + * Given n balloons, indexed from 0 to n-1. Each balloon is painted with a + * number on it represented by array nums. + * + * You are asked to burst all the balloons. If the you burst + * balloon i you will get nums[left] * nums[i] * nums[right] coins. Here left + * and right are adjacent indices of i. After the burst, the left and right + * then becomes adjacent. + * + * Find the maximum coins you can collect by bursting the balloons wisely. + * + * Note: + * (1) You may imagine nums[-1] = nums[n] = 1. They are not real therefore you can + * not burst them. + * (2) 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100 + * + * Example: + * + * Given [3, 1, 5, 8] + * + * Return 167 + * + * nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> [] + * coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167 + * + * Credits:Special thanks to @dietpepsi for adding this problem and creating all test + * cases. + ***************************************************************************************/ + + + +class Solution { +public: + int maxCoins(vector& nums) { + //remove all of zero item + nums.erase(remove_if(nums.begin(), nums.end(), [](int n){return n==0;}), nums.end()); + + //add 1 for head and tail + nums.insert(nums.begin(),1); + nums.push_back(1); + + int n = nums.size(); + vector< vector > matrix(n, vector(n,0)); + + return maxCoins_DP(nums, matrix); + return maxCoins_DC(nums, matrix, 0, n-1); + } + + + //Divide and Conquer + // + // If we seprate the array to two part, left part and right part. + // + // Then, we will find in this problem the left and right become adjacent + // and have effects on the maxCoins in the future. + // + // So, if we think reversely, if the balloon i is the last balloon of all to burst, + // the left and right section now has well defined boundary and do not affect each other! + // Therefore we can do either recursive method with memoization + // + int maxCoins_DC(vector& nums, vector>& matrix, int low, int high) { + if (low + 1 == high) return 0; + if (matrix[low][high] > 0) return matrix[low][high]; + int result = 0; + for (int i = low + 1; i < high; ++i){ + result = max(result, nums[low] * nums[i] * nums[high] + + maxCoins_DC(nums, matrix, low, i) + + maxCoins_DC(nums, matrix, i, high)); + } + matrix[low][high] = result; + return result; + } + + //Dynamic Programming + // + // using the same idea of above + // + int maxCoins_DP(vector& nums, vector>& dp) { + int n = nums.size(); + for (int k = 2; k < n; ++k) { + for (int low = 0; low < n - k; low++){ + int high = low + k; + for (int i = low + 1; i < high; ++i) + dp[low][high] = max( dp[low][high], + nums[low] * nums[i] * nums[high] + dp[low][i] + dp[i][high]); + } + } + return dp[0][n - 1]; + } + +private: + void printVector(vector& nums) { + cout << "nums: "; + for (auto n: nums) { + cout << n << ' '; + } + cout << '\n'; + } +}; diff --git a/algorithms/cpp/coinChange/CoinChange2.cpp b/algorithms/cpp/coinChange/CoinChange2.cpp new file mode 100644 index 000000000..2bcb99205 --- /dev/null +++ b/algorithms/cpp/coinChange/CoinChange2.cpp @@ -0,0 +1,84 @@ +// Source : https://leetcode.com/problems/coin-change-2/ +// Author : Hao Chen +// Date : 2019-03-18 + +/***************************************************************************************************** + * + * You are given coins of different denominations and a total amount of money. Write a function to + * compute the number of combinations that make up that amount. You may assume that you have infinite + * number of each kind of coin. + * + * Example 1: + * + * Input: amount = 5, coins = [1, 2, 5] + * Output: 4 + * Explanation: there are four ways to make up the amount: + * 5=5 + * 5=2+2+1 + * 5=2+1+1+1 + * 5=1+1+1+1+1 + * + * Example 2: + * + * Input: amount = 3, coins = [2] + * Output: 0 + * Explanation: the amount of 3 cannot be made up just with coins of 2. + * + * Example 3: + * + * Input: amount = 10, coins = [10] + * Output: 1 + * + * Note: + * + * You can assume that + * + * 0 <= amount <= 5000 + * 1 <= coin <= 5000 + * the number of coins is less than 500 + * the answer is guaranteed to fit into signed 32-bit integer + * + ******************************************************************************************************/ +class Solution { +public: + int change(int amount, vector& coins) { + return change_dp(amount, coins); + return change_recursive(amount, coins); // Time Limit Error + } + + + int change_recursive(int amount, vector& coins) { + int result = 0; + change_recursive_helper(amount, coins, 0, result); + return result; + } + + // the `idx` is used for remove the duplicated solutions. + void change_recursive_helper(int amount, vector& coins, int idx, int& result) { + if (amount == 0) { + result++; + return; + } + + for ( int i = idx; i < coins.size(); i++ ) { + if (amount < coins[i]) continue; + change_recursive_helper(amount - coins[i], coins, i, result); + } + return; + } + + int change_dp(int amount, vector& coins) { + vector dp(amount+1, 0); + dp[0] = 1; + for (int i=0; i= coins[i]) { + dp[n] += dp[n-coins[i]]; + } + } + } + + return dp[amount]; + } +}; + diff --git a/algorithms/cpp/coinChange/coinChange.cpp b/algorithms/cpp/coinChange/coinChange.cpp new file mode 100644 index 000000000..4948b2106 --- /dev/null +++ b/algorithms/cpp/coinChange/coinChange.cpp @@ -0,0 +1,103 @@ +// Source : https://leetcode.com/problems/coin-change/ +// Author : Calinescu Valentin, Hao Chen +// Date : 2015-12-28 + +/*************************************************************************************** + * + * You are given coins of different denominations and a total amount of money amount. + * Write a function to compute the fewest number of coins that you need to make up that + * amount. If that amount of money cannot be made up by any combination of the coins, + * return -1. + * + * Example 1: + * coins = [1, 2, 5], amount = 11 + * return 3 (11 = 5 + 5 + 1) + * + * Example 2: + * coins = [2], amount = 3 + * return -1. + * + * Note: + * You may assume that you have an infinite number of each kind of coin. + * + * Credits: + * Special thanks to @jianchao.li.fighter for adding this problem and creating all test + * cases. + * + ***************************************************************************************/ + + +/* Recursive solution - TIME LIMIT ERROR */ +class Solution { +public: + int coinChange(vector& coins, int amount) { + int result = INT_MAX; + if ( amount == 0 ) return 0; + if ( amount < 0 ) return -1; + for (int i=0; i r ) result = r + 1; + } + return result == INT_MAX ? -1 : result; + } +} + + + /* + * Solution 1 - O(N * amount) + * ========= + * + * This problem can be solved using dynamic programming, thus building the optimal + * solution from previous smaller ones. For every coin of value t and every sum of money + * i the sum can be traced back to a previous sum i - t that was already computed and uses + * the smallest number of coins possible. This way we can construct every sum i as the + * minimum of all these previous sums for every coin value. To be sure we'll find a minimum + * we can populate the solution vector with an amount bigger than the maximum possible, + * which is amount + 1(when the sum is made up of only coins of value 1). The only exception + * is sol[0] which is 0 as we need 0 coins to have a sum of 0. In the end we need to look + * if the program found a solution in sol[amount] or it remained the same, in which case we + * can return -1. + * + */ +class Solution { +public: + + int coinChange(vector& coins, int amount) { + int sol[amount + 1]; + sol[0] = 0; + for(int i = 1; i <= amount; i++) + sol[i] = amount + 1; + for(int i = 0; i < coins.size(); i++) + { + for(int j = coins[i]; j <= amount; j++) + sol[j] = min(sol[j], sol[j - coins[i]] + 1); + } + if(sol[amount] != amount + 1) + return sol[amount]; + else + return -1; + } +}; + + +//Another DP implmentation, same idea above +class Solution { +public: + int coinChange(vector& coins, int amount) { + const int MAX = amount +1; + vector dp(amount+1, MAX); + dp[0]=0; + + for(int i=1; i<=amount; i++) { + for (int j=0; j= coins[j]) { + dp[i] = min( dp[i], dp[i-coins[j]] + 1 ); + } + } + } + + return dp[amount]==MAX ? -1 : dp[amount]; + } +}; diff --git a/algorithms/cpp/combinationSumIV/combinationSumIV.cpp b/algorithms/cpp/combinationSumIV/combinationSumIV.cpp new file mode 100644 index 000000000..d3006375d --- /dev/null +++ b/algorithms/cpp/combinationSumIV/combinationSumIV.cpp @@ -0,0 +1,68 @@ +// Source : https://leetcode.com/problems/combination-sum-iv/ +// Author : Calinescu Valentin +// Date : 2016-08-07 + +/*************************************************************************************** + * + * Given an integer array with all positive numbers and no duplicates, find the number + * of possible combinations that add up to a positive integer target. + * + * Example: + * + * nums = [1, 2, 3] + * target = 4 + * + * The possible combination ways are: + * (1, 1, 1, 1) + * (1, 1, 2) + * (1, 2, 1) + * (1, 3) + * (2, 1, 1) + * (2, 2) + * (3, 1) + * + * Note that different sequences are counted as different combinations. + * + * Therefore the output is 7. + * Follow up: + * What if negative numbers are allowed in the given array? + * How does it change the problem? + * What limitation we need to add to the question to allow negative numbers? + * + ***************************************************************************************/ + + /* Solution + * -------- + * 1) Dynamic Programming - O(N * target) + * + * We notice that any sum S can be written as S_prev + nums[i], where S_prev is a sum of + * elements from nums and nums[i] is one element of the array. S_prev is always smaller + * than S so we can create the array sol, where sol[i] is the number of ways one can + * arrange the elements of the array to obtain sum i, and populate it from 1 to target, + * as the solution for i is made up of previously computed ones for numbers smaller than + * i. The final answer is sol[target], which is returned at the end. + * + * Follow up: + * + * If the array contains negative numbers as well as positive ones we can run into a cycle + * where some subset of the elements have sum 0 so they can always be added to an existing + * sum, leading to an infinite number of solutions. The limitation that we need is a rule + * to be followed by the input data, that which doesn't allow this type of subsets to exist. + */ +class Solution { +public: + int combinationSum4(vector& nums, int target) { + int sol[target + 1]; + sol[0] = 1;//starting point, only 1 way to obtain 0, that is to have 0 elements + for(int i = 1; i <= target; i++) + { + sol[i] = 0; + for(int j = 0; j < nums.size(); j++) + { + if(i >= nums[j])//if there is a previously calculated sum to add nums[j] to + sol[i] += sol[i - nums[j]]; + } + } + return sol[target]; + } +}; diff --git a/algorithms/cpp/compareStringsByFrequencyOfTheSmallestCharacter/CompareStringsByFrequencyOfTheSmallestCharacter.cpp b/algorithms/cpp/compareStringsByFrequencyOfTheSmallestCharacter/CompareStringsByFrequencyOfTheSmallestCharacter.cpp new file mode 100644 index 000000000..29aa35815 --- /dev/null +++ b/algorithms/cpp/compareStringsByFrequencyOfTheSmallestCharacter/CompareStringsByFrequencyOfTheSmallestCharacter.cpp @@ -0,0 +1,83 @@ +// Source : https://leetcode.com/problems/compare-strings-by-frequency-of-the-smallest-character/ +// Author : Hao Chen +// Date : 2019-10-01 + +/***************************************************************************************************** + * + * Let's define a function f(s) over a non-empty string s, which calculates the frequency of the + * smallest character in s. For example, if s = "dcce" then f(s) = 2 because the smallest character is + * "c" and its frequency is 2. + * + * Now, given string arrays queries and words, return an integer array answer, where each answer[i] is + * the number of words such that f(queries[i]) < f(W), where W is a word in words. + * + * Example 1: + * + * Input: queries = ["cbd"], words = ["zaaaz"] + * Output: [1] + * Explanation: On the first query we have f("cbd") = 1, f("zaaaz") = 3 so f("cbd") < f("zaaaz"). + * + * Example 2: + * + * Input: queries = ["bbb","cc"], words = ["a","aa","aaa","aaaa"] + * Output: [1,2] + * Explanation: On the first query only f("bbb") < f("aaaa"). On the second query both f("aaa") and + * f("aaaa") are both > f("cc"). + * + * Constraints: + * + * 1 <= queries.length <= 2000 + * 1 <= words.length <= 2000 + * 1 <= queries[i].length, words[i].length <= 10 + * queries[i][j], words[i][j] are English lowercase letters. + ******************************************************************************************************/ + +class Solution { +public: + vector numSmallerByFrequency(vector& queries, vector& words) { + cout << queries.size() << " : " << words.size() << endl; + vector freq; + for (auto w : words) { + freq.push_back(f(w)); + } + sort(freq.begin(), freq.end()); + + vector result; + for (auto q : queries) { + result.push_back(binary_search(freq, f(q))); + } + return result; + } + + int f(string& s) { + char ch = 'z' + 1; //stroe the smallest char + int cnt = 0; //stroe the frequency of the smallest char + for (auto c : s) { + if (c < ch) { //find the smaller char, reset the count + cnt = 1; + ch = c; + } if (c == ch) { + cnt++; + } + } + return cnt; + } + + int binary_search(vector &v, int target) { + int low=0, high=v.size()-1, mid; + + while (low < high) { + mid = low + (high - low) / 2; + if ( v[mid] > target) { + high = mid -1; + } else if (v[mid] <= target) { + low = mid + 1; + } + } + + low = v[low] > target ? low : low + 1; + + return v.size() - low; + } + +}; diff --git a/algorithms/cpp/convertANumberToHexadecimal/ConvertANumberToHexadecimal.cpp b/algorithms/cpp/convertANumberToHexadecimal/ConvertANumberToHexadecimal.cpp new file mode 100644 index 000000000..654e50e40 --- /dev/null +++ b/algorithms/cpp/convertANumberToHexadecimal/ConvertANumberToHexadecimal.cpp @@ -0,0 +1,56 @@ +// Source : https://leetcode.com/problems/convert-a-number-to-hexadecimal/ +// Author : Hao Chen +// Date : 2016-11-12 + +/*************************************************************************************** + * + * Given an integer, write an algorithm to convert it to hexadecimal. For negative + * integer, two’s complement method is used. + * + * Note: + * + * All letters in hexadecimal (a-f) must be in lowercase. + * The hexadecimal string must not contain extra leading 0s. If the number is zero, it + * is represented by a single zero character '0'; otherwise, the first character in the + * hexadecimal string will not be the zero character. + * The given number is guaranteed to fit within the range of a 32-bit signed integer. + * You must not use any method provided by the library which converts/formats the + * number to hex directly. + * + * Example 1: + * + * Input: + * 26 + * + * Output: + * "1a" + * + * Example 2: + * + * Input: + * -1 + * + * Output: + * "ffffffff" + ***************************************************************************************/ + +class Solution { +public: + + string toHex(int num) { + + if (num == 0) return "0"; + + unsigned int x = num; + + string result; + for(;x > 0; x/=16) { + int n = x % 16; + char c; + if (n < 10) c = n + '0'; + else c = 'a' + n - 10 ; + result = c + result; + } + return result; + } +}; diff --git a/algorithms/cpp/countNumbersWithUniqueDigits/CountNumbersWithUniqueDigits.cpp b/algorithms/cpp/countNumbersWithUniqueDigits/CountNumbersWithUniqueDigits.cpp new file mode 100644 index 000000000..6733dced3 --- /dev/null +++ b/algorithms/cpp/countNumbersWithUniqueDigits/CountNumbersWithUniqueDigits.cpp @@ -0,0 +1,70 @@ +// Source : https://leetcode.com/problems/count-numbers-with-unique-digits/ +// Author : Hao Chen +// Date : 2019-03-24 + +/***************************************************************************************************** + * + * Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. + * + * Example: + * + * Input: 2 + * Output: 91 + * Explanation: The answer should be the total numbers in the range of 0 ≤ x < 100, + * excluding 11,22,33,44,55,66,77,88,99 + * + ******************************************************************************************************/ + + +// Considering three digits +// - the first place could be [1-9] which has 9 choices. +// - the second place could be [0-9] with excluding the first digit, which is 10-1=9 choices. +// - the third place could be [0-9] with excluding the 1st and 2nd digits, which is 10-2=8 choices. +// So, three digits has 9*9*8 unique digits. +// +// After adds the 1 digit unique number,and 2 digits unique number, we can have the result: +// +// 9*9*8 + 9*9 + 10 = 648 + 81 + 10 = 739 +// +// n = 0, a[0] = 1; +// n = 1, a[1] = 9 + a[0]; +// n = 2, a[2] = 9*9 + a[1]; +// n = 3, a[3] = 9*9*8 + a[2]; +// n = 4, a[4] = 9*9*8*7 + a[3]; +// .... +class Solution { +public: + int countNumbersWithUniqueDigits(int n) { + int result = 1; + for (int i=0; i i. + * + * With these prefix sums, it is trivial to see that with O(n^2) time we can find all S(i, j) + * in the range [lower, upper] + * + * int countRangeSum(vector& nums, int lower, int upper) { + * int n = nums.size(); + * long[] sums = new long[n + 1]; + * for (int i = 0; i < n; ++i) { + * sums[i + 1] = sums[i] + nums[i]; + * } + * int ans = 0; + * for (int i = 0; i < n; ++i) { + * for (int j = i + 1; j <= n; ++j) { + * if (sums[j] - sums[i] >= lower && sums[j] - sums[i] <= upper) { + * ans++; + * } + * } + * } + * delete []sums; + * return ans; + * } + * + * The above solution would get time limit error. + * + * Recall `count smaller number after self` where we encountered the problem + * + * count[i] = count of nums[j] - nums[i] < 0 with j > i + * + * Here, after we did the preprocess, we need to solve the problem + * + * count[i] = count of a <= S[j] - S[i] <= b with j > i + * + * In other words, if we maintain the prefix sums sorted, and then are able to find out + * - how many of the sums are less than 'lower', say num1, + * - how many of the sums are less than 'upper + 1', say num2, + * Then 'num2 - num1' is the number of sums that lie within the range of [lower, upper]. + * + */ + +class Node{ + public: + long long val; + int cnt; //amount of the nodes + Node *left, *right; + Node(long long v):val(v), cnt(1), left(NULL), right(NULL) {} +}; + +// a tree stores all of prefix sums +class Tree{ + public: + Tree():root(NULL){ } + ~Tree() { freeTree(root); } + + void Insert(long long val) { + Insert(root, val); + } + int LessThan(long long sum, int val) { + return LessThan(root, sum, val, 0); + } + + private: + Node* root; + + //general binary search tree insert algorithm + void Insert(Node* &root, long long val) { + if (!root) { + root = new Node(val); + return; + } + + root->cnt++; + + if (val < root->val ) { + Insert(root->left, val); + }else if (val > root->val) { + Insert(root->right, val); + } + } + //return how many of the sums less than `val` + // - `sum` is the new sums which hasn't been inserted + // - `val` is the `lower` or `upper+1` + int LessThan(Node* root, long long sum, int val, int res) { + + if (!root) return res; + + if ( sum - root->val < val) { + //if (sum[j, i] < val), which means all of the right branch must be less than `val` + //so we add the amounts of sums in right branch, and keep going the left branch. + res += (root->cnt - (root->left ? root->left->cnt : 0) ); + return LessThan(root->left, sum, val, res); + }else if ( sum - root->val > val) { + //if (sum[j, i] > val), which means all of left brach must be greater than `val` + //so we just keep going the right branch. + return LessThan(root->right, sum, val, res); + }else { + //if (sum[j,i] == val), which means we find the correct place, + //so we just return the the amounts of right branch.] + return res + (root->right ? root->right->cnt : 0); + } + } + void freeTree(Node* root){ + if (!root) return; + if (root->left) freeTree(root->left); + if (root->right) freeTree(root->right); + delete root; + } + +}; + + + +class Solution { +public: + int countRangeSum(vector& nums, int lower, int upper) { + Tree tree; + tree.Insert(0); + long long sum = 0; + int res = 0; + + for (int n : nums) { + sum += n; + int lcnt = tree.LessThan(sum, lower); + int hcnt = tree.LessThan(sum, upper + 1); + res += (hcnt - lcnt); + tree.Insert(sum); + } + + return res; + } +}; diff --git a/algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp b/algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp index cac1435c4..badec47d2 100644 --- a/algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp +++ b/algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp @@ -1,5 +1,5 @@ // Source : https://leetcode.com/problems/count-of-smaller-numbers-after-self/ -// Author : Calinescu Valentin +// Author : Calinescu Valentin, Hao Chen // Date : 2015-12-08 /*************************************************************************************** @@ -73,3 +73,80 @@ class Solution { return sol; } }; + + +/*************************************************************************************** + * Another solution - Binary Search Tree + ***************************************************************************************/ + + +class BinarySearchTreeNode +{ + public: + int val; + int less; // count of members less than val + int count; // count of members equal val + BinarySearchTreeNode *left, *right; + BinarySearchTreeNode(int value) : val(value), less(0),count(1),left(NULL), right(NULL) {} +}; + +class BinarySearchTree +{ + private: + BinarySearchTreeNode* root; + public: + BinarySearchTree(const int value):root(new BinarySearchTreeNode(value)){ } + ~BinarySearchTree() { + freeTree(root); + } + void insert(const int value, int &numLessThan) { + insert(root, value, numLessThan); + } + private: + void freeTree(BinarySearchTreeNode* root){ + if (root == NULL) return; + if (root->left) freeTree(root->left); + if (root->right) freeTree(root->right); + delete root; + } + + void insert(BinarySearchTreeNode* root, const int value, int &numLessThan) { + + if(value < root->val) { // left + root->less++; + if(root->left == NULL) { + root->left = new BinarySearchTreeNode(value); + }else{ + this->insert(root->left, value, numLessThan); + } + } else if(value > root->val) { // right + numLessThan += root->less + root->count; + if(!root->right) { + root->right = new BinarySearchTreeNode(value); + }else{ + this->insert(root->right, value, numLessThan); + } + } else { + numLessThan += root->less; + root->count++; + return; + } + } +}; + +class Solution { + public: + vector countSmaller(vector& nums) { + vector counts(nums.size()); + if(nums.size() == 0) return counts; + + BinarySearchTree tree(nums[nums.size()-1]); + + for(int i = nums.size() - 2; i >= 0; i--) { + int numLessThan = 0; + tree.insert( nums[i], numLessThan); + counts[i] = numLessThan; + } + return counts; + } +}; diff --git a/algorithms/cpp/countingBits/CountingBits.cpp b/algorithms/cpp/countingBits/CountingBits.cpp new file mode 100644 index 000000000..0bfe843b1 --- /dev/null +++ b/algorithms/cpp/countingBits/CountingBits.cpp @@ -0,0 +1,67 @@ +// Source : https://leetcode.com/problems/counting-bits/ +// Author : Hao Chen +// Date : 2016-05-30 + +/*************************************************************************************** + * + * Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ + * num calculate the number of 1's in their binary representation and return them as an + * array. + * + * Example: + * For num = 5 you should return [0,1,1,2,1,2]. + * + * Follow up: + * + * It is very easy to come up with a solution with run time O(n*sizeof(integer)). But + * can you do it in linear time O(n) /possibly in a single pass? + * Space complexity should be O(n). + * Can you do it like a boss? Do it without using any builtin function like + * __builtin_popcount in c++ or in any other language. + * + * You should make use of what you have produced already. + * Divide the numbers in ranges like [2-3], [4-7], [8-15] and so on. And try to + * generate new range from previous. + * Or does the odd/even status of the number help you in calculating the number of 1s? + * + * Credits:Special thanks to @ syedee for adding this problem and creating all test + * cases. + ***************************************************************************************/ + +class Solution { +public: + /* + * Initialization + * + * bits_cnt[0] => 0000 => 0 + * bits_cnt[1] => 0001 => 1 + * + * if the number has 2 bits (2, 3), then we can split the binary to two parts, + * 2 = 10 + 0 and 3= 10 + 1, then we can reuse the bits_cnt[0] and bits_cnt[1] + * + * bits_cnt[2] => 0010 => 0010 + 0 => 1 + bits_cnt[0]; + * bits_cnt[3] => 0011 => 0010 + 1 => 1 + bits_cnt[1]; + * + * if the number has 3 bits (4,5,6,7), then we can split the binary to two parts, + * 4 = 100 + 0, 5 = 100 + 01, 6= 100 + 10, 7 = 100 +11 + * then we can reuse the bits_cnt[0] and bits_cnt[1] + * + * bits_cnt[4] => 0110 => 0100 + 00 => 1 + bits_cnt[0]; + * bits_cnt[5] => 0101 => 0100 + 01 => 1 + bits_cnt[1]; + * bits_cnt[6] => 0110 => 0100 + 10 => 1 + bits_cnt[2]; + * bits_cnt[7] => 0111 => 0100 + 11 => 1 + bits_cnt[3]; + * + * so, we can have the solution: + * + * bits_cnt[x] = bits_cnt[x & (x-1) ] + 1; + * + */ + vector countBits(int num) { + vector bits_cnt(num+1, 0); + + for (int i=1; i<=num; i++) { + bits_cnt[i] = bits_cnt[i & (i-1)] + 1; + } + return bits_cnt; + } +}; diff --git a/algorithms/cpp/courseSchedule/non-recursive/course_schedule.cpp b/algorithms/cpp/courseSchedule/non-recursive/course_schedule.cpp new file mode 100644 index 000000000..b7decde33 --- /dev/null +++ b/algorithms/cpp/courseSchedule/non-recursive/course_schedule.cpp @@ -0,0 +1,149 @@ +// +// course_schedule.cpp +// LeeteCodeOJ#207 +// +// Created by Wang Yi on 28/11/16. +// Copyright (c) 2016 Wang Yi. All rights reserved. +// + +#include + +#include +#include +#include +#include + +using std::stack; +using std::queue; +using std::vector; +using std::unordered_set; +using std::pair; + +typedef pair Val; +typedef vector> Graph; + +#define FOR(s, e) \ +for (s = 0; s < e; s++) { +#define END ;} + + typedef struct _node { + int val; + // int depth; + struct _node * parent; + } node; + + class Solution { + public: + bool canFinish(int numCourses, vector>& prerequisites) { + vector outdepth(numCourses, 0); + unordered_set vex; + if ((int) prerequisites.size() == 0) + return true; + vector> graph = to_neighbor_repr(numCourses, prerequisites, outdepth); + + return dsf(numCourses, graph, outdepth); + } + + vector> to_neighbor_repr(int numOfvex, vector& edges, + vector& outdepth) { + // std::cout << "building ... " << std::endl; + vector> graph(numOfvex); + for (auto edge : edges) { + graph[edge.second].insert(edge.first); // second -> first + outdepth[edge.second]++; + // std::cout << edge.first << " <- " << edge.second << std::endl; + } + + return graph; + + } + + + bool dsf(int numOfvex, vector>& graph, vector& outdepth) + { + // preparation + stack s; + vector visited(numOfvex, false); + vector onpath(numOfvex, false); + vector starts; + + int i; + + unordered_set children; + + + FOR(i, numOfvex) + if (outdepth[i] !=0 ) { + starts.push_back(i); + } + END + + if ((int)starts.size() == 0) + return false; // no vertex with indepth of 0 found, a circle found + + for (auto j: starts) { + // std::cout << "start from " << j << std::endl; + // do dsf search, if not visited + // when a circle in a path found, return false. + // else return true + if (visited[j]) + continue; + + node head; + head.val = j; + head.parent = NULL; + // head.depth = 1; + s.push(head); + + // non-recursive search + while (!s.empty()) { + node* curr = &(s.top()); + + if (visited[curr->val]) { + // all children have been read + s.pop(); + onpath[curr->val] = false; + continue; // ignore ... + } + + onpath[curr->val] = visited[curr->val]= true; + children = graph[curr->val]; + + if ((int)children.size() == 0) { + s.pop(); + onpath[curr->val] = false; + // std::cout << "==== reach the end ===="<val << "'s children is: "; + for (auto child: children) { + // std::cout << child << " "; + //if (onpath.find(child) == onpath.end()) + if (onpath[child]) { + + // std::cout << std::endl << "a circle found:" << std::endl; + // std::cout << child << " <- "; + // while (curr->parent != NULL) { + // std::cout << curr->val << " <- "; + // curr = curr->parent; + // } + // std::cout << curr->val << std::endl; + + return false; // a circle found, might print debug here + } + + node nd; + nd.val = child; + // nd.depth = curr->depth+1; + nd.parent = curr; // for debug purpose ... + s.push(nd); + } + // std::cout << std::endl; + } + + } // end of for + return true; + } + + }; \ No newline at end of file diff --git a/algorithms/cpp/courseSchedule/non-recursive/main.cpp b/algorithms/cpp/courseSchedule/non-recursive/main.cpp new file mode 100644 index 000000000..f667c8796 --- /dev/null +++ b/algorithms/cpp/courseSchedule/non-recursive/main.cpp @@ -0,0 +1,30 @@ +// +// main.cpp +// LeeteCodeOJ#207 +// +// Created by Wang Yi on 28/11/16. +// Copyright (c) 2016 Wang Yi. All rights reserved. +// + +#include +#include +#include + +#include "course_schedule.cpp" + +using std::make_pair; + +int main(int argc, const char * argv[]) { + // insert code here... + Solution sl; + int numCourses = 4; + vector prerequisites; + prerequisites.push_back(make_pair(0,1)); + prerequisites.push_back(make_pair(3,1)); + prerequisites.push_back(make_pair(1,3)); + prerequisites.push_back(make_pair(3,2)); + + + std::cout << sl.canFinish(numCourses, prerequisites); + return 0; +} diff --git a/algorithms/cpp/cousinsInBinaryTree/CousinsInBinaryTree.cpp b/algorithms/cpp/cousinsInBinaryTree/CousinsInBinaryTree.cpp new file mode 100644 index 000000000..fc68f2016 --- /dev/null +++ b/algorithms/cpp/cousinsInBinaryTree/CousinsInBinaryTree.cpp @@ -0,0 +1,74 @@ +// Source : https://leetcode.com/problems/cousins-in-binary-tree/ +// Author : Hao Chen +// Date : 2019-04-30 + +/***************************************************************************************************** + * + * In a binary tree, the root node is at depth 0, and children of each depth k node are at depth k+1. + * + * Two nodes of a binary tree are cousins if they have the same depth, but have different parents. + * + * We are given the root of a binary tree with unique values, and the values x and y of two different + * nodes in the tree. + * + * Return true if and only if the nodes corresponding to the values x and y are cousins. + * + * Example 1: + * + * Input: root = [1,2,3,4], x = 4, y = 3 + * Output: false + * + * Example 2: + * + * Input: root = [1,2,3,null,4,null,5], x = 5, y = 4 + * Output: true + * + * Example 3: + * + * Input: root = [1,2,3,null,4], x = 2, y = 3 + * Output: false + * + * Note: + * + * The number of nodes in the tree will be between 2 and 100. + * Each node has a unique integer value from 1 to 100. + * + ******************************************************************************************************/ + +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode(int x) : val(x), left(NULL), right(NULL) {} + * }; + */ +class Solution { +public: + bool isCousins(TreeNode* root, int x, int y) { + int dx=0, dy=0; + TreeNode *px=root, *py=root; + dx = DepthAndParent(root, px, 0, x); + dy = DepthAndParent(root, py, 0, y); + if (dx && dy){ + return (dx == dy && px != py); + } + + return false; + + } + + int DepthAndParent(TreeNode* root, TreeNode*& parent, int depth, int x) { + if (!root) return 0; + if ( root->val == x) return depth; + + int d=0; + parent = root; + if ( ( d = DepthAndParent(root->left, parent, depth+1, x)) > 0 ) return d; + + parent = root; + if ( ( d = DepthAndParent(root->right, parent, depth+1, x)) > 0 ) return d; + return 0; + } +}; diff --git a/algorithms/cpp/createMaximumNumber/CreateMaximumNumber.cpp b/algorithms/cpp/createMaximumNumber/CreateMaximumNumber.cpp new file mode 100644 index 000000000..dc88f9a41 --- /dev/null +++ b/algorithms/cpp/createMaximumNumber/CreateMaximumNumber.cpp @@ -0,0 +1,152 @@ +// Source : https://leetcode.com/problems/create-maximum-number/ +// Author : Hao Chen +// Date : 2016-01-21 + +/*************************************************************************************** + * + * Given two arrays of length m and n with digits 0-9 representing two numbers. + * Create the maximum number of length k from digits of the two. The relative + * order of the digits + * from the same array must be preserved. Return an array of the k digits. You + * should try to optimize your time and space complexity. + * + * Example 1: + * + * nums1 = [3, 4, 6, 5] + * nums2 = [9, 1, 2, 5, 8, 3] + * k = 5 + * return [9, 8, 6, 5, 3] + * + * Example 2: + * + * nums1 = [6, 7] + * nums2 = [6, 0, 4] + * k = 5 + * return [6, 7, 6, 0, 4] + * + * Example 3: + * + * nums1 = [3, 9] + * nums2 = [8, 9] + * k = 3 + * return [9, 8, 9] + * + * Credits:Special thanks to @dietpepsi for adding this problem and creating all test + * cases. + ***************************************************************************************/ + + + +/* + * Solution + * -------- + * + * 1) We split the `K` to two parts : `i` & `k-i` 0<= i <= k + * + * 2) Find the max number for both arrays with giving the length `i` and `k-i` + * - sub1 = FindMaxNumber(num1, len=i); + * - sub2 = FindMaxNumber(num2, len=k-i); + * Here, we need use stack-way to solve find the max number. + * + * 3) Merge two arrays + * - solution = Merge(sub1, sub2); + * Here, we need be careful if a two number are same which one we need to take. For examples: + * [6,7] + * [6,0,4] + * 5 + * + * [2,5,6,4,4,0] + * [7,3,8,0,6,5,7,6,2] + * 15 + * + * 4) compare with the last solution + * - result = max(result, solution); + * + * + */ + + +class Solution { +public: + vector maxNumber(vector& nums1, vector& nums2, int k) { + vector result; + int len1 = nums1.size(); + int len2 = nums2.size(); + for (int i=0; i<=k; i++){ + if (len1 < i || len2 < k-i) continue; + vector sub1 = findMaxSubArray(nums1, i); + vector sub2 = findMaxSubArray(nums2, k-i); + vector merge = mergeTwoArrays(sub1, sub2); + if (compareTwoArray(merge, 0, result, 0)) { + result = merge; + } + } + return result; + } + + + bool compareTwoArray(vector& nums1, int start1, vector& nums2, int start2) { + int n1 = nums1.size(); + int n2 = nums2.size(); + for(; start1 nums2[start2]) return true; + if (nums1[start1] < nums2[start2]) return false; + } + //if num1 still have numbers, return true, else return false + return start1 < nums1.size(); + } + + vector mergeTwoArrays(vector& nums1, vector& nums2) { + vector result; + int len1 = nums1.size(); + int len2 = nums2.size(); + int pos1=0, pos2=0; + while ( pos1 < len1 && pos2 < len2 ){ + // Be careful if two numbers are equal. consider the following case + // case 1: [6,7], [6,0,4] - we have same item - 6 + // case 2: [4,0,2], [2,0,3,1] - we have same item - 0 + // which one we need to merge? + // We need compare the rest of array. + if (nums1[pos1] == nums2[pos2]){ + result.push_back( compareTwoArray(nums1, pos1+1, nums2, pos2+1) ? + nums1[pos1++] : nums2[pos2++]); + }else { + result.push_back(nums1[pos1] > nums2[pos2] ? + nums1[pos1++] : nums2[pos2++]); + } + } + + if (pos1 < len1){ + result.insert(result.end(), nums1.begin()+pos1, nums1.end()); + } + if (pos2 < len2) { + result.insert(result.end(), nums2.begin()+pos2, nums2.end()); + } + + return result; + } + + + // using a stack method to find the max sub-array + // k <= nums.size() + vector findMaxSubArray(vector& nums, int k) { + int len = nums.size(); + if ( k >= len ) return nums; + vector result(k, 0); + int idx = 0; // the postion for result array + for (int i=0; i the last element of result[], + // and we still have enough numbers, + // then pop up the item + while (idx>0 && k - idx < len - i && result[idx-1] < nums[i]) { + idx--; + } + //push the number into the result[] + if (idx < k) { + result[idx++] = nums[i]; + } + } + return result; + } + +}; diff --git a/algorithms/cpp/decodeString/DecodeString.cpp b/algorithms/cpp/decodeString/DecodeString.cpp new file mode 100644 index 000000000..677818981 --- /dev/null +++ b/algorithms/cpp/decodeString/DecodeString.cpp @@ -0,0 +1,105 @@ +// Source : https://leetcode.com/problems/decode-string/ +// Author : Hao Chen +// Date : 2016-09-08 + +/*************************************************************************************** + * + * Given an encoded string, return it's decoded string. + * + * The encoding rule is: k[encoded_string], where the encoded_string inside the square + * brackets is being repeated exactly k times. Note that k is guaranteed to be a + * positive integer. + * + * You may assume that the input string is always valid; No extra white spaces, square + * brackets are well-formed, etc. + * + * Furthermore, you may assume that the original data does not contain any digits and + * that digits are only for those repeat numbers, k. For example, there won't be input + * like 3a or 2[4]. + * + * Examples: + * + * s = "3[a]2[bc]", return "aaabcbc". + * s = "3[a2[c]]", return "accaccacc". + * s = "2[abc]3[cd]ef", return "abcabccdcdcdef". + ***************************************************************************************/ + +class Solution { +public: + string decodeString(string s) { + if (!isValid(s)) return ""; + + stack _stack; + stack _nstack; + + string result; + string tmp; + int n=0; + for (int i=0; i0; n--) { + tmp += _stack.top(); + } + _stack.pop(); + _nstack.pop(); + if ( ! _stack.empty() ) { + _stack.top() += tmp; + }else { + result += tmp; + } + } else { + if ( ! _stack.empty() ) { + _stack.top() += s[i]; + } else { + result += s[i]; + } + + } + } + + return result; + } + +private: + + //only check the following rules: + // 1) the number must be followed by '[' + // 2) the '[' and ']' must be matched. + bool isValid(string& s) { + stack _stack; + for (int i=0; i='0' && ch<='9'); + } +}; + diff --git a/algorithms/cpp/detectCapital/DetectCapital.cpp b/algorithms/cpp/detectCapital/DetectCapital.cpp new file mode 100644 index 000000000..bc90ae674 --- /dev/null +++ b/algorithms/cpp/detectCapital/DetectCapital.cpp @@ -0,0 +1,50 @@ +// Source : https://leetcode.com/problems/detect-capital/ +// Author : Hao Chen +// Date : 2019-02-04 + +/***************************************************************************************************** + * + * + * Given a word, you need to judge whether the usage of capitals in it is right or not. + * + * We define the usage of capitals in a word to be right when one of the following cases holds: + * + * All letters in this word are capitals, like "USA". + * All letters in this word are not capitals, like "leetcode". + * Only the first letter in this word is capital if it has more than one letter, like "Google". + * + * Otherwise, we define that this word doesn't use capitals in a right way. + * + * Example 1: + * + * Input: "USA" + * Output: True + * + * Example 2: + * + * Input: "FlaG" + * Output: False + * + * Note: + * The input will be a non-empty word consisting of uppercase and lowercase latin letters. + ******************************************************************************************************/ +class Solution { + bool is_lower(char ch) { + return ch >='a' && ch <='z'; + } + bool is_upper(char ch) { + return ch >='A' && ch <='Z'; + } + bool is_alpha(char ch) { + return is_lower(ch) || is_upper(ch); + } +public: + bool detectCapitalUse(string word) { + bool all_upper = true, all_lower = true, first = is_upper(word[0]); + for(int i=1; i #include #include diff --git a/algorithms/cpp/distributeCoinsInBinaryTree/DistributeCoinsInBinaryTree.cpp b/algorithms/cpp/distributeCoinsInBinaryTree/DistributeCoinsInBinaryTree.cpp new file mode 100644 index 000000000..09f6a7f71 --- /dev/null +++ b/algorithms/cpp/distributeCoinsInBinaryTree/DistributeCoinsInBinaryTree.cpp @@ -0,0 +1,90 @@ +// Source : https://leetcode.com/problems/distribute-coins-in-binary-tree/ +// Author : Hao Chen +// Date : 2019-03-29 + +/***************************************************************************************************** + * + * Given the root of a binary tree with N nodes, each node in the tree has node.val coins, and there + * are N coins total. + * + * In one move, we may choose two adjacent nodes and move one coin from one node to another. (The + * move may be from parent to child, or from child to parent.) + * + * Return the number of moves required to make every node have exactly one coin. + * + * Example 1: + * + * Input: [3,0,0] + * Output: 2 + * Explanation: From the root of the tree, we move one coin to its left child, and one coin to its + * right child. + * + * Example 2: + * + * Input: [0,3,0] + * Output: 3 + * Explanation: From the left child of the root, we move two coins to the root [taking two moves]. + * Then, we move one coin from the root of the tree to the right child. + * + * Example 3: + * + * Input: [1,0,2] + * Output: 2 + * + * Example 4: + * + * Input: [1,0,0,null,3] + * Output: 4 + * + * Note: + * + * 1<= N <= 100 + * 0 <= node.val <= N + * + ******************************************************************************************************/ + +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode(int x) : val(x), left(NULL), right(NULL) {} + * }; + */ +class Solution { +public: + int distributeCoins(TreeNode* root) { + int result = 0; + dfs(root, result); + return result; + } + + // + // if a node has 0 coin, which means one move from its parent. + // 1 coin, which means zero move from its parent. + // N coins, which means N-1 moves to its parent. + // + // So, we can simply know, the movement = coins -1. + // - negative number means the the coins needs be moved in. + // - positive number means the the coins nees be moved out. + // + // A node needs to consider the movement requests from both its left side and right side. + // and need to calculate the coins after left and right movement. + // + // So, the node coins = my conins - the coins move out + the coins move in. + // + // Then we can have to code as below. + // + int dfs(TreeNode* root, int& result) { + if (root == NULL) return 0; + + int left_move = dfs(root->left, result); + int right_move = dfs(root->right, result); + result += (abs(left_move) + abs(right_move)); + + // the coin after movement: coins = root->val +left_move + right_move + // the movement needs: movement = coins - 1 + return root->val + left_move + right_move - 1; + } +}; diff --git a/algorithms/cpp/divideTwoInt/divideTwoInt.cpp b/algorithms/cpp/divideTwoInt/divideTwoInt.cpp index d205965a6..95601c6f0 100644 --- a/algorithms/cpp/divideTwoInt/divideTwoInt.cpp +++ b/algorithms/cpp/divideTwoInt/divideTwoInt.cpp @@ -24,7 +24,7 @@ int divide(int dividend, int divisor) { unsigned int dvd = dividend > 0 ? dividend : -dividend; unsigned int dvs = divisor > 0 ? divisor : -divisor; - unsigned int bit_num[32]; + unsigned int bit_num[33]; unsigned int i=0; long long d = dvs; bit_num[i] = d; diff --git a/algorithms/cpp/editDistance/editDistance.cpp b/algorithms/cpp/editDistance/editDistance.cpp index ec5612658..776e9661a 100644 --- a/algorithms/cpp/editDistance/editDistance.cpp +++ b/algorithms/cpp/editDistance/editDistance.cpp @@ -75,7 +75,7 @@ using namespace std; * "" 0 1 2 3 4 5 * a 1 0 1 2 3 4 * b 2 1 0 1 2 3 - * b 3 2 1 1 1 2 + * b 3 2 1 1 2 2 * */ int min(int x, int y, int z) { diff --git a/algorithms/cpp/eliminationGame/EliminationGame.cpp b/algorithms/cpp/eliminationGame/EliminationGame.cpp new file mode 100644 index 000000000..386c985fd --- /dev/null +++ b/algorithms/cpp/eliminationGame/EliminationGame.cpp @@ -0,0 +1,41 @@ +// Source : https://leetcode.com/problems/elimination-game +// Author : Hao Chen +// Date : 2016-09-07- + +/********************************************************************************** + * + * There is a list of sorted integers from 1 to n. Starting from left to right, remove the first number and every other + * number afterward until you reach the end of the list. + * + * Repeat the previous step again, but this time from right to left, remove the right most number and every other number + * from the remaining numbers. + * + * We keep repeating the steps again, alternating left to right and right to left, until a single number remains. + * + * Find the last number that remains starting with a list of length n. + * + * Example: + * + * Input: + * n = 9, + * 1 2 3 4 5 6 7 8 9 + * 2 4 6 8 + * 2 6 + * 6 + * + * Output: + * 6 +**********************************************************************************/ + +class Solution { +public: + int lastRemaining(int n) { + int start = 1, step = 1; + while (n > 1) { + start += step + (n-2)/2 * 2*step; + n /= 2; + step *= -2; + } + return start; + } +}; diff --git a/algorithms/cpp/evaluateDivision/EvaluateDivision.cpp b/algorithms/cpp/evaluateDivision/EvaluateDivision.cpp new file mode 100644 index 000000000..bd6d06ba8 --- /dev/null +++ b/algorithms/cpp/evaluateDivision/EvaluateDivision.cpp @@ -0,0 +1,93 @@ +// Source : https://leetcode.com/problems/evaluate-division/ +// Author : Hao Chen +// Date : 2016-11-05 + +/*************************************************************************************** + * + * Equations are given in the format A / B = k, where A and B are variables + * represented as strings, and k is a real number (floating point number). Given some + * queries, return the answers. If the answer does not exist, return -1.0. + * + * Example: + * Given a / b = 2.0, b / c = 3.0. queries are: a / c = ?, b / a = ?, a / e = ?, a + * / a = ?, x / x = ? . return [6.0, 0.5, -1.0, 1.0, -1.0 ]. + * + * The input is: vector> equations, vector& values, + * vector> queries , where equations.size() == values.size(), and + * the values are positive. This represents the equations. Return vector. + * + * According to the example above: + * equations = [ ["a", "b"], ["b", "c"] ], + * values = [2.0, 3.0], + * queries = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ]. + * + * The input is always valid. You may assume that evaluating the queries will result in + * no division by zero and there is no contradiction. + ***************************************************************************************/ + +class Solution { +private: + bool dfs( unordered_map>& m, + unordered_map& visited, + string& start, string& end, double& res ) { + + if ( m.find(start) == m.end() || m.find(end) == m.end() ) return false; + if ( start == end ) return true; + + for (auto it = m[start].begin(); it != m[start].end(); ++it) { + + auto key = it->first; + auto value = it->second; + + // already visited, skip it. + if (visited.find(key) != visited.end() ) { + continue; + } + + visited[key] = true; + double old = res; + res *= value; + + if (dfs(m, visited, key, end, res)) { + return true; + } + //didn't find the result, reset the current result, and go to next one + res = old; + visited.erase(key); + } + + return false; + } +public: + vector calcEquation(vector> equations, + vector& values, + vector> queries) { + + unordered_map> m; + for(int i=0; i result; + for(auto q : queries) { + string start = q.first; + string end = q.second; + + unordered_map visited; + visited[start] = true; + double res = 1.0; + + if(dfs(m, visited, start, end, res)) { + result.push_back(res); + } else { + result.push_back(-1.0); + } + } + + return result; + } +}; diff --git a/algorithms/cpp/expressionAddOperators/ExpressionAddOperators.cpp b/algorithms/cpp/expressionAddOperators/ExpressionAddOperators.cpp new file mode 100644 index 000000000..573d4fd26 --- /dev/null +++ b/algorithms/cpp/expressionAddOperators/ExpressionAddOperators.cpp @@ -0,0 +1,81 @@ +// Source : https://leetcode.com/problems/expression-add-operators/ +// Author : Hao Chen +// Date : 2016-01-16 + +/*************************************************************************************** + * + * Given a string that contains only digits 0-9 and a target value, return all + * possibilities to add binary operators (not unary) +, -, or * between the digits so + * they evaluate to the target value. + * + * Examples: + * "123", 6 -> ["1+2+3", "1*2*3"] + * "232", 8 -> ["2*3+2", "2+3*2"] + * "105", 5 -> ["1*0+5","10-5"] + * "00", 0 -> ["0+0", "0-0", "0*0"] + * "3456237490", 9191 -> [] + * + * Credits:Special thanks to @davidtan1890 for adding this problem and creating all + * test cases. + ***************************************************************************************/ + + +class Solution { +public: + vector addOperators(string num, int target) { + vector result; + if (num.size() == 0) return result; + helper(num, target, result, "", 0, 0, 0, ' '); + return result; + } + + //DFS algorithm + void helper(const string &num, const int target, //`num` and `target` never change + vector& result, // the array store all of the answers + string solution, //the current potential answer. + int idx, // the current index of `num` array + long long val, // the current value we calculated so far + long long prev, // the lastest value we used for calculation, which used for operation prioirty adjustment + char preop ) // the latest "+" or "-" operation, which used for operation prioirty adjustment + { + + if (target == val && idx == num.size()){ + result.push_back(solution); + return; + } + if (idx == num.size()) return; + + string n; + long long v=0; + for(int i=idx; i 1. + * + * Given N, calculate F(N). + * + * Example 1: + * + * Input: 2 + * Output: 1 + * Explanation: F(2) = F(1) + F(0) = 1 + 0 = 1. + * + * Example 2: + * + * Input: 3 + * Output: 2 + * Explanation: F(3) = F(2) + F(1) = 1 + 1 = 2. + * + * Example 3: + * + * Input: 4 + * Output: 3 + * Explanation: F(4) = F(3) + F(2) = 2 + 1 = 3. + * + * Note: + * + * 0 ≤ N ≤ 30. + ******************************************************************************************************/ + +class Solution { +public: + int fib(int N) { + if (N < 2 ) return N; + int first = 0, second = 1; + + for ( N-=1; N > 0; N-- ) { + second += first; + first = second - first; + } + return second; + } +}; diff --git a/algorithms/cpp/findMinimumInRotatedSortedArray/findMinimumInRotatedSortedArray.cpp b/algorithms/cpp/findMinimumInRotatedSortedArray/findMinimumInRotatedSortedArray.cpp index 2ac3e33a3..9c8cc43cb 100644 --- a/algorithms/cpp/findMinimumInRotatedSortedArray/findMinimumInRotatedSortedArray.cpp +++ b/algorithms/cpp/findMinimumInRotatedSortedArray/findMinimumInRotatedSortedArray.cpp @@ -38,7 +38,7 @@ int findMin(vector &num) { } // The array is rotated - // Spli it into two part, the minimal value must be the rotated part + // Split it into two part, the minimal value must be the rotated part // if the left part is rotated, warch the left part if (num[low] > num [mid]){ diff --git a/algorithms/cpp/findTheDifference/FindTheDifference.cpp b/algorithms/cpp/findTheDifference/FindTheDifference.cpp new file mode 100644 index 000000000..5e51e4f0e --- /dev/null +++ b/algorithms/cpp/findTheDifference/FindTheDifference.cpp @@ -0,0 +1,38 @@ +// Source : https://leetcode.com/problems/find-the-difference/ +// Author : Hao Chen +// Date : 2016-09-08 + +/*************************************************************************************** + * + * Given two strings s and t which consist of only lowercase letters. + * + * String t is generated by random shuffling string s and then add one more letter at a + * random position. + * + * Find the letter that was added in t. + * + * Example: + * + * Input: + * s = "abcd" + * t = "abcde" + * + * Output: + * e + * + * Explanation: + * 'e' is the letter that was added. + ***************************************************************************************/ + +class Solution { +public: + char findTheDifference(string s, string t) { + unordered_map m; + for(auto c : s) m[c]++; + for(auto c : t) { + m[c]--; + if (m[c] < 0) return c; + } + return '\0'; + } +}; diff --git a/algorithms/cpp/firstUniqueCharacterInAString/FirstUniqueCharacterInAString.cpp b/algorithms/cpp/firstUniqueCharacterInAString/FirstUniqueCharacterInAString.cpp new file mode 100644 index 000000000..29081bb3d --- /dev/null +++ b/algorithms/cpp/firstUniqueCharacterInAString/FirstUniqueCharacterInAString.cpp @@ -0,0 +1,55 @@ +// Source : https://leetcode.com/problems/first-unique-character-in-a-string/ +// Author : Hao Chen +// Date : 2016-08-23 + +/*************************************************************************************** + * + * Given a string, find the first non-repeating character in it and return it's index. + * If it doesn't exist, return -1. + * + * Examples: + * + * s = "leetcode" + * return 0. + * + * s = "loveleetcode", + * return 2. + * + * Note: You may assume the string contain only lowercase letters. + ***************************************************************************************/ + +class Solution { +public: + int firstUniqChar(string s) { + //As the question mentioned, there only have lower case chars, + //so the MAX_CHAR can be defined as 26, but I want this algorithm be more general for all ASCII + #define MAX_CHAR 256 + #define NOT_FOUND -1 + #define DUPLICATION -2 + + // initlize all chars status to NOT_FOUND + int pos_map[MAX_CHAR]; + memset(pos_map, NOT_FOUND,sizeof(pos_map)); + + // if it is the first time to find, set the status to its postion + // if it is the second time to find, set the status to duplication + // if it has already duplicated, do nothing + for (int i=0; i= 0 ) { + pos_map[s[i]] = DUPLICATION; + }else if ( pos_map[s[i]] == NOT_FOUND ) { + pos_map[s[i]] = i; + } + } + + // find the lowest postion + int pos = INT_MAX; + for (auto item : pos_map) { + cout << item << ","; + if (item >= 0 && item < pos) { + pos = item; + } + } + return pos == INT_MAX ? -1 : pos; + } +}; diff --git a/algorithms/cpp/fizzBuzz/FizzBuzz.cpp b/algorithms/cpp/fizzBuzz/FizzBuzz.cpp new file mode 100644 index 000000000..f4ec548e7 --- /dev/null +++ b/algorithms/cpp/fizzBuzz/FizzBuzz.cpp @@ -0,0 +1,91 @@ +// Source : https://leetcode.com/problems/fizz-buzz/ +// Author : Hao Chen +// Date : 2016-11-13 + +/*************************************************************************************** + * + * Write a program that outputs the string representation of numbers from 1 to n. + * + * But for multiples of three it should output “Fizz” instead of the number and for the + * multiples of five output “Buzz”. For numbers which are multiples of both three and + * five output “FizzBuzz”. + * + * Example: + * + * n = 15, + * + * Return: + * [ + * "1", + * "2", + * "Fizz", + * "4", + * "Buzz", + * "Fizz", + * "7", + * "8", + * "Fizz", + * "Buzz", + * "11", + * "Fizz", + * "13", + * "14", + * "FizzBuzz" + * ] + ***************************************************************************************/ + +class Solution { +public: + vector fizzBuzz_old_school_way(int n) { + vector result; + for (int i=1; i<=n; i++) { + if ( i%3 == 0 && i%5 ==0 ) { + result.push_back("FizzBuzz"); + }else if (i%3 == 0) { + result.push_back("Fizz"); + }else if (i%5 == 0) { + result.push_back("Buzz"); + }else{ + result.push_back(std::to_string(i)); + } + } + return result; + } + + + class FizzBuzz { + public: + FizzBuzz() : x(0) {} + + string operator()() { + x++; + if ( x%3 == 0 && x%5 ==0 ) { + return ("FizzBuzz"); + }else if (x%3 == 0) { + return ("Fizz"); + }else if (x%5 == 0) { + return("Buzz"); + } + return std::to_string(x); + } + + private: + int x; + }; + + vector fizzBuzz_cpp_way(int n) { + vector result(n); + generate(result.begin(), result.end(), FizzBuzz()); + return result; + } + + vector fizzBuzz(int n) { + + //both method has same performance + + if (rand() % 2 == 0) { + return fizzBuzz_cpp_way(n); + } + return fizzBuzz_old_school_way(n); + } +}; diff --git a/algorithms/cpp/flattenNestedListIterator/FlattenNestedListIterator.cpp b/algorithms/cpp/flattenNestedListIterator/FlattenNestedListIterator.cpp new file mode 100644 index 000000000..e62484864 --- /dev/null +++ b/algorithms/cpp/flattenNestedListIterator/FlattenNestedListIterator.cpp @@ -0,0 +1,74 @@ +// Source : https://leetcode.com/problems/flatten-nested-list-iterator/ +// Author : Hao Chen +// Date : 2016-05-30 + +/*************************************************************************************** + * + * Given a nested list of integers, implement an iterator to flatten it. + * + * Each element is either an integer, or a list -- whose elements may also be integers + * or other lists. + * + * Example 1: + * Given the list [[1,1],2,[1,1]], + * + * By calling next repeatedly until hasNext returns false, the order of elements + * returned by next should be: [1,1,2,1,1]. + * + * Example 2: + * Given the list [1,[4,[6]]], + * + * By calling next repeatedly until hasNext returns false, the order of elements + * returned by next should be: [1,4,6]. + ***************************************************************************************/ + +/** + * // This is the interface that allows for creating nested lists. + * // You should not implement it, or speculate about its implementation + * class NestedInteger { + * public: + * // Return true if this NestedInteger holds a single integer, rather than a nested list. + * bool isInteger() const; + * + * // Return the single integer that this NestedInteger holds, if it holds a single integer + * // The result is undefined if this NestedInteger holds a nested list + * int getInteger() const; + * + * // Return the nested list that this NestedInteger holds, if it holds a nested list + * // The result is undefined if this NestedInteger holds a single integer + * const vector &getList() const; + * }; + */ +class NestedIterator { +private: + vector v; + int index; + void flatten(vector &nestedList) { + for (auto item : nestedList){ + if (item.isInteger()){ + v.push_back( item.getInteger() ); + }else{ + flatten( item.getList() ); + } + } + } +public: + NestedIterator(vector &nestedList) { + flatten(nestedList); + index = 0; + } + + int next() { + return v[index++]; + } + + bool hasNext() { + return (index < v.size() ); + } +}; + +/** + * Your NestedIterator object will be instantiated and called as such: + * NestedIterator i(nestedList); + * while (i.hasNext()) cout << i.next(); + */ diff --git a/algorithms/cpp/friendCircles/FriendCircles.cpp b/algorithms/cpp/friendCircles/FriendCircles.cpp new file mode 100644 index 000000000..fd1932892 --- /dev/null +++ b/algorithms/cpp/friendCircles/FriendCircles.cpp @@ -0,0 +1,117 @@ +// Source : https://leetcode.com/problems/friend-circles/ +// Author : Hao Chen +// Date : 2019-03-26 + +/***************************************************************************************************** + * + * + * There are N students in a class. Some of them are friends, while some are not. Their friendship is + * transitive in nature. For example, if A is a direct friend of B, and B is a direct friend of C, + * then A is an indirect friend of C. And we defined a friend circle is a group of students who are + * direct or indirect friends. + * + * Given a N*N matrix M representing the friend relationship between students in the class. If M[i][j] + * = 1, then the ith and jth students are direct friends with each other, otherwise not. And you have + * to output the total number of friend circles among all the students. + * + * Example 1: + * + * Input: + * [[1,1,0], + * [1,1,0], + * [0,0,1]] + * Output: 2 + * Explanation:The 0th and 1st students are direct friends, so they are in a friend circle. The 2nd + * student himself is in a friend circle. So return 2. + * + * Example 2: + * + * Input: + * [[1,1,0], + * [1,1,1], + * [0,1,1]] + * Output: 1 + * Explanation:The 0th and 1st students are direct friends, the 1st and 2nd students are direct + * friends, so the 0th and 2nd students are indirect friends. All of them are in the same friend + * circle, so return 1. + * + * Note: + * + * N is in range [1,200]. + * M[i][i] = 1 for all students. + * If M[i][j] = 1, then M[j][i] = 1. + * + ******************************************************************************************************/ + +class Solution { +public: + + // ----------------------------------------------------------------------------- + //DFS solution is quite easy to understand, just like the "Number of Island" + int findCircleNum_DFS(vector>& M) { + int n = 0; + for (int i=0; i>& M, int i ) { + for ( int j=0; j>& M) { + + vector relations(M.size()); + for (int i=0; i b -> c -> d, then find(a),find(b) or find(c) would return d; + int find(vector& relations, int i ) { + while( relations[i] != i ) { + i = relations[i]; + } + return i; + } + // join the x cicle with y cicle, + // if x and y are already in same friend cicle, then return false, else return true; + bool join(vector &relations, int x, int y) { + int tx = find(relations, x); + int ty = find(relations, y); + if ( tx != ty ) relations[tx] = ty; + return tx != ty; + } + + // ----------------------------------------------------------------------------- + + int findCircleNum(vector>& M) { + return findCircleNum_UF(M); + return findCircleNum_DFS(M); + } +}; diff --git a/algorithms/cpp/frogJump/FrogJump.cpp b/algorithms/cpp/frogJump/FrogJump.cpp new file mode 100644 index 000000000..8bd302b89 --- /dev/null +++ b/algorithms/cpp/frogJump/FrogJump.cpp @@ -0,0 +1,125 @@ +// Source : https://leetcode.com/problems/frog-jump/ +// Author : Hao Chen +// Date : 2016-11-12 + +/*************************************************************************************** + * + * A frog is crossing a river. The river is divided into x units and at each unit there + * may or may not exist a stone. The frog can jump on a stone, but it must not jump + * into the water. + * + * Given a list of stones' positions (in units) in sorted ascending order, determine if + * the frog is able to cross the river by landing on the last stone. Initially, the + * frog is on the first stone and assume the first jump must be 1 unit. + * + * If the frog's last jump was k units, then its next jump must be either k - 1, k, or + * k + 1 units. Note that the frog can only jump in the forward direction. + * + * Note: + * + * The number of stones is ≥ 2 and is + * Each stone's position will be a non-negative integer 31. + * The first stone's position is always 0. + * + * Example 1: + * + * [0,1,3,5,6,8,12,17] + * + * There are a total of 8 stones. + * The first stone at the 0th unit, second stone at the 1st unit, + * third stone at the 3rd unit, and so on... + * The last stone at the 17th unit. + * + * Return true. The frog can jump to the last stone by jumping + * 1 unit to the 2nd stone, then 2 units to the 3rd stone, then + * 2 units to the 4th stone, then 3 units to the 6th stone, + * 4 units to the 7th stone, and 5 units to the 8th stone. + * + * Example 2: + * + * [0,1,2,3,4,8,9,11] + * + * Return false. There is no way to jump to the last stone as + * the gap between the 5th and 6th stone is too large. + ***************************************************************************************/ + +class Solution { +public: + bool canCross_recursion(vector& stones, int curr, int last_jump) { + for(int i=curr+1; i last_jump + 1) return false; + + if (i == stones.size() - 1 || canCross_recursion(stones, i, next_jump)) return true; + } + return false; + } + + bool canCross_recursion_with_cache(vector& stones, int curr, int last_jump, + unordered_map>& cache) + { + //check the cache is hitted ? + if (cache.find(curr) != cache.end() && cache[curr].find(last_jump)!=cache[curr].end()) { + return cache[curr][last_jump]; + } + + for(int i=curr+1; i last_jump + 1) break; + if (i == stones.size() - 1 || canCross_recursion_with_cache(stones, i, next_jump, cache)) { + cache[curr][last_jump] = true; + return true; + } + } + cache[curr][last_jump] = false; + return false; + } + + bool canCross_non_recursion(vector& stones) { + + // the `jumps` map store the all possible `last jumps` + unordered_map> jumps = {{0, {0}}}; + + for(int i=0; i& stones) { + + //Burst Force solution -- accepted ~500ms + return canCross_non_recursion(stones); + + //DFS with cache solution - accepted ~160ms + unordered_map> cache; + return canCross_recursion_with_cache(stones, 0, 0, cache); + + // Time Limit Error + return canCross_recursion(stones, 0, 0); + + } +}; diff --git a/algorithms/cpp/gameOfLife/GameOfLife.cpp b/algorithms/cpp/gameOfLife/GameOfLife.cpp new file mode 100644 index 000000000..328bf5e5a --- /dev/null +++ b/algorithms/cpp/gameOfLife/GameOfLife.cpp @@ -0,0 +1,94 @@ +// Source : https://leetcode.com/problems/game-of-life/ +// Author : Hao Chen +// Date : 2019-03-20 + +/***************************************************************************************************** + * + * According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellular + * automaton devised by the British mathematician John Horton Conway in 1970." + * + * Given a board with m by n cells, each cell has an initial state live (1) or dead (0). Each cell + * interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules + * (taken from the above Wikipedia article): + * + * Any live cell with fewer than two live neighbors dies, as if caused by under-population. + * Any live cell with two or three live neighbors lives on to the next generation. + * Any live cell with more than three live neighbors dies, as if by over-population.. + * Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction. + * + * Write a function to compute the next state (after one update) of the board given its current state. + * The next state is created by applying the above rules simultaneously to every cell in the current + * state, where births and deaths occur simultaneously. + * + * Example: + * + * Input: + * [ + * [0,1,0], + * [0,0,1], + * [1,1,1], + * [0,0,0] + * ] + * Output: + * [ + * [0,0,0], + * [1,0,1], + * [0,1,1], + * [0,1,0] + * ] + * + * Follow up: + * + * Could you solve it in-place? Remember that the board needs to be updated at the same time: + * You cannot update some cells first and then use their updated values to update other cells. + * In this question, we represent the board using a 2D array. In principle, the board is + * infinite, which would cause problems when the active area encroaches the border of the array. How + * would you address these problems? + * + ******************************************************************************************************/ + + +class Solution { +public: + // the problem here is we need store two states in one cell, + // one is the original state, another is the new state + // So, we could store the state into the bit. + // - Old State: the first bit from the right + // - New State: the second bit from the right + void liveCheck(vector>& board, int r, int c) { + int cnt = 0; + for (int i=r-1; i<=r+1; i++) { + if (i < 0 || i>=board.size()) continue; + for (int j=c-1; j<=c+1; j++) { + if (j<0 || j>=board[0].size() || (i==r && j==c)) continue; + if ( board[i][j] & 1 ) cnt++; + } + } + + //live -> die + //if (board[r][c]==1 && (cnt < 2 || cnt > 3)) board[r][c] = 1; + + //live -> live + if ( board[r][c] == 1 && (cnt == 2 || cnt == 3) ) board[r][c] = 3; + + //die -> live + if ( board[r][c] == 0 && cnt == 3 ) board[r][c] = 2; + + } + + void gameOfLife(vector>& board) { + for (int i=0; i>= 1; + } + + } + + } +}; diff --git a/algorithms/cpp/houseRobber/houseRobberIII.cpp b/algorithms/cpp/houseRobber/houseRobberIII.cpp new file mode 100644 index 000000000..2004fc398 --- /dev/null +++ b/algorithms/cpp/houseRobber/houseRobberIII.cpp @@ -0,0 +1,134 @@ +// Source : https://leetcode.com/problems/house-robber-iii/ +// Author : Calinescu Valentin, Hao Chen +// Date : 2016-04-29 + +/*************************************************************************************** + * + * The thief has found himself a new place for his thievery again. There is only one + * entrance to this area, called the "root." Besides the root, each house has one and + * only one parent house. After a tour, the smart thief realized that "all houses in + * this place forms a binary tree". It will automatically contact the police if two + * directly-linked houses were broken into on the same night. + * + * Determine the maximum amount of money the thief can rob tonight without alerting the + * police. + * + * Example 1: + * 3 + * / \ + * 2 3 + * \ \ + * 3 1 + * Maximum amount of money the thief can rob = 3 + 3 + 1 = 7. + * Example 2: + * 3 + * / \ + * 4 5 + * / \ \ + * 1 3 1 + * Maximum amount of money the thief can rob = 4 + 5 = 9. + * Credits: + * Special thanks to @dietpepsi for adding this problem and creating all test cases. + * + ***************************************************************************************/ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode(int x) : val(x), left(NULL), right(NULL) {} + * }; + */ + /* + * Solution 1 - O(N log N) + * ========= + * + * We can use a recursive function that computes the solution for every node of the tree + * using the previous solutions calculated for the left and right subtrees. At every step + * we have 2 options: + * + * 1) Take the value of the current node + the solution of the left and right subtrees of + * each of the left and right children of the current node. + * 2) Take the solution of the left and right subtrees of the current node, skipping over + * its value. + * + * This way we can make sure that we do not pick 2 adjacent nodes. + * + * If we implemented this right away we would get TLE. Thus, we need to optimize the + * algorithm. One key observation would be that we only need to compute the solution for + * a certain node once. We can use memoization to calculate every value once and then + * retrieve it when we get subsequent calls. As the header of the recursive function + * doesn't allow additional parameters we can use a map to link every node(a pointer) to + * its solution(an int). For every call the map lookup of an element and its insertion + * take logarithmic time and there are a constant number of calls for each node. Thus, the + * algorithm takes O(N log N) time to finish. + * + */ +class Solution { +public: + map dict; + int rob(TreeNode* root) { + if(root == NULL) + return 0; + else if(dict.find(root) == dict.end()) + { + int lwith = rob(root->left); + int rwith = rob(root->right); + int lwithout = 0, rwithout = 0; + if(root->left != NULL) + lwithout = rob(root->left->left) + rob(root->left->right); + if(root->right != NULL) + rwithout = rob(root->right->left) + rob(root->right->right); + //cout << lwith << " " << rwith << " " << lwithout << " " << rwithout << '\n'; + dict[root] = max(root->val + lwithout + rwithout, lwith + rwith); + } + return dict[root]; + } +}; + + +// Another implementation - Hao Chen + +class Solution { +public: + int max(int a, int b) { + return a > b ? a: b; + } + int max(int a, int b, int c) { + return max(a, max(b,c)); + } + int max(int a, int b, int c, int d) { + return max(a, max(b, max(c,d))); + } + + void rob_or_not(TreeNode* root, int& max_robbed, int& max_not_robbed) { + // NULL room return 0; + if (root == NULL) { + max_robbed = max_not_robbed = 0; + return ; + } + + // we have two options, rob current room or not. + int max_left_robbed, max_left_not_robbed; + int max_right_robbed, max_right_not_robbed; + rob_or_not(root->left, max_left_robbed, max_left_not_robbed); + rob_or_not(root->right, max_right_robbed, max_right_not_robbed); + + // If root is robbed, then both left and right must not be robbed. + max_robbed = root->val + max_left_not_robbed + max_right_not_robbed; + + // If root is not robbed, then 4 combinations are possible: + // left is robbed or not and right is either robbed or not robbed, + max_not_robbed = max(max_left_robbed + max_right_robbed, + max_left_robbed + max_right_not_robbed, + max_left_not_robbed + max_right_robbed, + max_left_not_robbed + max_right_not_robbed); + + } + int rob(TreeNode* root) { + int robbed, not_robbed; + rob_or_not(root, robbed, not_robbed); + return max(robbed, not_robbed); + } +}; diff --git a/algorithms/cpp/increasingTripletSubsequence/increasingTripletSubsequence.cpp b/algorithms/cpp/increasingTripletSubsequence/increasingTripletSubsequence.cpp new file mode 100644 index 000000000..d2a69b84c --- /dev/null +++ b/algorithms/cpp/increasingTripletSubsequence/increasingTripletSubsequence.cpp @@ -0,0 +1,65 @@ +// Source : https://leetcode.com/problems/increasing-triplet-subsequence/ +// Author : Calinescu Valentin, Hao Chen +// Date : 2016-02-27 + +/*************************************************************************************** + * + * Given an unsorted array return whether an increasing subsequence of length 3 exists + * or not in the array. + * + * Formally the function should: + * Return true if there exists i, j, k + * such that arr[i] < arr[j] < arr[k] given 0 ≤ i < j < k ≤ n-1 else return false. + * Your algorithm should run in O(n) time complexity and O(1) space complexity. + * + * Examples: + * Given [1, 2, 3, 4, 5], + * return true. + * + * Given [5, 4, 3, 2, 1], + * return false. + * + ***************************************************************************************/ +class Solution { +public: + bool increasingTriplet(vector& nums) { + bool solution = false; + if(nums.size()) + { + int first = nums[0]; + int second = 0x7fffffff; //MAX_INT so we can always find something smaller than it + for(int i = 1; i < nums.size() && !solution; i++) + { + if(nums[i] > second) + solution = true; + else if(nums[i] > first && nums[i] < second) + second = nums[i]; + else if(nums[i] < first) + first = nums[i]; + } + } + return solution; + } +}; + + +//Hao Chen's implementation +class Solution { +public: + bool increasingTriplet(vector& nums) { + if (nums.size() < 3) return false; + + int first=INT_MAX, second = INT_MAX; + + for(int i=0; i nums[i] ) { + first = nums[i]; + }else if ( first < nums[i] && nums[i] < second) { + second = nums[i]; + }else if (nums[i] > second){ + return true; + } + } + return false; + } +}; diff --git a/algorithms/cpp/insertDeleteGetRandom/InsertDeleteGetrandomO1.cpp b/algorithms/cpp/insertDeleteGetRandom/InsertDeleteGetrandomO1.cpp new file mode 100644 index 000000000..07a0bde1d --- /dev/null +++ b/algorithms/cpp/insertDeleteGetRandom/InsertDeleteGetrandomO1.cpp @@ -0,0 +1,98 @@ +// Source : https://leetcode.com/problems/insert-delete-getrandom-o1/ +// Author : Hao Chen +// Date : 2016-08-25 + +/*************************************************************************************** + * + * Design a data structure that supports all following operations in average O(1) time. + * + * insert(val): Inserts an item val to the set if not already present. + * remove(val): Removes an item val from the set if present. + * getRandom: Returns a random element from current set of elements. Each element must + * have the same probability of being returned. + * + * Example: + * + * // Init an empty set. + * RandomizedSet randomSet = new RandomizedSet(); + * + * // Inserts 1 to the set. Returns true as 1 was inserted successfully. + * randomSet.insert(1); + * + * // Returns false as 2 does not exist in the set. + * randomSet.remove(2); + * + * // Inserts 2 to the set, returns true. Set now contains [1,2]. + * randomSet.insert(2); + * + * // getRandom should return either 1 or 2 randomly. + * randomSet.getRandom(); + * + * // Removes 1 from the set, returns true. Set now contains [2]. + * randomSet.remove(1); + * + * // 2 was already in the set, so return false. + * randomSet.insert(2); + * + * // Since 1 is the only number in the set, getRandom always return 1. + * randomSet.getRandom(); + ***************************************************************************************/ + + +class RandomizedSet { +public: + /** Initialize your data structure here. */ + RandomizedSet() { + srand(time(NULL)); + } + + /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ + bool insert(int val) { + if ( find(val) ) return false; + data.push_back(val); + valpos[val] = data.size() - 1; + return true; + } + + /** Removes a value from the set. Returns true if the set contained the specified element. */ + bool remove(int val) { + if ( !find(val) ) return false; + + /* + * Tricky + * ------ + * 1) Copy the data from the last one to the place need be removed. + * 2) Remove the last one. + */ + int _idx = valpos[val]; + int _val = data.back(); + + data[_idx] = _val; + valpos[_val] = _idx; + + valpos.erase(val); + data.pop_back(); + return true; + } + + /** Get a random element from the set. */ + int getRandom() { + return data[ rand() % data.size() ]; + } + +private: + unordered_map valpos; //value position map + vector data; + bool find(int val) { + return (valpos.find(val) != valpos.end()); + } + +}; + +/** + * Your RandomizedSet object will be instantiated and called as such: + * RandomizedSet obj = new RandomizedSet(); + * bool param_1 = obj.insert(val); + * bool param_2 = obj.remove(val); + * int param_3 = obj.getRandom(); + */ diff --git a/algorithms/cpp/insertDeleteGetRandom/InsertDeleteGetrandomO1DuplicatesAllowed.cpp b/algorithms/cpp/insertDeleteGetRandom/InsertDeleteGetrandomO1DuplicatesAllowed.cpp new file mode 100644 index 000000000..3ae8de9b2 --- /dev/null +++ b/algorithms/cpp/insertDeleteGetRandom/InsertDeleteGetrandomO1DuplicatesAllowed.cpp @@ -0,0 +1,102 @@ +// Source : https://leetcode.com/problems/insert-delete-getrandom-o1-duplicates-allowed/ +// Author : Hao Chen +// Date : 2016-08-25 + +/*************************************************************************************** + * + * Design a data structure that supports all following operations in average O(1) time. + * Note: Duplicate elements are allowed. + * + * insert(val): Inserts an item val to the collection. + * remove(val): Removes an item val from the collection if present. + * getRandom: Returns a random element from current collection of elements. The + * probability of each element being returned is linearly related to the number of same + * value the collection contains. + * + * Example: + * + * // Init an empty collection. + * RandomizedCollection collection = new RandomizedCollection(); + * + * // Inserts 1 to the collection. Returns true as the collection did not contain 1. + * collection.insert(1); + * + * // Inserts another 1 to the collection. Returns false as the collection contained 1. + * Collection now contains [1,1]. + * collection.insert(1); + * + * // Inserts 2 to the collection, returns true. Collection now contains [1,1,2]. + * collection.insert(2); + * + * // getRandom should return 1 with the probability 2/3, and returns 2 with the + * probability 1/3. + * collection.getRandom(); + * + * // Removes 1 from the collection, returns true. Collection now contains [1,2]. + * collection.remove(1); + * + * // getRandom should return 1 and 2 both equally likely. + * collection.getRandom(); + ***************************************************************************************/ + +class RandomizedCollection { +public: + /** Initialize your data structure here. */ + RandomizedCollection() { + srand(time(NULL)); + } + + /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */ + bool insert(int val) { + data.push_back(val); + valpos[val].insert( data.size() - 1 ); + return (valpos[val].size() == 1); + } + + /** Removes a value from the collection. Returns true if the collection contained the specified element. */ + bool remove(int val) { + // not found + if (!find(val)) return false; + + + //same idea with non-duplication version, but need be careful with some edge case + int _idx = *(valpos[val].begin()); + int _val = data.back(); + + valpos[_val].insert(_idx); + data[_idx] = _val; + + valpos[val].erase(_idx); + if (valpos[val].size()==0){ + valpos.erase(val); + } + + data.pop_back(); + if ( _idx < data.size() ){ + valpos[_val].erase(data.size()); + valpos[_val].insert(_idx); + } + + return true; + } + + /** Get a random element from the collection. */ + int getRandom() { + return data[ rand() % data.size() ]; + } +private: + unordered_map> valpos; //value position map + vector data; + bool find(int val) { + return (valpos.find(val) != valpos.end()); + } + +}; + +/** + * Your RandomizedCollection object will be instantiated and called as such: + * RandomizedCollection obj = new RandomizedCollection(); + * bool param_1 = obj.insert(val); + * bool param_2 = obj.remove(val); + * int param_3 = obj.getRandom(); + */ diff --git a/algorithms/cpp/integerBreak/IntegerBreak.cpp b/algorithms/cpp/integerBreak/IntegerBreak.cpp new file mode 100644 index 000000000..373e12671 --- /dev/null +++ b/algorithms/cpp/integerBreak/IntegerBreak.cpp @@ -0,0 +1,59 @@ +// Source : https://leetcode.com/problems/integer-break/ +// Author : Hao Chen +// Date : 2016-05-29 + +/*************************************************************************************** + * + * Given a positive integer n, break it into the sum of at least two positive integers + * and maximize the product of those integers. Return the maximum product you can get. + * + * For example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return 36 (10 = 3 + 3 + * + 4). + * + * Note: you may assume that n is not less than 2. + * + * There is a simple O(n) solution to this problem. + * You may check the breaking results of n ranging from 7 to 10 to discover the + * regularities. + * + * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating + * all test cases. + ***************************************************************************************/ + +class Solution { +public: + // As the hint said, checking the n with ranging from 7 to 10 to discover the regularities. + // n = 7, 3*4 = 12 + // n = 8, 3*3*2 = 18 + // n = 9, 3*3*3 = 27 + // n = 10, 3*3*4 = 36 + // n = 11, 3*3*3*2 = 54 + // + // we can see we can break the number by 3 if it is greater than 4; + // + int integerBreak(int n) { + if ( n == 2 ) return 1; + if ( n == 3 ) return 2; + int result = 1; + while( n > 4 ) { + result *= 3; + n -= 3; + } + result *= n; + return result; + } +}; + +// DP +class Solution { +public: + int integerBreak(int n) { + vector dp(n+1,1); + for(int i=2;i<=n;i++){ + for(int j=1;j<=i/2;j++){ + dp[i] = max(dp[i],max(dp[j],j)*max(dp[i-j],i-j)); + } + } + return dp[n]; + } +}; diff --git a/algorithms/cpp/integerReplacement/IntegerReplacement.cpp b/algorithms/cpp/integerReplacement/IntegerReplacement.cpp new file mode 100644 index 000000000..70f20762b --- /dev/null +++ b/algorithms/cpp/integerReplacement/IntegerReplacement.cpp @@ -0,0 +1,84 @@ +// Source : https://leetcode.com/problems/integer-replacement/ +// Author : Hao Chen +// Date : 2016-11-04 + +/*************************************************************************************** + * + * Given a positive integer n and you can do operations as follow: + * + * If n is even, replace n with n/2. + * If n is odd, you can replace n with either n + 1 or n - 1. + * + * What is the minimum number of replacements needed for n to become 1? + * + * Example 1: + * + * Input: + * 8 + * + * Output: + * 3 + * + * Explanation: + * 8 -> 4 -> 2 -> 1 + * + * Example 2: + * + * Input: + * 7 + * + * Output: + * 4 + * + * Explanation: + * 7 -> 8 -> 4 -> 2 -> 1 + * or + * 7 -> 6 -> 3 -> 2 -> 1 + ***************************************************************************************/ + +class Solution { +public: + + + int integerReplacement_recursion(int n) { + if ( n <= 1) return 0; // recursive exited point + if ( n == INT_MAX ) return 32; // special case to avoid integer overflow. + if ( n % 2 == 0 ) return integerReplacement(n/2) + 1; + return min( integerReplacement(n+1), integerReplacement(n-1) ) + 1; + } + + int integerReplacement_recursionWithCache(int n) { + static unordered_map cache; + //if hitted the cache, just return the result + if (cache.find(n) != cache.end()) return cache[n]; + + int result; + if ( n <= 1) return 0; // recursive exited point + if ( n == INT_MAX ) return 32; // special case to avoid integer overflow. + if ( n % 2 == 0 ) result = integerReplacement(n/2) + 1; + else result = min( integerReplacement(n+1), integerReplacement(n-1) ) + 1; + + //add into cache + cache[n] = result; + return result; + } + + int integerReplacement_simple(int n){ + int ans = 0; + size_t m = n; + while (1 != m) { + if (1 == (m & 1)) { + if (m==3) --m; //special case + else m = (m&0b11^0b01) ? m + 1 : m - 1; + } + else m >>= 1; + ++ans; + } + return ans; + } + + int integerReplacement(int n) { + return integerReplacement_recursionWithCache(n); + return integerReplacement_simple(n); + } +}; diff --git a/algorithms/cpp/intersectionOfTwoArrays/intersectionOfTwoArrays.cpp b/algorithms/cpp/intersectionOfTwoArrays/intersectionOfTwoArrays.cpp new file mode 100644 index 000000000..79e32cbd8 --- /dev/null +++ b/algorithms/cpp/intersectionOfTwoArrays/intersectionOfTwoArrays.cpp @@ -0,0 +1,72 @@ +// Source : https://leetcode.com/problems/intersection-of-two-arrays/ +// Author : Calinescu Valentin, Hao Chen +// Date : 2016-05-20 + +/*************************************************************************************** + * + * Given two arrays, write a function to compute their intersection. + * + * Example: + * Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2]. + * + * Note: + * Each element in the result must be unique. + * The result can be in any order. + * + ***************************************************************************************/ +class Solution { +public: + set inter1, inter2;//we use sets so as to avoid duplicates + vector solution; + vector intersection(vector& nums1, vector& nums2) { + for(int i = 0; i < nums1.size(); i++) + inter1.insert(nums1[i]);//get all of the unique elements in nums1 sorted + for(int i = 0; i < nums2.size(); i++) + if(inter1.find(nums2[i]) != inter1.end())//search inter1 in O(logN) + inter2.insert(nums2[i]);//populate the intersection set + for(set::iterator it = inter2.begin(); it != inter2.end(); ++it) + solution.push_back(*it);//copy the set into a vector + return solution; + } +}; + +/* + * This Solution use one unordered_set + */ +class Solution2 { +public: + vector intersection(vector& nums1, vector& nums2) { + unordered_set hash_set(nums1.begin(), nums1.end()); + vector res ; + for (auto it& : nums2) { + if (hash_set.count(it)) { + res.push_back(it); + hash_set.erase(it); + } + } + return res; + } +}; + +/* + * This Solution use unordered_map, insert the data into a map is more efficent than set + */ + +class Solution { +public: + vector intersection(vector& nums1, vector& nums2) { + unordered_map m; + for (auto n : nums1) { + m[n] = true; + } + vector result; + for (auto n : nums2){ + if (m.find(n) != m.end() && m[n] ){ + result.push_back(n); + m[n]=false; + } + } + return result; + } +}; + diff --git a/algorithms/cpp/intersectionOfTwoArrays/intersectionOfTwoArraysII.cpp b/algorithms/cpp/intersectionOfTwoArrays/intersectionOfTwoArraysII.cpp new file mode 100644 index 000000000..9384d96da --- /dev/null +++ b/algorithms/cpp/intersectionOfTwoArrays/intersectionOfTwoArraysII.cpp @@ -0,0 +1,87 @@ +// Source : https://leetcode.com/problems/intersection-of-two-arrays-ii/ +// Author : Calinescu Valentin, Hao Chen +// Date : 2016-05-22 + +/*************************************************************************************** + * + * Given two arrays, write a function to compute their intersection. + * + * Example: + * Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2, 2]. + * + * Note: + * Each element in the result should appear as many times as it shows in both arrays. + * The result can be in any order. + * + * Follow up: + * What if the given array is already sorted? How would you optimize your algorithm? + * What if nums1's size is small compared to num2's size? Which algorithm is better? + * What if elements of nums2 are stored on disk, and the memory is limited such that you + * cannot load all elements into the memory at once? + * + ***************************************************************************************/ + + /* Solution + * -------- + * + * Follow up: + * + * 1)If the given array is already sorted we can skip the sorting. + * + * 2)If nums1 is significantly smaller than nums2 we can only sort nums1 and then binary + * search every element of nums2 in nums1 with a total complexity of (MlogN) or if nums2 + * is already sorted we can search every element of nums1 in nums2 in O(NlogM) + * + * 3)Just like 2), we can search for every element in nums2, thus having an online + * algorithm. + */ + +class Solution { // O(NlogN + MlogM) +public: + vector intersect(vector& nums1, vector& nums2) { + sort(nums1.begin(), nums1.end());//we sort both vectors in order to intersect + sort(nums2.begin(), nums2.end());//them later in O(N + M), where N = nums1.size() + vector solution; //M = nums2.size() + int index = 0; + bool finished = false; + for(int i = 0; i < nums1.size() && !finished; i++) + { + while(index < nums2.size() && nums1[i] > nums2[index])//we skip over the + index++;//smaller elements in nums2 + if(index == nums2.size())//we have reached the end of nums2 so we have no more + finished = true;//elements to add to the intersection + else if(nums1[i] == nums2[index])//we found a common element + { + solution.push_back(nums1[i]); + index++; + } + } + return solution; + } +}; + + + +/* + * Just simply use the map can have O(M+N) time complexity. + * + */ + + +class Solution { +public: + vector intersect(vector& nums1, vector& nums2) { + unordered_map m; + for (auto n: nums1) { + m[n]++; + } + vector result; + for (auto n:nums2){ + if (m.find(n) != m.end() && m[n]>0 ){ + result.push_back(n); + m[n]--; + } + } + return result; + } +}; diff --git a/algorithms/cpp/intervalListIntersectons/IntervalListIntersections.cpp b/algorithms/cpp/intervalListIntersectons/IntervalListIntersections.cpp new file mode 100644 index 000000000..8a3112b37 --- /dev/null +++ b/algorithms/cpp/intervalListIntersectons/IntervalListIntersections.cpp @@ -0,0 +1,94 @@ +// Source : https://leetcode.com/problems/interval-list-intersections/ +// Author : Hao Chen +// Date : 2019-02-05 + +/***************************************************************************************************** + * + * Given two lists of closed intervals, each list of intervals is pairwise disjoint and in sorted + * order. + * + * Return the intersection of these two interval lists. + * + * (Formally, a closed interval [a, b] (with a <= b) denotes the set of real numbers x with a <= x <= + * b. The intersection of two closed intervals is a set of real numbers that is either empty, or can + * be represented as a closed interval. For example, the intersection of [1, 3] and [2, 4] is [2, 3].) + * + * Example 1: + * + * 0 2 5 10 13 23 24 25 + * A +---+ +-------+ +-------------+ +--+ + * + * 1 5 8 12 15 24 25 26 + * B +------+ +------+ +----------+ +--+ + * + * 1 2 5 8 10 15 23 24 25 + * Ans ++ + +--+ +--------+ + + + * + * + * Input: A = [[0,2],[5,10],[13,23],[24,25]], B = [[1,5],[8,12],[15,24],[25,26]] + * Output: [[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]] + * Reminder: The inputs and the desired output are lists of Interval objects, and not arrays or lists. + * + * Note: + * + * 0 <= A.length < 1000 + * 0 <= B.length < 1000 + * 0 <= A[i].start, A[i].end, B[i].start, B[i].end < 109 + * + ******************************************************************************************************/ + +/** + * Definition for an interval. + * struct Interval { + * int start; + * int end; + * Interval() : start(0), end(0) {} + * Interval(int s, int e) : start(s), end(e) {} + * }; + */ +class Solution { +public: + //return true if lhs starts earlier than rhs + bool compareInterval(Interval& lhs, Interval& rhs) { + return lhs.start < rhs.start; + } + //check two interval overlapped or not + bool overlapped(Interval& lhs, Interval& rhs) { + return (compareInterval(lhs, rhs)) ? + lhs.end >= rhs.start: + rhs.end >= lhs.start; + + } + //merge two interval - return the intersections of two intervals + Interval mergeTwoInterval(Interval& lhs, Interval& rhs) { + Interval result; + result.start = max(lhs.start, rhs.start); + result.end = min(lhs.end, rhs.end); + return result; + } + + vector intervalIntersection(vector& A, vector& B) { + int lenA = A.size(); + int lenB = B.size(); + + vector result; + if (lenA <=0 || lenB<=0) return result; //edge case + + int i=0, j=0; + while ( i < lenA && j < lenB ) { + if( overlapped(A[i], B[j]) ) { + result.push_back(mergeTwoInterval(A[i], B[j])); + // if the current interval is not overlapped with next one, + // then we move the next interval. + int nexti = i; + if ( j==lenB-1 || !overlapped(A[i], B[j+1]) ) nexti=i+1; + if ( i==lenA-1 || !overlapped(A[i+1], B[j]) ) j++; + i = nexti; + }else{ + //if not overlapped, we just move the next one + compareInterval(A[i], B[j]) ? i++ : j++; + } + } + return result; + } +}; diff --git a/algorithms/cpp/isSubsequence/IsSubsequence.cpp b/algorithms/cpp/isSubsequence/IsSubsequence.cpp new file mode 100644 index 000000000..e2cd88371 --- /dev/null +++ b/algorithms/cpp/isSubsequence/IsSubsequence.cpp @@ -0,0 +1,50 @@ +// Source : https://leetcode.com/problems/is-subsequence/ +// Author : Hao Chen +// Date : 2016-09-08 + +/*************************************************************************************** + * + * Given a string s and a string t, check if s is subsequence of t. + * + * You may assume that there is only lower case English letters in both s and t. t is + * potentially a very long (length ~= 500,000) string, and s is a short string ( + * + * A subsequence of a string is a new string which is formed from the original string + * by deleting some (can be none) of the characters without disturbing the relative + * positions of the remaining characters. (ie, "ace" is a subsequence of "abcde" while + * "aec" is not). + * + * Example 1: + * s = "abc", t = "ahbgdc" + * + * Return true. + * + * Example 2: + * s = "axc", t = "ahbgdc" + * + * Return false. + * + * Follow up: + * If there are lots of incoming S, say S1, S2, ... , Sk where k >= 1B, and you want to + * check one by one to see if T has its subsequence. In this scenario, how would you + * change your code? + ***************************************************************************************/ + +class Solution { +public: + bool isSubsequence(string s, string t) { + if (s.size() <= 0) return true; + + int ps=0, pt=0; + while (pt < t.size()) { + if (s[ps] == t[pt]) { + ps++; pt++; + if (ps >= s.size()) return true; + }else { + pt++; + } + } + + return false; + } +}; diff --git a/algorithms/cpp/islandPerimeter/IslandPerimeter.cpp b/algorithms/cpp/islandPerimeter/IslandPerimeter.cpp new file mode 100644 index 000000000..c662c3f98 --- /dev/null +++ b/algorithms/cpp/islandPerimeter/IslandPerimeter.cpp @@ -0,0 +1,56 @@ +// Source : https://leetcode.com/problems/island-perimeter/ +// Author : Hao Chen +// Date : 2019-02-04 + +/***************************************************************************************************** + * + * You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 + * represents water. + * + * Grid cells are connected horizontally/vertically (not diagonally). The grid is completely + * surrounded by water, and there is exactly one island (i.e., one or more connected land cells). + * + * The island doesn't have "lakes" (water inside that isn't connected to the water around the island). + * One cell is a square with side length 1. The grid is rectangular, width and height don't exceed + * 100. Determine the perimeter of the island. + * + * Example: + * + * Input: + * [[0,1,0,0], + * [1,1,1,0], + * [0,1,0,0], + * [1,1,0,0]] + * + * Output: 16 + * + * Explanation: The perimeter is the 16 yellow stripes in the image below: + * + ******************************************************************************************************/ +class Solution { +public: + int edge(vector> &grid, int x, int y) { + int edge = 0; + + if (x==0 || (x>0 && grid[x-1][y] == 0 ) ) edge++; //up + if (y==0 || (y>0 && grid[x][y-1] == 0 ) ) edge++; //left + if (x == grid.size() - 1 || + (x < grid.size() - 1 && grid[x+1][y] == 0)) edge++; //down + if (y == grid[0].size() - 1 || + (y < grid[0].size() - 1 && grid[x][y+1] == 0)) edge++; //right + + return edge; + } + + int islandPerimeter(vector>& grid) { + int perimeter = 0; + for(int i=0; i& A) { + if (A.size() < 3) return 0; + sort(A.begin(), A.end(), greater()); + for (auto it = A.begin(); it != A.end() - 2; ++it) { + if (*it < *(it + 1) + *(it + 2)) + return *it + *(it + 1) + *(it + 2); + } + return 0; + } +}; + diff --git a/algorithms/cpp/largestRectangleInHistogram/largestRectangleInHistogram.cpp b/algorithms/cpp/largestRectangleInHistogram/largestRectangleInHistogram.cpp index d37c81fcd..e979b7f98 100644 --- a/algorithms/cpp/largestRectangleInHistogram/largestRectangleInHistogram.cpp +++ b/algorithms/cpp/largestRectangleInHistogram/largestRectangleInHistogram.cpp @@ -54,6 +54,43 @@ #include using namespace std; +//Time Limit Exceeded +int largestRectangleArea_01(vector& heights) { + if (heights.size() == 0) return 0; + + // idx of the first bar in the left or right that is lower than current bar + vector left(heights.size()); + vector right(heights.size()); + + right[heights.size() - 1] = heights.size(); + left[0] = -1; + + for (int i = 1; i < heights.size(); i++) { + int l = i - 1; + while (l >= 0 && heights[l] >= heights[i]) { + l--; + } + left[i] = l; + } + + for (int i = heights.size() - 2; i >= 0; i--) { + int r = i + 1; + while (r < heights.size() && heights[r] >= heights[i]) { + r++; + } + right[i] = r; + } + + int maxArea = 0; + for (int i = 0; i < heights.size(); i++) { + maxArea = max(maxArea, heights[i] * (right[i] - left[i] - 1)); + } + + return maxArea; + +} + + // As we know, the area = width * height // For every bar, the 'height' is determined by the loweset bar. // @@ -175,10 +212,10 @@ int main() } /*int main() -{ - int a[] = {2,1,5,6,2,3}; - vector v(a, a + sizeof(a)/sizeof(int)); - printArray(v); - cout << largestRectangleArea(v) << endl; - return 0; -}*/ + { + int a[] = {2,1,5,6,2,3}; + vector v(a, a + sizeof(a)/sizeof(int)); + printArray(v); + cout << largestRectangleArea(v) << endl; + return 0; + }*/ diff --git a/algorithms/cpp/lexicographicalNumbers/LexicographicalNumbers.cpp b/algorithms/cpp/lexicographicalNumbers/LexicographicalNumbers.cpp new file mode 100644 index 000000000..779e61077 --- /dev/null +++ b/algorithms/cpp/lexicographicalNumbers/LexicographicalNumbers.cpp @@ -0,0 +1,109 @@ +// Source : https://leetcode.com/problems/lexicographical-numbers/ +// Author : Hao Chen +// Date : 2016-08-23 + +/*************************************************************************************** + * + * Given an integer n, return 1 - n in lexicographical order. + * + * For example, given 13, return: [1,10,11,12,13,2,3,4,5,6,7,8,9]. + * + * Please optimize your algorithm to use less time and space. The input size may be as + * large as 5,000,000. + ***************************************************************************************/ +class Solution { + +//Solution 1: convert the int to string for sort, Time complexity is high (Time Limited Error) +public: + vector lexicalOrder01(int n) { + vector result; + for (int i=1; i<=n; i++) { + result.push_back(i); + } + sort(result.begin(), result.end(), this->myComp); + return result; + } +private: + static bool myComp(int i,int j) { + static char si[32]={0}, sj[32]={0}; + sprintf(si, "%d\0", i); + sprintf(sj, "%d\0", j); + return (strcmp(si, sj)<0); + } + + +//Solution 2 : using recursive way to solution the problem, 540ms +public: + vector lexicalOrder02(int n) { + vector result; + for (int i=1; i<=n && i<=9; i++) { + result.push_back(i); + lexicalOrder_helper(i, n, result); + } + return result; + } + +private: + void lexicalOrder_helper(int num, int& n, vector& result) { + for (int i=0; i<=9; i++) { + int tmp = num * 10 + i; + if (tmp > n) { + break; + } + result.push_back(tmp); + lexicalOrder_helper(tmp, n, result); + } + } + +//Solution 3: no recursive way, but the code is not easy to read +public : + vector lexicalOrder03(int n) { + vector result; + int curr = 1; + while (result.size() lexicalOrder(int n) { + srand(time(NULL)); + if (rand()%2) + return lexicalOrder02(n); // recursive way 560ms + else + return lexicalOrder03(n); // non-recursive way, 460ms + } + +}; diff --git a/algorithms/cpp/linkedListCycle/linkedListCycle.cpp b/algorithms/cpp/linkedListCycle/linkedListCycle.cpp index 38badae1d..085bf012f 100644 --- a/algorithms/cpp/linkedListCycle/linkedListCycle.cpp +++ b/algorithms/cpp/linkedListCycle/linkedListCycle.cpp @@ -12,21 +12,80 @@ * **********************************************************************************/ -/* - * if there is a cycle in the list, then we can use two pointers travers the list. - * - * one pointer traverse one step each time, another one traverse two steps each time. - * - * so, those two pointers meet together, that means there must be a cycle inside the list. + +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode(int x) : val(x), next(NULL) {} + * }; */ +class Solution { +public: + bool hasCycle(ListNode *head) { + return hasCycle04(head); + return hasCycle03(head); + return hasCycle02(head); + return hasCycle01(head); + } + + + // using a map to store the nodes we walked + bool hasCycle01(ListNode *head) { + unordered_map m; + ListNode* p = head; + m[(ListNode*)NULL] = true; + while( m.find(p) == m.end() ) { + m[p] = true; + p = p -> next; + } + return p != NULL; + } + + // Change the node's of value, mark the footprint by a special value + bool hasCycle02(ListNode *head) { + ListNode* p = head; + // using INT_MAX as the mark could be a bug! + while( p && p->val != INT_MAX ) { + p->val = INT_MAX; + p = p -> next; + } + return p != NULL; + } + + /* + * if there is a cycle in the list, then we can use two pointers travers the list. + * one pointer traverse one step each time, another one traverse two steps each time. + * so, those two pointers meet together, that means there must be a cycle inside the list. + */ + bool hasCycle03(ListNode *head) { + if (head==NULL || head->next==NULL) return false; + ListNode* fast=head; + ListNode* slow=head; + do{ + slow = slow->next; + fast = fast->next->next; + }while(fast != NULL && fast->next != NULL && fast != slow); + return fast == slow? true : false; + } + + // broken all of nodes + bool hasCycle04(ListNode *head) { + ListNode dummy (0); + ListNode* p = NULL; + + while (head != NULL) { + p = head; + head = head->next; + + // Meet the old Node that next pointed to dummy + //This is cycle of linked list + if (p->next == &dummy) return true; + + p->next = &dummy; // next point to dummy + } + return false; + } -bool hasCycle(ListNode *head) { - if (head==NULL || head->next==NULL) return false; - ListNode* fast=head; - ListNode* slow=head; - do{ - slow = slow->next; - fast = fast->next->next; - }while(fast != NULL && fast->next != NULL && fast != slow); - return fast == slow? true : false; -} +}; diff --git a/algorithms/cpp/linkedListRandomNode/LinkedListRandomNode.cpp b/algorithms/cpp/linkedListRandomNode/LinkedListRandomNode.cpp new file mode 100644 index 000000000..8cc97117c --- /dev/null +++ b/algorithms/cpp/linkedListRandomNode/LinkedListRandomNode.cpp @@ -0,0 +1,61 @@ +// Source : https://leetcode.com/problems/linked-list-random-node/ +// Author : Hao Chen +// Date : 2016-08-24 + +/*************************************************************************************** + * + * Given a singly linked list, return a random node's value from the linked list. Each + * node must have the same probability of being chosen. + * + * Follow up: + * What if the linked list is extremely large and its length is unknown to you? Could + * you solve this efficiently without using extra space? + * + * Example: + * + * // Init a singly linked list [1,2,3]. + * ListNode head = new ListNode(1); + * head.next = new ListNode(2); + * head.next.next = new ListNode(3); + * Solution solution = new Solution(head); + * + * // getRandom() should return either 1, 2, or 3 randomly. Each element should have + * equal probability of returning. + * solution.getRandom(); + ***************************************************************************************/ + +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode(int x) : val(x), next(NULL) {} + * }; + */ +class Solution { +public: + /** @param head The linked list's head. + Note that the head is guaranteed to be not null, so it contains at least one node. */ + Solution(ListNode* head) { + this->head = head; + this->len = 0; + for(ListNode*p = head; p!=NULL; p=p->next, len++); + srand(time(NULL)); + } + + /** Returns a random node's value. */ + int getRandom() { + int pos = rand() % len; + ListNode *p = head; + for (; pos > 0; pos--, p=p->next); + return p->val; + } + ListNode* head; + int len; +}; + +/** + * Your Solution object will be instantiated and called as such: + * Solution obj = new Solution(head); + * int param_1 = obj.getRandom(); + */ diff --git a/algorithms/cpp/longestAbsoluteFilePath/LongestAbsoluteFilePath.cpp b/algorithms/cpp/longestAbsoluteFilePath/LongestAbsoluteFilePath.cpp new file mode 100644 index 000000000..bf7f6ce33 --- /dev/null +++ b/algorithms/cpp/longestAbsoluteFilePath/LongestAbsoluteFilePath.cpp @@ -0,0 +1,107 @@ +// Source : https://leetcode.com/problems/longest-absolute-file-path/ +// Author : Hao Chen +// Date : 2016-08-23 + +/*************************************************************************************** + * + * Suppose we abstract our file system by a string in the following manner: + * + * The string "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext" represents: + * + * dir + * subdir1 + * subdir2 + * file.ext + * + * The directory dir contains an empty sub-directory subdir1 and a sub-directory + * subdir2 containing a file file.ext. + * + * The string + * "dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile + * 2.ext" represents: + * + * dir + * subdir1 + * file1.ext + * subsubdir1 + * subdir2 + * subsubdir2 + * file2.ext + * + * The directory dir contains two sub-directories subdir1 and subdir2. subdir1 contains + * a file file1.ext and an empty second-level sub-directory subsubdir1. subdir2 + * contains a second-level sub-directory subsubdir2 containing a file file2.ext. + * + * We are interested in finding the longest (number of characters) absolute path to a + * file within our file system. For example, in the second example above, the longest + * absolute path is "dir/subdir2/subsubdir2/file2.ext", and its length is 32 (not + * including the double quotes). + * + * Given a string representing the file system in the above format, return the length + * of the longest absolute path to file in the abstracted file system. If there is no + * file in the system, return 0. + * + * Note: + * + * The name of a file contains at least a . and an extension. + * The name of a directory or sub-directory will not contain a .. + * + * Time complexity required: O(n) where n is the size of the input string. + * + * Notice that a/aa/aaa/file1.txt is not the longest file path, if there is another + * path aaaaaaaaaaaaaaaaaaaaa/sth.png. + ***************************************************************************************/ + +class Solution { +public: + // Solution + // -------- + // We can see the input formation has the order + // so, we can maintain an array which states the current level's path length + // + // For example: + // dir + // subdir1 <- length[ level1 = len("dir")+len("/"), + // level2 = len("dir")+len("/")+len("subdir1")+len("/") ] + // file.ext + // subdir2 + // file.ext + // subsubdir1 <- length[ level1 = len("dir")+len("/"), + // level2 = len("dir")+len("/")+len("subdir2")+len("/"), + // level3 = len("dir")+len("/")+len("subdir2")+len("/")+len("subsubdir1")+len("/") ] + // file.ext + // + int lengthLongestPath(string input) { + + stringstream ss(input); + string line; + int result = 0; + + vector length; + length.push_back(0); //initialize top dummy level's length is zero + + while (getline(ss, line, '\n')) { + //get current level, start from 1 + int level = 0; + while ( line[level++] == '\t'); // get the level + int len = line.size() - level + 1; + + //if is a file, then cacualte the total length. + if (line.find('.') != string::npos) { + if ( length[level-1] + len > result ) { + result = length[level-1] + len; + } + } else { + + if (length.size() <= level) { + length.push_back(0); + } + + // if it a folder, then update the current level's length + length[level] = length[level-1] + len + 1; // 1 for "/" path delimiter + } + + } + return result; + } +}; diff --git a/algorithms/cpp/longestIncreasingPathInAMatrix/LongestIncreasingPathInAMatrix.cpp b/algorithms/cpp/longestIncreasingPathInAMatrix/LongestIncreasingPathInAMatrix.cpp new file mode 100644 index 000000000..a7e6a4423 --- /dev/null +++ b/algorithms/cpp/longestIncreasingPathInAMatrix/LongestIncreasingPathInAMatrix.cpp @@ -0,0 +1,81 @@ +// Source : https://leetcode.com/problems/longest-increasing-path-in-a-matrix/ +// Author : Hao Chen +// Date : 2016-01-21 + +/*************************************************************************************** + * + * Given an integer matrix, find the length of the longest increasing path. + * + * From each cell, you can either move to four directions: left, right, up or down. You + * may NOT move diagonally or move outside of the boundary (i.e. wrap-around is not + * allowed). + * + * Example 1: + * + * nums = [ + * [>9, 9, 4], + * [>6, 6, 8], + * [>2,>1, 1] + * ] + * + * Return 4 + * + * The longest increasing path is [1, 2, 6, 9]. + * + * Example 2: + * + * nums = [ + * [>3,>4,>5], + * [ 3, 2,>6], + * [ 2, 2, 1] + * ] + * + * Return 4 + * + * The longest increasing path is [3, 4, 5, 6]. Moving diagonally is not allowed. + * + * Credits:Special thanks to @dietpepsi for adding this problem and creating all test + * cases. + ***************************************************************************************/ + + +class Solution { +public: + int longestIncreasingPath(vector>& matrix) { + int result = 0; + int row = matrix.size(); + int col = row ? matrix[0].size() : 0; + vector> path = vector>(row, vector(col, 0)); + for (int r = 0; r < row; r++) { + for (int c = 0; c < col; c++) { + result = max(result, helper(matrix, path, row, col, r, c)); + } + } + return result; + } + + int helper(vector>& matrix, vector>& path, const int row, const int col, int r, int c) { + + if (path[r][c]>0) return path[r][c]; + + int maxPath = 0; + + int tmp = matrix[r][c]; + matrix[r][c]=INT_MIN; + if (r < row-1 && tmp < matrix[r+1][c]) { + maxPath = max(maxPath, helper(matrix, path, row, col, r+1, c)); + } + if (c < col-1 && tmp < matrix[r][c+1]) { + maxPath = max(maxPath, helper(matrix, path, row, col, r, c+1)); + } + if (r > 0 && tmp < matrix[r-1][c]) { + maxPath = max(maxPath, helper(matrix, path, row, col, r-1, c)); + } + if (c > 0 && tmp < matrix[r][c-1]) { + maxPath = max(maxPath, helper(matrix, path, row, col, r, c-1)); + } + matrix[r][c] = tmp; + path[r][c] = maxPath + 1; + return path[r][c]; + } +}; diff --git a/algorithms/cpp/longestIncreasingSubsequence/longestIncreasingSubsequence.cpp b/algorithms/cpp/longestIncreasingSubsequence/longestIncreasingSubsequence.cpp index 70a7fadab..30c65e9f4 100644 --- a/algorithms/cpp/longestIncreasingSubsequence/longestIncreasingSubsequence.cpp +++ b/algorithms/cpp/longestIncreasingSubsequence/longestIncreasingSubsequence.cpp @@ -1,5 +1,5 @@ // Source : https://leetcode.com/problems/longest-increasing-subsequence/ -// Author : Calinescu Valentin +// Author : Calinescu Valentin, Hao Chen // Date : 2015-11-06 /*************************************************************************************** @@ -22,6 +22,30 @@ * ***************************************************************************************/ + + +// O(n^2) - dynamic programming +class Solution { +public: + int lengthOfLIS(vector& nums) { + + int len = nums.size(); + int maxLen = 0; + vector dp(len, 1); + + for (int i=0; i=0 && right<=n-1 && s[left] == s[right]) { + left--; + right++; + } + if (right-left-1 > len){ + len = right-left-1; + start = left+1; + } +} + +//The following solution is better than previous solution. +//Because it remove the sub-string return in findPalindrome(). +string longestPalindrome_recursive_way2(string s) { + int n = s.size(); + if (n<=1) return s; + + int start=0, len=0; + string longest; + + string str; + for (int i=0; i= NO_OF_CHARS ) return s.size(); + + // find the most infrequent char + char least = 0; + for (int c = 0; c < NO_OF_CHARS; c++) { + if (count[c] == 0) continue; + if (least == 0) { + least = c; + } else if ( count[c] < count[least]) { + least = c; + } + } + + //split the string and run them recursively + vector subs; + split(s, least, subs); + + int res = 0; + for (string str: subs) { + res = max(res, longestSubstring(str, k)); + } + return res; + return 0; + } + +private: + + inline int max(int x, int y) { return x>y? x:y; } + + inline void split(const string &s, char delim, vector &elems) { + stringstream ss; + ss.str(s); + string item; + while (getline(ss, item, delim)) { + cout << item << endl; + elems.push_back(item); + } + } + + + inline vector split(const string &s, char delim) { + vector elems; + split(s, delim, elems); + return elems; + } +}; diff --git a/algorithms/cpp/longestTurbulentSubarray/LongestTurbulentSubarray.cpp b/algorithms/cpp/longestTurbulentSubarray/LongestTurbulentSubarray.cpp new file mode 100644 index 000000000..a38edfb46 --- /dev/null +++ b/algorithms/cpp/longestTurbulentSubarray/LongestTurbulentSubarray.cpp @@ -0,0 +1,138 @@ +// Source : https://leetcode.com/problems/longest-turbulent-subarray/ +// Author : Hao Chen +// Date : 2019-01-26 + +/***************************************************************************************************** + * + * A subarray A[i], A[i+1], ..., A[j] of A is said to be turbulent if and only if: + * + * For i <= k < j, A[k] > A[k+1] when k is odd, and A[k] < A[k+1] when k is even; + * OR, for i <= k < j, A[k] > A[k+1] when k is even, and A[k] < A[k+1] when k is odd. + * + * That is, the subarray is turbulent if the comparison sign flips between each adjacent pair of + * elements in the subarray. + * + * Return the length of a maximum size turbulent subarray of A. + * + * Example 1: + * + * Input: [9,4,2,10,7,8,8,1,9] + * Output: 5 + * Explanation: (A[1] > A[2] < A[3] > A[4] < A[5]) + * + * Example 2: + * + * Input: [4,8,12,16] + * Output: 2 + * + * Example 3: + * + * Input: [100] + * Output: 1 + * + * Note: + * + * 1 <= A.length <= 40000 + * 0 <= A[i] <= 109 + * + ******************************************************************************************************/ +class Solution { +public: + + int maxTurbulenceSize_01(vector& A) { + + if (A.size() <= 1) return A.size(); + + // declare status to mark the current pair status is go up or go down. + enum Status { + up, + down, + none + } s = none; + + int maxlen = 1; + int len = 1; + + for (int i=1; i< A.size(); i++) { + + // if there is a pair is equal, reset the status + if ( A[i] == A[i-1] ) { + s = none; + continue; + } + + // init the first status + if ( s == none ) { + s = A[i] > A[i-1] ? up : down; + len = 2; + continue; + } + + // keep tracking the status + // make sure the status is zigzag pattern...up-down-up-down... + if ( s == up ) { + if ( A[i] < A[i-1] ) { + len++; + s = down; + }else{ + len=2; + } + }else{ + if ( A[i] > A[i-1] ) { + len++; + s = up; + }else{ + len=2; + } + } + + maxlen = len > maxlen ? len : maxlen; + + } + return maxlen; + } + + // The previous solution is quite straight forward, but the code is a bit complcated + // the following solution tries to use another way to make the code simpler. + // + // Then, we need to tracking the previous length of the zigzag pattern. + // + // And we have to tacking the length for both UP and DOWN patterns + // + // - UP means the previous status goes up. and the previous length of the zigzog pattern. + // - DOWN is same. + // + // So, + // + // - if the previous is UP, then the previous DWON must be 1, and vice versa. + // + // - the current UP could be two values : 1 or DOWN + 1 , and vice versa. + // - if A[k] > A[k-1], UP = DWON +1, otherwise UP = 1 + // - if A[K] < A[K-1], DOWN = UP + 1, otherise DOWN = 1 + // + int maxTurbulenceSize_02(vector& A) { + + if (A.size() <= 1) return A.size(); + + int up = 1; + int down = 1; + int maxlen = 1; + + for (int k=1; k A[k-1]) ? d + 1 : 1; + down = (A[k] < A[k-1]) ? u + 1 : 1; + + int len = down > up ? down : up; + maxlen = len > maxlen ? len : maxlen; + } + return maxlen; + } + + int maxTurbulenceSize(vector& A) { + return maxTurbulenceSize_02(A); + return maxTurbulenceSize_01(A); + } +}; diff --git a/algorithms/cpp/majorityElement/majorityElement.II.cpp b/algorithms/cpp/majorityElement/majorityElement.II.cpp index 827e97a57..08b675d69 100644 --- a/algorithms/cpp/majorityElement/majorityElement.II.cpp +++ b/algorithms/cpp/majorityElement/majorityElement.II.cpp @@ -36,7 +36,7 @@ class Solution { //the same algorithm as Majority Element I problem int majority1=0, majority2=0, cnt1=0, cnt2=0; for(auto item: nums) { - if (cnt1 == 0) { + if (cnt1 == 0 && majority2 != item ) { majority1 = item; cnt1 = 1; } else if (majority1 == item) { diff --git a/algorithms/cpp/majorityElement/majorityElement.cpp b/algorithms/cpp/majorityElement/majorityElement.cpp index 2df47d1ef..802ef6283 100644 --- a/algorithms/cpp/majorityElement/majorityElement.cpp +++ b/algorithms/cpp/majorityElement/majorityElement.cpp @@ -32,7 +32,7 @@ int majorityElement(vector &num) { cnt++; }else{ majority == num[i] ? cnt++ : cnt --; - if (cnt >= num.size()/2) return majority; + if (cnt > num.size()/2) return majority; } } return majority; @@ -59,7 +59,8 @@ vector split(const string &s, char delim) { int main(int argc, char** argv) { - string array = "1,2,1,2,1,2,1,2,1,2,1"; + //string array = "1,2,1,2,1,2,1,2,1,2,1"; + string array = "2,2,1,1,1"; if (argc > 1){ array = argv[1]; } diff --git a/algorithms/cpp/maxAreaOfIsland/MaxAreaOfIsland.cpp b/algorithms/cpp/maxAreaOfIsland/MaxAreaOfIsland.cpp new file mode 100644 index 000000000..2c4825cc5 --- /dev/null +++ b/algorithms/cpp/maxAreaOfIsland/MaxAreaOfIsland.cpp @@ -0,0 +1,63 @@ +// Source : https://leetcode.com/problems/max-area-of-island/ +// Author : Hao Chen +// Date : 2019-03-26 + +/***************************************************************************************************** + * + * Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) + * connected 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are + * surrounded by water. + * + * Find the maximum area of an island in the given 2D array. (If there is no island, the maximum area + * is 0.) + * + * Example 1: + * + * [[0,0,1,0,0,0,0,1,0,0,0,0,0], + * [0,0,0,0,0,0,0,1,1,1,0,0,0], + * [0,1,1,0,1,0,0,0,0,0,0,0,0], + * [0,1,0,0,1,1,0,0,1,0,1,0,0], + * [0,1,0,0,1,1,0,0,1,1,1,0,0], + * [0,0,0,0,0,0,0,0,0,0,1,0,0], + * [0,0,0,0,0,0,0,1,1,1,0,0,0], + * [0,0,0,0,0,0,0,1,1,0,0,0,0]] + * + * Given the above grid, return 6. Note the answer is not 11, because the island must be connected + * 4-directionally. + * + * Example 2: + * + * [[0,0,0,0,0,0,0,0]] + * Given the above grid, return 0. + * + * Note: The length of each dimension in the given grid does not exceed 50. + ******************************************************************************************************/ + +class Solution { +public: + int maxAreaOfIsland(vector>& grid) { + int maxArea = 0; + for (int i=0; i>& grid, int i, int j, int& area ) { + if (i<0 || j<0 || i>=grid.size() || j>=grid[0].size() || grid[i][j] != 1 ) return; + + area++; + grid[i][j] = -1; + + maxAreaOfIsland_DFS(grid, i-1, j, area); + maxAreaOfIsland_DFS(grid, i+1, j, area); + maxAreaOfIsland_DFS(grid, i, j-1, area); + maxAreaOfIsland_DFS(grid, i, j+1, area); + } +}; diff --git a/algorithms/cpp/maximalRectangle/maximalRectangle.cpp b/algorithms/cpp/maximalRectangle/maximalRectangle.cpp index 5e0a8fd81..4f732ed73 100644 --- a/algorithms/cpp/maximalRectangle/maximalRectangle.cpp +++ b/algorithms/cpp/maximalRectangle/maximalRectangle.cpp @@ -56,7 +56,7 @@ int maximalRectangle(vector > &matrix) { if (matrix.size()<=0 || matrix[0].size()<=0) return 0; int row = matrix.size(); int col = matrix[0].size(); - vector< vector > heights(row, vector col); + vector< vector > heights(row, vector(col)); int maxArea = 0; for(int i=0; i& nums, int k) { + int sum=0; + for(int i=0; i sum) { + sum = s; + } + } + return (double)sum/k; + } +}; + diff --git a/algorithms/cpp/maximumDepthOfBinaryTree/maximumDepthOfBinaryTree.cpp b/algorithms/cpp/maximumDepthOfBinaryTree/maximumDepthOfBinaryTree.cpp index e33d6020d..c80336281 100644 --- a/algorithms/cpp/maximumDepthOfBinaryTree/maximumDepthOfBinaryTree.cpp +++ b/algorithms/cpp/maximumDepthOfBinaryTree/maximumDepthOfBinaryTree.cpp @@ -40,3 +40,11 @@ class Solution { } }; + +class Solution2 { +public: + int maxDepth(TreeNode *root) { + if (root==NULL) return 0; + return max(maxDepth(root->left), maxDepth(root->right)) + 1; + } +}; diff --git a/algorithms/cpp/maximumProductOfWordLengths/MaximumProductOfWordLengths.cpp b/algorithms/cpp/maximumProductOfWordLengths/MaximumProductOfWordLengths.cpp new file mode 100644 index 000000000..8e9ecf4e0 --- /dev/null +++ b/algorithms/cpp/maximumProductOfWordLengths/MaximumProductOfWordLengths.cpp @@ -0,0 +1,72 @@ +// Source : https://leetcode.com/problems/maximum-product-of-word-lengths/ +// Author : Hao Chen +// Date : 2017-01-02 + +/*************************************************************************************** + * + * Given a string array words, find the maximum value of length(word[i]) * + * length(word[j]) where the two words do not share common letters. + * You may assume that each word will contain only lower case letters. + * If no such two words exist, return 0. + * + * Example 1: + * + * Given ["abcw", "baz", "foo", "bar", "xtfn", "abcdef"] + * Return 16 + * The two words can be "abcw", "xtfn". + * + * Example 2: + * + * Given ["a", "ab", "abc", "d", "cd", "bcd", "abcd"] + * Return 4 + * The two words can be "ab", "cd". + * + * Example 3: + * + * Given ["a", "aa", "aaa", "aaaa"] + * Return 0 + * No such pair of words. + * + * Credits:Special thanks to @dietpepsi for adding this problem and creating all test + * cases. + ***************************************************************************************/ + +class Solution { +public: + // + // there are two algorithms: + // + // 1) compare two words is same or not + // - we can use bit-mask to solve that. + // - we need be careful about one word is subset of another one, such as: "abc" is subset of "abcabc" + // + // 2) find out the max product - that needs O(N^2) time complexity algorithm. + // + + int maxProduct(vector& words) { + //Key is the word's bitmask, and the value the max length of that bit mask + unordered_map maxLens; + //constructing the bitmask. + for(auto& w: words) { + int mask = 0; + for (auto& c: w) { + mask = mask | ( 1 << (c-'a') ); + } + if ( maxLens.find(mask) == maxLens.end() || maxLens[mask] < w.size() ) { + maxLens[mask] = w.size(); + } + } + + //find out the max product + int result = 0; + for (auto a : maxLens) { + for (auto b: maxLens) { + // if `a` and `b` is same, then just simply continue + if (a.first & b.first) continue; // there are common letters + result = max( result, a.second * b.second ); + } + } + + return result; + } +}; diff --git a/algorithms/cpp/maximumProductSubarray/maximumProductSubarray.cpp b/algorithms/cpp/maximumProductSubarray/maximumProductSubarray.cpp index fe294c0b1..cd209788b 100644 --- a/algorithms/cpp/maximumProductSubarray/maximumProductSubarray.cpp +++ b/algorithms/cpp/maximumProductSubarray/maximumProductSubarray.cpp @@ -27,6 +27,19 @@ #include using namespace std; +int max(int x, int y) { + return x>y?x:y; +} +int min(int x, int y){ + return x& cost) { + return minCostClimbingStairs02(cost); + return minCostClimbingStairs01(cost); + } + int minCostClimbingStairs01(vector& cost) { + vector dp(cost.size() , 0); + dp[0] = cost[0]; + dp[1] = cost[1]; + for (int i=2; i& cost) { + int dp1 = cost[0], dp2 = cost[1]; + for (int i=2; i &getList() const; + * }; + */ +class Solution { +public: + NestedInteger deserialize(string s) { + if (s.size()==0) return NestedInteger(); + int pos = 0; + if (s[pos]!='[') return atoni(s, pos); + + return helper(s, ++pos); + } +private: + NestedInteger helper(string& s, int& pos) { + + NestedInteger ni; + + while ( s[pos] != ']' && pos < s.size() ) { + + if (s[pos]=='-' || isnum(s[pos])){ + ni.add(atoni(s, pos)); + }else if (s[pos] == '[') { + pos++; + ni.add(helper(s, pos)); + }else { + pos++; + } + } + pos++; + return ni; + } + NestedInteger atoni(string& s, int& pos) { + int sign = 1; + int num = 0; + if (s[pos]=='-') { + sign = -1; + pos++; + } + for (; pos < s.size(); pos++) { + if (isnum(s[pos])) { + num = num * 10 + s[pos] - '0'; + }else{ + break; + } + } + return NestedInteger(sign * num); + } + bool isnum(char& c) { + return (c >='0' && c <='9'); + } +}; diff --git a/algorithms/cpp/minimumASCIIDeleteSumForTwoStrings/MinimumAsciiDeleteSumForTwoStrings.cpp b/algorithms/cpp/minimumASCIIDeleteSumForTwoStrings/MinimumAsciiDeleteSumForTwoStrings.cpp new file mode 100644 index 000000000..dc4de5933 --- /dev/null +++ b/algorithms/cpp/minimumASCIIDeleteSumForTwoStrings/MinimumAsciiDeleteSumForTwoStrings.cpp @@ -0,0 +1,55 @@ +// Source : https://leetcode.com/problems/minimum-ascii-delete-sum-for-two-strings/ +// Author : Hao Chen +// Date : 2019-01-30 + +/***************************************************************************************************** + * + * Given two strings s1, s2, find the lowest ASCII sum of deleted characters to make two strings equal. + * + * Example 1: + * + * Input: s1 = "sea", s2 = "eat" + * Output: 231 + * Explanation: Deleting "s" from "sea" adds the ASCII value of "s" (115) to the sum. + * Deleting "t" from "eat" adds 116 to the sum. + * At the end, both strings are equal, and 115 + 116 = 231 is the minimum sum possible to achieve this. + * + * Example 2: + * + * Input: s1 = "delete", s2 = "leet" + * Output: 403 + * Explanation: Deleting "dee" from "delete" to turn the string into "let", + * adds 100[d]+101[e]+101[e] to the sum. Deleting "e" from "leet" adds 101[e] to the sum. + * At the end, both strings are equal to "let", and the answer is 100+101+101+101 = 403. + * If instead we turned both strings into "lee" or "eet", we would get answers of 433 or 417, which + * are higher. + * + * Note: + * 0 . + * All elements of each string will have an ASCII value in [97, 122]. + ******************************************************************************************************/ + +class Solution { +public: + int minimumDeleteSum(string s1, string s2) { + // Dynamic Programm - simlar with : Edit Distance + vector < vector > dp ( s1.size()+1, vector( s2.size()+1, 0) ); + + // s1 is row, s2 is column + for (int i=1; i<=s2.size(); i++) dp[0][i] = dp[0][i-1] + s2[i-1]; + for (int i=1; i<=s1.size(); i++) dp[i][0] = dp[i-1][0] + s1[i-1]; + + for (int i=1; i<=s1.size(); i++){ + for (int j=1; j<=s2.size(); j++) { + if ( s1[i-1] == s2[j-1] ) { + dp[i][j] = dp[i-1][j-1]; + }else{ + dp[i][j] = min(dp[i-1][j] + s1[i-1], dp[i][j-1] + s2[j-1]); + } + } + } + + return dp[s1.size()][s2.size()]; + + } +}; diff --git a/algorithms/cpp/minimumCostForTickets/MinimumCostForTickets.cpp b/algorithms/cpp/minimumCostForTickets/MinimumCostForTickets.cpp new file mode 100644 index 000000000..79dff08f1 --- /dev/null +++ b/algorithms/cpp/minimumCostForTickets/MinimumCostForTickets.cpp @@ -0,0 +1,99 @@ +// Source : https://leetcode.com/problems/minimum-cost-for-tickets/ +// Author : Hao Chen +// Date : 2019-01-29 + +/***************************************************************************************************** + * + * In a country popular for train travel, you have planned some train travelling one year in advance. + * The days of the year that you will travel is given as an array days. Each day is an integer from 1 + * to 365. + * + * Train tickets are sold in 3 different ways: + * + * a 1-day pass is sold for costs[0] dollars; + * a 7-day pass is sold for costs[1] dollars; + * a 30-day pass is sold for costs[2] dollars. + * + * The passes allow that many days of consecutive travel. For example, if we get a 7-day pass on day + * 2, then we can travel for 7 days: day 2, 3, 4, 5, 6, 7, and 8. + * + * Return the minimum number of dollars you need to travel every day in the given list of days. + * + * Example 1: + * + * Input: days = [1,4,6,7,8,20], costs = [2,7,15] + * Output: 11 + * Explanation: + * For example, here is one way to buy passes that lets you travel your travel plan: + * On day 1, you bought a 1-day pass for costs[0] = $2, which covered day 1. + * On day 3, you bought a 7-day pass for costs[1] = $7, which covered days 3, 4, ..., 9. + * On day 20, you bought a 1-day pass for costs[0] = $2, which covered day 20. + * In total you spent $11 and covered all the days of your travel. + * + * Example 2: + * + * Input: days = [1,2,3,4,5,6,7,8,9,10,30,31], costs = [2,7,15] + * Output: 17 + * Explanation: + * For example, here is one way to buy passes that lets you travel your travel plan: + * On day 1, you bought a 30-day pass for costs[2] = $15 which covered days 1, 2, ..., 30. + * On day 31, you bought a 1-day pass for costs[0] = $2 which covered day 31. + * In total you spent $17 and covered all the days of your travel. + * + * Note: + * + * 1 <= days.length <= 365 + * 1 <= days[i] <= 365 + * days is in strictly increasing order. + * costs.length == 3 + * 1 <= costs[i] <= 1000 + * + ******************************************************************************************************/ + +class Solution { +private: + int min(int x, int y){ + return x < y ? x : y; + } + int min(int x, int y, int z) { + return min(min(x, y), z); + } +public: + int mincostTickets(vector& days, vector& costs) { + + // Dynamic Programming + vector dp(days.size(), INT_MAX); + + // dp[i] is the minimal cost from Days[0] to Days[i] + dp[0] = costs[0]; + + for (int i = 1; i< days.size(); i ++) { + + // the currnet day need at least 1-day pass cost + int OneDayPass = dp[i-1] + costs[0]; + + // Seprating the array to two parts. + // days[0] -> days[j] -> day[i] + // + // calculate the day[i] - day[j] whether can use 7-day pass or 30-day pass + // + // Traking the minimal costs, then can have dp[i] minimal cost + + int SevenDayPass = INT_MAX, ThrityDayPass = INT_MAX; + for (int j=i-1; j>=0; j--){ + if (days[i] - days[j] < 7 ) { + SevenDayPass = dp[j-1] + costs[1]; + } else if (days[i] - days[j] < 30 ) { + ThrityDayPass = dp[j-1] + costs[2]; + } else { + break; + } + int m = min(OneDayPass, SevenDayPass, ThrityDayPass); + if ( dp[i] > m ) dp[i] = m; + } + + } + + return dp[dp.size()-1]; + } +}; diff --git a/algorithms/cpp/minimumFallingPathSum/MinimumFallingPathSum.cpp b/algorithms/cpp/minimumFallingPathSum/MinimumFallingPathSum.cpp new file mode 100644 index 000000000..6ce6817d1 --- /dev/null +++ b/algorithms/cpp/minimumFallingPathSum/MinimumFallingPathSum.cpp @@ -0,0 +1,64 @@ +// Source : https://leetcode.com/problems/minimum-falling-path-sum/ +// Author : Hao Chen +// Date : 2019-01-30 + +/***************************************************************************************************** + * + * Given a square array of integers A, we want the minimum sum of a falling path through A. + * + * A falling path starts at any element in the first row, and chooses one element from each row. The + * next row's choice must be in a column that is different from the previous row's column by at most + * one. + * + * Example 1: + * + * Input: [[1,2,3],[4,5,6],[7,8,9]] + * Output: 12 + * Explanation: + * The possible falling paths are: + * + * [1,4,7], [1,4,8], [1,5,7], [1,5,8], [1,5,9] + * [2,4,7], [2,4,8], [2,5,7], [2,5,8], [2,5,9], [2,6,8], [2,6,9] + * [3,5,7], [3,5,8], [3,5,9], [3,6,8], [3,6,9] + * + * The falling path with the smallest sum is [1,4,7], so the answer is 12. + * + * Note: + * + * 1 <= A.length == A[0].length <= 100 + * -100 <= A[i][j] <= 100 + ******************************************************************************************************/ +class Solution { +private: + int min(int x, int y) { + return x < y ? x: y; + } + int min( int x, int y, int z) { + return min(min(x, y),z); + } +public: + int minFallingPathSum(vector>& A) { + int m = INT_MAX; + + for (int i=0; i 0) { + if (j == 0 ){ + A[i][j] += min( A[i-1][j], A[i-1][j+1]); + } else if ( j + 1 == A[i].size()) { + A[i][j] += min( A[i-1][j], A[i-1][j-1]); + }else { + A[i][j] += min( A[i-1][j], A[i-1][j-1], A[i-1][j+1]); + } + } + + if ( i + 1 == A.size() ) { + m = min(m, A[i][j]); + } + } + } + + return m; + } +}; diff --git a/algorithms/cpp/minimumHeightTrees/MinimumHeightTrees.cpp b/algorithms/cpp/minimumHeightTrees/MinimumHeightTrees.cpp new file mode 100644 index 000000000..9f3a125f2 --- /dev/null +++ b/algorithms/cpp/minimumHeightTrees/MinimumHeightTrees.cpp @@ -0,0 +1,98 @@ +// Source : https://leetcode.com/problems/minimum-height-trees/ +// Author : Hao Chen +// Date : 2016-01-24 + +/*************************************************************************************** + * + * For a undirected graph with tree characteristics, we can choose any node as the + * root. The result graph is then a rooted tree. Among all possible rooted trees, those + * with minimum height are called minimum height trees (MHTs). + * + * Given such a graph, write a function to find all the MHTs and return a list of + * their root labels. + * + * *Format* + * The graph contains n nodes which are labeled from 0 to n - 1. + * You will be given the number n and a list of undirected edges (each edge is a + * pair of labels). + * + * + * You can assume that no duplicate edges will appear in edges. Since all edges are + * undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges. + * + * Example 1: + * + * Given n = 4, edges = [[1, 0], [1, 2], [1, 3]] + * + * 0 + * | + * 1 + * / \ + * 2 3 + * + * return [1] + * + * Example 2: + * + * Given n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]] + * + * 0 1 2 + * \ | / + * 3 + * | + * 4 + * | + * 5 + * + * return [3, 4] + * + * How many MHTs can a graph have at most? + * + * Note: + * + * (1) According to the definition of tree on Wikipedia: https://en.wikipedia.org/wiki/Tree_(graph_theory) + * “a tree is an undirected graph in which any two vertices are connected by exactly one path. + * In other words, any connected graph without simple cycles is a tree.” + * + * (2) The height of a rooted tree is the number of edges on the longest downward path between + * the root and a leaf. + * + * Credits:Special thanks to @dietpepsi for adding this problem and creating all test + * cases. + ***************************************************************************************/ + +class Solution { +public: + vector findMinHeightTrees(int n, vector>& edges) { + //corner case + if ( n <= 1 ) return {0}; + + //construct a edges search data stucture + vector> graph(n); + for (auto e : edges) { + graph[e.first].insert(e.second); + graph[e.second].insert(e.first); + } + + //find all of leaf nodes + vector current; + for (int i=0; i next; + for (int node : current) { + for (int neighbor : graph[node]) { + graph[neighbor].erase(node); + if (graph[neighbor].size() == 1) next.push_back(neighbor); + } + } + if (next.empty()) break; + current = next; + } + return current; + } + +}; diff --git a/algorithms/cpp/minimumPathSum/minimumPathSum.cpp b/algorithms/cpp/minimumPathSum/minimumPathSum.cpp index c666184d2..11bac7f13 100644 --- a/algorithms/cpp/minimumPathSum/minimumPathSum.cpp +++ b/algorithms/cpp/minimumPathSum/minimumPathSum.cpp @@ -2,41 +2,43 @@ // Author : Hao Chen // Date : 2014-06-21 -/********************************************************************************** -* -* Given a m x n grid filled with non-negative numbers, find a path from top left to -* bottom right which minimizes the sum of all numbers along its path. -* -* Note: You can only move either down or right at any point in time. -* -**********************************************************************************/ +/***************************************************************************************************** + * + * Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right + * which minimizes the sum of all numbers along its path. + * + * Note: You can only move either down or right at any point in time. + * + * Example: + * + * Input: + * [ + * [1,3,1], + * [1,5,1], + * [4,2,1] + * ] + * Output: 7 + * Explanation: Because the path 1→3→1→1→1 minimizes the sum. + * + ******************************************************************************************************/ #include #include #include using namespace std; -int minPathSum(vector > &grid) { - if (grid.size()<=0){ - return 0; - } - int i, j; - for(i=0; i>& grid) { + for (int i=0; i= T.size() ) { - /* - * Find the beginning of the window - * 1) f[S[begin]] == NOT_EXISTED ===> the char at the `begin` is not in T - * 2) f[S[begin]] > m[S[begin]] ===> a same char appeared more than excepted. - */ - while ( f[S[begin]] == NOT_EXISTED || f[S[begin]] > m[S[begin]] ) { - if ( f[S[begin]] > m[S[begin]] ) { - f[S[begin]]--; - } - begin++; + int left = 0; + + for(int right=0; right= t.size() ) { + /* + * Find the left of the window - try to make the window smaller + * 1) windows[S[left]] == NOT_EXISTED ===> the char at the `left` is not in T + * 2) window[S[left]] > dict[S[left]] ===> a same char appeared more than excepted. + */ + char chl = s[left]; + while ( window[chl] == NOT_EXISTED || window[chl] > dict[chl] ) { + if (dict[chl] != NOT_EXISTED ) { + //move the left of window + window[chl]--; + // reduce the number of letters found + if (window[chl] < dict[chl] ) letterFound--; } - /* Calculate the minimized window size */ - if(winSize > i - begin + 1){ - start = begin; - winSize = i - begin + 1; - } - + chl = s[++left]; + } + + /* Calculate the minimized window size */ + if(winSize > right - left + 1){ + start = left; + winSize = right - left + 1; } - + } } if (start>=0 && winSize>0) { - win = S.substr(start, winSize); + win = s.substr(start, winSize); } return win; } - int main(int argc, char**argv) { string S = "ADOBECODEBANC"; diff --git a/algorithms/cpp/mirrorReflection/MirrorReflection.cpp b/algorithms/cpp/mirrorReflection/MirrorReflection.cpp new file mode 100644 index 000000000..c2d0d8201 --- /dev/null +++ b/algorithms/cpp/mirrorReflection/MirrorReflection.cpp @@ -0,0 +1,80 @@ +// Source : https://leetcode.com/problems/mirror-reflection/description/ +// Author : Hao Chen +// Date : 2018-06-27 + +/*************************************************************************************** + * + * There is a special square room with mirrors on each of the four walls. Except for + * the southwest corner, there are receptors on each of the remaining corners, numbered + * 0, 1, and 2. + * + * The square room has walls of length p, and a laser ray from the southwest corner + * first meets the east wall at a distance q from the 0th receptor. + * + * Return the number of the receptor that the ray meets first. (It is guaranteed that + * the ray will meet a receptor eventually.) + * + * + * + * + * Example 1: + * + * + * Input: p = 2, q = 1 + * Output: 2 + * Explanation: The ray meets receptor 2 the first time it gets reflected back to the + * left wall. + * + * + * + * + * Note: + * + * + * 1 <= p <= 1000 + * 0 <= q <= p + * + ***************************************************************************************/ + +/* + * Solution + * -------- + * + * We know the following things: + * 1)every reflection will increase the step of `q`. + * 2) when reach the top, the reflection would go down, when reach the bottom the reflection would go up. + * + * So, we can image if there have two walls, left one and right one, then the reflection can go up instanstly, + * + * - the reflection points on left wall would be even times of `q`. + * - the reflection points on right wall would be odd times of `q`. + * + * And in the right wall, the receptors `#0` would be the times of `2p`. + * + * So, we need find the least common multiple of `p` and `q`, then we can have the answer. + */ + + +class Solution { +private: + //GCD - greatest common divisor 最大公因数 + int greatestCommonDivisor (int a, int b) { + if(b) while((a %= b) && (b %= a)); + return a + b; + } + //LCM - least common multiple 最小公倍数 + int leastCommonMultiple(int a, int b) { + return a * b / greatestCommonDivisor(a, b); + } +public: + int mirrorReflection(int p, int q) { + int lcm = leastCommonMultiple(p, q); + if (lcm % (2*p) == 0 ) return 0; + + int nq = lcm / q; + + if (nq % 2 == 0 ) return 2; + return 1; + } +}; + diff --git a/algorithms/cpp/mostCommonWord/MostCommonWord.cpp b/algorithms/cpp/mostCommonWord/MostCommonWord.cpp new file mode 100644 index 000000000..12ffe2712 --- /dev/null +++ b/algorithms/cpp/mostCommonWord/MostCommonWord.cpp @@ -0,0 +1,100 @@ +// Source : https://leetcode.com/problems/most-common-word/ +// Author : Hao Chen +// Date : 2018-04-19 + +/*************************************************************************************** + * + * Given a paragraph and a list of banned words, return the most frequent word that is + * not in the list of banned words. It is guaranteed there is at least one word that + * isn't banned, and that the answer is unique. + * + * Words in the list of banned words are given in lowercase, and free of punctuation. + * Words in the paragraph are not case sensitive. The answer is in lowercase. + * + * + * Example: + * Input: + * paragraph = "Bob hit a ball, the hit BALL flew far after it was hit." + * banned = ["hit"] + * Output: "ball" + * Explanation: + * "hit" occurs 3 times, but it is a banned word. + * "ball" occurs twice (and no other word does), so it is the most frequent non-banned + * word in the paragraph. + * Note that words in the paragraph are not case sensitive, + * that punctuation is ignored (even if adjacent to words, such as "ball,"), + * and that "hit" isn't the answer even though it occurs more because it is banned. + * + * + * + * + * Note: + * + * + * 1 <= paragraph.length <= 1000. + * 1 <= banned.length <= 100. + * 1 <= banned[i].length <= 10. + * The answer is unique, and written in lowercase (even if its occurrences in + * paragraph may have uppercase symbols, and even if it is a proper noun.) + * paragraph only consists of letters, spaces, or the punctuation symbols !?',;. + * Different words in paragraph are always separated by a space. + * There are no hyphens or hyphenated words. + * Words only consist of letters, never apostrophes or other punctuation + * symbols. + * + * + * + ***************************************************************************************/ + + +class Solution { +private: + bool isLetter(char c) { + return c >= 'a' && c <= 'z'; + } +public: + string mostCommonWord(string paragraph, vector& banned) { + unordered_map banned_map, words_map; + for (auto w:banned) { + banned_map[w]++; + } + + //conert the string to lower case. + transform(paragraph.begin(), paragraph.end(), paragraph.begin(), ::tolower); + + //transfer the symbols to space. + for (int i=0; i0 ) { + words_map[word]++; + } + word=""; + } + } + if ( word.size()>0 ) words_map[word]++; + + string result; + int max_cnt=0; + // go through the words_map + for (auto const& w : words_map) { + + if ( banned_map.find(w.first) != banned_map.end() ) { + continue; + } + if (max_cnt < w.second) { + result = w.first; + max_cnt = w.second; + } + } + + return result; + } +}; diff --git a/algorithms/cpp/moveZeroes/moveZeroes.cpp b/algorithms/cpp/moveZeroes/moveZeroes.cpp index f6fcb9dab..1b86cb691 100644 --- a/algorithms/cpp/moveZeroes/moveZeroes.cpp +++ b/algorithms/cpp/moveZeroes/moveZeroes.cpp @@ -41,7 +41,7 @@ class Solution { int i = 0, poz = 0; for(i = 0; i < nums.size() && poz < nums.size(); i++) { - while(nums[poz] == 0) + while(poz < nums.size() && nums[poz] == 0) poz++; if(poz < nums.size()) nums[i] = nums[poz]; @@ -72,7 +72,7 @@ class Solution { // Find the first ZERO, where is the tail of the array. // (Notes: we can simply remove this!) - for (; nums[p1]!=0 && p1& solution, vector< //if no more row need to do, shape the result if (currentRow == n){ vector s; + vector s(n, string(n, '.')); for (int row = 0; row < n; row++) { - string sRow; - for (int col = 0; col < n; col++) { - sRow = sRow + (solution[row] == col ? "Q" :"." ); - } - s.push_back(sRow); + s[row][solution[row]] = 'Q'; } result.push_back(s); return; diff --git a/algorithms/cpp/nextPermutation/nextPermutation.cpp b/algorithms/cpp/nextPermutation/nextPermutation.cpp index 404c4b86c..8d4ab294e 100644 --- a/algorithms/cpp/nextPermutation/nextPermutation.cpp +++ b/algorithms/cpp/nextPermutation/nextPermutation.cpp @@ -33,11 +33,11 @@ * 2 1 3 4 * ... * - * The pattern as below: + * The pattern can be descripted as below: * - * 1) find the first place which num[i-1] < num[i] - * 2) find the first number from n-1 to i which >= num[i-1] - * 3) swap the 2) num with num[i-1] + * 1) from n-1 to 0, find the first place [i-1] which num[i-1] < num[i] + * 2) from n-1 to i, find the first number from n-1 to i which >= num[i-1] + * 3) swap the 2) num with the num[i-1] * 4) sort the sub-array [i, n) //actuall sort is fine as well * * For example: diff --git a/algorithms/cpp/nthDigit/NthDigit.cpp b/algorithms/cpp/nthDigit/NthDigit.cpp new file mode 100644 index 000000000..1351f2a84 --- /dev/null +++ b/algorithms/cpp/nthDigit/NthDigit.cpp @@ -0,0 +1,99 @@ +// Source : https://leetcode.com/problems/nth-digit/ +// Author : Hao Chen +// Date : 2016-11-05 + +/*************************************************************************************** + * + * Find the nth digit of the infinite integer sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + * 11, ... + * + * Note: + * n is positive and will fit within the range of a 32-bit signed integer (n 31). + * + * Example 1: + * + * Input: + * 3 + * + * Output: + * 3 + * + * Example 2: + * + * Input: + * 11 + * + * Output: + * 0 + * + * Explanation: + * The 11th digit of the sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... is a 0, which + * is part of the number 10. + ***************************************************************************************/ + + +#include +using namespace std; + +class Solution { +public: + int findNthDigit(int n) { + + // We can see the following pattern: + // + // 1, 2, .... 9 : there are 9 * 1 digits. + // 10, 11, ..., 99: there are 90 * 2 digits. + // 101, 102, 103, ..., 999: there are 900 * 3. + // ... + + + //we can count the digits with the above pattern + long digits_cnt = 0; + long digits_cnt_prev = 0; + int base = 0; + for ( ; digits_cnt < n; base++) { + digits_cnt_prev = digits_cnt; + digits_cnt = digits_cnt + 9 * pow(10 , base) * ( base + 1 ); + } + + + // Now, we got `digits_cnt_prev`, `digits_cnt` and `base` + // + // For examples: + // n = 20; digits_cnt_prev = 9, digits_cnt = 9+90*2 = 189, base = 2; + // n = 500; digits_cnt_prev = 9+90*2 = 189, digits_cnt = 9+90*2+900*3 = 2889, base = 3; + // n = 2000; digits_cnt_prev = 9+90*2 = 189, digits_cnt = 9+90*2+900*3 = 2889, base = 3; + // + // It means, we found the range where the number it is + // n = 20, the number located in the range 10 -- 99 + // n = 500, the number located in the range 100 - 999 + // + // and we can use `digits_cnt_prev` to know the previous rangs produce how many digits. + // n = 20, the previous ranges produce 9 digits, so there needs 20-9 = 11 digits in [10 - 99] + // n = 500, the previous ranges produce 189 digits, so there needs 500-189 = 311 digits in [100-999] + // + // the `base` told us in current ranges, each number can have how many digits. + // then we can locate the target number. + // n = 20, + // (n - digits_cnt_prev) / base = (20 - 9 ) / 2 = 5, so, [10 - 14] produces 10 digits (ZERO-based), + // now, we have 1 digits left, it is the first digit of the target number 15. + // + // n = 500, + // (n - digits_cnt_prev) / base = (500 - 189) / 3 = 103, so, [100 - 202] produces 309 digits(ZERO-based). + // now, we have (500 - 189 - 309) = 2 digits left, it is the second digit of the target number 203. + // + // We can write the code now... + // + int target = pow(10, base-1) + (n - digits_cnt_prev) / base - 1; + int left = n - digits_cnt_prev - (n - digits_cnt_prev) / base * base; + + //cout << "target = " << target << ", left = " << left << endl; + + //no digits left + if ( left == 0 ) return (target) % 10; + + //still have some digits left, it should be in next number. + target++; + return int( target / pow(10, base - left) ) % 10; + } +}; diff --git a/algorithms/cpp/numberOfIslands/NumberOfIslands.cpp b/algorithms/cpp/numberOfIslands/NumberOfIslands.cpp index 2eea8a877..9c5d140ee 100644 --- a/algorithms/cpp/numberOfIslands/NumberOfIslands.cpp +++ b/algorithms/cpp/numberOfIslands/NumberOfIslands.cpp @@ -39,14 +39,10 @@ void mark(vector >& grid, int r, int c){ grid[r][c] = 'M'; - //left - mark(grid, r, c+1); - //right - mark(grid, r, c-1); - //up - mark(grid, r-1, c); - //down - mark(grid, r+1, c); + mark(grid, r, c+1); //left + mark(grid, r, c-1); //right + mark(grid, r-1, c); //up + mark(grid, r+1, c); //down } int numIslands(vector >& grid) { diff --git a/algorithms/cpp/oddEvenLinkedList/OddEvenLinkedList.cpp b/algorithms/cpp/oddEvenLinkedList/OddEvenLinkedList.cpp new file mode 100644 index 000000000..6a206978e --- /dev/null +++ b/algorithms/cpp/oddEvenLinkedList/OddEvenLinkedList.cpp @@ -0,0 +1,53 @@ +// Source : https://leetcode.com/problems/odd-even-linked-list/ +// Author : Hao Chen +// Date : 2016-01-16 + +/*************************************************************************************** + * + * Given a singly linked list, group all odd nodes together followed by the even nodes. + * Please note here we are talking about the node number and not the value in the nodes. + * + * You should try to do it in place. The program should run in O(1) space complexity + * and O(nodes) time complexity. + * + * Example: + * Given 1->2->3->4->5->NULL, + * return 1->3->5->2->4->NULL. + * + * Note: + * The relative order inside both the even and odd groups should remain as it was in + * the input. + * The first node is considered odd, the second node even and so on ... + * + * Credits:Special thanks to @aadarshjajodia for adding this problem and creating all + * test cases. + ***************************************************************************************/ + +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode(int x) : val(x), next(NULL) {} + * }; + */ +class Solution { +public: + ListNode* oddEvenList(ListNode* head) { + if (!head) return head; + ListNode* pOdd = head; + ListNode* p = head->next; + ListNode* pNext = NULL; + while(p && (pNext=p->next)) { + + p->next = pNext->next; + pNext->next = pOdd->next; + pOdd->next = pNext; + + p = p->next; + pOdd = pOdd->next; + + } + return head; + } +}; diff --git a/algorithms/cpp/palindromeNumber/palindromeNumber.cpp b/algorithms/cpp/palindromeNumber/palindromeNumber.cpp index fde572f3b..021f55125 100644 --- a/algorithms/cpp/palindromeNumber/palindromeNumber.cpp +++ b/algorithms/cpp/palindromeNumber/palindromeNumber.cpp @@ -26,7 +26,12 @@ class Solution { public: - bool isPalindrome(int x) { + bool isPalindrome(int x) { + return isPalindrome1(x); + return isPalindrome2(x); + } + + bool isPalindrome1(int x) { if (x<0) { return false; } @@ -59,6 +64,9 @@ class Solution { int n; while( x!=0 ){ n = x%10; + //check if y is overflowed or not. + //if it is, then it's not palindrome + if ( y > INT_MAX/10 - n) return x-1; y = y*10 + n; x /= 10; } diff --git a/algorithms/cpp/palindromePairs/PalindromePairs.cpp b/algorithms/cpp/palindromePairs/PalindromePairs.cpp new file mode 100644 index 000000000..c7c6fada2 --- /dev/null +++ b/algorithms/cpp/palindromePairs/PalindromePairs.cpp @@ -0,0 +1,78 @@ +// Source : https://leetcode.com/problems/palindrome-pairs/ +// Author : Hao Chen +// Date : 2017-03-22 + +/*************************************************************************************** + * + * Given a list of unique words, find all pairs of distinct indices (i, j) in the given + * list, so that the concatenation of the two words, i.e. words[i] + words[j] is a + * palindrome. + * + * Example 1: + * Given words = ["bat", "tab", "cat"] + * Return [[0, 1], [1, 0]] + * The palindromes are ["battab", "tabbat"] + * + * Example 2: + * Given words = ["abcd", "dcba", "lls", "s", "sssll"] + * Return [[0, 1], [1, 0], [3, 2], [2, 4]] + * The palindromes are ["dcbaabcd", "abcddcba", "slls", "llssssll"] + * + * Credits:Special thanks to @dietpepsi for adding this problem and creating all test + * cases. + * + ***************************************************************************************/ + +class Solution { +public: + bool isPalindrome(string& str) { + int left = 0, right = str.size() - 1; + while( left < right) { + if (str[left++] != str[right--]) return false; + } + return true; + } + vector> palindromePairs(vector& words) { + unordered_map dict; + for(int i=0; i> result; + + //egde case: deal with empty string + if ( dict.find("") != dict.end() ) { + for(int i=0; i > dp(len, vector(len, false)); + + int cnt = 0; + for( int i=len-1; i>=0; i--) { + for (int j=i; j<=len-1; j++) { + if ( i == j || ( s[i] == s[j] && ( j-i<2 || dp[i+1][j-1]) ) ) { + dp[i][j] = true; + cnt++; + } + } + } + + return cnt; + + } +}; diff --git a/algorithms/cpp/partitionEqualSubsetSum/PartitionEqualSubsetSum.cpp b/algorithms/cpp/partitionEqualSubsetSum/PartitionEqualSubsetSum.cpp new file mode 100644 index 000000000..1ed6b5515 --- /dev/null +++ b/algorithms/cpp/partitionEqualSubsetSum/PartitionEqualSubsetSum.cpp @@ -0,0 +1,65 @@ +// Source : https://leetcode.com/problems/partition-equal-subset-sum/description/ +// Author : Hao Chen +// Date : 2018-06-24 + +/*************************************************************************************** + * + * Given a non-empty array containing only positive integers, find if the array can be + * partitioned into two subsets such that the sum of elements in both subsets is equal. + * + * + * Note: + * + * Each of the array element will not exceed 100. + * The array size will not exceed 200. + * + * + * + * Example 1: + * + * Input: [1, 5, 11, 5] + * + * Output: true + * + * Explanation: The array can be partitioned as [1, 5, 5] and [11]. + * + * + * + * Example 2: + * + * Input: [1, 2, 3, 5] + * + * Output: false + * + * Explanation: The array cannot be partitioned into equal sum subsets. + * + ***************************************************************************************/ + +class Solution { +public: + //back tracking + bool canPartitionRecrusion(vector& nums, int half, int index) { + for (int i=index; i& nums) { + int sum = 0; + for(auto n : nums) sum +=n; + if ( sum & 1 ) return false; // sum % 2 != 1 + int half = sum / 2; + + //sort the array in descending order + //so, the DFS could be very fast to find the answer because it's greedy. + std::sort(nums.begin(), nums.end(), std::greater()); + + //go to find a path which sum is half + return canPartitionRecrusion(nums, half, 0); + } +}; diff --git a/algorithms/cpp/patchingArray/PatchingArray.cpp b/algorithms/cpp/patchingArray/PatchingArray.cpp new file mode 100644 index 000000000..18b7ee51b --- /dev/null +++ b/algorithms/cpp/patchingArray/PatchingArray.cpp @@ -0,0 +1,115 @@ +// Source : https://leetcode.com/problems/patching-array/ +// Author : Hao Chen +// Date : 2016-03-01 + +/*************************************************************************************** + * + * Given a sorted positive integer array nums and an integer n, add/patch elements to + * the array such that any number in range [1, n] inclusive can be formed by the sum of + * some elements in the array. Return the minimum number of patches required. + * + * Example 1: + * nums = [1, 3], n = 6 + * Return 1. + * + * Combinations of nums are [1], [3], [1,3], which form possible sums of: 1, 3, 4. + * Now if we add/patch 2 to nums, the combinations are: [1], [2], [3], [1,3], [2,3], + * [1,2,3]. + * Possible sums are 1, 2, 3, 4, 5, 6, which now covers the range [1, 6]. + * So we only need 1 patch. + * + * Example 2: + * nums = [1, 5, 10], n = 20 + * Return 2. + * The two patches can be [2, 4]. + * + * Example 3: + * nums = [1, 2, 2], n = 5 + * Return 0. + * + * Credits:Special thanks to @dietpepsi for adding this problem and creating all test + * cases. + ***************************************************************************************/ + + +class Solution { +public: + int minPatches(vector& nums, int n) { + return minPatches_02(nums, n); + return minPatches_01(nums, n); + } + + + // Greedy Algorithm + // (Assume the array is sorted already) + // + // Let do some observation at first, + // + // 1) if we have [1,2] then we can cover 1, 2, 3 + // 2) if we have [1,2,3] then we can cover 1,2,3,4,5,6 + // So, it looks we can simply add all of nums together, then we can find out max number we can reach. + // + // 3) if we have [1,2,5], we can see + // 3.1) [1,2] can cover 1,2,3, but we cannot reach 4, + // 3.2) then we patch 4, then we have [1,2,4] which can cover 1,2,3(1+2),4,5(1+4),6(2+4), 7(1+2+4) + // 3.3) we can see [1,2,4] can reach to 7 - sum all of them + // 3.4) then [1,2,4,5], we can reach to 12 - 1,2,3,4,5,6,7,8(1+2+5),9(4+5),10(1+4+5), 11(2+4+5), 12(1+2+4+5) + // + // So, we can have figure out our solution + // + // 0) considering the `n` we need to cover. + // 1) maintain a variable we are trying to patch, suppose named `try_patch` + // 2) if `try_patch` >= nums[i] then, we just keep add the current array item, + // and set the `try_patch` to the next patch candidate number - `sum+1` + // 3) if `try_patch` < nums[i], which means we need to patch. + // + int minPatches_01(vector& nums, int n) { + long covered = 0; //avoid integer overflow + int patch_cnt = 0; + int i = 0; + while (i= nums[i]) { + covered += nums[i]; + i++; + } else { // if the `try_patch` cannot cover the current item, then we find the number we need to patch + patch_cnt++; + //cout << "patch " << try_patch << endl; + covered = covered + try_patch; + } + + if (covered >=n) break; + } + //for the case - [1], 7 + //the above while-loop just process all of the numbers in the array, + //but we might not reach the goal, so, we need keep patching. + while (covered < n) { + int try_patch = covered + 1; + patch_cnt++; + //cout << "patch " << try_patch << endl; + covered = covered + try_patch; + } + return patch_cnt; + } + + + //The following solution just re-organizes the solution above, and make it shorter + int minPatches_02(vector& nums, int n) { + long covered = 0; + int patch_cnt = 0; + int i = 0; + while ( covered < n){ + if (i > pathSum(TreeNode *root, int sum) { vector > result; vector v; - generatePathSum(root, sum, v, result); + generatePathSum(root, sum, 0, v, result); return result; } - - void generatePathSum(TreeNode *root, int sum, vector v, vector >& result) { - - if (root==NULL) { - return; - } - - if (root->left==NULL && root->right==NULL) { - if (root->val == sum){ - v.push_back(root->val); - result.push_back(v); - } - return; - } - + + void generatePathSum(TreeNode *root, int sum, int s, vector v, vector >& result) { + if (root==NULL) return ; + + s += root->val; v.push_back(root->val); - - if (root->left) { - generatePathSum(root->left, sum - root->val, v, result); - } - - if (root->right) { - generatePathSum(root->right, sum - root->val, v, result); + + if ( root->left==NULL && root->right==NULL) { + if (s == sum) result.push_back(v); + return; } + + generatePathSum(root->left, sum, s, v, result); + generatePathSum(root->right, sum, s, v, result); } }; diff --git a/algorithms/cpp/pathSum/pathSum.cpp b/algorithms/cpp/pathSum/pathSum.cpp index f019dee09..af2ec3e10 100644 --- a/algorithms/cpp/pathSum/pathSum.cpp +++ b/algorithms/cpp/pathSum/pathSum.cpp @@ -39,10 +39,16 @@ class Solution { srand(time(NULL)); } bool hasPathSum(TreeNode *root, int sum) { - if (random()%2){ - return hasPathSum1(root, sum); - } + return hasPathSum3(root, sum, 0); return hasPathSum2(root, sum); + return hasPathSum1(root, sum); + } + + bool hasPathSum3(TreeNode* root, int sum, int s) { + if ( root == NULL) return false; + s += root->val; + if ( !root->left && !root->right) return s == sum; + return (hasPathSum3(root->left, sum, s) || hasPathSum3(root->right, sum, s)); } bool hasPathSum1(TreeNode *root, int sum) { diff --git a/algorithms/cpp/peakIndexInAMountainArray/PeakIndexInAMountainArray.cpp b/algorithms/cpp/peakIndexInAMountainArray/PeakIndexInAMountainArray.cpp new file mode 100644 index 000000000..a1365b8e8 --- /dev/null +++ b/algorithms/cpp/peakIndexInAMountainArray/PeakIndexInAMountainArray.cpp @@ -0,0 +1,65 @@ +// Source : https://leetcode.com/problems/peak-index-in-a-mountain-array/description/ +// Author : Hao Chen +// Date : 2018-06-29 + +/*************************************************************************************** + * + * Let's call an array A a mountain if the following properties hold: + * + * + * A.length >= 3 + * There exists some 0 < i < A.length - 1 such that A[0] < A[1] < ... A[i-1] < + * A[i] > A[i+1] > ... > A[A.length - 1] + * + * + * Given an array that is definitely a mountain, return any i such that A[0] < A[1] < + * ... A[i-1] < A[i] > A[i+1] > ... > A[A.length - 1]. + * + * Example 1: + * + * + * Input: [0,1,0] + * Output: 1 + * + * + * + * Example 2: + * + * + * Input: [0,2,1,0] + * Output: 1 + * + * + * Note: + * + * + * 3 <= A.length <= 10000 + * 0 <= A[i] <= 10^6 + * A is a mountain, as defined above. + * + ***************************************************************************************/ + +class Solution { +public: + int peakIndexInMountainArray(vector& A) { + + // Put two dummy items at head and tail to avoid Out-of-Bound Error. + #define INT_MAX 2147483647 + #define INT_MIN (-INT_MAX - 1) + A.insert ( A.begin() , INT_MIN ); + A.push_back(INT_MIN); + + //binary search + int len = A.size(); + int left = 1, right = len - 2; + while(left <= right) { + int mid = left + (right - left)/2; //avoid integer overflow + if ( A[mid-1] < A[mid] && A[mid] > A[mid+1]) return mid-1; + if ( A[mid-1] < A[mid] && A[mid] < A[mid+1]) left = mid + 1; + if ( A[mid-1] > A[mid] && A[mid] > A[mid+1]) right = mid - 1; + + } + return -1; + } +}; + diff --git a/algorithms/cpp/perfectRectangle/PerfectRectangle.cpp b/algorithms/cpp/perfectRectangle/PerfectRectangle.cpp new file mode 100644 index 000000000..453020c6e --- /dev/null +++ b/algorithms/cpp/perfectRectangle/PerfectRectangle.cpp @@ -0,0 +1,80 @@ +// Source : https://leetcode.com/problems/perfect-rectangle/ +// Author : Hao Chen +// Date : 2016-09-08 + +/*************************************************************************************** + * + * Given N axis-aligned rectangles where N > 0, determine if they all together form an + * exact cover of a rectangular region. + * + * Each rectangle is represented as a bottom-left point and a top-right point. For + * example, a unit square is represented as [1,1,2,2]. (coordinate of bottom-left point + * is (1, 1) and top-right point is (2, 2)). + * + * Example 1: + * + * rectangles = [ + * [1,1,3,3], + * [3,1,4,2], + * [3,2,4,4], + * [1,3,2,4], + * [2,3,3,4] + * ] + * + * Return true. All 5 rectangles together form an exact cover of a rectangular region. + * + * Example 2: + * + * rectangles = [ + * [1,1,2,3], + * [1,3,2,4], + * [3,1,4,2], + * [3,2,4,4] + * ] + * + * Return false. Because there is a gap between the two rectangular regions. + * + * Example 3: + * + * rectangles = [ + * [1,1,3,3], + * [3,1,4,2], + * [1,3,2,4], + * [3,2,4,4] + * ] + * + * Return false. Because there is a gap in the top center. + * + * Example 4: + * + * rectangles = [ + * [1,1,3,3], + * [3,1,4,2], + * [1,3,2,4], + * [2,2,4,4] + * ] + * + * Return false. Because two of the rectangles overlap with each other. + ***************************************************************************************/ + + +class Solution { +public: + bool isRectangleCover(vector>& rectangles) { + unordered_map mp; + string corners[4]; + for(auto v: rectangles) + for(int i = 0; i<4; ++i){ + corners[i] = to_string(v[i/2*2]) + "," + to_string(v[(i%2)*2+1]); + if(mp[corners[i]] & int(pow(2,i))) return false; + else mp[corners[i]] |= int(pow(2,i)); + } + int corner = 0; + for(auto i=mp.begin(); i!=mp.end(); ++i){ + int val = i->second; + if(!(val & (val-1)) && (++corner >4)) return false; + if((val & (val-1)) && !(val == 3 || val==12 || val==10 || val==5 || val==15)) return false; + } + return true; + } +}; diff --git a/algorithms/cpp/powerOfFour/PowerOfFour.cpp b/algorithms/cpp/powerOfFour/PowerOfFour.cpp new file mode 100644 index 000000000..f66e6d9e2 --- /dev/null +++ b/algorithms/cpp/powerOfFour/PowerOfFour.cpp @@ -0,0 +1,37 @@ +// Source : https://leetcode.com/problems/power-of-four/ +// Author : Hao Chen +// Date : 2016-05-29 + +/*************************************************************************************** + * + * Given an integer (signed 32 bits), write a function to check whether it is a power + * of 4. + * + * Example: + * Given num = 16, return true. + * Given num = 5, return false. + * + * Follow up: Could you solve it without loops/recursion? + * + * Credits:Special thanks to @yukuairoy for adding this problem and creating all test + * cases. + ***************************************************************************************/ + + +class Solution { +public: + bool isPowerOfFour(int num) { + static int mask = 0b01010101010101010101010101010101; + + //edge case + if (num<=0) return false; + + // there are multiple bits are 1 + if ((num & num-1) != 0) return false; + + // check which one bit is zero, if the place is 1 or 3 or 5 or 7 or 9..., + // then it is the power of 4 + if ((num & mask) != 0) return true; + return false; + } +}; diff --git a/algorithms/cpp/powerOfThree/PowerOfThree.cpp b/algorithms/cpp/powerOfThree/PowerOfThree.cpp new file mode 100644 index 000000000..a75143b91 --- /dev/null +++ b/algorithms/cpp/powerOfThree/PowerOfThree.cpp @@ -0,0 +1,66 @@ +// Source : https://leetcode.com/problems/power-of-three/ +// Author : Hao Chen +// Date : 2016-01-14 + +/*************************************************************************************** + * + * Given an integer, write a function to determine if it is a power of three. + * + * Follow up: + * Could you do it without using any loop / recursion? + * + * Credits:Special thanks to @dietpepsi for adding this problem and creating all test + * cases. + * + ***************************************************************************************/ + +class Solution { + +public: + + bool isPowerOfThree(int n) { + return isPowerOfThree03(n); //140ms + return isPowerOfThree02(n);//130ms + return isPowerOfThree01(n); //140ms + return isPowerOfThree_loop(n); //136ms + return isPowerOfThree_recursive(n); //168ms + } + + bool isPowerOfThree03(int n) { + double logRes = log10(n)/log10(3); + return (logRes - int(logRes) == 0); + } + bool isPowerOfThree02(int n) { + return n>0 ? (1162261467%n==0) : false; + } + + void init(unordered_map& power ){ + int p = 1; + power[1]=true; + while(1){ + p *= 3; + power[p] = true; + if (p > INT_MAX/3) break; + + } + } + bool isPowerOfThree01(int n) { + static unordered_map power; + if (power.size()==0) init(power); + return power.find(n) != power.end(); + } + + bool isPowerOfThree_loop(int n) { + for(;n>0;n /= 3){ + if (n==1 || n==3) return true; + if (n%3 != 0) return false; + } + return false; + } + + bool isPowerOfThree_recursive(int n) { + if ( n == 1 || n == 3) return true; + if ( n==0 || n%3 != 0 ) return false; + return isPowerOfThree_recursive(n/3); + } +}; diff --git a/algorithms/cpp/queueReconstructionByHeight/QueueReconstructionByHeight.cpp b/algorithms/cpp/queueReconstructionByHeight/QueueReconstructionByHeight.cpp new file mode 100644 index 000000000..e648683a1 --- /dev/null +++ b/algorithms/cpp/queueReconstructionByHeight/QueueReconstructionByHeight.cpp @@ -0,0 +1,73 @@ +// Source : https://leetcode.com/problems/queue-reconstruction-by-height/ +// Author : Hao Chen +// Date : 2016-11-12 + +/*************************************************************************************** + * + * Suppose you have a random list of people standing in a queue. Each person is + * described by a pair of integers (h, k), where h is the height of the person and k is + * the number of people in front of this person who have a height greater than or equal + * to h. Write an algorithm to reconstruct the queue. + * + * Note: + * The number of people is less than 1,100. + * + * Example + * + * Input: + * [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]] + * + * Output: + * [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]] + ***************************************************************************************/ + +class Solution { + +public: + vector> reconstructQueue(vector>& people) { + //sort function + auto comp = [](const pair& p1, const pair& p2) + { return p1.first == p2.first ? p1.second < p2.second : p1.first > p2.first; }; + //sort the people with their height with descending order + // and if the height is same then sort by K with ascending order + sort(people.begin(), people.end(), comp); + + // For example: + // Original Queue: [7,0], [4,4], [7,1], [5,0], [6,1], [5,2] + // Sorted Queue: [7,0], [7,1], [6,1], [5,0], [5,2], [4,4] + + + // Why do we need to sort like this? + // + // ** The position of shorter people is ZERO impacted with higher people. ** + // + // and, the shortest people has no impacts to all of people. we can simpley insert it to the Kth position + // + // So, we sorted the people from highest to the shortest, then when we insert the people to another array, + // + // we always can guarantee the people is going to be inserted has nothing to do with the people has been inserted. + // + // Let's continue the about example above + // + // [7,0] => [] then [7,0] + // [7,1] => [7,0] then [7,0], [7,1] + // [6,1] => [7,0], [7,1] then [7,0], [6,1], [7,1] + // [5,0] => [7,0], [6,1], [7,1] then [5,0], [7,0], [6,1], [7,1] + // [5,2] => [5,0], [7,0], [6,1], [7,1] then [5,0], [7,0], [5,2], [6,1], [7,1] + // [4,4] => [5,0], [7,0], [5,2], [6,1], [7,1] then [5,0], [7,0], [5,2], [6,1], [4,4], [7,1] + // + // We alway can see, the people is going to be inserted has NO IMPACT with the current people. + // + // [6,1] => [7,0], [7,1] + // + // Whatever the people[6,1] placed, it has nothing to do with the people [7,0] [7,1], + // So, we can just insert the people to the place he like - the `Kth` place. + // + // + vector> res; + for (auto& p : people) { + res.insert(res.begin() + p.second, p); + } + return res; + } +}; diff --git a/algorithms/cpp/randomPickIndex/RandomPickIndex.cpp b/algorithms/cpp/randomPickIndex/RandomPickIndex.cpp new file mode 100644 index 000000000..f06f43ab3 --- /dev/null +++ b/algorithms/cpp/randomPickIndex/RandomPickIndex.cpp @@ -0,0 +1,54 @@ +// Source : https://leetcode.com/problems/random-pick-index/ +// Author : Hao Chen +// Date : 2016-11-04 + +/*************************************************************************************** + * + * Given an array of integers with possible duplicates, randomly output the index of a + * given target number. You can assume that the given target number must exist in the + * array. + * + * Note: + * The array size can be very large. Solution that uses too much extra space will not + * pass the judge. + * + * Example: + * + * int[] nums = new int[] {1,2,3,3,3}; + * Solution solution = new Solution(nums); + * + * // pick(3) should return either index 2, 3, or 4 randomly. Each index should have + * equal probability of returning. + * solution.pick(3); + * + * // pick(1) should return 0. Since in the array only nums[0] is equal to 1. + * solution.pick(1); + ***************************************************************************************/ + +class Solution { +private: + vector nums; +public: + Solution(vector nums) { + srand(time(0)); + this->nums = nums; + } + + int pick(int target) { + // we just randomly pick a number from the array, + // if the number is target just return the index. + // otherwise, keep picking the number randomly. + while(true) { + int idx = rand() % nums.size(); + if ( target == nums[idx] ) { + return idx; + } + } + } +}; + +/** + * Your Solution object will be instantiated and called as such: + * Solution obj = new Solution(nums); + * int param_1 = obj.pick(target); + */ diff --git a/algorithms/cpp/ransomNote/RansomNote.cpp b/algorithms/cpp/ransomNote/RansomNote.cpp new file mode 100644 index 000000000..c13922ea1 --- /dev/null +++ b/algorithms/cpp/ransomNote/RansomNote.cpp @@ -0,0 +1,38 @@ +// Source : https://leetcode.com/problems/ransom-note/ +// Author : Hao Chen +// Date : 2016-08-24 + +/*************************************************************************************** + * + * 
Given
 an 
arbitrary
 ransom
 note
 string 
and 
another 
string 
containing + * 
letters from
 all 
the 
magazines,
 write 
a 
function 
that 
will 
return 
true + * 
if 
the 
ransom 
 + * note 
can 
be 
constructed 
from 
the 
magazines ; 
otherwise, 
it 
will 
return + * 
false. 

 + * + * Each 
letter
 in
 the
 magazine 
string 
can
 only 
be
 used 
once
 in
 your + * 
ransom
 note. + * + * Note: + * You may assume that both strings contain only lowercase letters. + * + * canConstruct("a", "b") -> false + * canConstruct("aa", "ab") -> false + * canConstruct("aa", "aab") -> true + ***************************************************************************************/ + +class Solution { +public: + bool canConstruct(string ransomNote, string magazine) { + unordered_map m; + for(int i=0; i PEK, + b) JFK -> SHA -> JFK -> PEK + The a) is smaller than b), because PEK < SHA, however the b) is correct answer. + So, it means we need use all of tickets. + + 2) [["JFK", "PEK"], ["JFK", "SHA"]], which also has two itineraries: + a) JFK -> PEK + b) JFK -> SHA + for my understanding, the JFK -> SHA is the correct one, + however, the correct answer is JFK -> SHA -> PEK. + I don't understand, why the correct answer is not JFK -> PEK -> SHA + That really does not make sense to me. + + All right, we need assume all of the tickets can be connected in one itinerary. + Then, it's easy to have a DFS algorithm. +*/ + + +class Solution { +public: + //DFS + void travel(string& start, unordered_map>& map, vector& result) { + while (map[start].size() > 0 ) { + string next = *(map[start].begin()); + map[start].erase(map[start].begin()); + travel(next, map, result); + } + result.insert(result.begin(), start); + } + + vector findItinerary(vector> tickets) { + unordered_map> map; + for(auto t : tickets) { + map[t.first].insert(t.second); + } + vector result; + string start = "JFK"; + travel(start, map, result); + return result; + } +}; diff --git a/algorithms/cpp/recoverATreeFromPreorderTraversal/recoverATreeFromPreorderTraversal.cpp b/algorithms/cpp/recoverATreeFromPreorderTraversal/recoverATreeFromPreorderTraversal.cpp new file mode 100644 index 000000000..eabe784b2 --- /dev/null +++ b/algorithms/cpp/recoverATreeFromPreorderTraversal/recoverATreeFromPreorderTraversal.cpp @@ -0,0 +1,106 @@ +// Source : https://leetcode.com/problems/recover-a-tree-from-preorder-traversal/ +// Author : Ahmed Morsy +// Date : 2019-05-29 +// source : https://leetcode.com/problems/recover-a-tree-from-preorder-traversal/ +/***************************************************************************************************** + * + * We run a preorder depth first search on the root of a binary tree. + * + * At each node in this traversal, we output D dashes (where D is the depth of this node), then we + * output the value of this node. (If the depth of a node is D, the depth of its immediate child is + * D+1. The depth of the root node is 0.) + * + * If a node has only one child, that child is guaranteed to be the left child. + * + * Given the output S of this traversal, recover the tree and return its root. + * + * Example 1: + * + * Input: "1-2--3--4-5--6--7" + * Output: [1,2,5,3,4,6,7] + * + * Example 2: + * + * Input: "1-2--3---4-5--6---7" + * Output: [1,2,5,3,null,6,null,4,null,7] + * + * Example 3: + * + * Input: "1-401--349---90--88" + * Output: [1,401,null,349,88,90] + * + * Note: + * + * The number of nodes in the original tree is between 1 and 1000. + * Each node will have a value between 1 and 10^9. + * + ******************************************************************************************************/ + +/* Definition for a binary tree node. + struct TreeNode { + int val; + TreeNode *left; + TreeNode *right; + TreeNode(int x) : val(x), left(NULL), right(NULL) {} + }; +*/ + + +class Solution { +public: + + TreeNode* recoverFromPreorder(string S) { + vectorvalues,depth; + int cur_val = 0 , cur_depth = 0; + bool dash = false; + for(char s : S){ + if(s == '-'){ + if(!dash){ + values.push_back(cur_val); + depth.push_back(cur_depth); + cur_depth = 0; + cur_val = 0; + } + dash = true; + cur_depth++; + } + else{ + dash = false; + cur_val *= 10; + cur_val += s-'0'; + } + } + values.push_back(cur_val); + depth.push_back(cur_depth); + + unordered_mapdepths; + + + int ptr = 1; + TreeNode *root = new TreeNode(values[0]); + depths[root] = 0; + stackst; + st.push(root); + + while(ptr < (int)values.size()){ + TreeNode *cur = st.top(); + if(depth[ptr] == depths[cur]+1 && (cur->left == NULL || cur->right == NULL)){ + TreeNode *t = new TreeNode(values[ptr++]); + depths[t] = depths[cur]+1; + if(cur->left == NULL){ + cur->left = t; + } + else{ + cur->right = t; + } + st.push(t); + } + else{ + st.pop(); + } + } + return root; + + } +}; + diff --git a/algorithms/cpp/removeDuplicateLetters/RemoveDuplicateLetters.cpp b/algorithms/cpp/removeDuplicateLetters/RemoveDuplicateLetters.cpp new file mode 100644 index 000000000..e3ae9f3f4 --- /dev/null +++ b/algorithms/cpp/removeDuplicateLetters/RemoveDuplicateLetters.cpp @@ -0,0 +1,52 @@ +// Source : https://leetcode.com/problems/remove-duplicate-letters/ +// Author : Hao Chen +// Date : 2017-01-02 + +/*************************************************************************************** + * + * Given a string which contains only lowercase letters, remove duplicate letters so + * that every letter appear once and only once. You must make sure your result is the + * smallest in lexicographical order among all possible results. + * + * Example: + * + * Given "bcabc" + * Return "abc" + * + * Given "cbacdcbc" + * Return "acdb" + * + * Credits:Special thanks to @dietpepsi for adding this problem and creating all test + * cases. + ***************************************************************************************/ + + +class Solution { +public: + string removeDuplicateLetters(string s) { + const int ASCII_LEN = 256; + int counter[ASCII_LEN] = {0}; + bool visited[ASCII_LEN] = {false}; + + for (char ch : s) { + counter[ch]++; + } + + string result; + for (char ch : s) { + counter[ch]--; + // if the current `ch` has already put into the result. + if (visited[ch]) continue; + + // if the current `ch` is smaller than the last one char in result. + // and we still have duplicated last-one char behind, so we can remove the current one. + while ( !result.empty() && ch < result.back() && counter[result.back()] ) { + visited[result.back()] = false; + result.pop_back(); + } + result.push_back(ch); + visited[ch] = true; + } + return result; + } +}; diff --git a/algorithms/cpp/removeKDigits/RemoveKDigits.cpp b/algorithms/cpp/removeKDigits/RemoveKDigits.cpp new file mode 100644 index 000000000..9b33cf5c4 --- /dev/null +++ b/algorithms/cpp/removeKDigits/RemoveKDigits.cpp @@ -0,0 +1,107 @@ +// Source : https://leetcode.com/problems/remove-k-digits/ +// Author : Hao Chen +// Date : 2016-11-11 + +/*************************************************************************************** + * + * Given a non-negative integer num represented as a string, remove k digits from the + * number so that the new number is the smallest possible. + * + * Note: + * + * The length of num is less than 10002 and will be ≥ k. + * The given num does not contain any leading zero. + * + * Example 1: + * + * Input: num = "1432219", k = 3 + * Output: "1219" + * Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which + * is the smallest. + * + * Example 2: + * + * Input: num = "10200", k = 1 + * Output: "200" + * Explanation: Remove the leading 1 and the number is 200. Note that the output must + * not contain leading zeroes. + * + * Example 3: + * + * Input: num = "10", k = 2 + * Output: "0" + * Explanation: Remove all the digits from the number and it is left with nothing which + * is 0. + ***************************************************************************************/ + +class Solution { +public: + string removeKdigits_pick(string& num, int k) { + + int len = num.size(); + string result; + + int idx = 0; + for (int i=0; i < len - k; i++) { + int min_idx = idx; + for (int j=min_idx; j<=i+k; j++) { + if (num[min_idx] > num[j]) min_idx = j; + } + + //don't put zero at the beginning + if ( !(result.empty() && num[min_idx]=='0') ){ + result.push_back(num[min_idx]); + } + + //select the number started from next one, to make the order correctness. + idx = min_idx + 1; + } + + if (result.empty()) result = "0"; + return result; + } + + string removeKdigits_remove(string& num, int k) { + if ( num.size() <= k ) return "0"; + int left_len = num.size() - k; + int idx = 0; + for (int i=0; i num[j+1] ) { + num.erase(j, 1); + idx = j; + break; + } + } + } + + //remove all of ZEROs at the beginning. + for (int i=0; i<= num.size(); i++) { + if (num[i] != '0' || i == num.size()) { + num.erase(0, i); + break; + } + } + + // if the digits in the array are sorted, + // then, we need remove the digits at the ends. + if (num.size() > left_len ) { + num.erase(num.begin() + left_len, num.end()); + } + + if (num.empty()) num = "0"; + return num; + } + + string removeKdigits(string num, int k) { + srand(time(0)); + if (rand() % 2 ) { + return removeKdigits_pick(num, k); + } else { + return removeKdigits_remove(num, k); + } + } +}; diff --git a/algorithms/cpp/reverseString/ReverseString.cpp b/algorithms/cpp/reverseString/ReverseString.cpp new file mode 100644 index 000000000..c0f41088b --- /dev/null +++ b/algorithms/cpp/reverseString/ReverseString.cpp @@ -0,0 +1,24 @@ +// Source : https://leetcode.com/problems/reverse-string/ +// Author : Hao Chen +// Date : 2016-05-29 + +/*************************************************************************************** + * + * Write a function that takes a string as input and returns the string reversed. + * + * Example: + * Given s = "hello", return "olleh". + ***************************************************************************************/ + +class Solution { +public: + string reverseString(string s) { + int len = s.size(); + for (int i=0; i vowels; + set vows; + vows.insert('a'); + vows.insert('A'); + vows.insert('e'); + vows.insert('E'); + vows.insert('i'); + vows.insert('I'); + vows.insert('o'); + vows.insert('O'); + vows.insert('u'); + vows.insert('U'); + string result; + for(int i = 0; i < s.size(); i++) + { + if(vows.find(s[i]) != vows.end()) + vowels.push_back(s[i]); + } + for(int i = 0; i < s.size(); i++) + { + if(vows.find(s[i]) != vows.end()) + { + result.push_back(vowels.back()); + vowels.pop_back(); + } + else + result.push_back(s[i]); + } + return result; + } +}; + + +// Author: Hao Chen +// 1) preset a dictionary table to look up vowels +// 2) we have two pointer, the `left` one search vowels from the beginning to then end, the `right` one search from the end to the beginning. +// 3) swap the left one and the right one until left >= right. +class Solution { +private: + bool vowelsTable[256]; +public: + Solution(){ + memset(vowelsTable, 0, sizeof(vowelsTable)); + vowelsTable['a']=true; + vowelsTable['e']=true; + vowelsTable['i']=true; + vowelsTable['o']=true; + vowelsTable['u']=true; + + vowelsTable['A']=true; + vowelsTable['E']=true; + vowelsTable['I']=true; + vowelsTable['O']=true; + vowelsTable['U']=true; + } + bool isVowels(char ch) { + return vowelsTable[ch]; + } + string reverseVowels(string s) { + int left=0, right=s.size()-1; + while ( left < right ) { + while( !isVowels( s[left]) ) left++; + while( !isVowels( s[right] ) ) right--; + if (left >= right) break; + swap(s[left], s[right]); + left++; right--; + } + return s; + } +}; diff --git a/algorithms/cpp/reverseWordsInAString/reverseWordsInAString.cpp b/algorithms/cpp/reverseWordsInAString/reverseWordsInAString.cpp index b3f4d6147..89edd1062 100644 --- a/algorithms/cpp/reverseWordsInAString/reverseWordsInAString.cpp +++ b/algorithms/cpp/reverseWordsInAString/reverseWordsInAString.cpp @@ -1,5 +1,5 @@ // Source : https://oj.leetcode.com/problems/reverse-words-in-a-string/ -// Author : Hao Chen +// Author : Hao Chen, Siwei Xu // Date : 2014-06-16 /********************************************************************************** @@ -24,9 +24,13 @@ **********************************************************************************/ #include +#include +#include +#include #include #include #include +#include // for std::reverse using namespace std; void reverseWords(string &s) { @@ -71,7 +75,82 @@ void reverseWords(string &s) { } cout << "[" << s << "]" < -- Handwaving +void reverseWords2(string &s) { + if (s.length() == 0) return; + + string result = ""; + if (s[s.length()-1] == ' ') { + int last = s.find_last_not_of(' ') + 1; + s.erase(last, s.length() - last); + } + + int first = s.find_first_not_of(' ', 0); + while (first != string::npos) { + int wend = s.find(' ', first); // word end + if (wend == string::npos) wend = s.length(); + + string word = s.substr(first, wend - first); + reverse(word.begin(), word.end()); + result += word; + + first = s.find_first_not_of(' ', wend); // next word + if (first == string::npos) break; + + result += ' '; + } + reverse(result.begin(), result.end()); + s.swap(result); +} + + +// C solution in O(1) space +void reverse(char *b, char *e) { + for (--e; e - b > 0; b++, e--) { + char t = *b; + *b = *e; + *e = t; + } +} + +void reverseWords(char *s) { + char *p = s, *ws = NULL, *last = s; + + while (*p && *p == ' ') p++; // skip leading space + ws = p; + + for ( ; *p; p++) { + while (*p && *p != ' ') p++; // find word end + + reverse(ws, p); + strncpy(last, ws, p-ws); + last += (p-ws); + + while (*p && *p == ' ') p++; // for next word + ws = p; + + if (*p == '\0') break; + *last++ = ' '; + } + reverse(s, last); + *last = '\0'; +} + +void test() { +#define TEST(str) do { \ + char* s = strdup(str); \ + printf("\"%s\" => ", s); \ + reverseWords(s); \ + printf("\"%s\"\n\n", s); \ + free(s); \ + } while (0) + + TEST(" the blue sky is blue "); + TEST(" "); +} + + main() { string s; @@ -85,4 +164,5 @@ main() s="i love cpp"; reverseWords(s); + test(); } diff --git a/algorithms/cpp/rotateFunction/RotateFunction.cpp b/algorithms/cpp/rotateFunction/RotateFunction.cpp new file mode 100644 index 000000000..c8897dd27 --- /dev/null +++ b/algorithms/cpp/rotateFunction/RotateFunction.cpp @@ -0,0 +1,75 @@ +// Source : https://leetcode.com/problems/rotate-function/ +// Author : Hao Chen +// Date : 2016-11-03 + +/*************************************************************************************** + * + * Given an array of integers A and let n to be its length. + * + * Assume Bk to be an array obtained by rotating the array A k positions clock-wise, we + * define a "rotation function" F on A as follow: + * + * F(k) = 0 * Bk[0] + 1 * Bk[1] + ... + (n-1) * Bk[n-1]. + * + * Calculate the maximum value of F(0), F(1), ..., F(n-1). + * + * Note: + * n is guaranteed to be less than 105. + * + * Example: + * + * A = [4, 3, 2, 6] + * + * F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25 + * F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16 + * F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23 + * F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26 + * + * So the maximum value of F(0), F(1), F(2), F(3) is F(3) = 26. + ***************************************************************************************/ + + +// +// Asumming we have 4 numbers: a, b, c, d, then +// F(0) = 0a + 1b + 2c + 3d +// F(1) = 3a + 0b + 1c + 2d +// F(2) = 2a + 3b + 0c + 1d +// F(3) = 1a + 2b + 3c + 0d +// +// We can see how F(n) transfrom to F(n+1) +// F(0) - F(1) = -3a + b + c + d +// F(1) - F(2) = a + -3b + c + d +// F(2) - F(3) = a + b + -3c + d +// F(3) - F(0) = a + b + c + -3d +// +// So, we can tansfrom to the following experssion: +// +// F(1) = F(0) - (a+b+c+d) + 4a +// F(2) = F[1] - (a+b+c+d) + 4b +// F(3) = F[2] - (a+b+c+d) + 4c +// +// Then, we can see this fomular: +// +// F(n) = F(n-1) - sum(array) + len(array) * array[n-1] +// +class Solution { +public: + int maxRotateFunction(vector& A) { + int sum = 0; + int F = 0; + for (int i=0; i < A.size(); i++) { + sum += A[i]; + F += (i * A[i]); + } + int maxF = F; + int len = A.size(); + //cout << "F(0) = " << maxF <& equations) { + for (auto e : equations ) { + if (e[1] == '=' && e[0] != e[3]) { // equal + join(e[0], e[3]); + } + } + for (auto e : equations) { + if (e[1] == '!' && (e[0] == e[3] || find(e[0]) == find(e[3]) ) ) { + return false; + } + } + return true; + } +}; + + diff --git a/algorithms/cpp/search2DMatrix/search2DMatrix.II.cpp b/algorithms/cpp/search2DMatrix/search2DMatrix.II.cpp index b9ed7e441..dad85a35c 100644 --- a/algorithms/cpp/search2DMatrix/search2DMatrix.II.cpp +++ b/algorithms/cpp/search2DMatrix/search2DMatrix.II.cpp @@ -34,7 +34,6 @@ class Solution { public: - bool binary_search(vector &v, int target) { int low = 0; int high = v.size()-1; @@ -52,8 +51,9 @@ class Solution { } //using binary_search() to search each rows - slow O(n*log(n)) - //the run time is around 840ms for all test case + //the run time is around 140ms for all test case bool searchMatrix01(vector>& matrix, int target) { + if (matrix.size() == 0 || matrix[0].size()==0) return false; for (int i=0; i>& matrix, int target) { if (matrix.size() == 0 || matrix[0].size()==0) return false; int row=0, col = matrix[0].size() - 1; @@ -82,7 +80,7 @@ class Solution { return false; } - //a bit optimization for methed 2 - the run time is 300ms + //a bit optimization for methed 2 - the run time is 68ms bool searchMatrix021(vector>& matrix, int target) { if (matrix.size() == 0 || matrix[0].size()==0) return false; int row=0, col = matrix[0].size() - 1; @@ -91,7 +89,7 @@ class Solution { while ( col>=0 && target < matrix[row][col]) { col--; } - while(row < matrix.size() && target > matrix[row][col]){ + while(col >=0 && row < matrix.size() && target > matrix[row][col]){ row++; } @@ -100,7 +98,7 @@ class Solution { } //Optimization: using binary search methed to move `low` and `row` - //however, the run time is around 830ms + //However, the run time is 112ms bool searchMatrix022(vector>& matrix, int target) { if (matrix.size() == 0 || matrix[0].size()==0) return false; @@ -116,23 +114,24 @@ class Solution { int mid = start + (end - start)/2; if (target == matrix[row][mid]) return true; if (target > matrix[row][mid]) { - col = start = mid + 1; + start = mid + 1; }else { - col = end = mid - 1; + end = mid - 1; } } - + col = end; }else{ - int start=0, end=row; + int start=row, end=matrix.size()-1; while(start<=end){ int mid = start + (end - start)/2; if (target == matrix[mid][col]) return true; if (target > matrix[mid][col]) { - row = start = mid + 1; + start = mid + 1; }else{ - row = end = mid -1; + end = mid -1; } } + row = start; } } @@ -141,11 +140,9 @@ class Solution { bool searchMatrix(vector>& matrix, int target) { - - return searchMatrix022(matrix, target); //840ms ?? - return searchMatrix021(matrix, target); //320ms - return searchMatrix02(matrix, target); //340ms - - return searchMatrix01(matrix, target); // 840ms + return searchMatrix022(matrix, target); //112ms + return searchMatrix021(matrix, target); //68ms + return searchMatrix02(matrix, target); //64ms + return searchMatrix01(matrix, target); //148ms } }; diff --git a/algorithms/cpp/sentenceScreenFitting/main.cpp b/algorithms/cpp/sentenceScreenFitting/main.cpp new file mode 100644 index 000000000..b713ec859 --- /dev/null +++ b/algorithms/cpp/sentenceScreenFitting/main.cpp @@ -0,0 +1,45 @@ +// +// main.cpp +// LeeteCodeOJ#418 +// +// Created by Wang Yi on 25/10/16. +// Copyright (c) 2016 Wang Yi. All rights reserved. +// + +#include +#include +#include +#include +#include +#include "sentenceScreenFitting.h" +#define N 100 +#define M 10 + +using std::vector; + +int main(int argc, const char * argv[]) { + int rows, cols, ret; +// int i=0; +// char stc[N][M]; + vector sentence; + std::string word; + std::string line; + std::stringstream numbers, split; + + std::getline(std::cin, line); + numbers << line; + numbers >> rows >> cols; + std::getline(std::cin, line); + split << line; + + while (split >> word){ + sentence.push_back(word); +// strcpy(stc[i++], word.c_str()); + } + + Solution solution; + ret = solution.wordsTyping(sentence, rows, cols); +// ret = SentenceScreenFitting(stc, rows, cols, i); + std::cout << ret << std::endl; + return 0; +} diff --git a/algorithms/cpp/sentenceScreenFitting/sentenceScreenFitting.cpp b/algorithms/cpp/sentenceScreenFitting/sentenceScreenFitting.cpp new file mode 100644 index 000000000..b6d7542b8 --- /dev/null +++ b/algorithms/cpp/sentenceScreenFitting/sentenceScreenFitting.cpp @@ -0,0 +1,197 @@ +// +// OJ#418.cpp +// LeeteCodeOJ#418 +// +// Created by Wang Yi on 25/10/16. +// Copyright (c) 2016 Wang Yi. All rights reserved. +// + + +/********************************************************************************** + * + * Given a rows x cols screen and a sentence represented by a list of words, find + * how many times the given sentence can be fitted on the screen. + * + * Note: + * + * A word cannot be split into two lines. + * The order of words in the sentence must remain unchanged. + * Two consecutive words in a line must be separated by a single space. + * Total words in the sentence won't exceed 100. + * Length of each word won't exceed 10. + * 1 ≤ rows, cols ≤ 20,000. + * + * + * + * Example 1: + * + * Input: + * rows = 2, cols = 8, sentence = ["hello", "world"] + * + * Output: + * 1 + * + * Explanation: + * hello--- + * world--- + * + * The character '-' signifies an empty space on the screen. + * + * + * + * Example 2: + * + * Input: + * rows = 3, cols = 6, sentence = ["a", "bcd", "e"] + * + * Output: + * 2 + * + * Explanation: + * a-bcd- + * e-a--- + * bcd-e- + * + * The character '-' signifies an empty space on the screen. + * + * + * + * Example 3: + * + * Input: + * rows = 4, cols = 5, sentence = ["I", "had", "apple", "pie"] + * + * Output: + * 1 + * + * Explanation: + * I-had + * apple + * pie-I + * had-- + * + * The character '-' signifies an empty space on the screen. + * + * *********************************************************************************/ + + +#include "sentenceScreenFitting.h" +#include +#include +#include +#define FOR(START, END) for((START)=0;(START)<(END);(START)+=1) { +#define END ;} +#define N 100 + +// first brute force solution +int SentenceScreenFitting(char stc[][M], int row, int col, size_t l) +{ + int i, j, t, s, k=0, ret=0; + int len[N] = {0}; + FOR(i, l) len[i] = (int)strlen(stc[i]) END + + FOR(i, row) + j = col; + t = k; + while (j - len[k] >= 0) { + j -= len[k] + 1; + if (k+1 > l-1){ + FOR(s, k-t) std::cout << stc[t+s] << ' ' END; + std::cout << stc[t+s]; + if (j - len[0] >= 0) + std::cout << ' '; + k = 0; + t = 0; + ret++; + } else{ + k++; + } + } + FOR(s, k-t-1) std::cout << stc[t+s] << ' ' END; + if (k-t > 0) + std::cout << stc[t+s]; + + std::cout << std::setfill ('-') << std::setw(j == col ? col:j+1) << "" << std::endl; + END + + return ret; +} + +/* +int Solution::wordsTyping(vector& sentence, int rows, int cols) +{ + int i, j, t, s, k=0, ret=0, l=(int)sentence.size(); + int len[N] = {0}; + FOR(i, l) len[i] = (int)sentence[i].size() END + + FOR(i, rows) + j = cols; + t = k; + while (j - len[k] >= 0) { + j -= len[k] + 1; + if (k+1 > l-1){ +// FOR(s, k-t) std::cout << sentence[t+s] << ' ' END; +// std::cout << sentence[t+s]; +// if (j - len[0] >= 0) +// std::cout << ' '; + k = 0; + t = 0; + ret++; + } else{ + k++; + } + } +// FOR(s, k-t-1) std::cout << sentence[t+s] << ' ' END; +// if (k-t > 0) +// std::cout << sentence[t+s]; +// +// std::cout << std::setfill ('-') << std::setw(j == cols ? cols:j+1) << "" << std::endl; + END + + return ret; +} +*/ + +// second boosting +int Solution::wordsTyping(vector& sentence, int rows, int cols) +{ + int i, j, k=0, ret=0, l=(int)sentence.size(); +// int t, s; + int jump = 0; + int len[N] = {0}; + FOR(i, l) len[i] = (int)sentence[i].size();jump += len[i] END + jump += l; + + FOR(i, rows) + j = cols; +// t = k; + + if (k == 0){ + ret += j / jump; + j = j % jump; + } + + while (j - len[k] >= 0) { + j -= len[k] + 1; + if (k+1 > l-1){ + // FOR(s, k-t) std::cout << sentence[t+s] << ' ' END; + // std::cout << sentence[t+s]; + // if (j - len[0] >= 0) + // std::cout << ' '; + k = 0; +// t = 0; + ret += j / jump + 1; + j = j % jump; + } else { + k++; + } + } + // FOR(s, k-t-1) std::cout << sentence[t+s] << ' ' END; + // if (k-t > 0) + // std::cout << sentence[t+s]; + // + // std::cout << std::setfill ('-') << std::setw(j == cols ? cols:j+1) << "" << std::endl; + END + + return ret; +} diff --git a/algorithms/cpp/sentenceScreenFitting/sentenceScreenFitting.h b/algorithms/cpp/sentenceScreenFitting/sentenceScreenFitting.h new file mode 100644 index 000000000..e3a3523cb --- /dev/null +++ b/algorithms/cpp/sentenceScreenFitting/sentenceScreenFitting.h @@ -0,0 +1,28 @@ +// +// OJ#418.h +// LeeteCodeOJ#418 +// +// Created by Wang Yi on 25/10/16. +// Copyright (c) 2016 Wang Yi. All rights reserved. +// + +#ifndef __LeeteCodeOJ_418__OJ_418__ +#define __LeeteCodeOJ_418__OJ_418__ + +#define M 10 + +#include +#include +#include + +using std::vector; +using std::string; + +int SentenceScreenFitting(char stc[][M], int row, int col, size_t l); + +class Solution { +public: + int wordsTyping(vector& sentence, int rows, int cols); +}; + +#endif /* defined(__LeeteCodeOJ_418__OJ_418__) */ diff --git a/algorithms/cpp/shuffleAnArray/ShuffleAnArray.cpp b/algorithms/cpp/shuffleAnArray/ShuffleAnArray.cpp new file mode 100644 index 000000000..681a77519 --- /dev/null +++ b/algorithms/cpp/shuffleAnArray/ShuffleAnArray.cpp @@ -0,0 +1,59 @@ +// Source : https://leetcode.com/problems/shuffle-an-array/ +// Author : Hao Chen +// Date : 2016-08-24 + +/*************************************************************************************** + * + * Shuffle a set of numbers without duplicates. + * + * Example: + * + * // Init an array with set 1, 2, and 3. + * int[] nums = {1,2,3}; + * Solution solution = new Solution(nums); + * + * // Shuffle the array [1,2,3] and return its result. Any permutation of [1,2,3] must + * equally likely to be returned. + * solution.shuffle(); + * + * // Resets the array back to its original configuration [1,2,3]. + * solution.reset(); + * + * // Returns the random shuffling of array [1,2,3]. + * solution.shuffle(); + ***************************************************************************************/ + +class Solution { +public: + Solution(vector nums) : _nums(nums), _solution(nums) { + srand(time(NULL)); + } + + /** Resets the array to its original configuration and return it. */ + vector reset() { + return _solution = _nums; + } + + /** Returns a random shuffling of the array. */ + vector shuffle() { + //Fisher Yates + //https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle + + int i = _solution.size(); + + while ( --i > 0 ) { + int j = rand() % (i+1); + swap(_solution[i], _solution[j]); + } + return _solution; + } +private: + vector _nums, _solution; +}; + +/** + * Your Solution object will be instantiated and called as such: + * Solution obj = new Solution(nums); + * vector param_1 = obj.reset(); + * vector param_2 = obj.shuffle(); + */ diff --git a/algorithms/cpp/singleNumber/singleNumber.III.cpp b/algorithms/cpp/singleNumber/singleNumber.III.cpp new file mode 100644 index 000000000..d2f86bd52 --- /dev/null +++ b/algorithms/cpp/singleNumber/singleNumber.III.cpp @@ -0,0 +1,94 @@ +// Source : https://leetcode.com/problems/single-number-iii/ +// Author : Hao Chen +// Date : 2016-01-16 + +/*************************************************************************************** + * + * Given an array of numbers nums, in which exactly two elements appear only once and + * all the other elements appear exactly twice. Find the two elements that appear only + * once. + * + * For example: + * + * Given nums = [1, 2, 1, 3, 2, 5], return [3, 5]. + * + * Note: + * + * The order of the result is not important. So in the above example, [5, 3] is also + * correct. + * Your algorithm should run in linear runtime complexity. Could you implement it using + * only constant space complexity? + * + * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating + * all test cases. + ***************************************************************************************/ + + +/* + * For the problem - only one number appears once when all other numbers appears exactly twice. + * + * We know, we can XOR all of the array elements. Since X^X is zero, and X^0 is X, + * so all of the duplicated number will zero themselves out, and the only number would be the result. + * + * However, this solution cannot be applied directly to finding two numbers that appear once each. + * + * Suppose that these numbers that appear once are X and Y, and all other numbers appear twice. + * If we decide to XOR all the array's elements, the overall result would actually be `X^Y`. + * + * Unfortunately, there is no way to extract J and K out of their XOR. + * + * But since X and Y are different, we are sure that X^Y is different than zero. + * + * This information is valuable in sense that we know pieces of information that differ. + * If we pick up any bit that is 1 in X XOR Y, we can use it as a mask to test each element of the array. + * + * Obviously, that mask will be the discriminator between X and Y - + * + * Only one of them will have value 1 at that particular position. + * + * + * Now that we have the mask with exactly one bit set to 1, we can walk through the array once again. + * + * But this time we are going to maintain two XORed results. + * + * - One for numbers that have bit 1 at the mask's position + * - Another for numbers that have bit 0 at that position + * + * In this way, we are sure that all duplicates will go into the same pile. + * + * But likewise, we are sure that X and Y will go into separate piles. + * + * So, the overall result is that + * - the first XORed result will be equal to X + * - and the second XORed result will be equal to Y + * +*/ + +class Solution { +public: + vector singleNumber(vector& nums) { + int allxor = 0; + for (int n : nums) { + allxor ^= n; + } + int mask = 1; + while ( (mask & allxor) == 0 ) { + mask <<= 1; + } + + int zero = 0; + int one = 0; + for (int n : nums) { + if (n & mask ){ + one ^= n; + }else { + zero ^= n; + } + } + + vector result; + result.push_back(zero); + result.push_back(one); + return result; + } +}; diff --git a/algorithms/cpp/smallestStringStartingFromLeaf/SmallestStringStartingFromLeaf.cpp b/algorithms/cpp/smallestStringStartingFromLeaf/SmallestStringStartingFromLeaf.cpp new file mode 100644 index 000000000..a6b25b9f4 --- /dev/null +++ b/algorithms/cpp/smallestStringStartingFromLeaf/SmallestStringStartingFromLeaf.cpp @@ -0,0 +1,69 @@ +// Source : https://leetcode.com/problems/smallest-string-starting-from-leaf/ +// Author : Hao Chen +// Date : 2019-02-05 + +/***************************************************************************************************** + * + * Given the root of a binary tree, each node has a value from 0 to 25 representing the letters 'a' to + * 'z': a value of 0 represents 'a', a value of 1 represents 'b', and so on. + * + * Find the lexicographically smallest string that starts at a leaf of this tree and ends at the root. + * + * (As a reminder, any shorter prefix of a string is lexicographically smaller: for example, "ab" is + * lexicographically smaller than "aba". A leaf of a node is a node that has no children.) + * + * Example 1: + * + * Input: [0,1,2,3,4,3,4] + * Output: "dba" + * + * Example 2: + * + * Input: [25,1,3,1,3,0,2] + * Output: "adz" + * + * Example 3: + * + * Input: [2,2,1,null,1,0,null,0] + * Output: "abc" + * + * Note: + * + * The number of nodes in the given tree will be between 1 and 1000. + * Each node in the tree will have a value between 0 and 25. + * + ******************************************************************************************************/ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode(int x) : val(x), left(NULL), right(NULL) {} + * }; + */ +class Solution { +public: + string smallestFromLeaf(TreeNode* root) { + string str, result="{"; //'z'+1; + smallestFromLeafHelper(root, str, result); + return result; + } + + void smallestFromLeafHelper(TreeNode* root, string str, string& result) { + if (root->left == NULL && root->right == NULL) { + str.insert(0, 1, char(root->val+'a')); + result = min(result, str); + return; + } + + str.insert(0, 1, char(root->val+'a')); + + if (root->left) { + smallestFromLeafHelper(root->left, str, result); + } + if (root->right) { + smallestFromLeafHelper(root->right, str, result); + } + } +}; diff --git a/algorithms/cpp/sortArrayByParity/SortArrayByParity.II.cpp b/algorithms/cpp/sortArrayByParity/SortArrayByParity.II.cpp new file mode 100644 index 000000000..5084e030f --- /dev/null +++ b/algorithms/cpp/sortArrayByParity/SortArrayByParity.II.cpp @@ -0,0 +1,47 @@ +// Source : https://leetcode.com/problems/sort-array-by-parity-ii/ +// Author : Hao Chen +// Date : 2019-03-26 + +/***************************************************************************************************** + * + * Given an array A of non-negative integers, half of the integers in A are odd, and half of the + * integers are even. + * + * Sort the array so that whenever A[i] is odd, i is odd; and whenever A[i] is even, i is even. + * + * You may return any answer array that satisfies this condition. + * + * Example 1: + * + * Input: [4,2,5,7] + * Output: [4,5,2,7] + * Explanation: [4,7,2,5], [2,5,4,7], [2,7,4,5] would also have been accepted. + * + * Note: + * + * 2 <= A.length <= 20000 + * A.length % 2 == 0 + * 0 <= A[i] <= 1000 + * + ******************************************************************************************************/ + +class Solution { +public: + bool isEven(int &x) { + return x % 2 == 0; + } + vector sortArrayByParityII(vector& A) { + //two pointer, `even` and `odd`, + // - `even` pointer step into even position + // - `odd` pointer step into odd position. + // if `even` points to odd number, and `odd` points to even number switch them. + int even = 0; + int odd = 1; + while(even < A.size() && odd < A.size() ) { + if ( !isEven(A[even]) && isEven(A[odd]) ) swap( A[even], A[odd] ); + if ( isEven(A[even]) ) even += 2; + if ( !isEven(A[odd]) ) odd += 2; + } + return A; + } +}; diff --git a/algorithms/cpp/sortArrayByParity/SortArrayByParity.cpp b/algorithms/cpp/sortArrayByParity/SortArrayByParity.cpp new file mode 100644 index 000000000..969edf19d --- /dev/null +++ b/algorithms/cpp/sortArrayByParity/SortArrayByParity.cpp @@ -0,0 +1,41 @@ +// Source : https://leetcode.com/problems/sort-array-by-parity/ +// Author : Hao Chen +// Date : 2019-03-26 + +/***************************************************************************************************** + * + * Given an array A of non-negative integers, return an array consisting of all the even elements of + * A, followed by all the odd elements of A. + * + * You may return any answer array that satisfies this condition. + * + * Example 1: + * + * Input: [3,1,2,4] + * Output: [2,4,3,1] + * The outputs [4,2,3,1], [2,4,1,3], and [4,2,1,3] would also be accepted. + * + * Note: + * + * 1 <= A.length <= 5000 + * 0 <= A[i] <= 5000 + * + ******************************************************************************************************/ + +class Solution { +public: + bool isEven(int& x) { + return x % 2 == 0; + } + vector sortArrayByParity(vector& A) { + //two pointer, one from left to right, another from right to left + // if left is odd number and right is even number, switch them + int l=0, r=A.size()-1; + while ( l < r ) { + if ( !isEven(A[l]) && isEven(A[r]) ) swap(A[l], A[r]); + if ( isEven(A[l]) ) l++; + if ( !isEven(A[r]) ) r--; + } + return A; + } +}; diff --git a/algorithms/cpp/splitArrayLargestSum/SplitArrayLargestSum.cpp b/algorithms/cpp/splitArrayLargestSum/SplitArrayLargestSum.cpp new file mode 100644 index 000000000..450dda91d --- /dev/null +++ b/algorithms/cpp/splitArrayLargestSum/SplitArrayLargestSum.cpp @@ -0,0 +1,69 @@ +// Source : https://leetcode.com/problems/split-array-largest-sum/ +// Author : Hao Chen +// Date : 2016-11-13 + +/*************************************************************************************** + * + * Given an array which consists of non-negative integers and an integer m, you can + * split the array into m non-empty continuous subarrays. Write an algorithm to + * minimize the largest sum among these m subarrays. + * + * Note: + * Given m satisfies the following constraint: 1 ≤ m ≤ length(nums) ≤ 14,000. + * + * Examples: + * + * Input: + * nums = [7,2,5,10,8] + * m = 2 + * + * Output: + * 18 + * + * Explanation: + * There are four ways to split nums into two subarrays. + * The best way is to split it into [7,2,5] and [10,8], + * where the largest sum among the two subarrays is only 18. + ***************************************************************************************/ + +class Solution { +public: + // Idea + // 1) The max of the result is the sum of the whole array. + // 2) The min of the result is the max num among the array. + // 3) Then, we use Binary Search to find the resullt between the `min` and the `max` + + int splitArray(vector& nums, int m) { + int min = 0, max = 0; + for (int n : nums) { + min = std::max(min, n); + max += n; + } + while (min < max) { + int mid = min + (max - min) / 2; + if (hasSmallerSum(nums, m, mid)) max = mid; + else min = mid + 1; + } + return min; + } + + + // Using a specific `sum` to check wheter we can get `smaller sum` + // The idea here as below: + // find all of possible `sub array` whose sum greater than `sum` + // 1) if the number of `sub array` > m, whcih means the actual result is greater than `sum` + // 2) if the number of `sub array` <= m, whcih means we can have `smaller sum` + // + bool hasSmallerSum(vector& nums, int m, int sum) { + int cnt = 1, curSum = 0; + for (int n : nums) { + curSum += n; + if (curSum > sum) { + curSum = n; + cnt++; + if (cnt > m) return false; + } + } + return true; + } +}; diff --git a/algorithms/cpp/squaresOfASortedArray/SquaresOfASortedArray.cpp b/algorithms/cpp/squaresOfASortedArray/SquaresOfASortedArray.cpp new file mode 100644 index 000000000..ec9edf742 --- /dev/null +++ b/algorithms/cpp/squaresOfASortedArray/SquaresOfASortedArray.cpp @@ -0,0 +1,65 @@ +// Source : https://leetcode.com/problems/squares-of-a-sorted-array/ +// Author : Hao Chen +// Date : 2019-03-26 + +/***************************************************************************************************** + * + * Given an array of integers A sorted in non-decreasing order, return an array of the squares of each + * number, also in sorted non-decreasing order. + * + * Example 1: + * + * Input: [-4,-1,0,3,10] + * Output: [0,1,9,16,100] + * + * Example 2: + * + * Input: [-7,-3,2,3,11] + * Output: [4,9,9,49,121] + * + * Note: + * + * 1 <= A.length <= 10000 + * -10000 <= A[i] <= 10000 + * A is sorted in non-decreasing order. + * + ******************************************************************************************************/ + +class Solution { +public: + vector sortedSquares(vector& A) { + // find the place, negative numbers are right, positive number are right. + // two pointer, one goes left, another goes right. + + //using binary search algorithm + const int len = A.size(); + int low = 0, high = len- 1; + int mid =0; + while (low <= high) { + mid = low + (high - low)/2; + if (A[mid] >= 0 ) high = mid - 1; + if (A[mid] < 0 ) low = mid + 1; + } + + //TRICKY: make sure A[mid] <= 0 or A[mid] is A[0] + if (A[mid] > 0 && mid > 0 ) mid--; + //cout << mid << " - "<< A[mid]<< endl; + + vector result; + low = mid; high = mid+1; + while ( low >=0 && high < len ) { + if ( abs(A[low]) < abs(A[high]) ) { + result.push_back(A[low] * A[low]); + low --; + }else { + result.push_back(A[high] * A[high]); + high++; + } + } + + for (;low >= 0; low--) result.push_back(A[low] * A[low]); + for (;high 0 ) result += 'a'; + while ( B-- > 0 ) result += 'b'; + break; + } + + // if A+B >=3 and A !=B + + // if A > B, then we need consume 'a' more than 'b' + // So, only "aab" can be used. + if ( A > B ) { + result += "aab"; + A -= 2; + B--; + continue; + } + + // if A > B, then we need consume 'b' more than 'a' + // So, only "bba" can be used. + if (B > A ){ + result += "bba"; + B-=2; + A--; + continue; + } + + } + + return result; + } +}; diff --git a/algorithms/cpp/sumOfEvenNumbersAfterQueries/SumOfEvenNumbersAfterQueries.cpp b/algorithms/cpp/sumOfEvenNumbersAfterQueries/SumOfEvenNumbersAfterQueries.cpp new file mode 100644 index 000000000..71c013a26 --- /dev/null +++ b/algorithms/cpp/sumOfEvenNumbersAfterQueries/SumOfEvenNumbersAfterQueries.cpp @@ -0,0 +1,68 @@ +// Source : https://leetcode.com/problems/sum-of-even-numbers-after-queries/ +// Author : Hao Chen +// Date : 2019-02-05 + +/***************************************************************************************************** + * + * We have an array A of integers, and an array queries of queries. + * + * For the i-th query val = queries[i][0], index = queries[i][1], we add val to A[index]. Then, the + * answer to the i-th query is the sum of the even values of A. + * + * (Here, the given index = queries[i][1] is a 0-based index, and each query permanently modifies the + * array A.) + * + * Return the answer to all queries. Your answer array should have answer[i] as the answer to the + * i-th query. + * + * Example 1: + * + * Input: A = [1,2,3,4], queries = [[1,0],[-3,1],[-4,0],[2,3]] + * Output: [8,6,2,4] + * Explanation: + * At the beginning, the array is [1,2,3,4]. + * After adding 1 to A[0], the array is [2,2,3,4], and the sum of even values is 2 + 2 + 4 = 8. + * After adding -3 to A[1], the array is [2,-1,3,4], and the sum of even values is 2 + 4 = 6. + * After adding -4 to A[0], the array is [-2,-1,3,4], and the sum of even values is -2 + 4 = 2. + * After adding 2 to A[3], the array is [-2,-1,3,6], and the sum of even values is -2 + 6 = 4. + * + * Note: + * + * 1 <= A.length <= 10000 + * -10000 <= A[i] <= 10000 + * 1 <= queries.length <= 10000 + * -10000 <= queries[i][0] <= 10000 + * 0 <= queries[i][1] < A.length + * + ******************************************************************************************************/ +class Solution { +public: + vector sumEvenAfterQueries(vector& A, vector>& queries) { + int sum = 0; + for(int i=0; i result; + for(auto query : queries) { + int i = query[1]; + int x = A[i] + query[0]; + + if (A[i] % 2 == 0 && x %2 == 0) { + sum += ( -A[i] + x ); + A[i] = x; + } else if (A[i] % 2 != 0 && x %2 == 0) { + sum += x; + A[i] = x; + } else if (A[i] % 2 == 0 && x %2 != 0) { + sum -= A[i]; + A[i] = x; + } else if (A[i] % 2 != 0 && x %2 != 0){ + A[i] = x; + } + result.push_back(sum); + } + + if (result.size()<=0) result.push_back(0); + return result; + } +}; diff --git a/algorithms/cpp/sumOfLeftLeaves/SumOfLeftLeaves.cpp b/algorithms/cpp/sumOfLeftLeaves/SumOfLeftLeaves.cpp new file mode 100644 index 000000000..3db0ad26c --- /dev/null +++ b/algorithms/cpp/sumOfLeftLeaves/SumOfLeftLeaves.cpp @@ -0,0 +1,71 @@ +// Source : https://leetcode.com/problems/sum-of-left-leaves/ +// Author : Hao Chen +// Date : 2016-11-12 + +/*************************************************************************************** + * + * Find the sum of all left leaves in a given binary tree. + * + * Example: + * + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * + * There are two left leaves in the binary tree, with values 9 and 15 respectively. + * Return 24. + ***************************************************************************************/ + +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode(int x) : val(x), left(NULL), right(NULL) {} + * }; + */ +class Solution { +public: + + + void sumOfLeftLeaves_recursion_v1(TreeNode* root, int& result) { + if (root == NULL ) { + return; + } + + if (root->left && root->left->left == NULL && root->left->right == NULL) { + result += root->left->val; + } + sumOfLeftLeaves_recursion_v1(root->left, result); + sumOfLeftLeaves_recursion_v1(root->right, result); + + } + + int sumOfLeftLeaves_recursion_v2(TreeNode* root) { + if (root == NULL ) { + return 0; + } + int result = 0; + if (root->left && root->left->left == NULL && root->left->right == NULL) { + result = root->left->val; + } + result += sumOfLeftLeaves_recursion_v2(root->left) + sumOfLeftLeaves_recursion_v2(root->right); + return result; + } + + + int sumOfLeftLeaves(TreeNode* root) { + srand(time(NULL)); + if (rand()%2) { + int result = 0; + sumOfLeftLeaves_recursion_v1(root, result); + return result; + } else { + return sumOfLeftLeaves_recursion_v2(root); + } + + } +}; diff --git a/algorithms/cpp/sumOfTwoIntegers/SumOfTwoIntegers.cpp b/algorithms/cpp/sumOfTwoIntegers/SumOfTwoIntegers.cpp new file mode 100644 index 000000000..d636e94c3 --- /dev/null +++ b/algorithms/cpp/sumOfTwoIntegers/SumOfTwoIntegers.cpp @@ -0,0 +1,38 @@ +// Source : https://leetcode.com/problems/sum-of-two-integers/description/ +// Author : Hao Chen +// Date : 2018-06-25 + +/*************************************************************************************** + * + * Calculate the sum of two integers a and b, but you are not allowed to use the + * operator + and -. + * + * Example: + * Given a = 1 and b = 2, return 3. + * + * + * Credits:Special thanks to @fujiaozhu for adding this problem and creating all test + * cases. + ***************************************************************************************/ + +class Solution { +public: + int getSum(int x, int y) { + // Iterate till there is no carry + while (y != 0) { + // carry now contains common + //set bits of x and y + int carry = x & y; + + // Sum of bits of x and y where at + //least one of the bits is not set + x = x ^ y; + + // Carry is shifted by one so that adding + // it to x gives the required sum + y = carry << 1; + } + return x; + } +}; + diff --git a/algorithms/cpp/superUglyNumber/SuperUglyNumber.cpp b/algorithms/cpp/superUglyNumber/SuperUglyNumber.cpp new file mode 100644 index 000000000..66438fd46 --- /dev/null +++ b/algorithms/cpp/superUglyNumber/SuperUglyNumber.cpp @@ -0,0 +1,69 @@ +// Source : https://leetcode.com/problems/super-ugly-number/ +// Author : Hao Chen +// Date : 2017-01-02 + +/*************************************************************************************** + * + * Write a program to find the nth super ugly number. + * + * Super ugly numbers are positive numbers whose all prime factors are in the given + * prime list + * primes of size k. For example, [1, 2, 4, 7, 8, 13, 14, 16, 19, 26, 28, 32] + * is the sequence of the first 12 super ugly numbers given primes + * = [2, 7, 13, 19] of size 4. + * + * Note: + * (1) 1 is a super ugly number for any given primes. + * (2) The given numbers in primes are in ascending order. + * (3) 0 k ≤ 100, 0 n ≤ 106, 0 primes[i] + * + * Credits:Special thanks to @dietpepsi for adding this problem and creating all test + * cases. + ***************************************************************************************/ + +// As the solution we have for the ugly number II problem +// +// int nthUglyNumber(int n) { +// +// int i=0, j=0, k=0; +// vector ugly(1,1); +// +// while(ugly.size() < n){ +// int next = min(ugly[i]*2, ugly[j]*3, ugly[k]*5); +// if (next == ugly[i]*2) i++; +// if (next == ugly[j]*3) j++; +// if (next == ugly[k]*5) k++; +// ugly.push_back(next); +// } +// return ugly.back(); +// } +// +// The logic of solution is exacly same for both., except that instead of 3 numbers you have k numbers to consider. +// +// +// +class Solution { + +public: + int nthSuperUglyNumber(int n, vector& primes) { + vector ugly(1, 1); + int len = primes.size(); + vector pos(len, 0); + + while( ugly.size() < n ) { + int next = INT_MAX; + for(int i=0; i > &board); -//Runtime Error for 250 x 250 matrix void markOpen(vector< vector > &board, int row, int col, int r, int c) { - - if (board[r][c] == 'O'){ - - board[r][c]='N'; // 'N' means it's not closed - - if (r < row-1) { - markOpen(board, row, col, r+1, c); - } - if (r > 0) { - markOpen(board, row, col, r-1, c); - } - if (c < col-1 ) { - markOpen(board, row, col, r, c+1); - } - if (c>0) { - markOpen(board, row, col, r, c-1); - } - } + if (r<0 || c <0 || r>=row || c>=col || board[r][c] != 'O') return; + board[r][c]='N'; // 'N' means it's not closed + markOpen(board, row, col, r+1, c); + markOpen(board, row, col, r-1, c); + markOpen(board, row, col, r, c+1); + markOpen(board, row, col, r, c-1); } -//Runtime Error for 250 x 250 matrix void solve_recursively(vector< vector > &board) { if (board.size()<=0 || board[0].size()<=0) return; @@ -182,9 +168,95 @@ void solve_non_recursively(vector< vector > &board) { } } + +// refers to 4th edition. +class UnionFind { + int count_; // number of components + int* rank_; // to limits tree hights + int* id_; // id[i] parent of i +public: + UnionFind(int n) { + count_ = n; + rank_ = new int[n]; + id_ = new int[n]; + for (int i = 0; i < n; i++) { + id_[i] = i; + rank_[i] = 0; + } + } + + ~UnionFind() { + delete [] rank_; + delete [] id_; + } + + int count() { return count_; } + + int find(int p) { + while (p != id_[p]) { + id_[p] = id_[id_[p]]; // path compression + p = id_[p]; + } + return p; + } + + bool connected(int p, int q) { + return find(p) == find(q); + } + + void connect(int p, int q) { + int i = find(p); + int j = find(q); + if (i == j) return; + if (rank_[i] < rank_[j]) id_[i] = j; + else if (rank_[i] > rank_[j]) id_[j] = i; + else { // == + id_[j] = i; + rank_[i]++; + } + count_--; + } +}; + +class Solution { +public: + void solve(vector >& board) { + int n = board.size(); + if (n == 0) return; + int m = board[0].size(); + + UnionFind uf(n*m+1); + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + if (i == 0 || i == n-1 || j == 0 || j == m-1) { // side case, connect to dummy node + uf.connect(i*m + j, n*m); + continue; + } + char c = board[i][j]; // inner case, connect to same neighbor + if (board[i+1][j] == c) uf.connect((i+1)*m + j, i*m + j); + if (board[i-1][j] == c) uf.connect((i-1)*m + j, i*m + j); + if (board[i][j+1] == c) uf.connect(i*m + (j+1), i*m + j); + if (board[i][j-1] == c) uf.connect(i*m + (j-1), i*m + j); + } + } + + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + if (board[i][j] == 'O' && !uf.connected(i*m + j, n*m)) { + board[i][j] = 'X'; + } + } + } + } +}; + + void solve(vector< vector > &board) { - //Runtime Error for 250 x 250 matrix - /* solve_recursively(board); */ + if (rand() % 2) { + Solution().solve(board); + return; + } + solve_recursively(board); solve_non_recursively(board); } diff --git a/algorithms/cpp/swapNodesInPairs/swapNodesInPairs.cpp b/algorithms/cpp/swapNodesInPairs/swapNodesInPairs.cpp index b5d03dd04..9f90d7c0c 100644 --- a/algorithms/cpp/swapNodesInPairs/swapNodesInPairs.cpp +++ b/algorithms/cpp/swapNodesInPairs/swapNodesInPairs.cpp @@ -71,4 +71,23 @@ class Solution { return head; } + + ListNode* swapPairs3(ListNode* head) { + // Three pointers point current, previous and next node. + ListNode *Curr=head, *Prev=NULL, *Next=NULL; + + while (Curr && Curr->next ) { + Next = Curr->next; + + //swap nodes + Curr->next = Next->next; + Prev == NULL ? head = Prev = Next : Prev->next = Next; + Next->next = Curr; + + //set the pointers to next place. + Prev = Curr; + Curr = Curr->next; + } + return head; + } }; diff --git a/algorithms/cpp/thirdMaximumNumber/ThirdMaximumNumber.cpp b/algorithms/cpp/thirdMaximumNumber/ThirdMaximumNumber.cpp new file mode 100644 index 000000000..897dcdfd0 --- /dev/null +++ b/algorithms/cpp/thirdMaximumNumber/ThirdMaximumNumber.cpp @@ -0,0 +1,51 @@ +// Source : https://leetcode.com/problems/third-maximum-number/ +// Author : Hao Chen +// Date : 2016-11-12 + +/*************************************************************************************** + * + * Given a non-empty array of integers, return the third maximum number in this array. + * If it does not exist, return the maximum number. The time complexity must be in O(n). + * + * Example 1: + * + * Input: [3, 2, 1] + * + * Output: 1 + * + * Explanation: The third maximum is 1. + * + * Example 2: + * + * Input: [1, 2] + * + * Output: 2 + * + * Explanation: The third maximum does not exist, so the maximum (2) is returned + * instead. + * + * Example 3: + * + * Input: [2, 2, 3, 1] + * + * Output: 1 + * + * Explanation: Note that the third maximum here means the third maximum distinct + * number. + * Both numbers with value 2 are both considered as second maximum. + ***************************************************************************************/ + +class Solution { +public: + int nMax(vector& nums, int n) { + set topN; + for(auto num : nums) { + topN.insert(num); + if (topN.size() > n) topN.erase(topN.begin()); + } + return (topN.size() >= n) ? *(topN.begin()) : *(topN.rbegin()); + } + int thirdMax(vector& nums) { + return nMax(nums, 3); + } +}; diff --git a/algorithms/cpp/timeBasedKeyValueStore/TimeBasedKeyValueStore.cpp b/algorithms/cpp/timeBasedKeyValueStore/TimeBasedKeyValueStore.cpp new file mode 100644 index 000000000..16783b495 --- /dev/null +++ b/algorithms/cpp/timeBasedKeyValueStore/TimeBasedKeyValueStore.cpp @@ -0,0 +1,84 @@ +// Source : https://leetcode.com/problems/time-based-key-value-store/ +// Author : Hao Chen +// Date : 2019-01-30 + +/***************************************************************************************************** + * + * Create a timebased key-value store class Timeap, that supports two operations. + * + * 1. set(string key, string value, int timestamp) + * + * Stores the key and value, along with the given timestamp. + * + * 2. get(string key, int timestamp) + * + * Returns a value such that set(key, value, timestamp_prev) was called previously, with + * timestamp_prev <= timestamp. + * If there are multiple such values, it returns the one with the largest timestamp_prev. + * If there are no values, it returns the empty string (""). + * + * Example 1: + * + * Input: inputs = ["Timeap","set","get","get","set","get","get"], inputs = + * [[],["foo","bar",1],["foo",1],["foo",3],["foo","bar2",4],["foo",4],["foo",5]] + * Output: [null,null,"bar","bar",null,"bar2","bar2"] + * Explanation: + * Timeap kv; + * kv.set("foo", "bar", 1); // store the key "foo" and value "bar" along with timestamp = 1 + * kv.get("foo", 1); // output "bar" + * kv.get("foo", 3); // output "bar" since there is no value corresponding to foo at timestamp 3 and + * timestamp 2, then the only value is at timestamp 1 ie "bar" + * kv.set("foo", "bar2", 4); + * kv.get("foo", 4); // output "bar2" + * kv.get("foo", 5); //output "bar2" + * + * Example 2: + * + * Input: inputs = ["Timeap","set","set","get","get","get","get","get"], inputs = + * [[],["love","high",10],["love","low",20],["love",5],["love",10],["love",15],["love",20],["love",25]] + * Output: [null,null,null,"","high","high","low","low"] + * + * Note: + * + * All key/value strings are lowercase. + * All key/value strings have length in the range [1, 100] + * The timestamps for all Timeap.set operations are strictly increasing. + * 1 <= timestamp <= 107 + * Timeap.set and Timeap.get functions will be called a total of 120000 times (combined) per + * test case. + ******************************************************************************************************/ + +class TimeMap { +private: + unordered_map> key_time; + unordered_map time_value; +public: + /** Initialize your data structure here. */ + TimeMap() { + + } + + void set(string key, string value, int timestamp) { + key_time[key].insert(timestamp); + time_value[timestamp] = value; + } + + string get(string key, int timestamp) { + if ( key_time.find(key) == key_time.end() ) return ""; + auto it = key_time[key].lower_bound(timestamp); + if ( *it == timestamp ) return time_value[*it]; + if ( it != key_time[key].begin() ) { + it--; + return time_value[*it]; + } + return ""; + } +}; + + +/** + * Your TimeMap object will be instantiated and called as such: + * TimeMap* obj = new TimeMap(); + * obj->set(key,value,timestamp); + * string param_2 = obj->get(key,timestamp); + */ diff --git a/algorithms/cpp/topKFrequentElements/topKFrequentElements.cpp b/algorithms/cpp/topKFrequentElements/topKFrequentElements.cpp new file mode 100644 index 000000000..245c3ba0b --- /dev/null +++ b/algorithms/cpp/topKFrequentElements/topKFrequentElements.cpp @@ -0,0 +1,65 @@ +// Source : https://leetcode.com/problems/top-k-frequent-elements/ +// Author : Calinescu Valentin +// Date : 2016-05-02 + +/*************************************************************************************** + * + * Given a non-empty array of integers, return the k most frequent elements. + * + * For example, + * Given [1,1,1,2,2,3] and k = 2, return [1,2]. + * + * Note: + * You may assume k is always valid, 1 ≤ k ≤ number of unique elements. + * Your algorithm's time complexity must be better than O(n log n), where n is the + * array's size. + * + ***************************************************************************************/ + +class Solution { +public: + struct element//structure consisting of every distinct number in the vector, + //along with its frequency + { + int number, frequency; + bool operator < (const element arg) const + { + return frequency < arg.frequency; + } + }; + priority_queue sol;//we use a heap so we have all of the elements sorted + //by their frequency + vector solution; + + vector topKFrequent(vector& nums, int k) { + sort(nums.begin(), nums.end()); + int i = 1; + for(; i < nums.size(); i++) + { + int freq = 1; + while(i < nums.size() && nums[i] == nums[i - 1]) + { + i++; + freq++; + } + element el; + el.number = nums[i - 1]; + el.frequency = freq; + sol.push(el); + } + if(i == nums.size())//if we have 1 distinct element as the last + { + element el; + el.number = nums[nums.size() - 1]; + el.frequency = 1; + sol.push(el); + } + while(k)//we extract the first k elements from the heap + { + solution.push_back(sol.top().number); + sol.pop(); + k--; + } + return solution; + } +}; diff --git a/algorithms/cpp/totalHammingDistance/totalHammingDistance.cpp b/algorithms/cpp/totalHammingDistance/totalHammingDistance.cpp new file mode 100644 index 000000000..27971e2b0 --- /dev/null +++ b/algorithms/cpp/totalHammingDistance/totalHammingDistance.cpp @@ -0,0 +1,56 @@ +// Source : https://leetcode.com/problems/total-hamming-distance/ +// Author : Calinescu Valentin +// Date : 2017-01-09 + +/*************************************************************************************** + * + * The Hamming distance between two integers is the number of positions at which the + * corresponding bits are different. + * + * Now your job is to find the total Hamming distance between all pairs of the given + * numbers. + * + * Example: + * Input: 4, 14, 2 + * + * Output: 6 + * + * Explanation: In binary representation, the 4 is 0100, 14 is 1110, and 2 is 0010 (just + * showing the four bits relevant in this case). So the answer will be: + * HammingDistance(4, 14) + HammingDistance(4, 2) + HammingDistance(14, 2) = 2 + 2 + 2 = 6. + * + * Note: + * Elements of the given array are in the range of 0 to 10^9 + * Length of the array will not exceed 10^4. + ***************************************************************************************/ + +/* +* Solution 1 - O(N) +* +* The total Hamming Distance is equal to the sum of all individual Hamming Distances +* between every 2 numbers. However, given that this depends on the individual bits of +* each number, we can see that we only need to compute the number of 1s and 0s for each +* bit position. For example, we look at the least significant bit. Given that we need to +* calculate the Hamming Distance for each pair of 2 numbers, we see that the answer is +* equal to the number of 1s at this position * the number of 0s(which is the total number +* of numbers - the number of 1s), because for each 1 we need to have a 0 to form a pair. +* Thus, the solution is the sum of all these distances at every position. +*/ +class Solution { +public: + int totalHammingDistance(vector& nums) { + long long solution = 0; + int ones[31]; + for(int i = 0; i < 31; i++) + ones[i] = 0; + for(vector::iterator it = nums.begin(); it != nums.end(); ++it) + { + for(int i = 0; (1 << i) <= *it; i++) //i is the position of the bit + if((1 << i) & *it)//to see if the bit at i-position is a 1 + ones[i]++; + } + for(int i = 0; i < 31; i++) + solution += ones[i] * (nums.size() - ones[i]); + return solution; + } +}; diff --git a/algorithms/cpp/twoCityScheduling/TwoCityScheduling.cpp b/algorithms/cpp/twoCityScheduling/TwoCityScheduling.cpp new file mode 100644 index 000000000..03a39398b --- /dev/null +++ b/algorithms/cpp/twoCityScheduling/TwoCityScheduling.cpp @@ -0,0 +1,55 @@ +// Source : https://leetcode.com/problems/two-city-scheduling/ +// Author : Hao Chen +// Date : 2019-04-21 + +/***************************************************************************************************** + * + * There are 2N people a company is planning to interview. The cost of flying the i-th person to city + * A is costs[i][0], and the cost of flying the i-th person to city B is costs[i][1]. + * + * Return the minimum cost to fly every person to a city such that exactly N people arrive in each + * city. + * + * Example 1: + * + * Input: [[10,20],[30,200],[400,50],[30,20]] + * Output: 110 + * Explanation: + * The first person goes to city A for a cost of 10. + * The second person goes to city A for a cost of 30. + * The third person goes to city B for a cost of 50. + * The fourth person goes to city B for a cost of 20. + * + * The total minimum cost is 10 + 30 + 50 + 20 = 110 to have half the people interviewing in each city. + * + * Note: + * + * 1 <= costs.length <= 100 + * It is guaranteed that costs.length is even. + * 1 <= costs[i][0], costs[i][1] <= 1000 + ******************************************************************************************************/ + + +class Solution { +private: + static int diff(vector& x) { + return x[1] - x[0]; + } + static bool cmpfunc(vector& lhs, vector& rhs) { + return diff(lhs) > diff(rhs); + } + +public: + // Just simply sort the array by comparing the different cost go to A city and B city + // then the bigger difference would be in left and right side, and the smaller difference would be in the middle + // We could simply let the first half go to A city, and the second half go to B city. + int twoCitySchedCost(vector>& costs) { + sort(costs.begin(), costs.end(), cmpfunc); + int result = 0; + int len = costs.size(); + for (int i=0; i twoSum(vector& nums, int target) { + unordered_map m; + vector result; + for (int i=0; i "--...-." + * "zen" -> "--...-." + * "gig" -> "--...--." + * "msg" -> "--...--." + * + * There are 2 different transformations, "--...-." and "--...--.". + * + * + * + * + * Note: + * + * + * The length of words will be at most 100. + * Each words[i] will have length in range [1, 12]. + * words[i] will only consist of lowercase letters. + ***************************************************************************************/ + +class Solution { +public: + int uniqueMorseRepresentations(vector& words) { + + string MorseTable[26] = {".-","-...","-.-.","-..",".","..-.","--.", + "....","..",".---","-.-",".-..","--","-.", + "---",".--.","--.-",".-.","...","-","..-", + "...-",".--","-..-","-.--","--.."}; + unordered_map transformations; + for (auto word : words) { + string morse; + for (auto ch : word) { + morse += MorseTable[ ch - 'a' ]; + } + transformations[morse]=true; + } + return transformations.size(); + } +}; diff --git a/algorithms/cpp/uniquePaths/UniquePaths.III.cpp b/algorithms/cpp/uniquePaths/UniquePaths.III.cpp new file mode 100644 index 000000000..0dd78e4fd --- /dev/null +++ b/algorithms/cpp/uniquePaths/UniquePaths.III.cpp @@ -0,0 +1,100 @@ +// Source : https://leetcode.com/problems/unique-paths-iii/ +// Author : Hao Chen +// Date : 2019-02-03 + +/***************************************************************************************************** + * + * On a 2-dimensional grid, there are 4 types of squares: + * + * 1 represents the starting square. There is exactly one starting square. + * 2 represents the ending square. There is exactly one ending square. + * 0 represents empty squares we can walk over. + * -1 represents obstacles that we cannot walk over. + * + * Return the number of 4-directional walks from the starting square to the ending square, that walk + * over every non-obstacle square exactly once. + * + * Example 1: + * + * Input: [[1,0,0,0],[0,0,0,0],[0,0,2,-1]] + * Output: 2 + * Explanation: We have the following two paths: + * 1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2) + * 2. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2) + * + * Example 2: + * + * Input: [[1,0,0,0],[0,0,0,0],[0,0,0,2]] + * Output: 4 + * Explanation: We have the following four paths: + * 1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2),(2,3) + * 2. (0,0),(0,1),(1,1),(1,0),(2,0),(2,1),(2,2),(1,2),(0,2),(0,3),(1,3),(2,3) + * 3. (0,0),(1,0),(2,0),(2,1),(2,2),(1,2),(1,1),(0,1),(0,2),(0,3),(1,3),(2,3) + * 4. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2),(2,3) + * + * Example 3: + * + * Input: [[0,1],[2,0]] + * Output: 0 + * Explanation: + * There is no path that walks over every empty square exactly once. + * Note that the starting and ending square can be anywhere in the grid. + * + * Note: + * + * 1 <= grid.length * grid[0].length <= 20 + * + ******************************************************************************************************/ +class Solution { +public: + int uniquePathsIII(vector>& grid) { + + int path = 0; + int startX, startY; + if (!findStartPoint( grid, startX, startY)) return 0; + uniquePathsHelper(grid, startX, startY, path); + return path; + } + + bool findStartPoint(vector> &grid, int& x, int& y) { + for(int i=0; i> &grid ) { + for(int i=0; i> &grid, int x, int y, int& path ) { + + if (x < 0 || y < 0 || x>= grid.size() || y>=grid[0].size()) return; + + if ( grid[x][y] < 0) return; + + if ( grid[x][y] == 2) { + if (check(grid)) path++; + return; + } + + //back tracing - mark -2 means already passed. + grid[x][y] = -2; + uniquePathsHelper(grid, x, y-1, path); // up + uniquePathsHelper(grid, x, y+1, path); // down + uniquePathsHelper(grid, x+1, y, path); // right + uniquePathsHelper(grid, x-1, y, path); // left + grid[x][y] = 0; + + } +}; diff --git a/algorithms/cpp/uniquePaths/uniquePaths.II.cpp b/algorithms/cpp/uniquePaths/uniquePaths.II.cpp index 0b3b1027b..6cbe39d1b 100644 --- a/algorithms/cpp/uniquePaths/uniquePaths.II.cpp +++ b/algorithms/cpp/uniquePaths/uniquePaths.II.cpp @@ -30,11 +30,11 @@ using namespace std; //As same as DP solution with "Unique Path I", just need to consider the obstacles. -int uniquePathsWithObstacles(vector > &obstacleGrid) { - vector< vector > v = obstacleGrid; +int uniquePathsWithObstacles(vector>& obstacleGrid) { + vector> v (row, vector(col, 0)); unsigned int max=0; for (int i=0; i > &obstacleGrid) { return max; } +// the previous implemetation has too many if-else +// the following dynamic programming is much more easy to read +int uniquePathsWithObstacles(vector>& obstacleGrid) { + int row = obstacleGrid.size(); + int col = obstacleGrid[0].size(); + + vector< vector > dp (row, vector(col, 0)); + + dp[0][0] = obstacleGrid[0][0] ? 0 : 1; + for (int r=1; r #include -void printMatrix(int*a, int m, int n); +void printMatrix(int*a, int m, int n) +{ + for (int i=0; i +using namespace std; + +// using C++ STL vector , the code is much easy to read +int uniquePaths(int m, int n) { + vector< vector > dp (n, vector(m, 1)); + for (int row=1; row list; + split(preorder, ',', list); + //we initailize the counter as 1, + //because we expect at lease 1 node in the tree. + int node_expected = 1; + for (auto node : list) { + if (node_expected == 0) return false; + node == "#" ? node_expected-- : node_expected++; + } + return node_expected == 0; + } + + void split(const string &s, char delim, vector &elems) { + stringstream ss(s); + string item; + while (getline(ss, item, delim)) { + elems.push_back(item); + } + } +}; diff --git a/algorithms/cpp/verticalOrderTraversalOfABinaryTree/VerticalOrderTraversalOfABinaryTree.cpp b/algorithms/cpp/verticalOrderTraversalOfABinaryTree/VerticalOrderTraversalOfABinaryTree.cpp new file mode 100644 index 000000000..3eea51cb9 --- /dev/null +++ b/algorithms/cpp/verticalOrderTraversalOfABinaryTree/VerticalOrderTraversalOfABinaryTree.cpp @@ -0,0 +1,133 @@ +// Source : https://leetcode.com/problems/vertical-order-traversal-of-a-binary-tree/ +// Author : Hao Chen +// Date : 2019-02-05 + +/***************************************************************************************************** + * + * Given a binary tree, return the vertical order traversal of its nodes values. + * + * For each node at position (X, Y), its left and right children respectively will be at positions + * (X-1, Y-1) and (X+1, Y-1). + * + * Running a vertical line from X = -infinity to X = +infinity, whenever the vertical line touches + * some nodes, we report the values of the nodes in order from top to bottom (decreasing Y + * coordinates). + * + * If two nodes have the same position, then the value of the node that is reported first is the value + * that is smaller. + * + * Return an list of non-empty reports in order of X coordinate. Every report will have a list of + * values of nodes. + * + * Example 1: + * + * + * +--+ + * +----+3 +----+ + * | +--+ | + * | | + * +--+ +--+ + * |9 | +---+20+---+ + * +--+ | +--+ | + * | | + * +--+ +--+ + * |15| |7 | + * +--+ +--+ + * + * + * Input: [3,9,20,null,null,15,7] + * Output: [[9],[3,15],[20],[7]] + * Explanation: + * Without loss of generality, we can assume the root node is at position (0, 0): + * Then, the node with value 9 occurs at position (-1, -1); + * The nodes with values 3 and 15 occur at positions (0, 0) and (0, -2); + * The node with value 20 occurs at position (1, -1); + * The node with value 7 occurs at position (2, -2). + * + * Example 2: + * + * + * +-+ + * |1| + * +-----------+ + * | | + * +++ +++ + * |2| |3| + * +--------+ +--------+ + * | | | | + * +++ ++--++ +++ + * |4| |5||6| |7| + * +-+ +----+ +-+ + * + * + * Input: [1,2,3,4,5,6,7] + * Output: [[4],[2],[1,5,6],[3],[7]] + * Explanation: + * The node with value 5 and the node with value 6 have the same position according to the given + * scheme. + * However, in the report "[1,5,6]", the node value of 5 comes first since 5 is smaller than 6. + * + * Note: + * + * The tree will have between 1 and 1000 nodes. + * Each node's value will be between 0 and 1000. + * + ******************************************************************************************************/ + +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode(int x) : val(x), left(NULL), right(NULL) {} + * }; + */ +class Item { +public: + Item(int _x, int _y, int _val):x(_x), y(_y),val(_val) {} + int x, y; + int val; +}; + +class ItemCmp { +public: + bool operator () (const Item &lhs, const Item &rhs) const { + return lhs.y != rhs.y ? lhs.y > rhs.y : lhs.val < rhs.val; + } +}; + +int getValue(const Item& i) { + return i.val; +} + +class Solution { +public: + vector> verticalTraversal(TreeNode* root) { + set rows; + unordered_map> m; + + verticalTraversalHelper(root, 0, 0, rows, m); + + vector> result; + for(auto r : rows) { + vector v; + transform(m[r].begin(), m[r].end(), back_inserter(v), getValue); + result.push_back(v); + } + return result; + } + void verticalTraversalHelper(TreeNode* root, int x, int y, + set& rows, + unordered_map>& m) { + + if ( !root ) return; + + rows.insert(x); + m[x].insert(Item(x, y, root->val)); + verticalTraversalHelper(root->left, x-1, y-1, rows, m); //left + verticalTraversalHelper(root->right, x+1, y-1, rows, m); //right + + + } +}; diff --git a/algorithms/cpp/videoStitching/VideoStitching.cpp b/algorithms/cpp/videoStitching/VideoStitching.cpp new file mode 100644 index 000000000..3decbbfcc --- /dev/null +++ b/algorithms/cpp/videoStitching/VideoStitching.cpp @@ -0,0 +1,118 @@ +// Source : https://leetcode.com/problems/video-stitching/ +// Author : Hao Chen +// Date : 2019-10-01 + +/***************************************************************************************************** + * + * You are given a series of video clips from a sporting event that lasted T seconds. These video + * clips can be overlapping with each other and have varied lengths. + * + * Each video clip clips[i] is an interval: it starts at time clips[i][0] and ends at time + * clips[i][1]. We can cut these clips into segments freely: for example, a clip [0, 7] can be cut + * into segments [0, 1] + [1, 3] + [3, 7]. + * + * Return the minimum number of clips needed so that we can cut the clips into segments that cover the + * entire sporting event ([0, T]). If the task is impossible, return -1. + * + * Example 1: + * + * Input: clips = [[0,2],[4,6],[8,10],[1,9],[1,5],[5,9]], T = 10 + * Output: 3 + * Explanation: + * We take the clips [0,2], [8,10], [1,9]; a total of 3 clips. + * Then, we can reconstruct the sporting event as follows: + * We cut [1,9] into segments [1,2] + [2,8] + [8,9]. + * Now we have segments [0,2] + [2,8] + [8,10] which cover the sporting event [0, 10]. + * + * Example 2: + * + * Input: clips = [[0,1],[1,2]], T = 5 + * Output: -1 + * Explanation: + * We can't cover [0,5] with only [0,1] and [0,2]. + * + * Example 3: + * + * Input: clips = + * [[0,1],[6,8],[0,2],[5,6],[0,4],[0,3],[6,7],[1,3],[4,7],[1,4],[2,5],[2,6],[3,4],[4,5],[5,7],[6,9]], + * T = 9 + * Output: 3 + * Explanation: + * We can take clips [0,4], [4,7], and [6,9]. + * + * Example 4: + * + * Input: clips = [[0,4],[2,8]], T = 5 + * Output: 2 + * Explanation: + * Notice you can have extra video after the event ends. + * + * Note: + * + * 1 <= clips.length <= 100 + * 0 <= clips[i][0], clips[i][1] <= 100 + * 0 <= T <= 100 + * + ******************************************************************************************************/ + +class Solution { +public: + int videoStitching(vector>& clips, int T) { + + //sort the clips + std::sort(clips.begin(), clips.end(), [](vector& x, vector& y) { + return x[0] < y[0] || (x[0] == y[0] && x[1] < y[1]); + }); + + //print(clips); + + // dynamic programming + // dp[i] is the minmal clips from [o,i] + + vector dp(T+1, -1); + for (auto c : clips) { + //edge case: out of the range + if (c[0] > T) continue; + + // if clip is started from 0, then just simple initalize to 1 + if (c[0] == 0) { + for (int i=c[0]; i<=min(T,c[1]); i++) dp[i] = 1; + continue; + } + + //if clip is not started from 0, seprate the range to two parts + //the first part is the greater than 0, then second part is -1 + // 1) for the first part, need figure the minimal number + // 2) for the second part, just simple add 1 with minimal number of first part. + + if (dp[c[0]] == -1 ) continue; + + int m = dp[c[0]]; + + for (int i = c[0] + 1; i<= min(T, c[1]); i++) { + if ( dp[i] > 0 ) m = min(m, dp[i]); + else dp[i] = m + 1; + } + } + + //print(dp); + return dp[T]; + } + + + + //used for debug + void print(vector>& clips) { + for (auto c : clips) { + cout << "[" << c[0] <<","<< c[1] << "]"<< " "; + } + cout << endl; + } + + void print(vector& v) { + for (auto i : v) { + cout << i << ", "; + } + cout << endl; + } +}; diff --git a/algorithms/cpp/wiggleSort/WiggleSort.II.cpp b/algorithms/cpp/wiggleSort/WiggleSort.II.cpp new file mode 100644 index 000000000..a225c19b7 --- /dev/null +++ b/algorithms/cpp/wiggleSort/WiggleSort.II.cpp @@ -0,0 +1,93 @@ +// Source : https://leetcode.com/problems/wiggle-sort-ii/ +// Author : Hao Chen +// Date : 2017-01-02 + +/*************************************************************************************** + * + * Given an unsorted array nums, reorder it such that + * nums[0] nums[2] . + * + * Example: + * (1) Given nums = [1, 5, 1, 1, 6, 4], one possible answer is [1, 4, 1, 5, 1, 6]. + * (2) Given nums = [1, 3, 2, 2, 3, 1], one possible answer is [2, 3, 1, 3, 1, 2]. + * + * Note: + * You may assume all input has valid answer. + * + * Follow Up: + * Can you do it in O(n) time and/or in-place with O(1) extra space? + * + * Credits:Special thanks to @dietpepsi for adding this problem and creating all test + * cases. + ***************************************************************************************/ + +class Solution { + +public: + // + // Solution - O(N*logN) + // -------------------- + // 1) Sorting the array with descending order + // + // 2) Split the sorted array into two parts, + // and insert the 2nd half array into the 1st half array + // + // For example: [ 9 8 7 6 5 4 3 2 1 0 ] + // + // + // 1st Large half: . 9 . 8 . 7 . 6 . 5 + // 2nd Small half: 4 . 3 . 2 . 1 . 0 . + // --------------------------------------- + // Result: 4 9 3 8 2 7 1 6 0 5 + // + // Be careful if the length of array is odd number, + // Such as: [5 4 3 2 1], + // The 2nd half is [3 2 1] instead of [2 1] + // + + void wiggleSort01(vector& nums) { + sort(nums.begin(), nums.end(), [](int x, int y) { return x > y; }); + int half = (nums.size() / 2); + + for (int i=0; i& nums) { + int n = nums.size(); + + // Find a median. + auto midptr = nums.begin() + n / 2; + nth_element(nums.begin(), midptr, nums.end()); + int mid = *midptr; + + // Index-rewiring. + #define A(i) nums[(1+2*(i)) % (n|1)] + + // 3-way-partition-to-wiggly in O(n) time with O(1) space. + int i = 0, j = 0, k = n - 1; + while (j <= k) { + if (A(j) > mid) + swap(A(i++), A(j++)); + else if (A(j) < mid) + swap(A(j), A(k--)); + else + j++; + } + } + void wiggleSort(vector& nums) { + return wiggleSort02(nums); //~140ms + return wiggleSort01(nums); //~230ms + } +}; diff --git a/algorithms/cpp/wiggleSubsequence/wiggleSubsequence.cpp b/algorithms/cpp/wiggleSubsequence/wiggleSubsequence.cpp new file mode 100644 index 000000000..5631e5713 --- /dev/null +++ b/algorithms/cpp/wiggleSubsequence/wiggleSubsequence.cpp @@ -0,0 +1,88 @@ +// Source : https://leetcode.com/problems/wiggle-subsequence/ +// Author : Calinescu Valentin +// Date : 2016-08-08 + +/*************************************************************************************** + * + * A sequence of numbers is called a wiggle sequence if the differences between + * successive numbers strictly alternate between positive and negative. The first + * difference (if one exists) may be either positive or negative. A sequence with fewer + * than two elements is trivially a wiggle sequence. + * + * For example, [1,7,4,9,2,5] is a wiggle sequence because the differences (6,-3,5,-7,3) + * are alternately positive and negative. In contrast, [1,4,7,2,5] and [1,7,4,5,5] are + * not wiggle sequences, the first because its first two differences are positive and + * the second because its last difference is zero. + * + * Given a sequence of integers, return the length of the longest subsequence that is a + * wiggle sequence. A subsequence is obtained by deleting some number of elements + * (eventually, also zero) from the original sequence, leaving the remaining elements in + * their original order. + * + * Examples: + * Input: [1,7,4,9,2,5] + * Output: 6 + * The entire sequence is a wiggle sequence. + * + * Input: [1,17,5,10,13,15,10,5,16,8] + * Output: 7 + * There are several subsequences that achieve this length. One is [1,17,10,13,10,16,8]. + * + * Input: [1,2,3,4,5,6,7,8,9] + * Output: 2 + * + * Follow up: + * Can you do it in O(n) time? + * + ***************************************************************************************/ + + /* Solution + * -------- + * 1) O(N) + * + * We notice that adding a new number to an existing subsequence means finding one that + * is smaller or bigger than the previous number, according to the difference between the + * previous number and the number before that as we always need to alternate between increasing + * and decreasing subsequences. If we encounter increasing or decreasing sequences of 2 or + * more consecutive numbers we can treat the entire subsequence as a number, because that way + * we can always be sure we don't miss any solution, as finding a number smaller than any + * number of an increasing subsequence is guaranteed to be smaller than the biggest number + * in the subsequence. Thus, we can only check the difference between consecutive numbers. + * + * Follow up: + * + * The time complexity is already O(N). + */ +class Solution { +public: + int wiggleMaxLength(vector& nums) { + int solution = 0;//if we have an empty vector the solution is 0 + if(nums.size()) + { + solution = 1; + int bigger = 0;//0 is the starting point to be followed by either an increasing or decreasing sequence + for(int i = 1; i < nums.size(); i++) + { + if(nums[i] == nums[i - 1]) + continue;//we can ignore duplicates as they can always be omitted + else if(nums[i] > nums[i - 1]) + { + if(bigger == 0 || bigger == 2) + { + bigger = 1;//1 means we now have an increasing sequence + solution++; + } + } + else //if(nums[i] < nums[i - 1]) + { + if(bigger == 0 || bigger == 1) + { + bigger = 2;//2 means we now have a decreasing sequence + solution++; + } + } + } + } + return solution; + } +}; diff --git a/algorithms/cpp/wordPattern/WordPattern.cpp b/algorithms/cpp/wordPattern/WordPattern.cpp index 8d67a0edb..0d319f110 100644 --- a/algorithms/cpp/wordPattern/WordPattern.cpp +++ b/algorithms/cpp/wordPattern/WordPattern.cpp @@ -34,7 +34,7 @@ private:: string tok; while(getline(ss, tok, delimiter)) { - internal.push_back(tok); + internal.push_back(tok); } return internal; diff --git a/algorithms/cpp/wordSearch/wordSearch.cpp b/algorithms/cpp/wordSearch/wordSearch.cpp index e47b021df..1aa8a6c7c 100644 --- a/algorithms/cpp/wordSearch/wordSearch.cpp +++ b/algorithms/cpp/wordSearch/wordSearch.cpp @@ -3,53 +3,57 @@ // Date : 2014-07-19 /********************************************************************************** -* -* Given a 2D board and a word, find if the word exists in the grid. -* -* The word can be constructed from letters of sequentially adjacent cell, -* where "adjacent" cells are those horizontally or vertically neighboring. -* The same letter cell may not be used more than once. -* -* For example, -* Given board = -* -* [ -* ["ABCE"], -* ["SFCS"], -* ["ADEE"] -* ] -* -* word = "ABCCED", -> returns true, -* word = "SEE", -> returns true, -* word = "ABCB", -> returns false. -* -* -**********************************************************************************/ + * + * Given a 2D board and a word, find if the word exists in the grid. + * + * The word can be constructed from letters of sequentially adjacent cell, + * where "adjacent" cells are those horizontally or vertically neighboring. + * The same letter cell may not be used more than once. + * + * For example, + * Given board = + * + * [ + * ["ABCE"], + * ["SFCS"], + * ["ADEE"] + * ] + * + * word = "ABCCED", -> returns true, + * word = "SEE", -> returns true, + * word = "ABCB", -> returns false. + * + * + **********************************************************************************/ #include #include #include using namespace std; -//Recursive backtracking algorithm -bool exist(vector > &board, string word, int idx, int row, int col, vector< vector > &mask) { - int i = row; - int j = col; - if (board[i][j] == word[idx] && mask[i][j]==0 ) { - mask[i][j]=1; //mark the current char is matched - if (idx+1 == word.size()) return true; - //checking the next char in `word` through the right, left, up, down four directions in the `board`. - idx++; - if (( i+10 && exist(board, word, idx, i-1, j, mask) ) || - ( j+10 && exist(board, word, idx, i, j-1, mask) ) ) - { - return true; - } - mask[i][j]=0; //cannot find any successful solution, clear the mark. (backtracking) +bool exist(vector > &board, string& word, int idx, int row, int col) { + if ( row<0 || row>=board.size() || + col<0 || col>=board[0].size() || + board[row][col] != word[idx]) { + return false; } + + if (idx+1 == word.size()) return true; + + //replace to a special char to avoid duplication. + board[row][col] = '\0'; + + if ( exist(board, word, idx+1, row+1, col ) || + exist(board, word, idx+1, row-1, col ) || + exist(board, word, idx+1, row, col+1 ) || + exist(board, word, idx+1, row, col-1 ) ) { + return true; + } + + //restore the char + board[row][col] = word[idx]; + return false; } @@ -57,15 +61,11 @@ bool exist(vector > &board, string word) { if (board.size()<=0 || word.size()<=0) return false; int row = board.size(); int col = board[0].size(); - //using a mask to mark which char has been selected. - //do not use vector, it has big performance issue, could cause Time Limit Error - vector< vector > mask(row, vector(col, 0)); for(int i=0; i > m = mask; - if( exist(board, word, 0, i, j, m) ){ + if ( board[i][j]==word[0] ){ + if( exist(board, word, 0, i, j) ){ return true; } } @@ -93,10 +93,10 @@ int main(int argc, char** argv) s = "SEE"; cout << s << ":" << exist(board, s) << endl; - + s = "ABCCED"; cout << s << ":" << exist(board, s) << endl; - + s = "ABCB"; cout << s << ":" << exist(board, s) << endl; diff --git a/algorithms/golang/twoSum/twoSum.go b/algorithms/golang/twoSum/twoSum.go new file mode 100644 index 000000000..c1241ce15 --- /dev/null +++ b/algorithms/golang/twoSum/twoSum.go @@ -0,0 +1,12 @@ +package twoSum + +func twoSum(nums []int, target int) []int { + numMap := make(map[int]int) + for index, num := range nums { + if i, ok := numMap[target-num]; ok { + return []int{i, index} + } + numMap[num] = index + } + return nil +} \ No newline at end of file diff --git a/algorithms/java/src/countAndSay/CountAndSay.java b/algorithms/java/src/countAndSay/CountAndSay.java new file mode 100644 index 000000000..28a5151ad --- /dev/null +++ b/algorithms/java/src/countAndSay/CountAndSay.java @@ -0,0 +1,66 @@ +// Source : https://leetcode.com/problems/count-and-say/description/ +// Author : Tianming Cao +// Date : 2018-02-11 + +/********************************************************************************** + * + * The count-and-say sequence is the sequence of integers with the first five terms as following: + * + * 1. 1 + * 2. 11 + * 3. 21 + * 4. 1211 + * 5. 111221 + * 1 is read off as "one 1" or 11. + * 11 is read off as "two 1s" or 21. + * 21 is read off as "one 2, then one 1" or 1211. + * Given an integer n, generate the nth term of the count-and-say sequence. + * + * Note: Each term of the sequence of integers will be represented as a string. + * + * Example 1: + * + * Input: 1 + * Output: "1" + * + * Example 2: + * + * Input: 4 + * Output: "1211" + * + **********************************************************************************/ +package countAndSay; + +public class CountAndSay { + + public String nextString(String str) { + StringBuilder next = new StringBuilder(); + int len = str.length(); + int i = 0; + while (i < len) { + int j = i; + int count = 0; + char currentNumber = str.charAt(i); + while (j < len && str.charAt(j) == currentNumber) { + j++; + count++; + } + next.append(count).append(currentNumber); + i = j; + } + return next.toString(); + } + public String countAndSay(int n) { + if (n <= 1) { + return "1"; + } else { + String p = "1"; + for (int i = 2; i <= n; i++) { + String next = nextString(p); + p = next; + } + return p; + } + } + +} diff --git a/algorithms/java/src/countAndSay/TestCountAndSay.java b/algorithms/java/src/countAndSay/TestCountAndSay.java new file mode 100644 index 000000000..50e4b5be1 --- /dev/null +++ b/algorithms/java/src/countAndSay/TestCountAndSay.java @@ -0,0 +1,17 @@ +package countAndSay; + +import org.junit.Assert; +import org.junit.Test; +/** + * Test for 38. Count and Say + */ +public class TestCountAndSay { + @Test + public void test() { + CountAndSay solution = new CountAndSay(); + String next5 = solution.countAndSay(5); + Assert.assertTrue(next5.equals("111221")); + String next6 = solution.countAndSay(6); + Assert.assertTrue(next6.equals("312211")); + } +} diff --git a/algorithms/java/src/lengthOfLastWord/LengthOfLastWord.java b/algorithms/java/src/lengthOfLastWord/LengthOfLastWord.java new file mode 100644 index 000000000..2e661629a --- /dev/null +++ b/algorithms/java/src/lengthOfLastWord/LengthOfLastWord.java @@ -0,0 +1,44 @@ +// Source : https://leetcode.com/problems/length-of-last-word/description/ +// Author : Tianming Cao +// Date : 2018-02-11 + +/********************************************************************************** + * + * Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string. + * + * If the last word does not exist, return 0. + * + * Note: A word is defined as a character sequence consists of non-space characters only. + * + * Example: + * + * Input: "Hello World" + * Output: 5 + * + **********************************************************************************/ +package lengthOfLastWord; + +public class LengthOfLastWord { + + public int lengthOfLastWord(String s) { + // don't forget rangeCheck + if (s == null || s.length() == 0) { + return 0; + } + int len = s.length(); + int i = len - 1; + while (i >= 0 && s.charAt(i) == ' ') { + i--; + } + if (i == -1) { + return 0; + } + int count = 0; + while (i >= 0 && s.charAt(i) != ' ') { + count++; + i--; + } + return count; + } + +} diff --git a/algorithms/java/src/lengthOfLastWord/TestLengthOfLastWord.java b/algorithms/java/src/lengthOfLastWord/TestLengthOfLastWord.java new file mode 100644 index 000000000..936cb0f75 --- /dev/null +++ b/algorithms/java/src/lengthOfLastWord/TestLengthOfLastWord.java @@ -0,0 +1,18 @@ +package lengthOfLastWord; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Test for 58. Length of Last Word + */ +public class TestLengthOfLastWord { + @Test + public void test() { + LengthOfLastWord solution = new LengthOfLastWord(); + String str1 = "Hello World"; + Assert.assertTrue(solution.lengthOfLastWord(str1) == 5); + String str2 = "Thank you very much "; + Assert.assertTrue(solution.lengthOfLastWord(str2) == 4); + } +} diff --git a/algorithms/java/src/lruCache/LRUCache.java b/algorithms/java/src/lruCache/LRUCache.java new file mode 100644 index 000000000..5ea5c2950 --- /dev/null +++ b/algorithms/java/src/lruCache/LRUCache.java @@ -0,0 +1,45 @@ +/* +Analogous to the C++ solution at: +https://github.com/haoel/leetcode/blob/625ad10464701fc4177b9ef33c8ad052d0a7d984/algorithms/cpp/LRUCache/LRUCache.cpp +which uses linked list + hash map. But the Java stdlib provides LinkedHashMap +which already implements that for us, making this solution shorter. + +This could also be done by using, but that generates +some inheritance boilerplate, and ends up taking the same number of lines: +https://github.com/cirosantilli/haoel-leetcode/commit/ff04930b2dc31f270854e40b560723577c7b49fd +*/ + +import java.util.LinkedHashMap; +import java.util.Iterator; + +public class LRUCache { + + private int capacity; + private LinkedHashMap map; + + public LRUCache(int capacity) { + this.capacity = capacity; + this.map = new LinkedHashMap<>(); + } + + public int get(int key) { + Integer value = this.map.get(key); + if (value == null) { + value = -1; + } else { + this.set(key, value); + } + return value; + } + + public void set(int key, int value) { + if (this.map.containsKey(key)) { + this.map.remove(key); + } else if (this.map.size() == this.capacity) { + Iterator it = this.map.keySet().iterator(); + it.next(); + it.remove(); + } + map.put(key, value); + } +} diff --git a/algorithms/java/src/lruCache/LRUCacheTest.java b/algorithms/java/src/lruCache/LRUCacheTest.java new file mode 100644 index 000000000..b8166873e --- /dev/null +++ b/algorithms/java/src/lruCache/LRUCacheTest.java @@ -0,0 +1,49 @@ +import java.util.ArrayList; + +import org.junit.Test; +import static org.junit.Assert.*; + +public class LRUCacheTest { + + private LRUCache c; + + public LRUCacheTest() { + this.c = new LRUCache(2); + } + + @Test + public void testCacheStartsEmpty() { + assertEquals(c.get(1), -1); + } + + @Test + public void testSetBelowCapacity() { + c.set(1, 1); + assertEquals(c.get(1), 1); + assertEquals(c.get(2), -1); + c.set(2, 4); + assertEquals(c.get(1), 1); + assertEquals(c.get(2), 4); + } + + @Test + public void testCapacityReachedOldestRemoved() { + c.set(1, 1); + c.set(2, 4); + c.set(3, 9); + assertEquals(c.get(1), -1); + assertEquals(c.get(2), 4); + assertEquals(c.get(3), 9); + } + + @Test + public void testGetRenewsEntry() { + c.set(1, 1); + c.set(2, 4); + assertEquals(c.get(1), 1); + c.set(3, 9); + assertEquals(c.get(1), 1); + assertEquals(c.get(2), -1); + assertEquals(c.get(3), 9); + } +} diff --git a/algorithms/java/src/minStack/MinStack.java b/algorithms/java/src/minStack/MinStack.java new file mode 100644 index 000000000..7129779d9 --- /dev/null +++ b/algorithms/java/src/minStack/MinStack.java @@ -0,0 +1,60 @@ +// Source : https://leetcode.com/problems/min-stack/description/ +// Author : Tianming Cao +// Date : 2018-02-02 + +/********************************************************************************** + * Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. + * + * push(x) -- Push element x onto stack. + * pop() -- Removes the element on top of the stack. + * top() -- Get the top element. + * getMin() -- Retrieve the minimum element in the stack. + * Example: + * MinStack minStack = new MinStack(); + * minStack.push(-2); + * minStack.push(0); + * minStack.push(-3); + * minStack.getMin(); --> Returns -3. + * minStack.pop(); + * minStack.top(); --> Returns 0. + * minStack.getMin(); --> Returns -2. + * + **********************************************************************************/ +package minStack; + +import java.util.Stack; + +public class MinStack { + public Stack mainStack; + /** + * Call an extra stack named assistStack to store the min value. + * While we doing push operation, compare x with the top of assistStack and push the smaller value into assistStack. + * The other operations pop,top and getMin is very simple. + **/ + public Stack assistStack; + public MinStack() { + mainStack = new Stack(); + assistStack = new Stack(); + } + public void push(int x) { + mainStack.push(x); + if (assistStack.isEmpty()) { + assistStack.push(x); + } else { + assistStack.push(Math.min(x, getMin())); + } + } + + public void pop() { + mainStack.pop(); + assistStack.pop(); + } + + public int top() { + return mainStack.peek(); + } + + public int getMin() { + return assistStack.peek(); + } +} diff --git a/algorithms/java/src/minStack/TestMinStack.java b/algorithms/java/src/minStack/TestMinStack.java new file mode 100644 index 000000000..3c1f9c5f3 --- /dev/null +++ b/algorithms/java/src/minStack/TestMinStack.java @@ -0,0 +1,22 @@ +package minStack; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Test for 155. Min Stack + */ +public class TestMinStack { + @Test + public void test() { + MinStack minStack = new MinStack(); + minStack.push(3); + minStack.push(4); + minStack.push(1); + minStack.push(2); + Assert.assertTrue(minStack.getMin() == 1); + minStack.pop(); + minStack.pop(); + Assert.assertTrue(minStack.getMin() == 3); + } +} diff --git a/algorithms/java/src/myQueue/MyQueue.java b/algorithms/java/src/myQueue/MyQueue.java new file mode 100644 index 000000000..1abde5b6f --- /dev/null +++ b/algorithms/java/src/myQueue/MyQueue.java @@ -0,0 +1,102 @@ +// Source : https://leetcode.com/problems/implement-queue-using-stacks/description/ +// Author : Tianming Cao +// Date : 2018-02-02 + +/********************************************************************************** + * Implement the following operations of a queue using stacks. + * + * push(x) -- Push element x to the back of queue. + * pop() -- Removes the element from in front of queue. + * peek() -- Get the front element. + * empty() -- Return whether the queue is empty. + * + * Notes: + * You must use only standard operations of a stack -- which means only push to top, peek/pop from top, size, and is empty operations are valid. + * Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack. + * You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue). + * + **********************************************************************************/ +package myQueue; + +import java.util.Stack; + +/** + * This problem is a sibling of problem 225(https://leetcode.com/problems/implement-stack-using-queues/description/) + * The solution is: + * 1. stack1 is always in charge of push operation + * 2. stack2 is always in charge of peek and pop operation + * 3. if we want to do peek or pop operation, but stack2 is empty, + * we should first pop all the elements from stack1 and push them into stack2 in turn. + * Give a Example: + * + * First, push numbers "1,2,3,4,5" to stack1, then stack1's structure is: + * + * |5| + * |4| + * |3| + * |2| + * |1| + * + * Second, if we want to get the front element "1",we should pop all the elements of stack1 and push them into stack2, + * after this, stack1 is empty, and stack2's structrue is: + * + * |1| + * |2| + * |3| + * |4| + * |5| + * + * So we can get stack2's top element "1" as the front element of queue. + * + * Next, if we want to push "6" to the back of queue, we should push "6" into stack1 as before, so stack1's structure is: + * + * |6| + * + * Finally, if we want to do pop operation twice ,we should remove the top element of stack2 twice, so stack2's structure is: + * + * |3| + * |4| + * |5| + * + * as expect, the removed element is "1" and "2". + */ +public class MyQueue { + public Stack stack1; + public Stack stack2; + public int size; + public MyQueue() { + stack1 = new Stack(); + stack2 = new Stack(); + size = 0; + } + + public void push(int x) { + stack1.push(x); + size++; + } + + public int pop() { + if (stack2.isEmpty()) { + while (!stack1.isEmpty()) { + stack2.push(stack1.pop()); + } + } + int value = stack2.pop(); + size--; + return value; + } + + public int peek() { + if (stack2.isEmpty()) { + while (!stack1.isEmpty()) { + stack2.push(stack1.pop()); + } + } + int value = stack2.peek(); + return value; + } + + public boolean empty() { + return size == 0 ? true : false; + } +} diff --git a/algorithms/java/src/myQueue/TestMyQueue.java b/algorithms/java/src/myQueue/TestMyQueue.java new file mode 100644 index 000000000..cc77ca169 --- /dev/null +++ b/algorithms/java/src/myQueue/TestMyQueue.java @@ -0,0 +1,23 @@ +package myQueue; + +import org.junit.Assert; +import org.junit.Test; +/** + * Test for 232. Implement Queue using Stacks + */ +public class TestMyQueue { + @Test + public void test(){ + MyQueue queue=new MyQueue(); + Assert.assertTrue(queue.empty()); + queue.push(1); + queue.push(2); + queue.push(3); + queue.push(4); + Assert.assertTrue(queue.pop()==1); + Assert.assertTrue(queue.pop()==2); + queue.push(5); + Assert.assertTrue(queue.peek()==3); + Assert.assertTrue(!queue.empty()); + } +} diff --git a/algorithms/java/src/myStack/MyStack.java b/algorithms/java/src/myStack/MyStack.java new file mode 100644 index 000000000..1c995c554 --- /dev/null +++ b/algorithms/java/src/myStack/MyStack.java @@ -0,0 +1,94 @@ +// Source : https://leetcode.com/problems/implement-stack-using-queues/description/ +// Author : Tianming Cao +// Date : 2018-02-02 + +/********************************************************************************** + * Implement the following operations of a stack using queues. + + * push(x) -- Push element x onto stack. + * pop() -- Removes the element on top of the stack. + * top() -- Get the top element. + * empty() -- Return whether the stack is empty. + * Notes: + * You must use only standard operations of a queue -- which means only push to back, peek/pop from front, size, and is empty operations are valid. + * Depending on your language, queue may not be supported natively. You may simulate a queue by using a list or deque (double-ended queue), as long as you use only standard operations of a queue. + * You may assume that all operations are valid (for example, no pop or top operations will be called on an empty stack). + * + **********************************************************************************/ +package myStack; + +import java.util.LinkedList; +import java.util.Queue; +/********************************************************************************** + * This problem is a sibling of problem 232(https://leetcode.com/problems/implement-queue-using-stacks/description/). + * The train of thought is: + * If we want to pop a element,first we should judge which queue is not empty assumed queue1,another empty queue assumed queue2. + * Next,we pop all element from queue1 and push them into queue2 util queue1's size is 1. + * Finally the last element in queue1 is the correct pop value. + * If queue1 is empty and queue2 is not empty,the step is symmetric. + * The top operation is similar with pop operation. + **********************************************************************************/ +public class MyStack { + public Queue queue1; + public Queue queue2; + public int flag; + public int size; + public MyStack() { + queue1=new LinkedList(); + queue2=new LinkedList(); + flag=1; + size=0; + } + + public void push(int x) { + if(flag==1){ + queue1.offer(x); + }else{ + queue2.offer(x); + } + size++; + } + + public int pop() { + int value; + if(flag==1){ + while(queue1.size()>1){ + queue2.offer(queue1.poll()); + } + value=queue1.poll(); + flag=2; + }else{ + while(queue2.size()>1){ + queue1.offer(queue2.poll()); + } + value=queue2.poll(); + flag=1; + } + size--; + return value; + } + + public int top() { + if(flag==1){ + while(queue1.size()>1){ + queue2.offer(queue1.poll()); + } + int value=queue1.poll(); + queue2.offer(value); + flag=2; + return value; + }else{ + while(queue2.size()>1){ + queue1.offer(queue2.poll()); + } + int value=queue2.poll(); + queue1.offer(value); + flag=1; + return value; + } + } + + public boolean empty() { + return size==0?true:false; + } +} diff --git a/algorithms/java/src/myStack/TestMyStack.java b/algorithms/java/src/myStack/TestMyStack.java new file mode 100644 index 000000000..0dd54382b --- /dev/null +++ b/algorithms/java/src/myStack/TestMyStack.java @@ -0,0 +1,23 @@ +package myStack; + +import org.junit.Assert; +import org.junit.Test; +/** + * Test for 225. Implement Stack using Queues + */ +public class TestMyStack { +@Test +public void test(){ + MyStack stack=new MyStack(); + stack.push(1); + stack.push(2); + stack.push(3); + stack.push(4); + Assert.assertTrue(stack.empty()==false); + Assert.assertTrue(stack.pop()==4); + Assert.assertTrue(stack.pop()==3); + Assert.assertTrue(stack.top()==2); + stack.push(5); + Assert.assertTrue(stack.top()==5); +} +} diff --git a/algorithms/java/src/palindromeNumber/PalindromeNumber.java b/algorithms/java/src/palindromeNumber/PalindromeNumber.java new file mode 100644 index 000000000..06f61c2ec --- /dev/null +++ b/algorithms/java/src/palindromeNumber/PalindromeNumber.java @@ -0,0 +1,51 @@ +// Source : https://oj.leetcode.com/problems/palindrome-number/ +// Author : Tianming Cao +// Date : 2018-02-11 + +/********************************************************************************** + * + * Determine whether an integer is a palindrome. Do this without extra space. + * + * Some hints: + * Could negative integers be palindromes? (ie, -1) + * + * If you are thinking of converting the integer to string, note the restriction of using extra space. + * + * You could also try reversing an integer. + * However, if you have solved the problem "Reverse Integer", you know that the reversed integer might overflow. + * How would you handle such case? + * + * There is a more generic way of solving this problem. + * + **********************************************************************************/ +package palindromeNumber; + +public class PalindromeNumber { + + /** + * The simple way is : + * Reverse x to reverseX and judge whether reverseX is equal to x + * For example: + * x is 1234321, then reverseX is 1234321, they are equal, so 1234321 is palindrome + * x is 1234123, then reverseX is 3214321, they are not equal, so 1234123 is not palindrome + */ + public boolean isPalindrome(int x) { + if (x < 0) { + return false; + } + if (x < 10) { + return true; + } + int n = x; + int reverseX = 0; + while (n > 0) { + reverseX = 10 * reverseX + n % 10; + n /= 10; + } + if (reverseX == x) { + return true; + } else { + return false; + } + } +} diff --git a/algorithms/java/src/palindromeNumber/TestPalindromeNumber.java b/algorithms/java/src/palindromeNumber/TestPalindromeNumber.java new file mode 100644 index 000000000..d8462abdb --- /dev/null +++ b/algorithms/java/src/palindromeNumber/TestPalindromeNumber.java @@ -0,0 +1,20 @@ +package palindromeNumber; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Test for 9. Palindrome Number + */ +public class TestPalindromeNumber { + @Test + public void test() { + PalindromeNumber solution = new PalindromeNumber(); + boolean flag1 = solution.isPalindrome(1234567); + Assert.assertTrue(!flag1); + boolean flag2 = solution.isPalindrome(1234321); + Assert.assertTrue(flag2); + boolean flag3 = solution.isPalindrome(12344321); + Assert.assertTrue(flag3); + } +} diff --git a/algorithms/java/src/powXn/PowXn.java b/algorithms/java/src/powXn/PowXn.java new file mode 100644 index 000000000..296039323 --- /dev/null +++ b/algorithms/java/src/powXn/PowXn.java @@ -0,0 +1,98 @@ +// Source : https://leetcode.com/problems/powx-n/ +// Author : Tianming Cao +// Date : 2018-02-11 + +/********************************************************************************** + * + * Implement pow(x, n). + * + * Example 1: + * + * Input: 2.00000, 10 + * Output: 1024.00000 + * + * Example 2: + * + * Input: 2.10000, 3 + * Output: 9.26100 + * + **********************************************************************************/ +package powXn; + +public class PowXn { + + /** + * Divide-and-Conquer method + * For example: + * + * 3^9=(3^4)^2*3 + * ↓ + * 3^4=(3^2)^2 + * ↓ + * 3^2=3*3 + * ↓ + * 3=3 + * + * So, both Space and Time are O(logN) + */ + public double recursion(double x, long n) { + if (n == 1) { + return x; + } + //We'd better use unsigned right shift + double half = recursion(x, n >>> 1); + if ((n & 1) == 0) { + return half * half; + } else { + return half * half * x; + } + } + + public double myPow01(double x, int n) { + if (n == 0 || x == 1) { + return 1; + } + // Avoid being out of bounds, we should cast int to long + long m = n; + double result = recursion(x, Math.abs(m)); + if (n > 0) { + return result; + } else { + return 1 / result; + } + } + + public double myPow02(double x, int n) { + if (n == 0 || x == 1) { + return 1; + } + // Avoid being out of bounds, we should cast int to long + long m = n; + double result = bitFunction(x, Math.abs(m)); + if (n > 0) { + return result; + } else { + return 1 / result; + } + } + + /** + * Solution with bit-manipulation + * For example: + * 9=1001 + * 3^9=(3^1)^1*(3^2)^0*(3^4)^0*(3^8)^1 + * Space is O(1), Time is O(logN) + */ + public double bitFunction(double x, long n) { + double multy = 1; + double base = x; + for (long k = n; k >= 1; k >>>= 1) { + if ((k & 1) > 0) { + multy = multy * base; + } + base *= base; + } + return multy; + } + +} diff --git a/algorithms/java/src/powXn/TestPowXn.java b/algorithms/java/src/powXn/TestPowXn.java new file mode 100644 index 000000000..6b6835dc4 --- /dev/null +++ b/algorithms/java/src/powXn/TestPowXn.java @@ -0,0 +1,18 @@ +package powXn; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Test for 50. Pow(x, n) + */ +public class TestPowXn { + @Test + public void test() { + PowXn solution = new PowXn(); + Assert.assertTrue(solution.myPow01(3, 9) == 19683); + Assert.assertTrue(solution.myPow02(3, 9) == 19683); + Assert.assertTrue(solution.myPow01(2.10000, -3)-0.10798<0.0001); + Assert.assertTrue(solution.myPow02(2.10000, -3)-0.10798<0.0001); + } +} diff --git a/algorithms/java/src/removeDuplicatesFromSortedArray/RemoveDuplicatesFromSortedArray.java b/algorithms/java/src/removeDuplicatesFromSortedArray/RemoveDuplicatesFromSortedArray.java new file mode 100644 index 000000000..fb877c838 --- /dev/null +++ b/algorithms/java/src/removeDuplicatesFromSortedArray/RemoveDuplicatesFromSortedArray.java @@ -0,0 +1,38 @@ +// Source : https://leetcode.com/problems/remove-duplicates-from-sorted-array/description/ +// Author : Tianming Cao +// Date : 2018-02-02 + +/********************************************************************************** + * Implement the following operations of a stack using queues. + + * Given a sorted array, remove the duplicates in-place such that each element appear only once and return the new length. + + * Do not allocate extra space for another array, + * you must do this by modifying the input array in-place with O(1) extra memory. + + * Example: + + * Given nums = [1,1,2], + + * Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. + * It doesn't matter what you leave beyond the new length. + * + **********************************************************************************/ +package removeDuplicatesFromSortedArray; + +public class RemoveDuplicatesFromSortedArray { + public int removeDuplicates(int[] nums) { + if (nums == null || nums.length == 0) { + return 0; + } + int n = nums.length; + int len = 0; + for (int i = 1; i < n; i++) { + if (nums[i] != nums[len]) { + nums[len + 1] = nums[i]; + len++; + } + } + return len + 1; + } +} diff --git a/algorithms/java/src/removeDuplicatesFromSortedArray/TestRemoveDuplicates.java b/algorithms/java/src/removeDuplicatesFromSortedArray/TestRemoveDuplicates.java new file mode 100644 index 000000000..7756f45b6 --- /dev/null +++ b/algorithms/java/src/removeDuplicatesFromSortedArray/TestRemoveDuplicates.java @@ -0,0 +1,27 @@ +package removeDuplicatesFromSortedArray; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Test for 26. Remove Duplicates from Sorted Array + */ +public class TestRemoveDuplicates { + @Test + public void test() { + int[] nums1 = {0, 0, 0, 0, 0, 1, 2, 2, 3, 3, 4, 4}; + RemoveDuplicatesFromSortedArray solution = new RemoveDuplicatesFromSortedArray(); + int len1 = solution.removeDuplicates(nums1); + Assert.assertTrue(len1 == 5); + assertSorted(nums1, len1); + int[] nums2 = {1, 2, 2, 2, 3, 4, 5, 6, 6, 7, 7, 7, 8}; + int len2 = solution.removeDuplicates(nums2); + Assert.assertTrue(len2 == 8); + assertSorted(nums2, len2); + } + private void assertSorted(int[] array, int len) { + for (int i = 0; i < len - 1; i++) { + Assert.assertTrue(array[i] < array[i + 1]); + } + } +} diff --git a/algorithms/java/src/reverseLinkedList/ListNode.java b/algorithms/java/src/reverseLinkedList/ListNode.java new file mode 100644 index 000000000..b38b556b2 --- /dev/null +++ b/algorithms/java/src/reverseLinkedList/ListNode.java @@ -0,0 +1,46 @@ +package reverseLinkedList; + +public class ListNode { + public int val; + public ListNode next; + public ListNode(int x) { + val = x; + } + @Override + public String toString() { + return "ListNode [val=" + val + "]"; + } + public ListNode(int val, ListNode next) { + super(); + this.val = val; + this.next = next; + } + /** + * This is an assistant function, use it, we can easily see the structure of list + */ + public static String listToString(ListNode head) { + if (head == null) { + return ""; + } + StringBuilder sb = new StringBuilder(); + while (head.next != null) { + sb.append(head.val).append(","); + head = head.next; + } + sb.append(head.val); + return sb.toString(); + } + + /** + * This is an assistant function, use it, we can create a linkedList by array. + */ + public static ListNode arrayToList(int[] array) { + ListNode head = new ListNode(0); + ListNode p = head; + for (int i : array) { + p.next = new ListNode(i); + p = p.next; + } + return head.next; + } +} diff --git a/algorithms/java/src/reverseLinkedList/ReverseLinkedList.java b/algorithms/java/src/reverseLinkedList/ReverseLinkedList.java new file mode 100644 index 000000000..06ae90bcc --- /dev/null +++ b/algorithms/java/src/reverseLinkedList/ReverseLinkedList.java @@ -0,0 +1,58 @@ +// Source : https://leetcode.com/problems/reverse-linked-list/description/ +// Author : Tianming Cao +// Date : 2018-02-11 + +/********************************************************************************** + * + * Reverse a singly linked list. + * + * Hint: + * A linked list can be reversed either iteratively or recursively. Could you implement both? + * + **********************************************************************************/ +package reverseLinkedList; + +public class ReverseLinkedList { + + /** + * The iterative solution + */ + public ListNode reverseList(ListNode head) { + if (head == null) { + return head; + } + ListNode p = head; + ListNode next = p.next; + while (next != null) { + ListNode temp = next.next; + next.next = p; + p = next; + next = temp; + } + head.next = null; + return p; + } + + public ListNode reverseListRecursion(ListNode head) { + if (head == null) { + return head; + } + ListNode newHead = recursion(head); + head.next = null; + return newHead; + } + /** + * The recursive solution + */ + public ListNode recursion(ListNode p) { + if (p.next == null) { + return p; + } else { + ListNode next = p.next; + ListNode newHead = recursion(next); + next.next = p; + return newHead; + } + } + +} diff --git a/algorithms/java/src/reverseLinkedList/TestReverseLinkedList.java b/algorithms/java/src/reverseLinkedList/TestReverseLinkedList.java new file mode 100644 index 000000000..f87e5e0a2 --- /dev/null +++ b/algorithms/java/src/reverseLinkedList/TestReverseLinkedList.java @@ -0,0 +1,22 @@ +package reverseLinkedList; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Test for 206. Reverse Linked List + */ +public class TestReverseLinkedList { + @Test + public void test(){ + ReverseLinkedList solution=new ReverseLinkedList(); + int[] array1={1,2,3,4,5,6}; + ListNode head1=ListNode.arrayToList(array1); + ListNode newHead1=solution.reverseList(head1); + Assert.assertTrue(ListNode.listToString(newHead1).equals("6,5,4,3,2,1")); + int[] array2={6,5,4,3,2,1}; + ListNode head2=ListNode.arrayToList(array2); + ListNode newHead2=solution.reverseListRecursion(head2); + Assert.assertTrue(ListNode.listToString(newHead2).equals("1,2,3,4,5,6")); + } +} diff --git a/algorithms/java/src/reverseLinkedListII/ListNode.java b/algorithms/java/src/reverseLinkedListII/ListNode.java new file mode 100644 index 000000000..a2b1c208b --- /dev/null +++ b/algorithms/java/src/reverseLinkedListII/ListNode.java @@ -0,0 +1,46 @@ +package reverseLinkedListII; + +public class ListNode { + public int val; + public ListNode next; + public ListNode(int x) { + val = x; + } + @Override + public String toString() { + return "ListNode [val=" + val + "]"; + } + public ListNode(int val, ListNode next) { + super(); + this.val = val; + this.next = next; + } + /** + * This is an assistant function, use it, we can easily see the structure of list + */ + public static String listToString(ListNode head) { + if (head == null) { + return ""; + } + StringBuilder sb = new StringBuilder(); + while (head.next != null) { + sb.append(head.val).append(","); + head = head.next; + } + sb.append(head.val); + return sb.toString(); + } + + /** + * This is an assistant function, use it, we can create a linkedList by array. + */ + public static ListNode arrayToList(int[] array) { + ListNode head = new ListNode(0); + ListNode p = head; + for (int i : array) { + p.next = new ListNode(i); + p = p.next; + } + return head.next; + } +} diff --git a/algorithms/java/src/reverseLinkedListII/ReverseLinkedListII.java b/algorithms/java/src/reverseLinkedListII/ReverseLinkedListII.java new file mode 100644 index 000000000..e2d5d0b7d --- /dev/null +++ b/algorithms/java/src/reverseLinkedListII/ReverseLinkedListII.java @@ -0,0 +1,53 @@ +// Source : https://leetcode.com/problems/reverse-linked-list-ii/description/ +// Author : Tianming Cao +// Date : 2018-02-11 + +/********************************************************************************** + * + * Reverse a linked list from position m to n. Do it in-place and in one-pass. + * + * For example: + * Given 1->2->3->4->5->NULL, m = 2 and n = 4, + * + * return 1->4->3->2->5->NULL. + * + * Note: + * Given m, n satisfy the following condition: + * 1 ≤ m ≤ n ≤ length of list. + * + **********************************************************************************/ +package reverseLinkedListII; + +public class ReverseLinkedListII { + public ListNode reverseBetween(ListNode head, int m, int n) { + // Assume that the list is:[1,2,3,4,5,6,7] m=3 n=5 + if (head == null || m == n) { + // bounds check + return head; + } + // We'd better create a default head due to m may equals 1 + ListNode defaultHead = new ListNode(0); + defaultHead.next = head; + int index = 1; + ListNode pre = defaultHead; + while (index < m) { + pre = pre.next; + index++; + } + // pre is 2, first is 3 + ListNode first = pre.next; + ListNode p = first; + ListNode next = p.next; + while (index < n) { + ListNode t = next.next; + next.next = p; + p = next; + next = t; + index++; + } + // next is 6 + first.next = next; + pre.next = p; + return defaultHead.next; + } +} diff --git a/algorithms/java/src/reverseLinkedListII/TestReverseLinkedListII.java b/algorithms/java/src/reverseLinkedListII/TestReverseLinkedListII.java new file mode 100644 index 000000000..b0aae856a --- /dev/null +++ b/algorithms/java/src/reverseLinkedListII/TestReverseLinkedListII.java @@ -0,0 +1,24 @@ +package reverseLinkedListII; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Test for 92. Reverse Linked List II + */ +public class TestReverseLinkedListII { + @Test + public void test() { + ReverseLinkedListII solution = new ReverseLinkedListII(); + int[] array1 = {1, 2, 3, 4, 5, 6, 7}; + ListNode head1 = ListNode.arrayToList(array1); + ListNode newHead1 = solution.reverseBetween(head1, 3, 5); + Assert.assertTrue(ListNode.listToString(newHead1).equals( + "1,2,5,4,3,6,7")); + int[] array2 = {7, 6, 5, 4, 3, 2, 1}; + ListNode head2 = ListNode.arrayToList(array2); + ListNode newHead2 = solution.reverseBetween(head2, 1, 7); + Assert.assertTrue(ListNode.listToString(newHead2).equals( + "1,2,3,4,5,6,7")); + } +} diff --git a/algorithms/java/src/reverseWordsInAString/ReverseWordsInAString.java b/algorithms/java/src/reverseWordsInAString/ReverseWordsInAString.java new file mode 100644 index 000000000..c866af57b --- /dev/null +++ b/algorithms/java/src/reverseWordsInAString/ReverseWordsInAString.java @@ -0,0 +1,35 @@ +// Source : https://leetcode.com/problems/reverse-words-in-a-string/description/ +// Author : Tianming Cao +// Date : 2018-02-11 + +/********************************************************************************** + * + * Given an input string, reverse the string word by word. + * + * For example, + * Given s = "the sky is blue", + * return "blue is sky the". + * + * Update (2015-02-12): + * For C programmers: Try to solve it in-place in O(1) space. + * + **********************************************************************************/ +package reverseWordsInAString; + +public class ReverseWordsInAString { + + public String reverseWords(String s) { + if (s == null || s.length() == 0) { + return s; + } + s = s.trim(); + String[] array = s.split("\\s+"); + StringBuilder sb = new StringBuilder(); + int len = array.length; + for (int i = len - 1; i > 0; i--) { + sb.append(array[i]).append(" "); + } + sb.append(array[0]); + return sb.toString(); + } +} diff --git a/algorithms/java/src/reverseWordsInAString/TestReverseWordsInAString.java b/algorithms/java/src/reverseWordsInAString/TestReverseWordsInAString.java new file mode 100644 index 000000000..4a5db14cd --- /dev/null +++ b/algorithms/java/src/reverseWordsInAString/TestReverseWordsInAString.java @@ -0,0 +1,17 @@ +package reverseWordsInAString; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Test for 151. Reverse Words in a String + */ +public class TestReverseWordsInAString { + @Test + public void test() { + ReverseWordsInAString solution = new ReverseWordsInAString(); + String str = " the sky is blue "; + String result = solution.reverseWords(str); + Assert.assertTrue(result.equals("blue is sky the")); + } +} diff --git a/algorithms/java/src/rotateArray/RotateArray.java b/algorithms/java/src/rotateArray/RotateArray.java new file mode 100644 index 000000000..899f53be8 --- /dev/null +++ b/algorithms/java/src/rotateArray/RotateArray.java @@ -0,0 +1,55 @@ +// Source : https://leetcode.com/problems/rotate-array/description/ +// Author : Tianming Cao +// Date : 2018-02-02 + +/********************************************************************************** + * Rotate an array of n elements to the right by k steps. + * + * For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4]. + * + * Note: + * Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem. + * + * Hint: + * Could you do it in-place with O(1) extra space? + * Related problem: Reverse Words in a String II + * + **********************************************************************************/ +package rotateArray; +/********************************************************************************** + * + * For example, with n = 9 and k = 4, the array is [1,2,3,4,5,6,7,8,9] + * The train of thought is: + * 1. Reverse 1-5 to [5,4,3,2,1] + * 2. Reverse 6-9 to [9,8,7,6] + * 3. Reverse the entire array [5,4,3,2,1,9,8,7,6] to [6,7,8,9,1,2,3,4,5] + * It's a liner time and in-place algorithm + * + **********************************************************************************/ +public class RotateArray { + + public void rotate(int[] nums, int k) { + //bounds check + if (nums == null || nums.length == 0 || k == 0) { + return; + } + int n = nums.length; + //k may be larger than n + k = k % n; + rotateRange(0, n - k - 1, nums); + rotateRange(n - k, n - 1, nums); + rotateRange(0, n - 1, nums); + } + + private void rotateRange(int start, int end, int[] array) { + for (int i = start, j = end; i < j; i++, j--) { + swap(array, i, j); + } + } + private void swap(int[] array, int i, int j) { + int t = array[i]; + array[i] = array[j]; + array[j] = t; + } + +} diff --git a/algorithms/java/src/rotateArray/TestRotateArray.java b/algorithms/java/src/rotateArray/TestRotateArray.java new file mode 100644 index 000000000..15a41ca77 --- /dev/null +++ b/algorithms/java/src/rotateArray/TestRotateArray.java @@ -0,0 +1,27 @@ +package rotateArray; + +import java.util.Arrays; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Test for 189. Rotate Array + * + */ +public class TestRotateArray { + @Test + public void test() { + RotateArray solution = new RotateArray(); + int[] array1 = {1, 2, 3, 4, 5, 6, 7}; + int k1 = 24; + solution.rotate(array1, k1); + int[] expectArray1 = {5, 6, 7, 1, 2, 3, 4}; + Assert.assertTrue(Arrays.equals(array1, expectArray1)); + int[] array2 = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + int k2 = 4; + solution.rotate(array2, k2); + int[] expectArray2 = {6, 7, 8, 9, 1, 2, 3, 4, 5}; + Assert.assertTrue(Arrays.equals(array2, expectArray2)); + } +} diff --git a/algorithms/java/src/searchA2DMatrixII/SearchA2DMatrixII.java b/algorithms/java/src/searchA2DMatrixII/SearchA2DMatrixII.java new file mode 100644 index 000000000..ca38cabb4 --- /dev/null +++ b/algorithms/java/src/searchA2DMatrixII/SearchA2DMatrixII.java @@ -0,0 +1,57 @@ +// Source : https://leetcode.com/problems/search-a-2d-matrix-ii/description/ +// Author : Tianming Cao +// Date : 2018-01-27 +/********************************************************************************** + * Write an efficient algorithm that searches for a value in an m x n matrix. + * This matrix has the following properties: + * + * Integers in each row are sorted in ascending from left to right. + * Integers in each column are sorted in ascending from top to bottom. + * For example, + * + * Consider the following matrix: + * + * [ + * [1, 4, 7, 11, 15], + * [2, 5, 8, 12, 19], + * [3, 6, 9, 16, 22], + * [10, 13, 14, 17, 24], + * [18, 21, 23, 26, 30] + * ] + * Given target = 5, return true. + * + * Given target = 20, return false. + * + **********************************************************************************/ +package searchA2DMatrixII; +/********************************************************************************** + * This probleam is similar to problem 74(https://leetcode.com/problems/search-a-2d-matrix/description/). + * One solution is: + * Compare rightTopNumber with target to judge rowIndex and colIndex which place to move, + * until thay out of range or find target. + * Another solution is using binarySearch. + **********************************************************************************/ +public class SearchA2DMatrixII { + public boolean searchMatrix(int[][] matrix, int target) { + if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { + return false; + } else { + int m=matrix.length; + int n=matrix[0].length; + int row=0; + int col=n-1; + while(row=0){ + int rightTopNumber=matrix[row][col]; + if(rightTopNumber==target){ + return true; + }else if(target>rightTopNumber){ + row++; + }else{ + col--; + } + } + return false; + } + } + +} diff --git a/algorithms/java/src/searchA2DMatrixII/Test_240.java b/algorithms/java/src/searchA2DMatrixII/Test_240.java new file mode 100644 index 000000000..b70d0ef40 --- /dev/null +++ b/algorithms/java/src/searchA2DMatrixII/Test_240.java @@ -0,0 +1,19 @@ +package searchA2DMatrixII; + +import org.junit.Assert; +import org.junit.Test; +/** + * Test for 240. Search a 2D Matrix II + */ +public class Test_240 { + @Test + public void test() { + SearchA2DMatrixII solution = new SearchA2DMatrixII(); + int[][] matrix = {{1, 4, 7, 11, 15}, {2, 5, 8, 12, 19}, + {3, 6, 9, 16, 22}, {10, 13, 14, 17, 24}, {18, 21, 23, 26, 30}}; + int target = 5; + Assert.assertTrue(solution.searchMatrix(matrix, target)); + target = 20; + Assert.assertTrue(!solution.searchMatrix(matrix, target)); + } +} diff --git a/algorithms/java/src/strStr/StrStrKmp.java b/algorithms/java/src/strStr/StrStrKmp.java new file mode 100644 index 000000000..a5fe657dc --- /dev/null +++ b/algorithms/java/src/strStr/StrStrKmp.java @@ -0,0 +1,126 @@ +// Source : https://leetcode.com/problems/implement-strstr/description/ +// Inspired by : http://wiki.jikexueyuan.com/project/kmp-algorithm/define.html +// Author : Tianming Cao +// Date : 2018-02-11 + +/********************************************************************************** + * + * Implement strStr(). + * + * Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. + * + * Example 1: + * + * Input: haystack = "hello", needle = "ll" + * Output: 2 + * + * Example 2: + * + * Input: haystack = "aaaaa", needle = "bba" + * Output: -1 + * + **********************************************************************************/ +package strStr; + +public class StrStrKmp { + + /** + * KMP-Algorithm + */ + public int strStr(String haystack, String needle) { + if (haystack == null && needle == null) { + return 0; + } + if (haystack == null && needle != null) { + return -1; + } + if (haystack != null && needle == null) { + return -1; + } + int m = haystack.length(); + int n = needle.length(); + if (m < n) { + return -1; + } + if (n == 0) { + return 0; + } + int[] nextArray = getNext(needle); + int i = 0; + int j = 0; + while (i < m) { + if (j == -1) { + // If pointer j is in boundary, move i to the right and reset j + i++; + j = 0; + } else { + if (haystack.charAt(i) == needle.charAt(j)) { + // While matching succeess, move both pointer i and pointer j to the right + i++; + j++; + if (j == n) { + return i - n; + } + } else { + /*** + * For example: + * + * next: [-1,0,0,0,0,1,2] + * + * i + * ↓ + * haystack:BBC ABCDAB ABCDABCDABDE + * j + * ↓ + * needle: ABCDABD + * + * + * So the next step is: + * + * i + * ↓ + * haystack:BBC ABCDAB ABCDABCDABDE + * j + * ↓ + * needle: ABCDABD + */ + j = nextArray[j]; + } + } + } + return -1; + } + /** + * Generate the next-array of needle string + * + * For example: + * + * next-array of "ABCDABD" is: [-1,0,0,0,0,1,2] + * + * For letter "D", the longest prefix "AB" is equal to the longest suffix "AB", + * the string "AB"'s length is 2, so letter "D"'s next value is 2. + */ + public int[] getNext(String str) { + int len = str.length(); + int[] next = new int[len]; + next[0] = -1; + int k = -1; + int j = 0; + while (j < len - 1) { + if (k == -1) { + k = 0; + next[j + 1] = 0; + j++; + } else { + if (str.charAt(j) == str.charAt(k)) { + next[j + 1] = k + 1; + k++; + j++; + } else { + k = next[k]; + } + } + } + return next; + } +} diff --git a/algorithms/java/src/strStr/TestStrStrKmp.java b/algorithms/java/src/strStr/TestStrStrKmp.java new file mode 100644 index 000000000..9cc68e9f7 --- /dev/null +++ b/algorithms/java/src/strStr/TestStrStrKmp.java @@ -0,0 +1,25 @@ +package strStr; + +import org.junit.Assert; +import org.junit.Test; +/** + * Test for 28. Implement strStr() using KMP-Algorithm + */ +public class TestStrStrKmp { + @Test + public void testKmp() { + StrStrKmp solution = new StrStrKmp(); + String hayStack1 = "aabbccagdbbccdec"; + String needle1 = "bbccd"; + int result1 = solution.strStr(hayStack1, needle1); + Assert.assertTrue(result1 == 9); + String hayStack2 = "aabbccagdbbccdec"; + String needle2 = "bbccf"; + int result2 = solution.strStr(hayStack2, needle2); + Assert.assertTrue(result2 == -1); + String hayStack3 = "BBC ABCDAB ABCDABCDABDE"; + String needle3 = "ABCDABD"; + int result3 = solution.strStr(hayStack3, needle3); + Assert.assertTrue(result3 == 15); + } +} diff --git a/algorithms/java/src/validAnagram/TestValidAnagram.java b/algorithms/java/src/validAnagram/TestValidAnagram.java new file mode 100644 index 000000000..015dcb848 --- /dev/null +++ b/algorithms/java/src/validAnagram/TestValidAnagram.java @@ -0,0 +1,16 @@ +package validAnagram; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Test for 242. Valid Anagram + */ +public class TestValidAnagram { + @Test + public void test() { + ValidAnagram solution = new ValidAnagram(); + Assert.assertTrue(solution.isAnagram("anagram", "nagaram")); + Assert.assertTrue(!solution.isAnagram("rat", "car")); + } +} diff --git a/algorithms/java/src/validAnagram/ValidAnagram.java b/algorithms/java/src/validAnagram/ValidAnagram.java new file mode 100644 index 000000000..b1bfe9904 --- /dev/null +++ b/algorithms/java/src/validAnagram/ValidAnagram.java @@ -0,0 +1,53 @@ +// Source : https://leetcode.com/problems/valid-anagram/description/ +// Author : Tianming Cao +// Date : 2018-02-11 + +/********************************************************************************** + * + * Given two strings s and t, write a function to determine if t is an anagram of s. + * + * For example, + * s = "anagram", t = "nagaram", return true. + * s = "rat", t = "car", return false. + * + * Note: + * You may assume the string contains only lowercase alphabets. + * + * Follow up: + * What if the inputs contain unicode characters? How would you adapt your solution to such case? + * + **********************************************************************************/ +package validAnagram; + +public class ValidAnagram { + + /** + * Like counting-sort + */ + public boolean isAnagram(String s, String t) { + if (s == null && t == null) { + return true; + } + if (s.length() != t.length()) { + return false; + } + final int mapLen = 26; + int[] map1 = new int[mapLen]; + int[] map2 = new int[mapLen]; + int len = s.length(); + for (int i = 0; i < len; i++) { + char c1 = s.charAt(i); + map1[c1 - 'a']++; + // ASCII of letter a is 97 + int c2 = t.charAt(i); + map2[c2 - 97]++; + } + for (int i = 0; i < mapLen; i++) { + if (map1[i] != map2[i]) { + return false; + } + } + return true; + } + +} diff --git a/algorithms/java/src/validPalindrome/TestValidPalindrome.java b/algorithms/java/src/validPalindrome/TestValidPalindrome.java new file mode 100644 index 000000000..c66ca43b4 --- /dev/null +++ b/algorithms/java/src/validPalindrome/TestValidPalindrome.java @@ -0,0 +1,17 @@ +package validPalindrome; + +import org.junit.Assert; +import org.junit.Test; +/** + * Test for 125. Valid Palindrome + */ +public class TestValidPalindrome { + @Test + public void test() { + ValidPalindrome solution = new ValidPalindrome(); + String str1 = "A man, a plan, a canal: Panama"; + Assert.assertTrue(solution.isPalindrome(str1)); + String str2 = "race a car"; + Assert.assertTrue(!solution.isPalindrome(str2)); + } +} diff --git a/algorithms/java/src/validPalindrome/ValidPalindrome.java b/algorithms/java/src/validPalindrome/ValidPalindrome.java new file mode 100644 index 000000000..73185d22e --- /dev/null +++ b/algorithms/java/src/validPalindrome/ValidPalindrome.java @@ -0,0 +1,59 @@ +// Source : https://leetcode.com/problems/valid-palindrome/description/ +// Author : Tianming Cao +// Date : 2018-02-11 + +/********************************************************************************** + * + * Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. + * + * For example, + * "A man, a plan, a canal: Panama" is a palindrome. + * "race a car" is not a palindrome. + * + * Note: + * Have you consider that the string might be empty? This is a good question to ask during an interview. + * + * For the purpose of this problem, we define empty string as valid palindrome. + * + **********************************************************************************/ +package validPalindrome; + +public class ValidPalindrome { + private boolean isAlphaNumber(char c) { + if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9')) { + return true; + } else { + return false; + } + } + /** + * We need two pointers like below: + * + * i j + * ↓-------> <--------↓ + * a,b c d e e d;c b a + + * + * Move them from border to mid, util i meet j or s[i]!=s[j] + */ + public boolean isPalindrome(String s) { + if (s == null || s.length() <= 1) { + return true; + } + s = s.toLowerCase(); + int i = 0, j = s.length() - 1; + while (i < j) { + while (!isAlphaNumber(s.charAt(i)) && i < j) { + i++; + } + while (!isAlphaNumber(s.charAt(j)) && i < j) { + j--; + } + if (s.charAt(i) != s.charAt(j)) { + return false; + } + i++; + j--; + } + return true; + } +} diff --git a/algorithms/python/1-bitAnd2-bitCharacters/isOneBitCharacter.py b/algorithms/python/1-bitAnd2-bitCharacters/isOneBitCharacter.py new file mode 100644 index 000000000..bcdfc7069 --- /dev/null +++ b/algorithms/python/1-bitAnd2-bitCharacters/isOneBitCharacter.py @@ -0,0 +1,10 @@ +def isOneBitCharacter(self, bits): + i = 0 + while i < len(bits): + if bits[i] == 0: + i += 1 + if i >= len(bits): return True + if bits[i] == 1: + i += 2 + if i >= len(bits): return False + if i == len(bits) - 1: return True \ No newline at end of file diff --git a/algorithms/python/AddOneRowToTree/addOneRow.py b/algorithms/python/AddOneRowToTree/addOneRow.py new file mode 100644 index 000000000..524ffc312 --- /dev/null +++ b/algorithms/python/AddOneRowToTree/addOneRow.py @@ -0,0 +1,12 @@ +# get the nodes at (d - 1) layer: + +def addOneRow(self, root, v, d): + dummy, dummy.left = TreeNode(v), root + row = [dummy] + for _ in range(d - 1): + row = [kid for node in row for kid in (node.left, node.right) if kid] + + for node in row: + node.left, node.left.left = TreeNode(v), node.left + node.right, node.right.right = TreeNode(v), node.right + return dummy.left \ No newline at end of file diff --git a/algorithms/python/BinarySearchTreeIterator/BSTIterator.py b/algorithms/python/BinarySearchTreeIterator/BSTIterator.py new file mode 100644 index 000000000..7081aa712 --- /dev/null +++ b/algorithms/python/BinarySearchTreeIterator/BSTIterator.py @@ -0,0 +1,39 @@ +# straight forward solution: do a inorder traversal + +class BSTIterator(object): + def __init__(self, root): + self.inorder = [] + def helper(root): + if root: + helper(root.left) + self.inorder.append(root.val) + helper(root.right) + helper(root) + + def hasNext(self): + return len(self.inorder) != 0 + + def next(self): + return self.inorder.pop(0) + +# Alternative solution: +class BSTIterator(object): + def __init__(self, root): + self.stack = [] + while root: + self.stack.append(root) + root = root.left + + + def hasNext(self): + return len(self.stack) != 0 + + + def next(self): + node = self.stack.pop() + x = node.right + while x: + self.stack.append(x) + x = x.left + return node.val + \ No newline at end of file diff --git a/algorithms/python/BinaryTreePostorderTraversal/postorderTraversal.py b/algorithms/python/BinaryTreePostorderTraversal/postorderTraversal.py new file mode 100644 index 000000000..40bee1b6e --- /dev/null +++ b/algorithms/python/BinaryTreePostorderTraversal/postorderTraversal.py @@ -0,0 +1,31 @@ +""" +Method 1: recursive +""" +def postorderTraversal(self, root): + res = [] + def helper(root): + if root: + helper(root.left) + helper(root.right) + res.append(root.val) + helper(root) + return res + +""" +Method 2: iterative, using two stacks +initialize first stack with root node, do the following if first is not None: + pop from first stack, append the popped element to second stack, + add left and right node to first stack if they are not None +return the second stack's value in reverse order +""" +def postorderTraversal(self, root): + if not root: return [] + first, second = [root], [] + while first: + node = first.pop() + second.append(node) + if node.left: first.append(node.left) + if node.right: first.append(node.right) + res = [node.val for node in second] + res.reverse() + return res \ No newline at end of file diff --git a/algorithms/python/BinaryTreeTilt/findTilt.py b/algorithms/python/BinaryTreeTilt/findTilt.py new file mode 100644 index 000000000..19f1ad00b --- /dev/null +++ b/algorithms/python/BinaryTreeTilt/findTilt.py @@ -0,0 +1,10 @@ +def findTilt(self, root): + self.res = 0 + def helper(root): + if not root: return 0 + left = helper(root.left) + right = helper(root.right) + self.res += abs(left - right) + return root.val + left + right + helper(root) + return self.res \ No newline at end of file diff --git a/algorithms/python/BinaryTreeZigzagLevelOrderTraversal/zigzagLevelOrder.py b/algorithms/python/BinaryTreeZigzagLevelOrderTraversal/zigzagLevelOrder.py new file mode 100644 index 000000000..71c5ed75f --- /dev/null +++ b/algorithms/python/BinaryTreeZigzagLevelOrderTraversal/zigzagLevelOrder.py @@ -0,0 +1,18 @@ +""" +simple bfs +""" + +def zigzagLevelOrder(self, root): + if not root: return [] + stack = [[root]] + res = [[root.val]] + level = 0 + while True: + level += 1 + children = [child for node in stack[-1] for child in (node.left, node.right) if child] + if not children: break + temp = [node.val for node in children] + if level % 2 == 1: temp.reverse() + res.append(temp) + stack.append(children) + return res \ No newline at end of file diff --git a/algorithms/python/CheckCompletenessOfABinaryTree/isCompleteTree.py b/algorithms/python/CheckCompletenessOfABinaryTree/isCompleteTree.py new file mode 100644 index 000000000..a03ad7f45 --- /dev/null +++ b/algorithms/python/CheckCompletenessOfABinaryTree/isCompleteTree.py @@ -0,0 +1,14 @@ +def isCompleteTree(self, root): + stack = [[(root, 0)]] + layer = 0 + while True: + children = [] + for node, value in stack[-1]: + if node.left: children.append((node.left, 2 * value)) + if node.right: children.append((node.right, 2 * value + 1)) + if node.right and not node.left: return False + if not children: break + if len(stack[-1]) != pow(2, layer): return False + stack.append(children) + layer += 1 + return len(stack[-1]) == stack[-1][-1][1] + 1 \ No newline at end of file diff --git a/algorithms/python/ConstructBinaryTreeFromInorderAndPostorderTraversal/buildTree.py b/algorithms/python/ConstructBinaryTreeFromInorderAndPostorderTraversal/buildTree.py new file mode 100644 index 000000000..44bfec2d1 --- /dev/null +++ b/algorithms/python/ConstructBinaryTreeFromInorderAndPostorderTraversal/buildTree.py @@ -0,0 +1,7 @@ +def buildTree(self, inorder, postorder): + if inorder: + i = inorder.index(postorder.pop()) + root = TreeNode(inorder[i]) + root.right = self.buildTree(inorder[i+1:], postorder) + root.left = self.buildTree(inorder[:i], postorder) + return root \ No newline at end of file diff --git a/algorithms/python/ConstructBinaryTreeFromPreorderAndInorderTraversal/buildTree.py b/algorithms/python/ConstructBinaryTreeFromPreorderAndInorderTraversal/buildTree.py new file mode 100644 index 000000000..07fe597a9 --- /dev/null +++ b/algorithms/python/ConstructBinaryTreeFromPreorderAndInorderTraversal/buildTree.py @@ -0,0 +1,7 @@ +def buildTree(self, preorder, inorder): + if inorder: + i = inorder.index(preorder.pop(0)) + root = TreeNode(inorder[i]) + root.left = self.buildTree(preorder, inorder[:i]) + root.right = self.buildTree(preorder, inorder[i+1:]) + return root \ No newline at end of file diff --git a/algorithms/python/ContainsDuplicateII/containsNearbyDuplicate.py b/algorithms/python/ContainsDuplicateII/containsNearbyDuplicate.py new file mode 100644 index 000000000..372539e74 --- /dev/null +++ b/algorithms/python/ContainsDuplicateII/containsNearbyDuplicate.py @@ -0,0 +1,21 @@ +# Method 1: using set + +def containsNearbyDuplicate(self, nums, k): + if len(nums) <= k + 1: return len(nums) != len(set(nums)) + if k == 0: return False + s = set(nums[:k]) + for i in range(k, len(nums)): + if nums[i] in s: return True + else: + s.remove(nums[i - k]) + s.add(nums[i]) + return False + +# Method 2: using dictionary +def containsNearbyDuplicate(self, nums, k): + d = {} + for i, n in enumerate(nums): + if n in d and i - d[v] <= k: + return True + d[n] = i + return False \ No newline at end of file diff --git a/algorithms/python/ContainsDuplicateIII/containsNearbyAlmostDuplicate.py b/algorithms/python/ContainsDuplicateIII/containsNearbyAlmostDuplicate.py new file mode 100644 index 000000000..4bb450920 --- /dev/null +++ b/algorithms/python/ContainsDuplicateIII/containsNearbyAlmostDuplicate.py @@ -0,0 +1,12 @@ +def containsNearbyAlmostDuplicate(self, nums, k, t): + if k < 1 or t < 0: return False + d = {} + w = t + 1 + for i, n in enumerate(nums): + m = n // w + if m in d: return True + if m - 1 in d and abs(d[m-1] - n) <= t: return True + if m + 1 in d and abs(d[m+1] - n) <= t: return True + d[m] = n + if i >= k: del d[nums[i - k] // w] + return False \ No newline at end of file diff --git a/algorithms/python/ConvertBSTtoGreaterTree/convertBST.py b/algorithms/python/ConvertBSTtoGreaterTree/convertBST.py new file mode 100644 index 000000000..5f33c3db3 --- /dev/null +++ b/algorithms/python/ConvertBSTtoGreaterTree/convertBST.py @@ -0,0 +1,18 @@ +""" +since this is a BST, we can do a inorder traversal (inversed, from right to left), +during this process, track the sum and update the node.val +""" + +class Solution: + def convertBST(self, root): + self.total = 0 + + def helper(node): + if not node: return + helper(node.right) + node.val += self.total + self.total = node.val + helper(node.left) + + helper(root) + return root \ No newline at end of file diff --git a/algorithms/python/CopyListWithRandomPointer/copyRandomList.py b/algorithms/python/CopyListWithRandomPointer/copyRandomList.py new file mode 100644 index 000000000..997fd0de6 --- /dev/null +++ b/algorithms/python/CopyListWithRandomPointer/copyRandomList.py @@ -0,0 +1,51 @@ +# method 1: using a dict and store each node as key, each copied node as value +# Space complexity: O(n) +# Time complexity: O(n) + +def copyRandomList(self, head): + d = {} + m = n = head + while m: + d[m] = RandomListNode(m.label) + m = m.next + + while n: + d[n].next = d.get(n.next) + d[n].random = d.get(n.random) + n = n.next + + return d.get(head) + +# Method 2: +# Space complexity: O(1) +# Time complexity: O(n) + +def copyRandomList(self, head): + if not head: return None + + # Step 1: copy each node and link them together with original ones + curr = head + while curr: + new = RandomListNode(curr.label) + new.next = curr.next + curr.next = new + curr = curr.next.next + + # Step 2: build random node for each copied nodes + curr = head + while curr: + if curr.random: curr.next.random = curr.random.next + curr = curr.next.next + + # Step 3: restore the original list and extract copied list + newhead = head.next + pold = head + pnew = newhead + while pnew.next: + pold.next = pnew.next + pold = pold.next + pnew.next = pold.next + pnew = pnew.next + pold.next = None + pnew.next = None + return newhead \ No newline at end of file diff --git a/algorithms/python/CountCompleteTreeNodes/countNodes.py b/algorithms/python/CountCompleteTreeNodes/countNodes.py new file mode 100644 index 000000000..5175d9b04 --- /dev/null +++ b/algorithms/python/CountCompleteTreeNodes/countNodes.py @@ -0,0 +1,12 @@ +def countNodes(self, root): + if not root: return 0 + hl, hr = 0, 0 + l, r = root, root + while l: + hl += 1 + l = l.left + while r: + hr += 1 + r = r.right + if hl == hr: return pow(2, hl) - 1 + return 1 + self.countNodes(root.left) + self.countNodes(root.right) \ No newline at end of file diff --git a/algorithms/python/DeleteNodeInABST/deleteNode.py b/algorithms/python/DeleteNodeInABST/deleteNode.py new file mode 100644 index 000000000..2c50e85f2 --- /dev/null +++ b/algorithms/python/DeleteNodeInABST/deleteNode.py @@ -0,0 +1,32 @@ +""" +case 1: if node we want to delete has no children: simply delete it +case 2: if it has only one child, then replace it with its child +case 3: if it has two children, first find the inorder successor (or predecessor), + then replace the node's value with successor's value, and finally delete this successor +""" + +def deleteNode(self, root, key): + if not root: return None + if key < root.val: + root.left = self.deleteNode(root.left, key) + elif key > root.val: + root.right = self.deleteNode(root.right, key) + else: + # if this node has only one child or no child: + if not root.left: + temp = root.right + root = None + return temp + elif not root.right: + temp = root.left + root = None + return temp + + # otherwise, find the inorder successor: + curr = root.right + while curr.left: + curr = curr.left + + root.val = curr.val + root.right = self.deleteNode(root.right, curr.val) + return root \ No newline at end of file diff --git a/algorithms/python/DiameterOfBinaryTree/diameterOfBinaryTree.py b/algorithms/python/DiameterOfBinaryTree/diameterOfBinaryTree.py new file mode 100644 index 000000000..42dc20173 --- /dev/null +++ b/algorithms/python/DiameterOfBinaryTree/diameterOfBinaryTree.py @@ -0,0 +1,9 @@ +def diameterOfBinaryTree(self, root): + self.res = 0 + def helper(root): + if not root: return 0 + left, right = helper(root.left), helper(root.right) + self.res = max(self.res, left + right) + return 1 + max(left, right) + helper(root) + return self.res \ No newline at end of file diff --git a/algorithms/python/DifferentWaysToAddParentheses/diffWaysToCompute.py b/algorithms/python/DifferentWaysToAddParentheses/diffWaysToCompute.py new file mode 100644 index 000000000..62831e4a4 --- /dev/null +++ b/algorithms/python/DifferentWaysToAddParentheses/diffWaysToCompute.py @@ -0,0 +1,5 @@ +def diffWaysToCompute(self, input): + return [a + b if c == '+' else a - b if c == '-' else a * b \ + for i, c in enumerate(input) if c in '+-*' \ + for a in self.diffWaysToCompute(input[:i]) \ + for b in self.diffWaysToCompute(input[i+1:])] or [int(input)] \ No newline at end of file diff --git a/algorithms/python/FibonacciNumber/fib.py b/algorithms/python/FibonacciNumber/fib.py new file mode 100644 index 000000000..0459a8d17 --- /dev/null +++ b/algorithms/python/FibonacciNumber/fib.py @@ -0,0 +1,27 @@ +""" +Method 1: iterative: +""" +def fib1(self, N): + if N <= 1: return N + a, b = 0, 1 + for _ in range(2, N + 1): + a, b = b, a + b + return b + +""" +Method 2: recursive without memorization: +""" +def fib2(self, N): + if N <= 1: return N + return self.fib(N - 1) + self.fib(N - 2) + +""" +Method 3: recursive with memorization +""" +def fib3(self, N): + memo = {0:0, 1:1} + def helper(n): + if n not in memo: + memo[n] = helper(n - 1) + helper(n - 2) + return memo[n] + return helper(N) \ No newline at end of file diff --git a/algorithms/python/FindDuplicateSubtrees/findDuplicateSubtrees.py b/algorithms/python/FindDuplicateSubtrees/findDuplicateSubtrees.py new file mode 100644 index 000000000..b6fb7dd62 --- /dev/null +++ b/algorithms/python/FindDuplicateSubtrees/findDuplicateSubtrees.py @@ -0,0 +1,11 @@ +def findDuplicateSubtrees(self, root): + nodes = collections.defaultdict(list) + + def helper(root): + if not root: return 'None' + struct = '%s,%s,%s' % (str(root.val), helper(root.left), helper(root.right)) + nodes[struct].append(root) + return struct + + helper(root) + return [nodes[struct][0] for struct in nodes if len(nodes[struct]) > 1] \ No newline at end of file diff --git a/algorithms/python/FindTheDuplicateNumber/findDuplicate.py b/algorithms/python/FindTheDuplicateNumber/findDuplicate.py new file mode 100644 index 000000000..f682b4c76 --- /dev/null +++ b/algorithms/python/FindTheDuplicateNumber/findDuplicate.py @@ -0,0 +1,13 @@ +# the same as linked list cycle problem +def findDuplicate(self, nums): + if len(nums) <= 1: return -1 + slow, fast = nums[0], nums[nums[0]] + while slow != fast: + slow = nums[slow] + fast = nums[nums[fast]] + + fast = 0 + while slow != fast: + slow = nums[slow] + fast = nums[fast] + return slow \ No newline at end of file diff --git a/algorithms/python/FlattenBinaryTreeToLinkedList/flatten.py b/algorithms/python/FlattenBinaryTreeToLinkedList/flatten.py new file mode 100644 index 000000000..7a7af3c97 --- /dev/null +++ b/algorithms/python/FlattenBinaryTreeToLinkedList/flatten.py @@ -0,0 +1,11 @@ +class Solution(object): + def __init__(self): + self.prev = None + + def flatten(self, root): + if not root: return None + self.flatten(root.right) + self.flatten(root.left) + root.right = self.prev + root.left = None + self.prev = root \ No newline at end of file diff --git a/algorithms/python/FlipBinaryTreeToMatchPreorderTraversal/flipMatchVoyage.py b/algorithms/python/FlipBinaryTreeToMatchPreorderTraversal/flipMatchVoyage.py new file mode 100644 index 000000000..1e81010a1 --- /dev/null +++ b/algorithms/python/FlipBinaryTreeToMatchPreorderTraversal/flipMatchVoyage.py @@ -0,0 +1,12 @@ +def flipMatchVoyage(self, root, voyage): + res = [] + self.i = 0 + def dfs(root): + if not root: return True + if root.val != voyage[self.i]: return False + self.i += 1 + if root.left and root.left.val != voyage[self.i]: + res.append(root.val) + root.left, root.right = root.right, root.left + return dfs(root.left) and dfs(root.right) + return res if dfs(root) else [-1] \ No newline at end of file diff --git a/algorithms/python/FlipEquivalentBinaryTrees/flipEquiv.py b/algorithms/python/FlipEquivalentBinaryTrees/flipEquiv.py new file mode 100644 index 000000000..927d3acda --- /dev/null +++ b/algorithms/python/FlipEquivalentBinaryTrees/flipEquiv.py @@ -0,0 +1,45 @@ +""" +Method 1: + naive recursive solution, divide the original problem into four subproblems, + time complexity and space complexity are both O(n^2) +""" +def flipEquiv1(self, root1, root2): + if not root1 or not root2: + return root1 == root2 + if root1.val != root2.val: + return False + return self.flipEquiv(root1.left, root2.left) and \ + self.flipEquiv(root1.right, root2.right) or \ + self.flipEquiv(root1.left, root2.right) and \ + self.flipEquiv(root1.right, root2.left) + +""" +Method 2: + Step 1: first preprocessing these two trees, sort them in the following order: + if node.left.val > node.right.val, then swap them, make the smaller one to be left node + if the left node is None, then also swap them, make the non-None node to be left node + + Step 2: compare the swapped trees + + After preprocessing, the original problem is divided into two subproblems, time complexity: O(n) +""" +def flipEquiv2(self, root1, root2): + def flip(root): + if root: + if root.left and root.right and root.left.val > root.right.val: + root.left, root.right = root.right, root.left + if not root.left: + root.left, root.right = root.right, root.left + flip(root.left) + flip(root.right) + + def is_equal(root1, root2): + if not root1 or not root2: + return root1 == root2 + return root1.val == root2.val and \ + is_equal(root1.left, root2.left) and \ + is_equal(root1.right, root2.right) + + flip(root1) + flip(root2) + return is_equal(root1, root2) \ No newline at end of file diff --git a/algorithms/python/HappyNumber/isHappy.py b/algorithms/python/HappyNumber/isHappy.py new file mode 100644 index 000000000..2e2103911 --- /dev/null +++ b/algorithms/python/HappyNumber/isHappy.py @@ -0,0 +1,33 @@ +# Method 1: straight forward solution, use a set to track if there is a cycle + +def isHappy1(self, n): + if n <= 0: return False + s = set() + while n not in s: + s.add(n) + n = sum([int(i) ** 2 for i in str(n)]) + if n == 1: return True + return False + +# Method 2: using a slow and fast pointer to determine cycle (like in linked list) +# No extra space needed +def isHappy2(self, n): + """ + :type n: int + :rtype: bool + """ + if n <= 0: return False + def helper(n): + res = 0 + while n: + res += (n % 10) ** 2 + n = n // 10 + return res + + slow = fast = n + while True: + slow = helper(slow) + fast = helper(helper(fast)) + if slow == 1: return True + if slow == fast: break + return False \ No newline at end of file diff --git a/algorithms/python/HouseRobber/rob.py b/algorithms/python/HouseRobber/rob.py new file mode 100644 index 000000000..a408de34f --- /dev/null +++ b/algorithms/python/HouseRobber/rob.py @@ -0,0 +1,6 @@ +def rob(self, nums): + temp = [0, 0] + for n in nums: + temp[0], temp[1] = max(temp), n + temp[0] + + return max(temp) \ No newline at end of file diff --git a/algorithms/python/HouseRobberIII/rob.py b/algorithms/python/HouseRobberIII/rob.py new file mode 100644 index 000000000..f55a654ef --- /dev/null +++ b/algorithms/python/HouseRobberIII/rob.py @@ -0,0 +1,30 @@ +""" +Answe inspired by the post from here: +https://leetcode.com/problems/house-robber-iii/discuss/79330/Step-by-step-tackling-of-the-problem +""" +# Method 1: dynamic programming solution: +def rob1(self, root): + lookup = {} + def helper(root): + if not root: return 0 + if root in lookup: return lookup[root] + val = 0 + + if root.left: + val += helper(root.left.left) + helper(root.left.right) + if root.right: + val += helper(root.right.left) + helper(root.right.right) + val = max(val + root.val, helper(root.left) + helper(root.right)) + lookup[root] = val + return val + return helper(root) + +# Method 2: Greedy approach: +def rob2(self, root): + def helper(root): + if not root: return [0, 0] + left, right = helper(root.left), helper(root.right) + not_robbed = max(left) + max(right) + robbed = root.val + left[0] + right[0] + return [not_robbed, robbed] + return max(helper(root)) \ No newline at end of file diff --git a/algorithms/python/ImageSmoother/imageSmoother.py b/algorithms/python/ImageSmoother/imageSmoother.py new file mode 100644 index 000000000..f90828d7b --- /dev/null +++ b/algorithms/python/ImageSmoother/imageSmoother.py @@ -0,0 +1,13 @@ +def imageSmoother(self, M): + from copy import deepcopy + + if not M or not M[0]: return [[]] + row, col = len(M), len(M[0]) + res = deepcopy(M) + for x in range(row): + for y in range(col): + temp = [M[i][j] for i in [x - 1, x, x + 1] for j in [y - 1, y, y + 1] if \ + 0 <= i < row and 0 <= j < col] + res[x][y] = sum(temp) // len(temp) + + return res \ No newline at end of file diff --git a/algorithms/python/InsertionSortList/insertionSortList.py b/algorithms/python/InsertionSortList/insertionSortList.py new file mode 100644 index 000000000..07c73d96f --- /dev/null +++ b/algorithms/python/InsertionSortList/insertionSortList.py @@ -0,0 +1,19 @@ +def insertionSortList(self, head): + if not head: return head + + dummy = ListNode(0) + curr = head + prev = dummy + + while curr: + next = curr.next + while prev.next and prev.next.val < curr.val: + prev = prev.next + + curr.next = prev.next + prev.next = curr + prev = dummy + + curr = next + + return dummy.next \ No newline at end of file diff --git a/algorithms/python/K-diffPairsInAnArray/findPairs.py b/algorithms/python/K-diffPairsInAnArray/findPairs.py new file mode 100644 index 000000000..271a39668 --- /dev/null +++ b/algorithms/python/K-diffPairsInAnArray/findPairs.py @@ -0,0 +1,6 @@ +def findPairs(self, nums, k): + if k > 0: + return len(set(nums) & set(a + k for a in nums)) + elif k == 0: + return sum(v > 1 for v in collections.Counter(nums).values()) + return 0 \ No newline at end of file diff --git a/algorithms/python/KthSmallestElementInABST/kthSmallest.py b/algorithms/python/KthSmallestElementInABST/kthSmallest.py new file mode 100644 index 000000000..f139a2eb3 --- /dev/null +++ b/algorithms/python/KthSmallestElementInABST/kthSmallest.py @@ -0,0 +1,23 @@ +# Method 1: recursive in-order traversal +def kthSmallest1(self, root, k): + inorder = [] + def helper(root): + if root: + helper(root.left) + inorder.append(root.val) + helper(root.right) + + helper(root) + return inorder[k-1] + +# Method 2: iterative in-order traversal +def kthSmallest2(self, root, k): + stack = [] + while root or stack: + while root: + stack.append(root) + root = root.left + root = stack.pop() + k -= 1 + if k == 0: return root.val + root = root.right \ No newline at end of file diff --git a/algorithms/python/LargestNumberAtLeastTwiceOfOthers/dominantIndex.py b/algorithms/python/LargestNumberAtLeastTwiceOfOthers/dominantIndex.py new file mode 100644 index 000000000..676bea452 --- /dev/null +++ b/algorithms/python/LargestNumberAtLeastTwiceOfOthers/dominantIndex.py @@ -0,0 +1,6 @@ +def dominantIndex(self, nums): + i = nums.index(max(nums)) + l = nums[i] + del nums[i] + if not nums: return 0 + return i if l >= 2 * max(nums) else -1 \ No newline at end of file diff --git a/algorithms/python/LargestPerimeterTriangle/largestPerimeter.py b/algorithms/python/LargestPerimeterTriangle/largestPerimeter.py new file mode 100644 index 000000000..2052086c6 --- /dev/null +++ b/algorithms/python/LargestPerimeterTriangle/largestPerimeter.py @@ -0,0 +1,7 @@ +def largestPerimeter(self, A): + A.sort() + n = len(A) + for i in range(1, len(A) - 1): + if A[n - i - 2] + A[n - i - 1] > A[n - i]: + return A[n - i - 2] + A[n - i - 1] + A[n - i] + return 0 \ No newline at end of file diff --git a/algorithms/python/LinkedListCycleII/detectCycle.py b/algorithms/python/LinkedListCycleII/detectCycle.py new file mode 100644 index 000000000..5fc5876e3 --- /dev/null +++ b/algorithms/python/LinkedListCycleII/detectCycle.py @@ -0,0 +1,13 @@ +def detectCycle(self, head): + slow, fast = head, head + while fast and fast.next: + slow = slow.next + fast = fast.next.next + if slow == fast: break + + if not fast or not fast.next: return None + slow = head + while slow != fast: + slow = slow.next + fast = fast.next + return slow \ No newline at end of file diff --git a/algorithms/python/LongestContinuousIncreasingSubsequence/findLengthOfLCIS.py b/algorithms/python/LongestContinuousIncreasingSubsequence/findLengthOfLCIS.py new file mode 100644 index 000000000..3588468a0 --- /dev/null +++ b/algorithms/python/LongestContinuousIncreasingSubsequence/findLengthOfLCIS.py @@ -0,0 +1,11 @@ +def findLengthOfLCIS(self, nums): + if not nums: return 0 + res = 1 + temp = 1 + for i in range(1, len(nums)): + if nums[i] > nums[i - 1]: + temp += 1 + else: + res = max(temp, res) + temp = 1 + return max(temp, res) \ No newline at end of file diff --git a/algorithms/python/LongestTurbulentSubarray/maxTurbulenceSize.py b/algorithms/python/LongestTurbulentSubarray/maxTurbulenceSize.py new file mode 100644 index 000000000..242287628 --- /dev/null +++ b/algorithms/python/LongestTurbulentSubarray/maxTurbulenceSize.py @@ -0,0 +1,14 @@ +def maxTurbulenceSize(self, A): + res = inc = dec = 1 + for i in range(1, len(A)): + if A[i] > A[i - 1]: + inc = dec + 1 + dec = 1 + elif A[i] < A[i - 1]: + dec = inc + 1 + inc = 1 + else: + inc = 1 + dec = 1 + res = max(res, max(inc, dec)) + return res \ No newline at end of file diff --git a/algorithms/python/LongestUnivaluePath/longestUnivaluePath.py b/algorithms/python/LongestUnivaluePath/longestUnivaluePath.py new file mode 100644 index 000000000..1af0982c2 --- /dev/null +++ b/algorithms/python/LongestUnivaluePath/longestUnivaluePath.py @@ -0,0 +1,11 @@ +def longestUnivaluePath(self, root): + self.longest = 0 + def helper(root): + if not root: return 0 + l, r = helper(root.left), helper(root.right) + left = (l + 1) if root.left and root.left.val == root.val else 0 + right = (r + 1) if root.right and root.right.val == root.val else 0 + self.longest = max(self.longest, left + right) + return max(left, right) + helper(root) + return self.longest \ No newline at end of file diff --git a/algorithms/python/LowestCommonAncestorOfABinarySearchTree/lowestCommonAncestor.py b/algorithms/python/LowestCommonAncestorOfABinarySearchTree/lowestCommonAncestor.py new file mode 100644 index 000000000..fe063a493 --- /dev/null +++ b/algorithms/python/LowestCommonAncestorOfABinarySearchTree/lowestCommonAncestor.py @@ -0,0 +1,9 @@ +# straight forward recursive solution + +def lowestCommonAncestor(self, root, p, q): + if not root: return None + if root.val > p.val and root.val > q.val: + return self.lowestCommonAncestor(root.left, p, q) + elif root.val < p.val and root.val < q.val: + return self.lowestCommonAncestor(root.right, p, q) + return root \ No newline at end of file diff --git a/algorithms/python/LowestCommonAncestorOfABinaryTree/lowestCommonAncestor.py b/algorithms/python/LowestCommonAncestorOfABinaryTree/lowestCommonAncestor.py new file mode 100644 index 000000000..b2d51cc00 --- /dev/null +++ b/algorithms/python/LowestCommonAncestorOfABinaryTree/lowestCommonAncestor.py @@ -0,0 +1,5 @@ +def lowestCommonAncestor(self, root, p, q): + if root in (None, p, q): return root + left = self.lowestCommonAncestor(root.left, p, q) + right = self.lowestCommonAncestor(root.right, p, q) + return root if left and right else left or right \ No newline at end of file diff --git a/algorithms/python/MaximizeDistanceToClosestPerson/maxDistToClosest.py b/algorithms/python/MaximizeDistanceToClosestPerson/maxDistToClosest.py new file mode 100644 index 000000000..c72de387b --- /dev/null +++ b/algorithms/python/MaximizeDistanceToClosestPerson/maxDistToClosest.py @@ -0,0 +1,16 @@ +def maxDistToClosest(self, seats): + first = seats.index(1) + last = 0 + for i in range(len(seats) - 1, -1, -1): + if seats[i]: + last = i + break + res = 0 + temp = 0 + for i in range(first, last + 1): + if seats[i] == 1: + res = max(temp, res) + temp = 0 + else: + temp += 1 + return max(first, len(seats) - last - 1, (res + 1) // 2) \ No newline at end of file diff --git a/algorithms/python/MaximumAverageSubarrayI/findMaxAverage.py b/algorithms/python/MaximumAverageSubarrayI/findMaxAverage.py new file mode 100644 index 000000000..496a4facc --- /dev/null +++ b/algorithms/python/MaximumAverageSubarrayI/findMaxAverage.py @@ -0,0 +1,22 @@ +# Method 1: sliding window + +def findMaxAverage(self, nums, k): + total = 0 + temp = float('-inf') + for i, n in enumerate(nums): + total += n + if i >= k: total -= nums[i- k] + if i >= k - 1: + temp = max(temp, total) + return temp / k + + + +# Method 2: prefix sum + def findMaxAverage(self, nums, k): + temp = [0] + for n in nums: + temp.append(temp[-1] + n) + + res = max(temp[i + k] - temp[i] for i in range(len(nums) - k + 1)) + return res / k \ No newline at end of file diff --git a/algorithms/python/MaximumProductOfThreeNumbers/maximumProduct.py b/algorithms/python/MaximumProductOfThreeNumbers/maximumProduct.py new file mode 100644 index 000000000..ea36a256a --- /dev/null +++ b/algorithms/python/MaximumProductOfThreeNumbers/maximumProduct.py @@ -0,0 +1,11 @@ +# simply find the three largest and two smallest +# Method 1: sort +def maximumProduct(self, nums): + nums.sort() + return max(nums[0] * nums[1] * nums[-1], nums[-1] * nums[-2] * nums[-3]) + +# Method 2: using heapq, O(n) time +def maximumProduct(self, nums): + import heapq + a, b = heapq.nlargest(3, nums), heapq.nsmallest(2, nums) + return max(a[0] * a[1] * a[2], a[0] * b[0] * b[1]) \ No newline at end of file diff --git a/algorithms/python/MaximumWidthOfBinaryTree/widthOfBinaryTree.py b/algorithms/python/MaximumWidthOfBinaryTree/widthOfBinaryTree.py new file mode 100644 index 000000000..076717e4e --- /dev/null +++ b/algorithms/python/MaximumWidthOfBinaryTree/widthOfBinaryTree.py @@ -0,0 +1,13 @@ +def widthOfBinaryTree(self, root): + if not root: return 0 + stack = [[(root, 0)]] + res = 1 + while True: + children = [] + for node, value in stack[-1]: + if node.left: children.append((node.left, value * 2)) + if node.right: children.append((node.right, value * 2 + 1)) + if not children: break + stack.append(children) + res = max(res, children[-1][1] - children[0][1] + 1) + return res \ No newline at end of file diff --git a/algorithms/python/MinCostClimbingStairs/minCostClimbingStairs.py b/algorithms/python/MinCostClimbingStairs/minCostClimbingStairs.py new file mode 100644 index 000000000..403946efc --- /dev/null +++ b/algorithms/python/MinCostClimbingStairs/minCostClimbingStairs.py @@ -0,0 +1,5 @@ +def minCostClimbingStairs(self, cost): + temp = [0, cost[0]] + for i in range(1, len(cost)): + temp[0], temp[1] = temp[1], min(temp) + cost[i] + return min(temp) \ No newline at end of file diff --git a/algorithms/python/Non-decreasingArray/checkPossibility.py b/algorithms/python/Non-decreasingArray/checkPossibility.py new file mode 100644 index 000000000..5c8f27e80 --- /dev/null +++ b/algorithms/python/Non-decreasingArray/checkPossibility.py @@ -0,0 +1,10 @@ +def checkPossibility(self, nums): + count = 0 + for i in range(1, len(nums)): + if nums[i] < nums[i - 1]: + count += 1 + if i == 1 or nums[i - 2] <= nums[i]: nums[i - 1] = nums[i] + else: nums[i] = nums[i - 1] + + if count >= 2: return False + return True \ No newline at end of file diff --git a/algorithms/python/NumberOfIslands/numIslands.py b/algorithms/python/NumberOfIslands/numIslands.py new file mode 100644 index 000000000..ccb7ac135 --- /dev/null +++ b/algorithms/python/NumberOfIslands/numIslands.py @@ -0,0 +1,24 @@ +def numIslands(self, grid): + if not grid or not grid[0]: return 0 + row, col = len(grid), len(grid[0]) + self.visited = [[False for _ in range(col)] for _ in range(row)] + + def floodfill(i, j): + if grid[i][j] == '1' and self.visited[i][j] == False: + self.visited[i][j] = True + if i > 0: + floodfill(i - 1, j) + if i < row - 1: + floodfill(i + 1, j) + if j > 0: + floodfill(i, j - 1) + if j < col - 1: + floodfill(i, j + 1) + + res = 0 + for i in range(row): + for j in range(col): + if grid[i][j] == '1' and self.visited[i][j] == False: + res += 1 + floodfill(i, j) + return res \ No newline at end of file diff --git a/algorithms/python/PancakeSorting/pancakeSort.py b/algorithms/python/PancakeSorting/pancakeSort.py new file mode 100644 index 000000000..9c9a8974e --- /dev/null +++ b/algorithms/python/PancakeSorting/pancakeSort.py @@ -0,0 +1,19 @@ +""" +basic idea: find the index of smallest element in A, filp the list from that index, this makes the smallest element +comes to the first, then filp the whole list, to make smallest element goes to the tail. And then delete that element. + +Do this step until all the smallest element comes to the tail, then just filp the whole list again, and we can get what we want +""" + +def pancakeSort(self, A): + res = [] + n = len(A) + while A: + smallest = A.index(min(A)) + res.append(smallest + 1) + res.append(len(A)) + A = list(reversed(A[:smallest + 1])) + A[smallest + 1:] + A.reverse() + del A[-1] + res.append(n) + return res \ No newline at end of file diff --git a/algorithms/python/PartitionList/partition.py b/algorithms/python/PartitionList/partition.py new file mode 100644 index 000000000..6c404919d --- /dev/null +++ b/algorithms/python/PartitionList/partition.py @@ -0,0 +1,14 @@ +def partition(self, head, x): + h1 = l1 = ListNode(0) + h2 = l2 = ListNode(0) + while head: + if head.val < x: + l1.next = head + l1 = l1.next + else: + l2.next = head + l2 = l2.next + head = head.next + l2.next = None + l1.next = h2.next + return h1.next \ No newline at end of file diff --git a/algorithms/python/PathSumII/pathSum.py b/algorithms/python/PathSumII/pathSum.py new file mode 100644 index 000000000..47bef137a --- /dev/null +++ b/algorithms/python/PathSumII/pathSum.py @@ -0,0 +1,27 @@ +""" +Method 1 +""" +def pathSum(self, root, sum): + if not root: return [] + res = [] + + def dfs(root, sum, ls, res): + if not root.left and not root.right and sum == root.val: + ls.append(root.val) + res.append(ls) + if root.left: + dfs(root.left, sum - root.val, ls + [root.val], res) + if root.right: + dfs(root.right, sum - root.val, ls + [root.val], res) + + dfs(root, sum, [], res) + return res + +""" +Method 2 +""" +def pathSum(self, root, sum): + if not root: return [] + if not root.left and not root.right and root.val == sum: return [[root.val]] + temp = self.pathSum(root.left, sum - root.val) + self.pathSum(root.right, sum - root.val) + return [[root.val] + i for i in temp] \ No newline at end of file diff --git a/algorithms/python/PathSumIII/pathSum.py b/algorithms/python/PathSumIII/pathSum.py new file mode 100644 index 000000000..717b02525 --- /dev/null +++ b/algorithms/python/PathSumIII/pathSum.py @@ -0,0 +1,21 @@ +def pathSum(self, root, target): + self.result = 0 + cache = {0:1} + + def dfs(root, currPathSum): + if not root: return + + currPathSum += root.val + oldPathSum = currPathSum - target + + self.result += cache.get(oldPathSum, 0) + cache[currPathSum] = cache.get(currPathSum, 0) + 1 + + + dfs(root.left, currPathSum) + dfs(root.right, currPathSum) + + cache[currPathSum] -= 1 + + dfs(root, 0) + return self.result \ No newline at end of file diff --git a/algorithms/python/PopulatingNextRightPointersInEachNode/connect.py b/algorithms/python/PopulatingNextRightPointersInEachNode/connect.py new file mode 100644 index 000000000..596712ecb --- /dev/null +++ b/algorithms/python/PopulatingNextRightPointersInEachNode/connect.py @@ -0,0 +1,9 @@ +def connect(self, root): + if not root: return + stack = [[root]] + while True: + children = [child for node in stack[-1] for child in (node.left, node.right) if child] + if not children: break + stack.append(children) + for i in range(len(children) - 1): + children[i].next = children[i+1] \ No newline at end of file diff --git a/algorithms/python/PopulatingNextRightPointersInEachNodeII/connect.py b/algorithms/python/PopulatingNextRightPointersInEachNodeII/connect.py new file mode 100644 index 000000000..f7a0ccb78 --- /dev/null +++ b/algorithms/python/PopulatingNextRightPointersInEachNodeII/connect.py @@ -0,0 +1,9 @@ +def connect(self, root): + if not root: return root + stack = [[root]] + while True: + children = [child for node in stack[-1] for child in (node.left, node.right) if child] + if not children: break + stack.append(children) + for i in range(len(children) - 1): + children[i].next = children[i + 1] \ No newline at end of file diff --git a/algorithms/python/PositionsOfLargeGroups/largeGroupPositions.py b/algorithms/python/PositionsOfLargeGroups/largeGroupPositions.py new file mode 100644 index 000000000..616d19a49 --- /dev/null +++ b/algorithms/python/PositionsOfLargeGroups/largeGroupPositions.py @@ -0,0 +1,13 @@ +def largeGroupPositions(self, S): + res = [] + i = 0 + while i < len(S) - 2: + if S[i] == S[i + 1] and S[i] == S[i + 2]: + val = S[i] + index = i + while i < len(S) and S[i] == val: + i += 1 + res.append([index, i - 1]) + i -= 1 + i += 1 + return res \ No newline at end of file diff --git a/algorithms/python/PrintBinaryTree/printTree.py b/algorithms/python/PrintBinaryTree/printTree.py new file mode 100644 index 000000000..de6be60d2 --- /dev/null +++ b/algorithms/python/PrintBinaryTree/printTree.py @@ -0,0 +1,20 @@ +# recursive solution: takes O(n) time +# first get the height of the tree, then recusivly update the value + +def printTree(self, root): + def get_height(root): + if not root: return 0 + return 1 + max(get_height(root.left), get_height(root.right)) + + def update(res, node, row, left, right): + if not node: return + mid = (left + right) // 2 + res[row][mid] = str(node.val) + update(res, node.left, row + 1, left, mid - 1) + update(res, node.right, row + 1, mid + 1, right) + + height = get_height(root) + width = 2 ** height - 1 + res = [['' for _ in range(width)] for _ in range(height)] + update(res, root, 0, 0, width - 1) + return res \ No newline at end of file diff --git a/algorithms/python/RedundantConnection/findRedundantConnection.py b/algorithms/python/RedundantConnection/findRedundantConnection.py new file mode 100644 index 000000000..c2a078a4f --- /dev/null +++ b/algorithms/python/RedundantConnection/findRedundantConnection.py @@ -0,0 +1,28 @@ +""" +simple union find with path compression: +at first, each vertices are disjoint, there are N connected components at the begining, +after add each edge, we unify those two connected components, if two vertices are already +in the same connected component, then this edge will form a circle, just return this edge +""" + +def findRedundantConnection(self, edges): + id = list(range(len(edges) + 1)) + + def find(u): + root = u + while root != id[root]: root = id[root] + + # path compression: + while u != root: + next = id[u] + id[u] = root + u = next + + return root + + for u, v in edges: + root1, root2 = find(u), find(v) + if root1 == root2: return [u, v] + + # else, unify these two components: + id[root1] = root2 \ No newline at end of file diff --git a/algorithms/python/RemoveDuplicatesFromSortedListII/deleteDuplicates.py b/algorithms/python/RemoveDuplicatesFromSortedListII/deleteDuplicates.py new file mode 100644 index 000000000..2f528c6be --- /dev/null +++ b/algorithms/python/RemoveDuplicatesFromSortedListII/deleteDuplicates.py @@ -0,0 +1,13 @@ +def deleteDuplicates(self, head): + dummy = prev = ListNode(0) + dummy.next = head + while head and head.next: + if head.val == head.next.val: + while head and head.next and head.val == head.next.val: + head = head.next + head = head.next + prev.next = head + else: + prev = prev.next + head = head.next + return dummy.next \ No newline at end of file diff --git a/algorithms/python/RemoveNthNodeFromEndOfList/removeNthFromEnd.py b/algorithms/python/RemoveNthNodeFromEndOfList/removeNthFromEnd.py new file mode 100644 index 000000000..75b80198b --- /dev/null +++ b/algorithms/python/RemoveNthNodeFromEndOfList/removeNthFromEnd.py @@ -0,0 +1,10 @@ +def removeNthFromEnd(self, head, n): + slow = fast = head + for i in range(n): + fast = fast.next + if not fast: return head.next + while fast.next: + fast = fast.next + slow = slow.next + slow.next = slow.next.next + return head \ No newline at end of file diff --git a/algorithms/python/ReorderList/reorderList.py b/algorithms/python/ReorderList/reorderList.py new file mode 100644 index 000000000..7234b021f --- /dev/null +++ b/algorithms/python/ReorderList/reorderList.py @@ -0,0 +1,25 @@ +def reorderList(self, head): + if not head or not head.next: return + + # Step 1: find the middle node + middle = None + slow, fast = head, head + while fast and fast.next: + middle = slow + slow = slow.next + fast = fast.next.next + middle.next = None + + # Step 2: reverse the second half + prev = None + while slow: + nextNode = slow.next + slow.next = prev + prev, slow = slow, nextNode + + # Step 3: merge two lists + while head and prev: + first, second = head.next, prev.next + head.next = prev + if first: prev.next = first + head, prev = first, second \ No newline at end of file diff --git a/algorithms/python/RevealCardsInIncreasingOrder/deckRevealedIncreasing.py b/algorithms/python/RevealCardsInIncreasingOrder/deckRevealedIncreasing.py new file mode 100644 index 000000000..06ba3ae1e --- /dev/null +++ b/algorithms/python/RevealCardsInIncreasingOrder/deckRevealedIncreasing.py @@ -0,0 +1,9 @@ +def deckRevealedIncreasing(self, deck): + deck.sort() + res = [0] * len(deck) + index = list(range(len(deck))) + + for i in range(len(deck)): + res[index.pop(0)] = deck[i] + if index: index.append(index.pop(0)) + return res \ No newline at end of file diff --git a/algorithms/python/ReverseLinkedListII/reverseBetween.py b/algorithms/python/ReverseLinkedListII/reverseBetween.py new file mode 100644 index 000000000..8f43316e5 --- /dev/null +++ b/algorithms/python/ReverseLinkedListII/reverseBetween.py @@ -0,0 +1,14 @@ +def reverseBetween(self, head, m, n): + if not head or n == m: return head + p = dummy = ListNode(0) + dummy.next = head + for _ in range(m - 1): + p = p.next + tail = p.next + + for _ in range(n - m): + temp = p.next + p.next = tail.next + tail.next = tail.next.next + p.next.next = temp + return dummy.next \ No newline at end of file diff --git a/algorithms/python/SearchA2DMatrixII/searchMatrix.py b/algorithms/python/SearchA2DMatrixII/searchMatrix.py new file mode 100644 index 000000000..3e372606c --- /dev/null +++ b/algorithms/python/SearchA2DMatrixII/searchMatrix.py @@ -0,0 +1,28 @@ +# Method 1: Binary Search on each row, if the first element of the row is already bigger than target, then skip +# Time Complexity: O(mlogn) +def searchMatrix1(self, matrix, target): + def helper(low, high, row): + while low <= high: + mid = (low + high) // 2 + if matrix[row][mid] < target: low = mid + 1 + elif matrix[row][mid] > target: high = mid - 1 + else: return True + return False + + if not matrix or not matrix[0]: return False + for i in range(len(matrix)): + if matrix[i][0] > target: return False + elif matrix[i][0] == target: return True + if helper(0, len(matrix[i]) - 1, i): return True + return False + +# Method 2: compare the element with top-right corner, and reduce the search range +# Time complexity: O(m + n) +def searchMatrix2(self, matrix, target): + if not matrix or not matrix[0]: return False + row, col = 0, len(matrix[0]) - 1 + while row < len(matrix) and col >= 0: + if matrix[row][col] > target: col -= 1 + elif matrix[row][col] < target: row += 1 + else: return True + return False \ No newline at end of file diff --git a/algorithms/python/SecondMinimumNodeInABinaryTree/findSecondMinimumValue.py b/algorithms/python/SecondMinimumNodeInABinaryTree/findSecondMinimumValue.py new file mode 100644 index 000000000..6e8a9ea88 --- /dev/null +++ b/algorithms/python/SecondMinimumNodeInABinaryTree/findSecondMinimumValue.py @@ -0,0 +1,15 @@ +""" +because of the special porperty of the tree, the question basically is asking to find +the smallest element in the subtree of root. So, we can recursively find left and right +value that is not equal to the root's value, and then return the smaller one of them +""" +def findSecondMinimumValue(self, root): + if not root: return -1 + if not root.left and not root.right: return -1 + + left, right = root.left.val, root.right.val + if left == root.val: left = self.findSecondMinimumValue(root.left) + if right == root.val: right = self.findSecondMinimumValue(root.right) + if left != -1 and right != -1: return min(left, right) + if left == -1: return right + if right == -1: return left \ No newline at end of file diff --git a/algorithms/python/SerializeAndDeserializeBST/serialize.py b/algorithms/python/SerializeAndDeserializeBST/serialize.py new file mode 100644 index 000000000..efe975b2c --- /dev/null +++ b/algorithms/python/SerializeAndDeserializeBST/serialize.py @@ -0,0 +1,26 @@ +class Codec: + + def serialize(self, root): + preorder = [] + + def helper(node): + if node: + preorder.append(node.val) + helper(node.left) + helper(node.right) + helper(root) + return ' '.join(map(str, preorder)) + + + def deserialize(self, data): + vals = collections.deque(int(val) for val in data.split()) + + def build(minval, maxval): + if vals and minval < vals[0] < maxval: + val = vals.popleft() + node = TreeNode(val) + node.left = build(minval, val) + node.right = build(val, maxval) + return node + + return build(float('-infinity'), float('infinity')) \ No newline at end of file diff --git a/algorithms/python/ShortestUnsortedContinuousSubarray/findUnsortedSubarray.py b/algorithms/python/ShortestUnsortedContinuousSubarray/findUnsortedSubarray.py new file mode 100644 index 000000000..631bc04a9 --- /dev/null +++ b/algorithms/python/ShortestUnsortedContinuousSubarray/findUnsortedSubarray.py @@ -0,0 +1,3 @@ +def findUnsortedSubarray(self, nums): + same = [a == b for a, b in zip(nums, sorted(nums))] + return 0 if all(same) else len(nums) - same.index(False) - same[::-1].index(False) \ No newline at end of file diff --git a/algorithms/python/SortList/sortList.py b/algorithms/python/SortList/sortList.py new file mode 100644 index 000000000..543624440 --- /dev/null +++ b/algorithms/python/SortList/sortList.py @@ -0,0 +1,37 @@ +# merge sort: + +def sortList(self, head): + if not head or not head.next: return head + leftHalf, rightHalf = self.split(head) + left = self.sortList(leftHalf) + right = self.sortList(rightHalf) + return self.mergeSorted(left, right) + +def mergeSorted(self, a, b): + res = dummy = ListNode(0) + while a and b: + if a.val < b.val: + dummy.next = a + dummy = a + a = a.next + else: + dummy.next = b + dummy = b + b = b.next + if not a: dummy.next = b + else: dummy.next = a + + return res.next + +def split(self, node): + if not node or not node.next: + return node, None + slow, fast = node, node + prev = None + while fast.next: + prev = slow + slow = slow.next + fast = fast.next.next + if not fast: break + prev.next = None + return node, slow \ No newline at end of file diff --git a/algorithms/python/SquaresOfSortedArray/sortedSquares.py b/algorithms/python/SquaresOfSortedArray/sortedSquares.py new file mode 100644 index 000000000..cbbe06ccf --- /dev/null +++ b/algorithms/python/SquaresOfSortedArray/sortedSquares.py @@ -0,0 +1,2 @@ +def sortedSquares(self, A): + return list(sorted([a ** 2 for a in A])) \ No newline at end of file diff --git a/algorithms/python/Subsets/subsets.py b/algorithms/python/Subsets/subsets.py new file mode 100644 index 000000000..6f810b551 --- /dev/null +++ b/algorithms/python/Subsets/subsets.py @@ -0,0 +1,12 @@ +def subsets(self, nums): + res = [] + def backtracking(temp, start): + res.append(temp[:]) + for i in range(start, len(nums)): + temp.append(nums[i]) + backtracking(temp, i + 1) + temp.pop() + + backtracking([], 0) + return res + \ No newline at end of file diff --git a/algorithms/python/SubtreeOfAnotherTree/isSubtree.py b/algorithms/python/SubtreeOfAnotherTree/isSubtree.py new file mode 100644 index 000000000..afb242470 --- /dev/null +++ b/algorithms/python/SubtreeOfAnotherTree/isSubtree.py @@ -0,0 +1,15 @@ +def isSubtree(self, s, t): + stack = [s] + while stack: + node = stack.pop(0) + if node.val == t.val: + if self.check(node, t): return True + stack += [child for child in [node.left, node.right] if child] + return False + +def check(self, first, second): + if not first and not second: + return True + if first and second: + return first.val == second.val and self.check(first.left, second.left) and self.check(first.right, second.right) + return False \ No newline at end of file diff --git a/algorithms/python/SumOfLeftLeaves/sumOfLeftLeaves.py b/algorithms/python/SumOfLeftLeaves/sumOfLeftLeaves.py new file mode 100644 index 000000000..8b27154b5 --- /dev/null +++ b/algorithms/python/SumOfLeftLeaves/sumOfLeftLeaves.py @@ -0,0 +1,10 @@ +""" +straight forward recursive solution: +if left node is leave, add the value and the the right subtree +if not, then recursively call left and right subtree +""" +def sumOfLeftLeaves(self, root): + if not root: return 0 + if root.left and not root.left.left and not root.left.right: + return root.left.val + self.sumOfLeftLeaves(root.right) + return self.sumOfLeftLeaves(root.left) + self.sumOfLeftLeaves(root.right) \ No newline at end of file diff --git a/algorithms/python/SumRootToLeafNumbers/sumNumbers.py b/algorithms/python/SumRootToLeafNumbers/sumNumbers.py new file mode 100644 index 000000000..644bc1505 --- /dev/null +++ b/algorithms/python/SumRootToLeafNumbers/sumNumbers.py @@ -0,0 +1,29 @@ +""" +Method 1: dfs +""" +def sumNumbers(self, root): + if not root: return 0 + stack, res = [(root, root.val)], 0 + while stack: + node, value = stack.pop() + if not node.left and not node.right: + res += value + if node.right: + stack.append((node.right, value * 10 + node.right.val)) + if node.left: + stack.append((node.left, value * 10 + node.left.val)) + return res + + + +""" +Method 2: recursive solution +""" +def sumNumbers(self, root): + return self.helper(root, 0) + +def helper(self, node, s): + if not node: return 0 + if not node.left and not node.right: return s * 10 + node.val + return self.helper(node.left, s * 10 + node.val) + \ + self.helper(node.right, s * 10 + node.val) \ No newline at end of file diff --git a/algorithms/python/ThirdMaximumNumber/thirdMax.py b/algorithms/python/ThirdMaximumNumber/thirdMax.py new file mode 100644 index 000000000..36f46d90b --- /dev/null +++ b/algorithms/python/ThirdMaximumNumber/thirdMax.py @@ -0,0 +1,14 @@ +def thirdMax(self, nums): + if len(set(nums)) < 3: return max(nums) + first = second = third = float('-inf') + for n in nums: + if n > first: + third = second + second = first + first = n + elif second < n < first: + third = second + second = n + elif third < n < second: + third = n + return third \ No newline at end of file diff --git a/algorithms/python/UniqueBinarySearchTrees/numTrees.py b/algorithms/python/UniqueBinarySearchTrees/numTrees.py new file mode 100644 index 000000000..f0ab85e90 --- /dev/null +++ b/algorithms/python/UniqueBinarySearchTrees/numTrees.py @@ -0,0 +1,9 @@ +def numTrees(self, n): + if n == 1: return 1 + res = [1, 1] + for i in range(2, n + 1): + val = 0 + for j in range(i): + val += res[j] * res[i - j - 1] + res.append(val) + return res[n] \ No newline at end of file diff --git a/algorithms/python/UniqueBinarySearchTreesII/generateTrees.py b/algorithms/python/UniqueBinarySearchTreesII/generateTrees.py new file mode 100644 index 000000000..fee07dc5e --- /dev/null +++ b/algorithms/python/UniqueBinarySearchTreesII/generateTrees.py @@ -0,0 +1,24 @@ +def generateTrees(self, n): + if n == 0: return [] + + def helper(start, end): + ls = [] + if start > end: + ls.append(None) + return ls + if start == end: + ls.append(TreeNode(start)) + return ls + + for i in range(start, end + 1): + left = helper(start, i - 1) + right = helper(i + 1, end) + for lnode in left: + for rnode in right: + root = TreeNode(i) + root.left = lnode + root.right = rnode + ls.append(root) + return ls + + return helper(1, n) \ No newline at end of file diff --git a/algorithms/python/ValidMountainArray/validMountainArray.py b/algorithms/python/ValidMountainArray/validMountainArray.py new file mode 100644 index 000000000..c40f5db3a --- /dev/null +++ b/algorithms/python/ValidMountainArray/validMountainArray.py @@ -0,0 +1,20 @@ +# Method 1: using index find the max first, and then process + +def validMountainArray(self, A): + if len(A) < 3: return False + index = A.index(max(A)) + if index == 0 or index == len(A) -1: return False + for i in range(1, len(A)): + if i <= index: + if A[i] <= A[i - 1]: return False + else: + if A[i] >= A[i - 1]: return False + return True + + +# Method 2: one pass, using two pointers trace from the begining and end +def validMountainArray(self, A): + i, j = 0, len(A) - 1 + while i < len(A) - 1 and A[i] < A[i + 1]: i += 1 + while j > 0 and A[j - 1] > A[j]: j -= 1 + return 0 < i == j < len(A) - 1 \ No newline at end of file diff --git a/algorithms/python/ValidateBinarySearchTree/isValidBST.py b/algorithms/python/ValidateBinarySearchTree/isValidBST.py new file mode 100644 index 000000000..06a1243e0 --- /dev/null +++ b/algorithms/python/ValidateBinarySearchTree/isValidBST.py @@ -0,0 +1,26 @@ +# method 1: using recursion + +def isValidBST1(self, root, lower = float('-inf'), upper = float('inf')): + """ + :type root: TreeNode + :rtype: bool + """ + if not root: return True + if root.val <= lower or root.val >= upper: return False + return self.isValidBST(root.left, lower, min(upper, root.val)) \ + and self.isValidBST(root.right, max(lower, root.val), upper) + + +# method 2: a proper BST should have this porperty: inorder traversal is increasing +def isValidBST2(self, root): + inorder = [] + def helper(root): + if root: + helper(root.left) + inorder.append(root.val) + helper(root.right) + + helper(root) + for i in range(len(inorder) - 1): + if inorder[i + 1] <= inorder[i]: return False + return True \ No newline at end of file diff --git a/algorithms/python/XOfAKindInADeckOfCards/hasGroupsSizeX.py b/algorithms/python/XOfAKindInADeckOfCards/hasGroupsSizeX.py new file mode 100644 index 000000000..e65e2554f --- /dev/null +++ b/algorithms/python/XOfAKindInADeckOfCards/hasGroupsSizeX.py @@ -0,0 +1,19 @@ +# Method 1: find the greatest common divisor using iteration + +def hasGroupsSizeX(self, deck): + if len(deck) < 2: return False + vals = collections.Counter(deck).values() + for n in range(2, max(vals) + 1): + if all(v % n == 0 for v in vals): return True + return False + +# Method 2: find the greatest common divisor using reduce +# Time complexity: O(n) +def hasGroupsSizeX(self, deck): + from functools import reduce + if len(deck) < 2: return False + vals = collections.Counter(deck).values() + def gcd(a, b): + while b: a, b = b, a % b + return a + return reduce(gcd, vals) \ No newline at end of file diff --git a/database/README.md b/database/README.md new file mode 100644 index 000000000..930500a76 --- /dev/null +++ b/database/README.md @@ -0,0 +1,6 @@ +### LeetCode Database + + +| # | Title | Solution | Difficulty | +|---| ----- | -------- | ---------- | +|1|[Trips and Users](https://leetcode.com/problems/trips-and-users/)| [MySQL](./TripsAndUsers.sql)|Hard| diff --git a/database/TripsAndUsers.sql b/database/TripsAndUsers.sql new file mode 100644 index 000000000..ed57bf8c3 --- /dev/null +++ b/database/TripsAndUsers.sql @@ -0,0 +1,9 @@ +SELECT t.`Request_at` AS Day, +ROUND(COUNT(CASE WHEN t.`Status` = 'cancelled_by_driver' OR t.`Status` = 'cancelled_by_client' THEN 1 END) / COUNT(*), 2) AS "Cancellation Rate" +FROM Trips t +INNER JOIN Users u +ON t.Client_Id = u.Users_Id +WHERE u.Banned = 'No' +AND t.Request_at >= '2013-10-01' +AND t.Request_at <= '2013-10-03' +GROUP BY t.Request_at \ No newline at end of file diff --git a/scripts/README.md b/scripts/README.md index 6972133fa..6349e5f00 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -44,3 +44,16 @@ The comments would be generated by above examples as below: ``` + +### readme.sh + +`readme.sh` - it's used to generate the table item in README.md + +For example: + +``` +$ ./readme.sh ../algorithms/cpp/nextPermutation/nextPermutation.cpp +|31|[Next Permutation](https://oj.leetcode.com/problems/next-permutation/) | [C++](./algorithms/cpp/nextPermutation/nextPermutation.cpp)|Medium| +``` + + diff --git a/scripts/comments.sh b/scripts/comments.sh index 1d518fe24..bb5eeae0a 100755 --- a/scripts/comments.sh +++ b/scripts/comments.sh @@ -1,13 +1,20 @@ #!/bin/bash set -e -AUTHOR="Hao Chen" -LEETCODE_URL=https://leetcode.com/problems/ -LEETCODE_NEW_URL=https://leetcode.com/problems/ -LEETCODE_OLD_URL=https://oj.leetcode.com/problems/ +AUTHOR="NOBODY" COMMENT_TAG="//" FILE_EXT=".cpp" +pushd `dirname $0` > /dev/null +SCRIPTPATH=`pwd -P` +popd > /dev/null +SCRIPTFILE=`basename $0` + +COLOR_INFO='\033[0;36m' +COLOR_NONE='\033[0m' + +source ${SCRIPTPATH}/lib/query_problem.sh + function usage() { @@ -23,6 +30,18 @@ function usage() echo -e "" } +function get_author_name() +{ + TRUE_CMD=`which true` + git=`type -P git || ${TRUE_CMD}` + if [ ! -z "${git}" ]; then + AUTHOR=`git config --get user.name` + else + AUTHOR=`whoami` + fi +} + + function detect_os() { platform='unknown' @@ -35,57 +54,6 @@ function detect_os() echo ${platform} } -function install_xidel() -{ - echo "Install xidel ..." - if [ ! -d ./xidel ]; then - mkdir xidel - fi - cd xidel - - platform=`detect_os` - - if [[ "$platform" == "unknown" ]]; then - echo "Unknown platform, please install 'xidel' manually!" - exit 1; - fi - - #install the xidel on Linux platform - if [[ "$platform" == "linux" ]]; then - hardware=`uname -m` - xidel_tar=xidel-0.8.4.linux64.tar.gz - case $hardware in - x86_64 ) xidel_tar=xidel-0.8.4.linux64.tar.gz - ;; - i686 ) xidel_tar=xidel-0.8.4.linux32.tar.gz - ;; - * ) echo "Cannot install xidel, please install it manually!" - exit 1; - esac - if [ ! -f ${xidel_tar} ]; then - echo "Downloading xidel......" - curl -L http://softlayer-sng.dl.sourceforge.net/project/videlibri/Xidel/Xidel%200.8.4/${xidel_tar} -o ${xidel_tar} - fi - tar -zxvf ${xidel_tar} - ./install.sh - fi - - #install the xidel on MacOS platform - #refer to: https://www.evernote.com/shard/s69/sh/ff1e78f3-a369-4855-b18f-6184ce789c45/f3511927d0fb356ce883835f2eb712e0 - if [[ "$platform" == "macos" ]]; then - echo "Downloading xidel......" - xidel_zip=xidel.zip - if [ ! -f ${xidel_zip} ]; then - curl -L https://www.evernote.com/shard/s69/sh/ff1e78f3-a369-4855-b18f-6184ce789c45/f3511927d0fb356ce883835f2eb712e0/res/9f156868-01b4-4838-9c2f-935d7a236e05/${xidel_zip} -o ${xidel_zip} - fi - unzip ${xidel_zip} - mv xidel /usr/local/bin/ - fi - - cd .. - echo "Install xidel successfullly !" -} - if [ $# -lt 1 ] || [[ "${1}" != ${LEETCODE_NEW_URL}* ]] && [[ "${1}" != ${LEETCODE_OLD_URL}* ]]; then usage @@ -96,17 +64,29 @@ if [[ "${1}" == ${LEETCODE_OLD_URL}* ]]; then LEETCODE_URL=${LEETCODE_OLD_URL} fi -IS_SHELL=`curl ${1} 2>/dev/null | grep Bash |wc -l` -if [ ${IS_SHELL} -gt 0 ]; then - COMMENT_TAG='#' - FILE_EXT='.sh' -fi - leetcode_url=$1 current_time=`date +%Y-%m-%d` platform=`detect_os` +get_question_slug ${leetcode_url} + + +TRUE_CMD=`which true` +xidel=`type -P xidel || ${TRUE_CMD}` +if [ -z "${xidel}" ]; then + echo "xidel not found !" + install_xidel +fi + +#grab the problem information +query_problem ${leetcode_url} ${QUESTION_TITLE_SLUG} + +if [ "${QUESTION_CATEGORY}" == "Shell" ]; then + COMMENT_TAG='#' + FILE_EXT='.sh' +fi + if [ $# -gt 1 ] && [ -f $2 ]; then source_file=$2 if [[ "$platform" == "linux" ]]; then @@ -115,8 +95,8 @@ if [ $# -gt 1 ] && [ -f $2 ]; then current_time=`stat -f %a ${source_file} | xargs -I time date -r time +%Y-%m-%d` fi else - source_file=${1#${LEETCODE_URL}} - source_file=${source_file::${#source_file}-1} + source_file=$QUESTION_TITLE_SLUG + #source_file=${source_file::${#source_file}-1} source_file=`echo $source_file | awk -F '-' '{for (i=1; i<=NF; i++) printf("%s", toupper(substr($i,1,1)) substr($i,2)) }'`${FILE_EXT} if [ ! -f ${source_file} ]; then @@ -132,12 +112,16 @@ else fi fi -# the source file is existed but it is empty, add a line, + +# the source file is existed but it is empty, add a line, # otherwise it could casue the comments inserts failed. if [ ! -s $source_file ]; then - echo "" > $source_file + echo "" > $source_file fi +#detect the author name +get_author_name; + #adding the Copyright Comments if ! grep -Fq "${COMMENT_TAG} Author :" $source_file ; then sed -i.bak '1i\'$'\n'"${COMMENT_TAG} Source : ${leetcode_url}"$'\n' $source_file @@ -147,38 +131,71 @@ if ! grep -Fq "${COMMENT_TAG} Author :" $source_file ; then rm ${source_file}.bak fi -#grab the problem description and add the comments -TRUE_CMD=`which true` -xidel=`type -P xidel || ${TRUE_CMD}` -if [ -z "${xidel}" ]; then - echo "xidel not found !" - install_xidel -fi -# using xidel grab the problem description -# 1) the `fold` command is used to wrap the text at centain column -# 2) the last two `sed` commands are used to add the comments tags -case $FILE_EXT in - .cpp ) xidel ${leetcode_url} -q -e "css('div.question-content')" | \ - grep -v ' ' | sed '/^$/N;/^\n$/D' | fold -w 85 -s |\ - sed 's/^/ * /' | sed '1i\'$'\n'"/*$(printf '%.0s*' {0..85}) "$'\n' |\ - sed '2i\'$'\n''!@#$%'$'\n' | sed 's/!@#$%/ */' | \ - sed '$a\'$'\n'"*$(printf '%.0s*' {0..85})*/"$'\n'| \ - sed 's/^*/ /' > /tmp/tmp.txt - ;; - .sh ) xidel ${leetcode_url} -q -e "css('div.question-content')" | \ - grep -v ' ' |sed '/^$/N;/^\n$/D' | fold -w 85 -s| \ - sed 's/^/# /' | sed '1i\'$'\n'"#$(printf '%.0s#' {0..85}) "$'\n' | \ - sed '2i\'$'\n''#'$'\n' | sed '$a\'$'\n'"#$(printf '%.0s#' {0..85})"$'\n'\ - > /tmp/tmp.txt - ;; - * ) echo "Bad file extension!" - exit 1; +#echo "--------------" +#echo "$QUESTION_CONTENT" +#echo $QUESTION_DIFFICULTY +#echo $QUESTION_TITLE +#echo $QUESTION_ID +#echo $QUESTION_CATEGORY +#echo "--------------" + + +function make_comments() { + + # arguments - comment content, style and the outputfile + CONTENT=${1} + STYLE=${2} + OUTPUT_FILE=${3} + + # the width of comments + WIDTH=100 + WIDTH_SEQ=$(seq 1 ${WIDTH}) + + # 1) the `fold` command is used to wrap the text at centain column + # 2) the last two `sed` commands are used to add the comments tags + case ${STYLE} in + clike ) echo "${CONTENT}" | + sed 's/^[[:space:]]*$/'"$(printf '\n')"'/g' | cat -s | # replace the multiple empty line with a single empty line + fold -w ${WIDTH} -s | # wrap the text at centain column + sed 's/^/ * /' | # add the '*' for each line + sed '1i\'$'\n'"/*$(printf '%.0s*' ${WIDTH_SEQ}) "$'\n' | # add the first line - /*********** + sed '2i\'$'\n'"@@@*"$'\n' | sed 's/^@@@/ /g' | # add the second line - * (lead by a space) + sed '$a\'$'\n'"@@@*$(printf '%.0s*' ${WIDTH_SEQ})*/"$'\n'| # add the end line - **********/ + sed 's/^@@@/ /' > ${OUTPUT_FILE} + ;; + script ) echo "${CONTENT}" | + sed 's/^[[:space:]]*$/'"$(printf '\n')"'/g' | cat -s | # replace the multiple empty line with a single empty line + fold -w ${WIDTH} -s | # wrap the text at centain column + sed 's/^/# /' | # add the '*' for each line + sed '1i\'$'\n'"#$(printf '%.0s#' ${WIDTH_SEQ}) "$'\n' | # add the first line - ############ + sed '2i\'$'\n'"#"$'\n' | # add the second line - # + sed '$a\'$'\n'"#$(printf '%.0s#' ${WIDTH_SEQ})"$'\n' > ${OUTPUT_FILE} # add the end line - ############# + ;; + * ) echo "Bad Comment Style!" + exit 1; + esac +} +TMP_FILE=/tmp/tmp.txt +case ${FILE_EXT} in + .c | .cpp | .java ) + make_comments "${QUESTION_CONTENT}" clike "${TMP_FILE}" + ;; + .sh | .py ) + make_comments "${QUESTION_CONTENT}" script "${TMP_FILE}" + ;; + * ) + echo "Bad file extension!" + exit 1; esac +#remove the ^M chars +tr -d $'\r' < ${TMP_FILE} > ${TMP_FILE}.1 +mv ${TMP_FILE}.1 ${TMP_FILE} + #insert the problem description into the source file, and remove it -sed -i.bak '4 r /tmp/tmp.txt' ${source_file} +sed -i.bak '4 r '${TMP_FILE}'' ${source_file} rm -f ${source_file}.bak rm -f /tmp/tmp.txt diff --git a/scripts/lib/query_problem.sh b/scripts/lib/query_problem.sh new file mode 100644 index 000000000..8c26dc1ea --- /dev/null +++ b/scripts/lib/query_problem.sh @@ -0,0 +1,134 @@ +#!/bin/bash + +LEETCODE_URL=https://leetcode.com/problems/ +LEETCODE_NEW_URL=https://leetcode.com/problems/ +LEETCODE_OLD_URL=https://oj.leetcode.com/problems/ + + +function get_question_slug() +{ + QUESTION_TITLE_SLUG=${1#${LEETCODE_URL}} + QUESTION_TITLE_SLUG=$(echo $QUESTION_TITLE_SLUG | sed 's/\/.*//g') # remove the needless url path +} + +function query_problem() +{ + TMP_JSON_FILE=tmp.json + +# curl -s "https://leetcode.com/graphql?query=query%20getQuestionDetail(%24titleSlug%3A%20String!)%20%7B%0A%20%20isCurrentUserAuthenticated%0A%20%20question(titleSlug%3A%20%24titleSlug)%20%7B%0A%20%20%20%20questionId%0A%20%20%20%20questionFrontendId%0A%20%20%20%20questionTitle%0A%20%20%20%20translatedTitle%0A%20%20%20%20questionTitleSlug%0A%20%20%20%20content%0A%20%20%20%20translatedContent%0A%20%20%20%20difficulty%0A%20%20%20%20stats%0A%20%20%20%20contributors%0A%20%20%20%20similarQuestions%0A%20%20%20%20discussUrl%0A%20%20%20%20mysqlSchemas%0A%20%20%20%20randomQuestionUrl%0A%20%20%20%20sessionId%0A%20%20%20%20categoryTitle%0A%20%20%20%20submitUrl%0A%20%20%20%20interpretUrl%0A%20%20%20%20codeDefinition%0A%20%20%20%20sampleTestCase%0A%20%20%20%20enableTestMode%0A%20%20%20%20metaData%0A%20%20%20%20enableRunCode%0A%20%20%20%20enableSubmit%0A%20%20%20%20judgerAvailable%0A%20%20%20%20infoVerified%0A%20%20%20%20envInfo%0A%20%20%20%20urlManager%0A%20%20%20%20article%0A%20%20%20%20questionDetailUrl%0A%20%20%20%20discussCategoryId%0A%20%20%20%20discussSolutionCategoryId%0A%20%20%20%20libraryUrl%0A%20%20%20%20companyTags%20%7B%0A%20%20%20%20%20%20name%0A%20%20%20%20%20%20slug%0A%20%20%20%20%20%20translatedName%0A%20%20%20%20%7D%0A%20%20%20%20topicTags%20%7B%0A%20%20%20%20%20%20name%0A%20%20%20%20%20%20slug%0A%20%20%20%20%20%20translatedName%0A%20%20%20%20%7D%0A%20%20%7D%0A%20%20interviewed%20%7B%0A%20%20%20%20interviewedUrl%0A%20%20%20%20companies%20%7B%0A%20%20%20%20%20%20id%0A%20%20%20%20%20%20name%0A%20%20%20%20%20%20slug%0A%20%20%20%20%7D%0A%20%20%20%20timeOptions%20%7B%0A%20%20%20%20%20%20id%0A%20%20%20%20%20%20name%0A%20%20%20%20%7D%0A%20%20%20%20stageOptions%20%7B%0A%20%20%20%20%20%20id%0A%20%20%20%20%20%20name%0A%20%20%20%20%7D%0A%20%20%7D%0A%20%20subscribeUrl%0A%20%20isPremium%0A%20%20loginUrl%0A%7D%0A&operationName=getQuestionDetail&variables=%7B%22titleSlug%22%3A%22${2}%22%7D" > ${TMP_JSON_FILE} + + # + # NOTE: leetcode server supports `br` encoding and make it high priority. But curl doesn't support it, + # So, you need make sure the `accept-encoding` hasn't br in the request header. + # (if you copy & paste the curl script from Chrome, the `br` could be added!) + # + curl -s 'https://leetcode.com/graphql' \ + -H 'origin: https://leetcode.com' \ + -H 'accept-encoding: gzip, deflate' \ + -H 'accept-language: zh-CN,zh;q=0.9,und;q=0.8,en;q=0.7' \ + -H 'cookie: __cfduid=dae082e425ee3916c04a5170b832e268e1524142659; _ga=GA1.2.1432146910.1524142661; _gid=GA1.2.650843898.1529736240; csrftoken=iSKedVXxGDkBBXbP9chsyXhbIrRedF7iw2EMRZiemtzKD8vjHSWZJKkKQVIwZKp7; __atuvc=2%7C25; __atuvs=5b2ded02313c83c4001; _gat=1' \ + -H 'x-csrftoken: iSKedVXxGDkBBXbP9chsyXhbIrRedF7iw2EMRZiemtzKD8vjHSWZJKkKQVIwZKp7' \ + -H 'pragma: no-cache' \ + -H 'content-type: application/json' \ + -H 'accept: */*' -H 'cache-control: no-cache' \ + -H 'authority: leetcode.com' \ + -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36' \ + -H "referer: ${1}" \ + --data-binary '{"operationName":"questionData","variables":{"titleSlug":"'${2}'"},"query":"query questionData($titleSlug: String!) {\n question(titleSlug: $titleSlug) {\n questionId\n questionFrontendId\n boundTopicId\n title\n titleSlug\n content\n translatedTitle\n translatedContent\n isPaidOnly\n difficulty\n likes\n dislikes\n isLiked\n similarQuestions\n contributors {\n username\n profileUrl\n avatarUrl\n __typename\n }\n langToValidPlayground\n topicTags {\n name\n slug\n translatedName\n __typename\n }\n companyTagStats\n codeSnippets {\n lang\n langSlug\n code\n __typename\n }\n stats\n hints\n solution {\n id\n canSeeDetail\n __typename\n }\n status\n sampleTestCase\n metaData\n judgerAvailable\n judgeType\n mysqlSchemas\n enableRunCode\n enableTestMode\n envInfo\n __typename\n }\n}\n"}' --compressed > ${TMP_JSON_FILE} + + # xidel change the -q option to -s after 0.9.4 version, so we have to check that + # if xidel has -q option, then it will return error. + + OPT= + + set +e + xidel -q 2>/dev/null + if [ $? -ne 0 ]; then + OPT=-q + else + # if xidel has -s option, then it will return error. + xidel -s 2>/dev/null + if [ $? -ne 0 ]; then + OPT=-s + fi + fi + set -e + + QUESTION_CONTENT=$(xidel ${OPT} ${TMP_JSON_FILE} -e '$json("data").question.content' | sed -e 's/<[^>]*>//g; s/ / /g; s/&/\&/g; s/</\/g; s/"/\"/g; s/'/\'"'"'/g; s/“/\"/g;') + + QUESTION_DIFFICULTY=$(xidel ${OPT} ${TMP_JSON_FILE} -e '$json("data").question.difficulty') + + QUESTION_TITLE=$(xidel ${OPT} ${TMP_JSON_FILE} -e '$json("data").question.title') + + QUESTION_ID=$(xidel ${OPT} ${TMP_JSON_FILE} -e '$json("data").question.questionId') + + QUESTION_FRONTEND_ID=$(xidel ${OPT} ${TMP_JSON_FILE} -e '$json("data").question.questionFrontendId') + + QUESTION_CATEGORY=$(xidel ${OPT} ${TMP_JSON_FILE} -e '$json("data").question.categoryTitle') + + rm -f $TMP_JSON_FILE +} + +function detect_os() +{ + platform='unknown' + ostype=`uname` + if [[ "$ostype" == 'Linux' ]]; then + platform='linux' + elif [[ "$ostype" == 'Darwin' ]]; then + platform='macos' + fi + echo ${platform} +} + +function install_xidel() +{ + echo "Install xidel ..." + if [ ! -d ./xidel ]; then + mkdir xidel + fi + cd xidel + + platform=`detect_os` + + if [[ "$platform" == "unknown" ]]; then + echo "Unknown platform, please install 'xidel' manually!" + exit 1; + fi + + #install the xidel on Linux platform + xidel_ver=0.9.6 + if [[ "$platform" == "linux" ]]; then + hardware=`uname -m` + xidel_tar=xidel-${xidel_ver}.linux64.tar.gz + case $hardware in + x86_64 ) xidel_tar=xidel-${xidel_ver}.linux64.tar.gz + ;; + i686 ) xidel_tar=xidel-${xidel_ver}.linux32.tar.gz + ;; + * ) echo "Cannot install xidel, please install it manually!" + exit 1; + esac + if [ ! -f ${xidel_tar} ]; then + echo "Downloading xidel......" + curl -s -L https://jaist.dl.sourceforge.net/project/videlibri/Xidel/Xidel%20${xidel_ver}/${xidel_tar} -o ${xidel_tar} + fi + tar -zxvf ${xidel_tar} + sudo ./install.sh + fi + + #install the xidel on MacOS platform + #refer to: https://www.evernote.com/shard/s69/sh/ff1e78f3-a369-4855-b18f-6184ce789c45/f3511927d0fb356ce883835f2eb712e0 + if [[ "$platform" == "macos" ]]; then + echo "Downloading xidel......" + xidel_zip=xidel.zip + if [ ! -f ${xidel_zip} ]; then + curl -L https://www.evernote.com/shard/s69/sh/ff1e78f3-a369-4855-b18f-6184ce789c45/f3511927d0fb356ce883835f2eb712e0/res/de33e89a-cdc6-42b5-a476-32e2df1cf4bc/${xidel_zip} -o ${xidel_zip} + fi + unzip ${xidel_zip} + mv xidel /usr/local/bin/ + fi + + cd .. + echo "Install xidel successfullly !" +} diff --git a/scripts/readme.sh b/scripts/readme.sh new file mode 100755 index 000000000..a66a3b355 --- /dev/null +++ b/scripts/readme.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +pushd `dirname $0` > /dev/null +SCRIPTPATH=`pwd -P` +popd > /dev/null +SCRIPTFILE=`basename $0` + +COLOR_INFO='\033[0;36m' +COLOR_NONE='\033[0m' + +source ${SCRIPTPATH}/lib/query_problem.sh + +function usage() +{ + + echo -e "Usage: ${0} [file]" + echo -e "" + echo -e "Example:" + echo -e "" + echo -e " ${0} ./LargestNumber.cpp" + echo -e "" +} + + + +if [ $# -lt 1 ] || [[ ! -f ${1} ]]; then + usage + exit 255 +fi + +DIR=`cd $(dirname ${1}) && pwd -P` +FILE=${DIR}/$(basename ${1}) + +URL=`grep Source ${FILE} | awk '{print $4}'` + +URL=$(echo $URL | sed -e 's/oj\.leetcode\.com/leetcode\.com/g') + +get_question_slug ${URL} +query_problem ${URL} ${QUESTION_TITLE_SLUG} + +#echo "$QUESTION_CONTENT" +#echo $QUESTION_DIFFICULTY +#echo $QUESTION_TITLE +#echo $QUESTION_ID +#echo $QUESTION_FRONTEND_ID +#echo $QUESTION_CATEGORY + + +FILE=`echo ${FILE} | sed "s/.*\/algorithms/\.\/algorithms/"` + +echo "|${QUESTION_FRONTEND_ID}|[${QUESTION_TITLE}](${URL}) | [C++](${FILE})|${QUESTION_DIFFICULTY}|"