├── .coveragerc ├── .gitignore ├── .travis.yml ├── .vscode └── settings.json ├── Contest ├── LeetCodeBiweeklyContest │ └── BiweeklyContest36 │ │ ├── 1.py │ │ ├── 2.py │ │ └── 4_fail.py ├── LeetCodeWeeklyContest │ ├── WeeklyContest163 │ │ └── 1260-Shift2DGrid.py │ ├── WeeklyContest165 │ │ ├── 1275-FindWinnerOnATicTacToeGame.py │ │ └── 1276-NumberOfBurgersWithNoWastesOfIngredients.py │ ├── WeeklyContest167 │ │ ├── 1290-ConvertBinaryNumberInALinkedListToInteger.py │ │ └── 1291-SequentialDigits.py │ ├── WeeklyContest169 │ │ ├── AllElementsInTwoBinarySearchTrees.py │ │ ├── FindNUniqueIntegersSumUpToZero.py │ │ ├── JumpGameIII.py │ │ └── VerbalArithmeticPuzzle.py │ ├── WeeklyContest170 │ │ ├── AllElementsInTwoBinarySearchTrees_DCMem.py │ │ ├── AllElementsInTwoBinarySearchTrees_Naive.py │ │ ├── AllElementsInTwoBinarySearchTrees_XOR.py │ │ ├── FindNUniqueIntegersSumUpToZero.py │ │ ├── GetWatchedVideosByYourFriends.py │ │ └── test_170_2.py │ ├── WeeklyContest171 │ │ └── MinimumFlipsToMakeAOrBEqualToC.py │ ├── WeeklyContest176 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 3.py │ │ ├── 4.py │ │ ├── 4_2.py │ │ └── MaximumNumberOfEventsThatCanBeAttended.md │ ├── WeeklyContest177 │ │ ├── 1.py │ │ ├── 2.py │ │ └── ClosestDivisors.md │ ├── WeeklyContest178 │ │ ├── 1.py │ │ └── 3.py │ ├── WeeklyContest179 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 2_2.py │ │ └── 2_3.py │ ├── WeeklyContest180 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 3.py │ │ ├── 4.py │ │ ├── 4_2.py │ │ └── MaximumPerformanceOfATeam.md │ ├── WeeklyContest181 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 3.py │ │ └── 4.py │ ├── WeeklyContest182 │ │ ├── 1.py │ │ ├── 2.py │ │ └── 3.py │ ├── WeeklyContest184 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 3.py │ │ └── 4.py │ ├── WeeklyContest186 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 2_2.py │ │ ├── 2_3.py │ │ └── 3.py │ ├── WeeklyContest187 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 3.py │ │ ├── 3_2.py │ │ ├── 3_3.py │ │ ├── 4.py │ │ ├── 4_2.py │ │ ├── FindTheKthSmallestSumOfAMatrixWithSortedRows.md │ │ └── LongestContinuousSubarrayWithAbsoluteDiffLessThanOrEqualToLimit.md │ ├── WeeklyContest188 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 2_2.py │ │ └── 3.py │ ├── WeeklyContest189 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 3.py │ │ ├── 4.py │ │ ├── 4_2.py │ │ ├── 4_3.py │ │ └── MaximumNumberOfDartsInsideOfACircularDartboard.md │ ├── WeeklyContest190 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 2_2.py │ │ ├── 3.py │ │ ├── 4.py │ │ ├── 4_2.py │ │ └── MaxDotProductOfTwoSubsequences.md │ ├── WeeklyContest192 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 3.py │ │ └── 4.py │ ├── WeeklyContest195 │ │ ├── 1.py │ │ └── 2.py │ ├── WeeklyContest196 │ │ ├── 1.py │ │ ├── 1_2.py │ │ ├── 2.py │ │ ├── 2_2.py │ │ ├── 3.py │ │ ├── 3_2.py │ │ └── 4.py │ ├── WeeklyContest197 │ │ ├── 1.py │ │ ├── 2.py │ │ └── 3.py │ ├── WeeklyContest198 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 2_2.py │ │ └── 4.py │ ├── WeeklyContest199 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 3.py │ │ ├── 3_2.py │ │ ├── 4.py │ │ └── 4_fail.py │ ├── WeeklyContest200 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 3.py │ │ ├── 3_2.py │ │ ├── 3_fail.py │ │ ├── 4.py │ │ ├── 4_2.py │ │ ├── 4_3.py │ │ └── 4_fail.py │ ├── WeeklyContest201 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 3_fail.py │ │ ├── 4_2_fail.py │ │ └── 4_fail.py │ ├── WeeklyContest202 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 2_other.py │ │ ├── 3_fixed.py │ │ ├── 3_other.py │ │ ├── 4_2_fail.py │ │ ├── 4_fail.py │ │ └── 4_other.py │ ├── WeeklyContest204 │ │ ├── 1.py │ │ ├── 2.py │ │ └── 3_fail.py │ ├── WeeklyContest205 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 2_2_fail.py │ │ ├── 2_3_fail.py │ │ ├── 2_4_fail.py │ │ ├── 2_fail.py │ │ ├── 3.py │ │ └── 4_other.py │ ├── WeeklyContest206 │ │ ├── 1.py │ │ ├── 1_2_other.py │ │ ├── 1_fail.py │ │ ├── 1_other.py │ │ ├── 2.py │ │ ├── 3.py │ │ ├── 3_other.py │ │ ├── 4_fail.py │ │ └── 4_other.py │ ├── WeeklyContest207 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 3.py │ │ └── 3_fail.py │ ├── WeeklyContest209 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 3_fail.py │ │ ├── 3_fail2.py │ │ └── 3_fail3.py │ ├── WeeklyContest210 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 3.py │ │ └── 3_fail.py │ ├── WeeklyContest211 │ │ ├── 1.py │ │ ├── 2_other.py │ │ ├── 2_other2.py │ │ ├── 2_other3.py │ │ ├── 3_fail.py │ │ ├── 3_other.py │ │ ├── 3_other2.py │ │ ├── 4_fail.py │ │ └── 4_other.py │ ├── WeeklyContest212 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 3_fail.py │ │ ├── 3_other.py │ │ └── 3_other2.py │ ├── WeeklyContest213 │ │ ├── 1.py │ │ ├── 1_fail.py │ │ ├── 2.py │ │ ├── 2_fail.py │ │ ├── 3.py │ │ ├── 4_fail.py │ │ └── 4_other.py │ ├── WeeklyContest224 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 3_fail.py │ │ ├── 3_other.py │ │ └── 4_other.py │ ├── WeeklyContest225 │ │ ├── 1.py │ │ ├── 2_fail.py │ │ ├── 3.py │ │ └── 4_fail.py │ ├── WeeklyContest226 │ │ ├── 1.py │ │ ├── 2_other.py │ │ ├── 2_other2.py │ │ ├── 3.py │ │ └── 4.py │ ├── WeeklyContest236 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 3.py │ │ ├── 3_fail.py │ │ └── 4.py │ ├── WeeklyContest239 │ │ ├── 1.py │ │ ├── 2_fail.py │ │ └── 4_fail.py │ ├── WeeklyContest243 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 3.py │ │ ├── 3_fail.py │ │ ├── 3_fail2.py │ │ ├── 3_fail3.py │ │ ├── 3_fail4.py │ │ └── 4_fail.py │ ├── WeeklyContest245 │ │ ├── 1.py │ │ ├── 2_fail.py │ │ ├── 2_fail2.py │ │ ├── 2_fail3.py │ │ ├── 2_fail4.py │ │ ├── 2_fail5.py │ │ ├── 2_fail6.py │ │ ├── 2_other.py │ │ ├── 3.py │ │ └── 3_2.py │ ├── WeeklyContest247 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 3_fail.py │ │ ├── 3_fail2.py │ │ ├── 3_other.py │ │ ├── 4_fail.py │ │ └── 4_other.py │ ├── WeeklyContest248 │ │ ├── 1.py │ │ ├── 2.py │ │ ├── 2_fail.py │ │ ├── 2_fail2.py │ │ ├── 2_fail3.py │ │ ├── 2_fail4.py │ │ ├── 2_fail5.py │ │ ├── 3.py │ │ ├── 3_fail.cpp │ │ ├── 3_fail.py │ │ ├── 3_fail2.cpp │ │ ├── 3_fail2.py │ │ ├── 3_fail3.py │ │ └── 3_fail4.py │ ├── WeeklyContest325 │ │ ├── 1 │ │ │ ├── Naive.py │ │ │ └── test_325_1.py │ │ └── 2 │ │ │ ├── DFS.py │ │ │ └── test_325_2.py │ ├── WeeklyContest334 │ │ ├── 1 │ │ │ └── Naive.py │ │ ├── 2 │ │ │ ├── Improve.py │ │ │ └── Naive.py │ │ ├── 3 │ │ │ ├── Heap.py │ │ │ ├── Naive.py │ │ │ ├── Naive2.py │ │ │ ├── Naive3.py │ │ │ ├── Sorted.py │ │ │ ├── Sorted2.py │ │ │ ├── Sorted3.py │ │ │ └── Sorted4.py │ │ └── 4 │ │ │ ├── BFS.py │ │ │ └── Dijkstra.py │ ├── WeeklyContest337 │ │ ├── 1 │ │ │ └── Naive.py │ │ ├── 2 │ │ │ └── Naive.py │ │ └── 3 │ │ │ ├── DFS.py │ │ │ ├── Naive_TLE.py │ │ │ ├── WA.py │ │ │ └── test_2597.py │ ├── WeeklyContest338 │ │ ├── 1 │ │ │ ├── Better.py │ │ │ └── Naive.py │ │ ├── 2 │ │ │ ├── Naive.py │ │ │ ├── Naive2.py │ │ │ └── Naive3.py │ │ └── 3 │ │ │ ├── BinarySearchMath.py │ │ │ ├── Math.py │ │ │ └── Naive.py │ ├── WeeklyContest339 │ │ ├── 1 │ │ │ └── Naive.py │ │ ├── 2 │ │ │ └── Greedy.py │ │ └── 3 │ │ │ └── Greedy.py │ ├── WeeklyContest340 │ │ ├── 1 │ │ │ └── Naive.py │ │ ├── 2 │ │ │ └── Naive.py │ │ └── 3 │ │ │ └── Naive.py │ └── WeeklyContest344 │ │ ├── 1 │ │ └── Naive.py │ │ ├── 2 │ │ └── Naive.py │ │ ├── 3 │ │ └── Naive.py │ │ └── 4 │ │ ├── Naive.py │ │ └── Trick.py └── README.md ├── Learn ├── Algorithm │ └── Graph │ │ ├── BellmanFord │ │ └── README.md │ │ ├── DijkstraShortestPath │ │ ├── README.md │ │ ├── dijkstra.py │ │ └── dijkstra_heap.py │ │ └── Prim │ │ └── README.md ├── Cpp │ ├── Queue │ │ └── CircularQueue.cpp │ └── Stack │ │ └── MinStack.cpp └── DataStructure │ └── DoubleLinkedList │ └── DoubleLinkedList.py ├── Notes ├── Algorithm │ ├── Backtracking.md │ ├── BinarySearch.md │ ├── BinarySearchTemplates.md │ ├── DynamicProgramming.md │ ├── PatternSearching.md │ ├── SweepLine.md │ └── TopologicalSort.md ├── DataStructure │ ├── BinaryTree.md │ ├── DisjointSet_UnionFind.md │ ├── FenwickTree_BinaryIndexedTree.md │ ├── Graph.md │ ├── MoreTree.md │ ├── PriorityQueue_Heap.md │ ├── QueueStack.md │ ├── README.md │ ├── SizeBalancedTree.md │ └── Trie_PrefixTree.md ├── Pattern │ └── Interval.md ├── PracticeOrder │ └── Order1.md ├── Technique │ └── TwoPointers.md └── Trick │ ├── BitManipulation.md │ └── Python.md ├── Python3 ├── AdHoc │ └── ExclusiveTimeOfFunctions │ │ └── Naive636.py ├── Array │ ├── 3Sum │ │ ├── BinarySearch015.py │ │ ├── Naive015.py │ │ ├── Note015.md │ │ ├── TwoPointer015.py │ │ ├── TwoPointer2_015.py │ │ └── test_015.py │ ├── 3SumClosest │ │ ├── Note016.md │ │ ├── TwoPointer016.py │ │ └── test_016.py │ ├── 4Sum │ │ ├── GeneralizedTwoPointer018.py │ │ ├── Note018.md │ │ └── test_018.py │ ├── AddDigits │ │ ├── Iterative258.py │ │ ├── Naive258.py │ │ ├── NoLoop258.py │ │ ├── Note258.md │ │ └── test_258.py │ ├── AddToArrayFormOfInteger │ │ ├── Naive989.py │ │ ├── Python989.py │ │ └── test_989.py │ ├── AdvantageShuffle │ │ ├── Sorting870.py │ │ ├── SortingWithQueue870.py │ │ └── test_870.py │ ├── ArithmeticSlices │ │ └── Naive413.py │ ├── AverageSalaryExcludingtheMinimumAndMaximumSalary │ │ ├── Naive1491.py │ │ └── test_1491.py │ ├── BeautifulArrangement │ │ ├── BacktrackingWithMemory526.py │ │ └── BruteForce526.py │ ├── BestTimeToBuyAndSellStockWithCooldown │ │ ├── DP309.py │ │ ├── StateMachine309.py │ │ ├── StateMachine_DP309.py │ │ └── test_309.py │ ├── BestTimetoBuyandSellStock │ │ ├── BruteForce121.py │ │ ├── DP121.py │ │ ├── DP2_121.py │ │ ├── Naive121.py │ │ ├── Note121.md │ │ └── test_121.py │ ├── BestTimetoBuyandSellStockII │ │ ├── Greedy122.py │ │ ├── Greedy2_122.py │ │ ├── Max122.py │ │ ├── Note122.md │ │ ├── Tricky122.py │ │ └── test_122.py │ ├── BinarySearch │ │ ├── Bisect704.py │ │ ├── Iterative704.py │ │ ├── Recursive704.py │ │ └── test_704.py │ ├── BoatsToSavePeople │ │ ├── Greedy881.py │ │ └── test_881.py │ ├── CanPlaceFlowers │ │ ├── Naive605.py │ │ └── test_605.py │ ├── Candy │ │ ├── BruteForce135.py │ │ ├── TwoArrays135.py │ │ └── test_135.py │ ├── CapacityToShipPackagesWithinDDays │ │ ├── BinarySearch1011.py │ │ ├── BinarySearchImprove1011.py │ │ └── test_1011.py │ ├── CarPooling │ │ └── Naive1094.py │ ├── CheckArrayFormationThroughConcatenation │ │ ├── HT1640.py │ │ └── Note1640.md │ ├── ClimbingStairs │ │ ├── DP070.py │ │ ├── Naive070.py │ │ ├── Note070.md │ │ ├── Recursive070.py │ │ └── test_070.py │ ├── CoinChange │ │ ├── DP322.py │ │ ├── Naive322.py │ │ └── test_322.py │ ├── CoinChange2 │ │ ├── DP518.py │ │ ├── Naive518.py │ │ ├── Note518.md │ │ └── test_518.py │ ├── CombinationSum │ │ ├── Backtracking039.py │ │ ├── Naive039.py │ │ ├── Note039.md │ │ └── test_039.py │ ├── ConstrainedSubsequenceSum │ │ └── Note1425.md │ ├── ContainerWithMostWater │ │ ├── Naive011.py │ │ ├── Naive2_011.py │ │ ├── Note011.md │ │ ├── TwoPointer011.py │ │ ├── TwoPointer2_011.py │ │ └── test_011.py │ ├── ContiguousArray │ │ ├── ExtraArray525.py │ │ ├── HT2_525.py │ │ ├── HT525.py │ │ ├── Naive525.py │ │ └── test_525.py │ ├── CountOfSmallerNumbersAfterSelf │ │ ├── BinaryIndexedTree315.py │ │ ├── MergeSort315.py │ │ ├── Note315.md │ │ └── test_315.py │ ├── CountSquareSubmatricesWithAllOnes │ │ ├── DP1277.py │ │ └── Naive1277.py │ ├── CountingElements │ │ ├── Naive.py │ │ └── SinglePass.py │ ├── CourseSchedule │ │ ├── CycleDetect207.py │ │ ├── DFS207.py │ │ ├── Note207.md │ │ ├── TopologicalSort207.py │ │ └── test_207.py │ ├── CourseScheduleII │ │ ├── Note210.md │ │ └── TopologicalSort210.py │ ├── CourseScheduleIII │ │ ├── Naive630.py │ │ ├── PriorityQueue630.py │ │ ├── TopDownDP630.py │ │ └── test_630.py │ ├── DailyTemperatures │ │ ├── Naive2_739.py │ │ ├── Naive739.py │ │ ├── Note739.md │ │ ├── Stack739.py │ │ └── test_739.py │ ├── DecodeWays │ │ ├── Naive91.py │ │ ├── Note91.md │ │ └── test_91.py │ ├── DungeonGame │ │ ├── DP174.py │ │ └── test_174.py │ ├── EvaluateReversePolishNotation │ │ ├── Note150.md │ │ ├── Stack150.py │ │ └── test_150.py │ ├── FinalPricesWithASpecialDiscountInAShop │ │ ├── Naive1475.py │ │ ├── Stack1475.py │ │ └── test_1475.py │ ├── FindKClosestElements │ │ ├── DoubleSort658.py │ │ ├── FindLeftBound658.py │ │ ├── Naive658.py │ │ ├── Note658.md │ │ └── test_658.py │ ├── FindKPairsWithSmallestSums │ │ ├── HeapMergeSort373.py │ │ └── PriorityQueue373.py │ ├── FindMinimumInRotatedSortedArray │ │ ├── Naive153.py │ │ ├── Simpler153.py │ │ └── test_153.py │ ├── FindMinimumInRotatedSortedArrayII │ │ ├── Naive154.py │ │ ├── YetAnother154.py │ │ └── test_154.py │ ├── FindSubsequenceOfLengthKWithTheLargestSum │ │ ├── Naive2099.py │ │ └── test_2099.py │ ├── FindTheDuplicateNumber │ │ ├── LinkedList287.py │ │ ├── Naive287.py │ │ ├── Set287.py │ │ └── TwoPointer287.py │ ├── FindTheTownJudge │ │ ├── Improve997.py │ │ ├── Naive2_997.py │ │ ├── Naive997.py │ │ └── test_997.py │ ├── FirstBadVersion │ │ └── Naive278.py │ ├── FloodFill │ │ ├── DFS733.py │ │ ├── IterativeDFS733.py │ │ └── Naive733.py │ ├── FruitIntoBaskets │ │ ├── Greedy904.py │ │ ├── Naive904.py │ │ ├── SlidingWindow904.py │ │ └── test_904.py │ ├── H-Index │ │ ├── CumulativeSum274.py │ │ └── test_274.py │ ├── H-IndexII │ │ ├── BinarySearch275.py │ │ ├── Linear275.py │ │ └── test_275.py │ ├── IPO │ │ ├── Naive502.py │ │ ├── SortHeap502.py │ │ ├── SortHeapImprove502.py │ │ └── test_502.py │ ├── IntervalListIntersections │ │ ├── Note986.md │ │ └── TwoPointer986.py │ ├── IslandPerimeter │ │ ├── CountEdge463.py │ │ ├── Naive463.py │ │ ├── Neighbour463.py │ │ └── StringEdge463.py │ ├── JumpGame │ │ ├── Backtracking055.py │ │ ├── DPBottomUp055.py │ │ ├── DPTopDown055.py │ │ ├── Greedy055.py │ │ ├── Greedy2_055.py │ │ ├── Note055.md │ │ └── test_055.py │ ├── JumpGameII │ │ ├── BFS045.py │ │ ├── DP045.py │ │ ├── Greedy045.py │ │ ├── Greedy2_045.py │ │ └── test_045.py │ ├── K-diffPairsInAnArray │ │ ├── HT532.py │ │ ├── Naive2_532.py │ │ ├── Naive532.py │ │ ├── README.md │ │ └── test_532.py │ ├── KokoEatingBananas │ │ ├── BinarySearch875.py │ │ ├── Naive875.py │ │ └── test_875.py │ ├── KthLargestElementInAnArray │ │ ├── Heap215.py │ │ ├── HeapCheat215.py │ │ ├── Naive215.py │ │ ├── Note215.md │ │ ├── QuickSelect215.py │ │ ├── QuickSelect2_215.py │ │ ├── QuickSort215.py │ │ ├── SelectionSortLike215.py │ │ └── test_215.py │ ├── KthMissingPositiveNumber │ │ ├── BinarySearch1539.py │ │ ├── Bisect1539.py │ │ ├── Naive1539.py │ │ ├── Naive2_1539.py │ │ └── test_1539.py │ ├── KthSmallestElementInASortedMatrix │ │ ├── Naive378.py │ │ ├── Note378.md │ │ └── test_378.py │ ├── LargestDivisibleSubset │ │ ├── DP368.py │ │ ├── Naive368.py │ │ ├── Note368.md │ │ └── test_368.py │ ├── LastStoneWeight │ │ ├── Heap1046.py │ │ ├── InsertionSort1046.py │ │ └── test_1046.py │ ├── LongestCommonPrefix │ │ ├── Naive014.py │ │ ├── Note014.md │ │ └── test_014.py │ ├── LongestConsecutiveSequence │ │ ├── HT128.py │ │ ├── Naive128.py │ │ ├── Note128.md │ │ └── test_128.py │ ├── LongestHarmoniousSubsequence │ │ └── Naive594.py │ ├── LongestIncreasingSubsequence │ │ ├── BinarySearch2_300.py │ │ ├── BinarySearch300.py │ │ ├── BruteForce300.py │ │ ├── DP2_300.py │ │ ├── DP300.py │ │ ├── MemoryRecursive300.py │ │ ├── Note300.md │ │ └── test_300.py │ ├── MajorityElement │ │ ├── Counter169.py │ │ ├── Naive169.py │ │ ├── Sorting169.py │ │ └── Voting169.py │ ├── MatrixDiagonalSum │ │ ├── Better1572.py │ │ ├── Naive1572.py │ │ └── test_1572.py │ ├── MaxConsecutiveOnesIII │ │ ├── Naive1004.py │ │ └── test_1004.py │ ├── MaxSumOfRectangleNoLargerThanK │ │ └── PrefixSum363.py │ ├── MaximalRectangle │ │ └── Note085.md │ ├── MaximalSquare │ │ ├── BruteForce221.py │ │ ├── DP221.py │ │ ├── DP_2_221.py │ │ ├── Naive221.py │ │ ├── Note221.md │ │ └── test_221.py │ ├── MaximumBagsWithFullCapacityOfRocks │ │ ├── Greedy2279.py │ │ └── test_2279.py │ ├── MaximumDistanceInArrays │ │ └── Naive624.py │ ├── MaximumLengthOfRepeatedSubarray │ │ ├── DP718.py │ │ └── test_718.py │ ├── MaximumSubarray │ │ ├── DC053.py │ │ ├── DP053.py │ │ ├── Naive053.py │ │ ├── Note053.md │ │ └── test_053.py │ ├── MaximumSumCircularSubarray │ │ ├── MinSumSubarray918.py │ │ ├── Naive918.py │ │ ├── Note918.md │ │ └── test_918.py │ ├── MeetingRooms │ │ ├── Note252.md │ │ ├── Sorting252.py │ │ ├── interval.py │ │ └── test_252.py │ ├── MeetingRoomsII │ │ ├── Note253.md │ │ ├── Sorting253.py │ │ ├── interval.py │ │ └── test_253.py │ ├── MergeIntervals │ │ ├── Better056.py │ │ ├── Graph056.py │ │ ├── Naive056.py │ │ ├── Note056.md │ │ ├── Sorting056.py │ │ ├── Tree056.py │ │ └── test_056.py │ ├── MergeSortedArray │ │ ├── Naive088.py │ │ └── test_088.py │ ├── MinimizeDeviationInArray │ │ └── Greedy1675.py │ ├── MinimumCostToCutAStick │ │ ├── TopDownDP1547.py │ │ └── test_1547.py │ ├── MinimumCostToHireKWorkers │ │ ├── Greedy857.py │ │ ├── GreedyPQ857.py │ │ ├── Note857.md │ │ └── test_857.py │ ├── MinimumNumberOfArrowsToBurstBalloons │ │ ├── Naive452.py │ │ └── test_452.py │ ├── MinimumPathSum │ │ ├── Backtracking064.py │ │ ├── BacktrackingWithEarlyStop064.py │ │ ├── DP064.py │ │ ├── Naive064.py │ │ ├── NoAdditionalSpace064.py │ │ └── test_064.py │ ├── MinimumRoundsToCompleteAllTasks │ │ ├── Greedy2244.py │ │ ├── Greedy2_2244.py │ │ ├── Note2244.md │ │ └── test_2244.py │ ├── MinimumSwapsToMakeSequencesIncreasing │ │ └── Note801.md │ ├── MinimumTimeToCompleteTrips │ │ ├── BinarySearch2187.py │ │ └── test_2187.py │ ├── MissingNumber │ │ ├── BitManipulation268.py │ │ ├── Naive268.py │ │ └── test_268.py │ ├── MoveZeroes │ │ ├── Naive283.py │ │ └── TwoPointer283.py │ ├── NQueens │ │ └── Naive051.py │ ├── NQueensII │ │ └── Naive052.py │ ├── NextPermutation │ │ ├── Note031.md │ │ ├── SinglePass031.py │ │ └── test_031.py │ ├── NonDecreasingArray │ │ ├── Greedy665.py │ │ └── Note665.md │ ├── NumberOfAirplanesInTheSky │ │ ├── HeapSort391.py │ │ ├── SweepLine391.py │ │ └── test_391.py │ ├── NumberOfWaysOfCuttingAPizza │ │ ├── PrefixSumDP1444.py │ │ └── test_1444.py │ ├── NumberOfZero-FilledSubarrays │ │ ├── Math2348.py │ │ ├── SimplifiedMath2348.py │ │ └── test_2348.py │ ├── PairsOfSongsWithTotalDurationsDivisibleBy60 │ │ ├── Naive1010.py │ │ ├── Note1010.md │ │ └── PrefixSum1010.py │ ├── PalindromeNumber │ │ ├── Naive009.py │ │ ├── NotString009.py │ │ ├── Note009.md │ │ └── test_009.py │ ├── PascalsTriangle │ │ ├── Naive118.py │ │ ├── Note118.md │ │ └── test_118.py │ ├── PatchingArray │ │ ├── Naive330.py │ │ └── Trick330.py │ ├── Permutations │ │ ├── Backtracking046.py │ │ ├── DFS046.py │ │ ├── Note046.md │ │ ├── Recursive046.py │ │ └── test_Permutations.py │ ├── PlusOne │ │ ├── FullAdder066.py │ │ ├── Naive066.py │ │ └── test_066.py │ ├── PrisonCellsAfterNDays │ │ ├── LoopDetection957.py │ │ ├── Naive957.py │ │ ├── Note957.md │ │ └── test_957.py │ ├── ProductOfArrayExceptSelf │ │ ├── Note238.md │ │ ├── ProductList238.py │ │ ├── ProductList2_238.py │ │ ├── SingleProductList238.py │ │ └── test_238.py │ ├── QueueReconstructionByHeight │ │ ├── Insert402.py │ │ ├── InsertFromHighest402.py │ │ ├── InsertFromLowest402.py │ │ ├── Note402.md │ │ └── Sorting402.py │ ├── ReconstructItinerary │ │ ├── DFS332.py │ │ ├── EulerianPath332.py │ │ ├── Naive332.py │ │ └── test_332.py │ ├── ReduceArraySizeToTheHalf │ │ ├── Naive1338.py │ │ └── test_1338.py │ ├── RemoveCoveredIntervals │ │ ├── Naive1288.py │ │ └── test_1288.py │ ├── RemoveDuplicatesfromSortedArray │ │ ├── Better026.py │ │ ├── Naive026.py │ │ ├── Note026.md │ │ └── test_026.py │ ├── RemoveElement │ │ ├── Naive027.py │ │ ├── Naive2027.py │ │ ├── Note027.md │ │ └── test_027.py │ ├── ReshapeTheMatrix │ │ └── Naive566.py │ ├── RestoreIPAddresses │ │ ├── Backtracking093.py │ │ ├── Note93.md │ │ └── test_093.py │ ├── ReverseInteger │ │ ├── Naive007.py │ │ ├── Note007.md │ │ └── test_007.py │ ├── RotateArray │ │ ├── NaiveInPlace189.py │ │ ├── Note189.md │ │ ├── Simplest189.py │ │ ├── UseArray189.py │ │ └── test_189.py │ ├── RotateImage │ │ ├── Naive048.py │ │ ├── Note048.md │ │ └── test_048.py │ ├── RunningSumOf1dArray │ │ ├── InPlace1480.py │ │ └── Naive1480.py │ ├── SearchInRotatedSortedArray │ │ ├── BinarySearch033.py │ │ ├── BinarySearch2_033.py │ │ ├── Note033.md │ │ └── test_033.py │ ├── SearchInsertPosition │ │ ├── BinarySearch035.py │ │ ├── BinarySearch2_035.py │ │ ├── Naive035.py │ │ ├── Note035.md │ │ └── test_035.py │ ├── ShortestSubarrayWithSumAtLeastK │ │ └── Note862.md │ ├── SingleElementInASortedArray │ │ ├── BinarySearch540.py │ │ ├── BinarySearchXOR540.py │ │ ├── Naive540.py │ │ ├── XOR540.py │ │ └── test_540.py │ ├── SingleNumber │ │ ├── BM136.py │ │ ├── HT136.py │ │ ├── Note136.md │ │ ├── Set136.py │ │ └── test_136.py │ ├── SingleNumberII │ │ ├── BitManipulation137.py │ │ ├── BitManipulation2_137.py │ │ ├── Math137.py │ │ └── Naive137.py │ ├── SingleNumberIII │ │ ├── BitManipulation260.py │ │ ├── Naive260.py │ │ └── test_260.py │ ├── SingleThreadedCPU │ │ ├── Greedy1834.py │ │ ├── Heap1834.py │ │ ├── HeapImprove1834.py │ │ └── test_1834.py │ ├── SortAnArray │ │ ├── HeapSort2_912.py │ │ ├── HeapSort912.py │ │ ├── MergeSort912.py │ │ ├── QuickSort912.py │ │ ├── ThreeWayQuickSort912.py │ │ └── test_912.py │ ├── SortColors │ │ ├── CountingSort075.py │ │ ├── DutchNationalFlagProblem075.py │ │ └── Note075.md │ ├── SubarraySumEqualsK │ │ ├── BruteForce560.py │ │ ├── CumulativeSum560.py │ │ ├── HT560.py │ │ ├── Note560.md │ │ ├── WithoutSpace560.py │ │ └── test_560.py │ ├── SudokuSolver │ │ └── Note037.md │ ├── SurroundedRegions │ │ ├── Boarders130.py │ │ ├── Naive130.py │ │ ├── Note130.md │ │ └── test_130.py │ ├── TargetSum │ │ ├── DP_1D_494.py │ │ ├── DP_2D_494.py │ │ ├── Naive494.py │ │ ├── Note494.md │ │ ├── RecursiveWithMemory494.py │ │ └── test_494.py │ ├── TaskScheduler │ │ ├── Naive621.py │ │ ├── Note621.md │ │ └── test_621.py │ ├── TheKWeakestRowsInAMatrix │ │ └── Naive1337.py │ ├── TopKFrequentElements │ │ ├── BucketSort347.py │ │ ├── HT347.py │ │ ├── HTHeap2_347.py │ │ ├── HTHeap347.py │ │ ├── Naive347.py │ │ ├── Note347.md │ │ ├── Quickselect347.py │ │ └── test_374.py │ ├── TransposeMatrix │ │ ├── Naive867.py │ │ └── Numpy867.py │ ├── Triangle │ │ ├── Naive120.py │ │ ├── Note120.md │ │ └── test_120.py │ ├── TwoCityScheduling │ │ ├── Diff1029.py │ │ ├── Naive1029.py │ │ ├── Sorting1029.py │ │ └── test_1029.py │ ├── TwoSum │ │ ├── HashTable001.py │ │ ├── Naive001.py │ │ ├── Note001.md │ │ ├── SortedHashTable001.py │ │ └── test_001.py │ ├── TwoSumII │ │ ├── Note167.md │ │ ├── TwoPointer167.py │ │ └── test_167.py │ ├── UncrossedLines │ │ ├── BottomUpDP1035.py │ │ ├── Naive1035.py │ │ └── Note1035.md │ ├── UniquePaths │ │ ├── DP062.py │ │ ├── Naive062.py │ │ └── test_062.py │ ├── ValidSudoku │ │ ├── HashTable036.py │ │ ├── Note036.md │ │ └── test_036.py │ ├── ValidTriangleNumber │ │ ├── BinarySearch2_611.py │ │ ├── BinarySearch611.py │ │ ├── BruteForce611.py │ │ ├── TwoPointer611.py │ │ └── test_611.py │ ├── ValidateStackSequences │ │ ├── Better946.py │ │ ├── Naive946.py │ │ └── test_946.py │ ├── WiggleSortII │ │ ├── Median324.py │ │ └── Naive324.py │ ├── WiggleSubsequence │ │ ├── BottomUpDP376.py │ │ ├── Naive376.py │ │ └── test_376.py │ ├── WordSearch │ │ ├── DFS079.py │ │ ├── DFS2_079.py │ │ ├── Naive079.py │ │ └── test_079.py │ ├── WordSearchII │ │ ├── Naive212.py │ │ ├── large_case.txt │ │ └── test_212.py │ └── ZigZagConversion │ │ ├── Naive006.py │ │ ├── Note006.md │ │ └── test_006.py ├── BinaryTree │ ├── BalancedBinaryTree │ │ ├── Naive110.py │ │ ├── Note110.md │ │ ├── PostorderIterative110.py │ │ └── Recursive110.py │ ├── BinaryTreeInorderTraversal │ │ ├── Iterative94.py │ │ ├── Note94.md │ │ └── Recursive94.py │ ├── BinaryTreeLevelOrderTraversal │ │ ├── BFS102.py │ │ └── Note102.md │ ├── BinaryTreeLevelOrderTraversalII │ │ ├── Naive107.py │ │ └── Naive2_107.py │ ├── BinaryTreeMaximumPathSum │ │ └── Recursive124.py │ ├── BinaryTreePaths │ │ ├── Iterative257.py │ │ ├── Note257.md │ │ └── Recursive257.py │ ├── BinaryTreePostorderTraversal │ │ ├── Iterative145.py │ │ ├── Note145.md │ │ └── Recursive145.py │ ├── BinaryTreePreorderTraversal │ │ ├── Iterative144.py │ │ ├── Note144.md │ │ └── Recursive144.py │ ├── BinaryTreeRightSideView │ │ └── Naive199.py │ ├── BinaryTreeTilt │ │ └── Naive559.py │ ├── BinaryTreeZigzagLevelOrderTraversal │ │ ├── BFS103.py │ │ ├── Naive103.py │ │ ├── WithoutReverse103.py │ │ └── WithoutReverse2_103.py │ ├── CheckCompletenessOfABinaryTree │ │ ├── BFS958.py │ │ ├── DFS958.py │ │ └── Note958.md │ ├── CheckIfAStringIsAValidSequenceFromRootToLeavesPathInABinaryTree │ │ ├── IterativeDFS.py │ │ └── Naive.py │ ├── ConstructBinarySearchTreeFromPreorderTraversal │ │ ├── Naive1008.py │ │ ├── Naive2_1008.py │ │ └── Note1008.md │ ├── ConstructBinaryTreefromInorderandPostorderTraversal │ │ ├── Better106.py │ │ ├── DivideAndConquer106.py │ │ ├── Naive106.py │ │ ├── Naive2_106.py │ │ ├── Naive3_106.py │ │ └── Note106.md │ ├── ConstructBinaryTreefromPreorderandInorderTraversal │ │ ├── DivideAndConquer105.py │ │ └── Note105.md │ ├── ConvertBSTToGreaterTree │ │ ├── Array538.py │ │ └── DFS538.py │ ├── ConvertSortedArrayToBinarySearchTree │ │ ├── Note108.md │ │ └── Recursive108.py │ ├── ConvertSortedListToBinarySearchTree │ │ ├── ArrayRecursive109.py │ │ ├── Note109.md │ │ └── TwoPointerRecursive109.py │ ├── CountCompleteTreeNodes │ │ ├── BinarySearch221.py │ │ └── Naive221.py │ ├── CousinsInBinaryTree │ │ ├── IterativeBFS993.py │ │ └── RecursiveDFS993.py │ ├── DiameterOfBinaryTree │ │ └── DFS543.py │ ├── FindACorrespondingNodeOfABinaryTreeInACloneOfThatTree │ │ ├── Naive1379.py │ │ └── Note1379.md │ ├── FlattenBinaryTreeToLinkedList │ │ ├── Naive114.py │ │ └── Note114.md │ ├── InorderSuccessorInBST │ │ └── Note285.md │ ├── InsertIntoABinarySearchTree │ │ ├── Naive701.py │ │ └── Recursive701.py │ ├── InvertBinaryTree │ │ ├── Naive226.py │ │ ├── Note226.md │ │ └── Recursive226.py │ ├── KthSmallestElementInABST │ │ ├── Iterative230.py │ │ ├── Naive230.py │ │ └── Note230.md │ ├── LongestUnivaluePath │ │ └── Note687.md │ ├── LowestCommonAncestorOfABinarySearchTree │ │ └── Naive235.py │ ├── LowestCommonAncestorofaBinaryTree │ │ ├── Elegant236.py │ │ ├── Naive236.py │ │ ├── Naive2_236.py │ │ ├── Naive3_236.py │ │ └── Note236.md │ ├── MaximumDepthOfNaryTree │ │ ├── DFS559.py │ │ ├── Naive559.py │ │ └── Note559.md │ ├── MaximumDepthofBinaryTree │ │ ├── BottomUp104.py │ │ ├── Note104.md │ │ ├── TopDown104.py │ │ └── TopDown104_2.py │ ├── MaximumWidthOfBinaryTree │ │ ├── Naive662.py │ │ └── Note662.md │ ├── MinimumDepthOfBinaryTree │ │ └── BFS111.py │ ├── MinimumDistanceBetweenBSTNodes │ │ ├── DFS783.py │ │ └── DFSImprove783.py │ ├── PathSum │ │ ├── Naive112.py │ │ └── Note112.md │ ├── PathSumII │ │ ├── Naive113.py │ │ └── Note113.md │ ├── PopulatingNextRightPointersInEachNode │ │ ├── DFS116.py │ │ ├── Naive116.py │ │ └── Note116.md │ ├── PopulatingNextRightPointersInEachNodeII │ │ ├── DFS117.py │ │ └── Note117.md │ ├── SameTree │ │ ├── Naive100.py │ │ ├── Note100.md │ │ └── Recursive100.py │ ├── SearchInABinarySearchTree │ │ └── Naive700.py │ ├── SerializeandDeserializeBinaryTree │ │ ├── Naive297.py │ │ ├── Naive2_297.py │ │ └── Note297.md │ ├── SumOfLeftLeaves │ │ └── Naive404.py │ ├── SumRootToLeafNumbers │ │ ├── DFS129.py │ │ ├── Naive129.py │ │ └── StackDFS129.py │ ├── SymmetricTree │ │ ├── Iterative101.py │ │ ├── IterativeBFS101.py │ │ ├── Note101.md │ │ ├── Preorder101.py │ │ └── Recursive101.py │ ├── TreeNodeModule.py │ ├── TrimABinarySearchTree │ │ └── RecursiveDFS669.py │ ├── UniqueBinarySearchTree │ │ ├── Naive096.py │ │ └── test_096.py │ ├── ValidateBinarySearchTree │ │ ├── DFS098.py │ │ ├── InorderTraversal098.py │ │ └── Note098.md │ ├── __init__.py │ ├── test_BalancedBinaryTree.py │ ├── test_BinaryTreeLevelOrderTraversalII.py │ ├── test_BinaryTreePaths.py │ ├── test_BinaryTreeTilt.py │ ├── test_BinaryTreeTraversal.py │ ├── test_BinaryTreeZigzagLevelOrderTraversal.py │ ├── test_ConstructBinaryTree.py │ ├── test_FlattenBinaryTreeToLinkedList.py │ ├── test_LCA.py │ ├── test_LevelOrderTraversal.py │ ├── test_MaximumDepthofBinaryTree.py │ ├── test_MaximumWidthOfBinaryTree.py │ ├── test_MinimumDepthofBinaryTree.py │ ├── test_MinimumDistanceBetweenBSTNodes.py │ ├── test_PathSum.py │ ├── test_PathSumII.py │ ├── test_SameTree.py │ ├── test_SerializeAndDeserializeBinaryTree.py │ ├── test_SumRootToLeafNumbers.py │ ├── test_SymmetricTree.py │ └── test_ValidateBST.py ├── BitManipulation │ ├── BitwiseANDOfNumbersRange │ │ ├── Improve201.py │ │ ├── Naive201.py │ │ └── test_201.py │ ├── ComplementOfBase10Integer │ │ ├── BM1009.py │ │ ├── Naive1009.py │ │ └── Pythonic1009.py │ ├── CountingBits │ │ ├── Naive2_338.py │ │ ├── Naive338.py │ │ └── test_338.py │ ├── GrayCode │ │ ├── Better89.py │ │ ├── BinaryToGray89.py │ │ ├── DirectOrdering89.py │ │ └── MirrorOrdering89.py │ ├── HammingDistance │ │ └── Naive461.py │ ├── NumberOf1Bits │ │ └── Naive191.py │ ├── ReverseBits │ │ ├── Naive190.py │ │ └── String190.py │ └── Subsets │ │ ├── Backtracking078.py │ │ ├── Binary078.py │ │ ├── DFS078.py │ │ ├── Naive078.py │ │ ├── Note078.md │ │ └── test_078.py ├── Design │ ├── AddAndSearchWord │ │ ├── Naive211.py │ │ ├── Note211.md │ │ ├── RegEx211.py │ │ ├── Tire211.py │ │ ├── Tire2_211.py │ │ └── test_211.py │ ├── BinaryHeap │ │ ├── BinaryHeap.md │ │ ├── BinaryHeap.py │ │ └── test_BinaryHeap.py │ ├── DeleteColumnsToMakeSorted │ │ └── Naive944.py │ ├── DesignBrowserHistory │ │ └── Naive1472.py │ ├── DesignHashSet │ │ ├── HashFunction705.py │ │ ├── Naive705.py │ │ └── test_705.py │ ├── FirstUniqueNumber │ │ ├── DLL.py │ │ ├── DLLHT.py │ │ ├── HTCounter.py │ │ ├── Naive.py │ │ └── Note.md │ ├── ImplementQueueusingStacks │ │ ├── Note232.md │ │ ├── TwoStack232.py │ │ └── test_232.py │ ├── ImplementStackusingQueues │ │ ├── Note225.md │ │ ├── TwoQueue225.py │ │ └── test_225.py │ ├── ImplementTrie │ │ ├── Naive208.py │ │ ├── Note208.md │ │ ├── Trie208.py │ │ ├── Trie2_208.py │ │ ├── Trie_array208.py │ │ └── test_208.py │ ├── InsertDeleteGetRandomO(1) │ │ └── Naive380.py │ ├── KthLargestElementInAStream │ │ ├── Heap703.py │ │ ├── Naive703.py │ │ └── Note703.md │ ├── LFUCache │ │ ├── Naive460.py │ │ ├── Note460.md │ │ └── test_460.py │ ├── LRUCache │ │ ├── DoubleLinkedList146.py │ │ ├── Naive146.py │ │ ├── Note146.md │ │ ├── OrderedDict146.py │ │ ├── Queue146.py │ │ └── test_146.py │ ├── MinStack │ │ ├── Improve155.py │ │ ├── Naive155.py │ │ ├── Note155.md │ │ └── test_155.py │ ├── NumberOfRecentCells │ │ ├── BinarySearch933.py │ │ ├── CircularList933.py │ │ ├── Naive2_933.py │ │ ├── Naive933.py │ │ └── Queue933.py │ ├── OnlineStockSpan │ │ ├── Count901.py │ │ ├── Naive901.py │ │ └── Stack901.py │ ├── PeekingIterator │ │ └── Naive284.py │ ├── PrefixAndSuffixSearch │ │ ├── DoubleSet745.py │ │ ├── PairedTrie745.py │ │ ├── RE745.py │ │ └── SuffixWrappedWords745.py │ ├── RandomPickWithWeight │ │ ├── BinarySearch528.py │ │ ├── Naive2_528.py │ │ ├── Naive528.py │ │ ├── Note528.md │ │ └── OnePass528.py │ ├── RangeSumQuery-Immutable │ │ └── PrefixSum303.py │ └── RangeSumQuery2D-Immutable │ │ ├── Naive304.py │ │ └── PrefixSum304.py ├── DynamicProgramming │ └── HouseRobber │ │ ├── DP198.py │ │ ├── Note198.md │ │ └── test_198.py ├── Graph │ ├── AllPathsFromSourceToTarget │ │ ├── Backtracking797.py │ │ ├── Naive797.py │ │ └── test_797.py │ ├── CheapestFlightsWithinKStops │ │ ├── BFS787.py │ │ ├── DP787.py │ │ ├── Naive2_787.py │ │ ├── Naive787.py │ │ ├── Note787.md │ │ └── test_787.py │ ├── CloneGraph │ │ ├── BFS133.py │ │ ├── DFS133.py │ │ ├── Note133.md │ │ └── Recursive133.py │ ├── ConstructQuadTree │ │ └── Naive427.py │ ├── CountUnreachablePairsOfNodesInAnUndirectedGraph │ │ ├── BFS2316.py │ │ ├── DFS2316.py │ │ ├── Note2316.md │ │ ├── UnionFind2316.py │ │ └── UnionFindImprove2316.py │ ├── FindIfPathExistsInGraph │ │ ├── BFS1971.py │ │ ├── DFS1971.py │ │ ├── UnionFind1971.py │ │ └── test_1971.py │ ├── GraphNodeModule.py │ ├── IsGraphBipartite │ │ ├── Color785.py │ │ └── test_785.py │ ├── KeysAndRooms │ │ ├── DFS841.py │ │ ├── DFS_loop841.py │ │ └── test_841.py │ ├── LongestCycleInAGraph │ │ ├── DFSWithTime2360.py │ │ └── test_2360.py │ ├── LongestIncreasingPathInAMatrix │ │ ├── DFS329.py │ │ └── test_329.py │ ├── MaximumNumberOfAchievableTransferRequests │ │ └── Naive1601.py │ ├── MinimumScoreOfAPathBetweenTwoCities │ │ ├── BFS2492.py │ │ ├── UnionFind2492.py │ │ └── test_2942.py │ ├── NumberOfEnclaves │ │ ├── DFS1020.py │ │ ├── SimplerDFS1020.py │ │ └── test_1020.py │ ├── NumberOfOperationsToMakeNetworkConnected │ │ ├── DFS1319.py │ │ └── test_1319.py │ ├── PossibleBipartition │ │ ├── BFS886.py │ │ ├── Note886.md │ │ └── test_886.py │ ├── RedundantConnection │ │ ├── CyclePreventionDFS684.py │ │ ├── DSU684.py │ │ ├── UnionFind684.py │ │ └── test_684.py │ ├── ReorderRoutesToMakeAllPathsLeadToTheCityZero │ │ └── BFS1466.py │ ├── RottingOranges │ │ └── Naive994.py │ ├── ShortestPathInAGridWithObstaclesElimination │ │ ├── BFS1293.py │ │ └── test_1293.py │ ├── ShortestPathInBinaryMatrix │ │ └── Naive1091.py │ ├── SumOfDistancesInTree │ │ ├── Naive834.py │ │ ├── SubtreeSumAndCount834.py │ │ └── test_834.py │ ├── TopologicalSorting │ │ └── BFS127.py │ ├── __init__.py │ └── test_CloneGraph.py ├── Interactive │ └── LeftmostColumnWithAtLeastAOne │ │ ├── BinarySearch.py │ │ ├── Improve.py │ │ ├── LeftmostColumnWithAtLeastAOne.md │ │ └── Naive.py ├── LinkedList │ ├── AddTwoNumbers │ │ ├── Naive002.py │ │ └── Note002.md │ ├── CopyListWithRandomPointer │ │ ├── Interweave138.py │ │ ├── Map138.py │ │ └── Naive138.py │ ├── DeleteNodeInALinkedList │ │ └── Naive237.py │ ├── FlattenAMultilevelDoublyLinkedList │ │ ├── Naive430.py │ │ └── Stack430.py │ ├── InsertionSortList │ │ ├── Naive147.py │ │ └── Note147.md │ ├── LinkedListCycle │ │ ├── Naive141.py │ │ ├── Note141.md │ │ ├── TwoPointer141.py │ │ └── TwoPointer2_141.py │ ├── LinkedListCycleII │ │ ├── Naive142.py │ │ ├── TwoPointer142.py │ │ └── TwoPointer2_142.py │ ├── LinkedListRandomNode │ │ ├── Naive382.py │ │ ├── ReservoirSampling382.py │ │ └── WeightedSampling382.py │ ├── ListNodeModule.py │ ├── MergeKSortedLists │ │ ├── DC023.py │ │ ├── DC2_023.py │ │ ├── Heap023.py │ │ ├── Naive023.py │ │ ├── Naive2_023.py │ │ ├── Note023.md │ │ └── run_heap.ps1 │ ├── MergeTwoSortedLists │ │ ├── Better021.py │ │ ├── Naive021.py │ │ └── Note021.md │ ├── MiddleOfTheLinkedList │ │ ├── Naive876.py │ │ └── TwoPointer876.py │ ├── OddEvenLinkedList │ │ └── Naive328.py │ ├── PartitionList │ │ ├── Naive086.py │ │ └── TwoPointer086.py │ ├── RemoveDuplicatesFromSortedList │ │ └── Naive083.py │ ├── RemoveDuplicatesFromSortedListII │ │ └── Naive082.py │ ├── RemoveLinkedListElements │ │ ├── Naive203.py │ │ ├── Note203.md │ │ └── SinglePointer203.py │ ├── RemoveNthNodeFromEndOfList │ │ ├── HT019.py │ │ ├── Note019.md │ │ └── TwoPointer019.py │ ├── ReorderList │ │ ├── Improved143.py │ │ └── Naive143.py │ ├── ReverseLinkedList │ │ ├── Iterative206.py │ │ ├── Note206.md │ │ └── Recursive206.py │ ├── ReverseLinkedListII │ │ └── Naive092.py │ ├── RotateList │ │ └── Naive061.py │ ├── SortList │ │ └── MergeSort148.py │ ├── SwapNodesInPairs │ │ ├── Naive024.py │ │ ├── Note024.md │ │ └── Recursive024.py │ ├── __init__.py │ ├── run_AddTwoNumber.sh │ ├── test_AddTwoNumbers.py │ ├── test_InsertionSortList.py │ ├── test_MergeKSortedLists.py │ ├── test_MergeTwoSortedLists.py │ ├── test_RemoveDuplicatesFromSortedList.py │ ├── test_RemoveLinkedListElements.py │ ├── test_RemoveNthNodeFromEndOfList.py │ ├── test_ReverseLinkedList.py │ ├── test_RotateList.py │ └── test_SwapNodesInPairs.py ├── Math │ ├── AngleBetweenHandsOfAClock │ │ ├── Naive1344.py │ │ └── test_1344.py │ ├── ArrangingCoins │ │ ├── BinarySearch441.py │ │ ├── Math441.py │ │ ├── Naive441.py │ │ └── test_441.py │ ├── CheckIfItIsAStraightLine │ │ ├── Naive1232.py │ │ └── test_1232.py │ ├── CountVowelsPermutation │ │ └── DP1220.py │ ├── HappyNumber │ │ └── Naive202.py │ ├── NumberOfStepsToReduceANumberToZero │ │ ├── Naive1342.py │ │ └── Naive2_1342.py │ ├── PowXN │ │ ├── BitManipulation050.py │ │ ├── Naive050.py │ │ ├── Recursive050.py │ │ ├── Recursive2_050.py │ │ └── test_050.py │ ├── PowerOfFour │ │ ├── BitManipulation342.py │ │ ├── Iterative342.py │ │ ├── Math342.py │ │ ├── Naive342.py │ │ ├── Recursive342.py │ │ └── test_342.py │ ├── PowerOfTwo │ │ ├── BitManipulation231.py │ │ ├── Naive231.py │ │ ├── String231.py │ │ └── test_231.py │ ├── SequentialDigits │ │ └── Recursive1291.py │ ├── SignOfTheProductOfAnArray │ │ ├── Better1822.py │ │ ├── Naive1822.py │ │ ├── Python1822.py │ │ └── test_1822.py │ ├── UglyNumber │ │ ├── Naive263.py │ │ └── test_263.py │ ├── UglyNumberII │ │ ├── DP264.py │ │ ├── Note264.md │ │ ├── PriorityQueue264.py │ │ └── test_264.py │ └── ValidPerfectSquare │ │ ├── BinarySearch367.py │ │ └── Naive367.py ├── Search │ ├── NumberOfIslands │ │ ├── BFS200.py │ │ ├── DFS200.py │ │ ├── Note200.md │ │ └── test_200.py │ ├── OpenTheLock │ │ ├── BFS752.py │ │ ├── Note752.md │ │ └── test_752.py │ ├── PerfectSquares │ │ ├── BFS279.py │ │ ├── BottomUpDP279.py │ │ ├── LinearCheck279.py │ │ ├── Math279.py │ │ ├── Note279.md │ │ ├── Recursive279.py │ │ ├── TopDownDP279.py │ │ └── test_279.py │ └── Sqrt_x │ │ ├── BinarySearch069.py │ │ ├── BinarySearch2_069.py │ │ ├── BinarySearch3_069.py │ │ ├── Naive069.py │ │ └── test_069.py └── String │ ├── AddBinary │ ├── Adder067.py │ ├── Iterative067.py │ ├── Python067.py │ └── test_067.py │ ├── BackspaceStringCompare │ ├── Naive844.py │ ├── TwoPointer844.py │ └── test_844.py │ ├── BuddyStrings │ ├── Better859.py │ ├── Naive2_859.py │ ├── Naive859.py │ └── test_859.py │ ├── CompareVersionNumbers │ ├── Improve167.py │ └── Naive167.py │ ├── CountAndSay │ ├── Naive038.py │ ├── Note038.md │ └── test_038.py │ ├── DetectCapital │ ├── CapitalCount520.py │ ├── Naive520.py │ ├── RegEx520.py │ └── test_520.py │ ├── EditDistance │ ├── DP072.py │ ├── DP2_072.py │ ├── Note072.md │ ├── Recursive072.py │ ├── RecursiveWithMemory072.py │ └── test_072.py │ ├── FindAllAnagramsInAString │ └── Naive438.py │ ├── FirstUniqueCharacterInAString │ └── Naive387.py │ ├── GenerateParentheses │ ├── Backtracking022.py │ ├── Naive022.py │ ├── Note022.md │ └── test_022.py │ ├── GreatestCommonDivisorOfStrings │ ├── Naive1071.py │ └── test_1071.py │ ├── GroupAnagrams │ ├── Counter049.py │ ├── Naive049.py │ ├── Note049.md │ ├── Sorting049.py │ └── test_049.py │ ├── Implement_strStr │ ├── Naive028.py │ ├── Note028.md │ └── test_028.py │ ├── IntegerToRoman │ ├── Naive012.py │ └── Note012.md │ ├── IsSubsequence │ ├── Naive392.py │ └── test_IsSubsequence.py │ ├── JewelsAndStones │ ├── Naive2_771.py │ └── Naive771.py │ ├── LetterCasePermutation │ ├── Naive2_784.py │ └── Naive784.py │ ├── LetterCombinationsOfAPhoneNumber │ ├── Backtracking017.py │ ├── Note017.md │ └── test_017.py │ ├── LongestCommonSubsequence │ ├── BruteForce1143.py │ ├── DP1143.py │ ├── DP_2_1143.py │ ├── DP_ReturnSubsequence.py │ ├── Note1143.md │ ├── test_1143.py │ └── test_nc92.py │ ├── LongestDuplicateSubstring │ ├── BinarySearch_RabinKarp1044.py │ ├── Naive1044.py │ ├── Note1044.md │ └── test_1044.py │ ├── LongestPalindromicSubsequence │ ├── BottomUpDP516.py │ ├── TopDownDP516.py │ └── test_516.py │ ├── LongestPalindromicSubstring │ ├── DP005.py │ ├── ExpandAroundCenter005.py │ ├── Naive005.py │ ├── Note005.md │ └── test_005.py │ ├── LongestSubstringWithoutRepeatingCharacters │ ├── Note003.md │ ├── SlidingWindow003.py │ ├── SlidingWindowOptimized003.py │ └── test_003.py │ ├── MergeStringsAlternatively │ ├── Naive1768.py │ └── test_1768.py │ ├── MinimumInsertionStepsToMakeAStringPalindrome │ ├── TopDownDP1312.py │ └── test_1312.py │ ├── MinimumRemoveToMakeValidParentheses │ ├── Naive1249.py │ ├── Naive2_1249.py │ └── test_1249.py │ ├── OptimalPartitionOfString │ ├── Greedy2405.py │ └── test_2405.py │ ├── PartitionLabels │ └── Naive763.py │ ├── PerformStringShifts │ └── Naive.py │ ├── PermutationInString │ └── Naive567.py │ ├── PermutationSequence │ ├── Backtracking060.py │ ├── Math060.py │ ├── Naive060.py │ └── test_060.py │ ├── RansomNote │ ├── Better383.py │ ├── Naive383.py │ └── test_383.py │ ├── RegularExpressionMatching │ ├── BottomUpDP010.py │ ├── DC010.py │ ├── Note010.md │ ├── TopDownDP010.py │ └── test_010.py │ ├── RemoveAllAdjacentDuplicatesInString │ ├── Naive1047.py │ ├── RemovePattern1047.py │ └── Stack1047.py │ ├── RemoveDuplicateLetters │ └── Greedy316.py │ ├── RemoveKDigits │ └── Greedy402.py │ ├── RemovingStarsFromAString │ ├── Stack2390.py │ └── test_2390.py │ ├── ReverseString │ ├── Naive344.py │ ├── Note344.md │ ├── Recursive344.py │ └── test_344.py │ ├── ReverseWordsInAString │ ├── CStyle151.py │ ├── Naive151.py │ ├── Note151.md │ ├── Pythonic151.py │ ├── Trick151.py │ └── test_151.py │ ├── RomanToInteger │ ├── Naive013.py │ ├── Note013.md │ └── test_013.py │ ├── ShortestDistanceToACharacter │ └── Naive821.py │ ├── ShortestPalindrome │ └── Note214.md │ ├── SimplifyPath │ ├── Naive071.py │ ├── Note071.md │ ├── Stack071.py │ ├── Stack2_071.py │ └── test_071.py │ ├── SortCharactersByFrequency │ ├── Naive451.py │ └── PQ451.py │ ├── SplitArrayIntoFibonacciSequence │ ├── Backtracking842.py │ └── test_842.py │ ├── StringCompression │ ├── Naive443.py │ ├── TwoPointer2_443.py │ ├── TwoPointer443.py │ └── test_443.py │ ├── StringToInteger │ ├── Naive008.py │ ├── Note008.md │ └── test_008.py │ ├── ValidAnagram │ └── Naive242.py │ ├── ValidPalindrome │ ├── Naive125.py │ ├── Naive2_125.py │ └── test_125.py │ ├── ValidParentheses │ ├── Dict020.py │ ├── Naive020.py │ ├── Note020.md │ ├── Stack020.py │ └── test_020.py │ ├── ValidParenthesisString │ ├── DP678.py │ ├── Greedy678.py │ ├── Naive678.py │ ├── Note678.md │ └── test_678.py │ ├── ValidateIPAddress │ ├── Naive468.py │ └── test_468.py │ ├── WildcardMatching │ └── Note044.md │ ├── WordBreak │ ├── DP139.py │ ├── Note139.md │ ├── Recursive139.py │ └── test_139.py │ ├── WordBreakII │ ├── Backtracking140.py │ ├── DP140.py │ ├── Naive140.py │ └── test_140.py │ ├── WordLadder │ ├── BFS127.py │ ├── Note127.md │ └── test_127.py │ ├── WordPattern │ ├── HashMap290.py │ ├── Note290.md │ └── test_290.py │ └── WordSubsets │ ├── Counter916.py │ ├── Improve916.py │ └── Naive916.py ├── README.md └── requirements.txt /.travis.yml: -------------------------------------------------------------------------------- 1 | # https://blog.travis-ci.com/2019-08-07-extensive-python-testing-on-travis-ci 2 | language: python 3 | python: 4 | - 3.9 5 | before_install: 6 | - python --version 7 | # command to install dependencies 8 | install: 9 | - pip install -U pip 10 | - pip install -U pytest 11 | - pip install -U pytest-cov 12 | - pip install codecov 13 | # command to run tests 14 | script: # run tests 15 | - pytest --cov-report term --cov Python3/ 16 | after_success: 17 | - codecov # submit coverage -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://stackoverflow.com/questions/29973619/how-to-associate-a-file-extension-with-a-certain-language-in-vs-code 3 | // https://medium.com/@zulhhandyplast/how-to-disable-vs-code-formatonsave-for-specific-file-extensions-c60e8f254243 4 | // https://code.visualstudio.com/docs/languages/identifiers 5 | "[markdown]": { 6 | "editor.formatOnSave": false 7 | }, 8 | "[python]": { 9 | "editor.defaultFormatter": "ms-python.black-formatter" 10 | }, 11 | "python.formatting.provider": "none" 12 | } -------------------------------------------------------------------------------- /Contest/LeetCodeBiweeklyContest/BiweeklyContest36/1.py: -------------------------------------------------------------------------------- 1 | class ParkingSystem: 2 | 3 | def __init__(self, big: int, medium: int, small: int): 4 | self.position = [big, medium, small] 5 | 6 | def addCar(self, carType: int) -> bool: 7 | if self.position[carType - 1] > 0: 8 | self.position[carType - 1] -= 1 9 | return True 10 | else: 11 | return False 12 | 13 | 14 | 15 | # Your ParkingSystem object will be instantiated and called as such: 16 | # obj = ParkingSystem(big, medium, small) 17 | # param_1 = obj.addCar(carType) -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest167/1290-ConvertBinaryNumberInALinkedListToInteger.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | class ListNode: 3 | def __init__(self, x): 4 | self.val = x 5 | self.next = None 6 | 7 | 8 | class Solution: 9 | def getDecimalValue(self, head: ListNode) -> int: 10 | total = 0 11 | while head is not None: 12 | total *= 2 13 | total += head.val 14 | head = head.next 15 | 16 | return total 17 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest169/FindNUniqueIntegersSumUpToZero.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | class Solution: 4 | def sumZero(self, n: int) -> List[int]: 5 | ans = [] 6 | for i in range(1, n//2+1): 7 | ans.append(i) 8 | ans.append(-i) 9 | 10 | if n % 2 == 1: 11 | # odd 12 | ans.append(0) 13 | 14 | return ans -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest170/AllElementsInTwoBinarySearchTrees_Naive.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def xorQueries(self, arr: List[int], queries: List[List[int]]) -> List[int]: 6 | ans = [] 7 | for L, R in queries: 8 | temp = 0 9 | for i in range(L, R+1): 10 | temp ^= arr[i] 11 | ans.append(temp) 12 | return ans 13 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest170/AllElementsInTwoBinarySearchTrees_XOR.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def xorQueries(self, arr: List[int], queries: List[List[int]]) -> List[int]: 6 | xorPrefix = [0] 7 | for num in arr: 8 | xorPrefix.append(xorPrefix[-1] ^ num) 9 | 10 | ans = [] 11 | for L, R in queries: 12 | # the XOR property 13 | ans.append(xorPrefix[R+1] ^ xorPrefix[L]) 14 | return ans -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest170/FindNUniqueIntegersSumUpToZero.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def freqAlphabets(self, s: str) -> str: 3 | alphabetDict = {i + 1: chr(i + 97) for i in range(26)} 4 | i = 0 5 | nums = [] 6 | while i < len(s): 7 | if i + 2 < len(s) and s[i+2] == '#': 8 | nums.append(int(s[i:i+2])) 9 | i = i + 3 10 | else: 11 | nums.append(int(s[i])) 12 | i = i + 1 13 | ans = '' 14 | for num in nums: 15 | ans += alphabetDict[num] 16 | 17 | return ans 18 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest176/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def countNegatives(self, grid: List[List[int]]) -> int: 6 | if not grid: 7 | return 0 8 | 9 | answer = 0 10 | 11 | for row in grid: 12 | for item in row: 13 | if item < 0: 14 | answer += 1 15 | 16 | return answer 17 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest177/1.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | 3 | class Solution: 4 | """ https://stackoverflow.com/questions/8419564/difference-between-two-dates-in-python """ 5 | def daysBetweenDates(self, date1: str, date2: str) -> int: 6 | d1 = datetime.strptime(date1, r"%Y-%m-%d") 7 | d2 = datetime.strptime(date2, r"%Y-%m-%d") 8 | return abs((d2 - d1).days) 9 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest178/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def smallerNumbersThanCurrent(self, nums: List[int]) -> List[int]: 6 | answer = [0] * len(nums) 7 | 8 | for i in range(len(nums)): 9 | for j in range(len(nums)): 10 | if nums[i] > nums[j]: 11 | answer[i] += 1 12 | 13 | return answer 14 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest179/1.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def generateTheString(self, n: int) -> str: 3 | if n % 2 == 0: 4 | return "a" * (n - 1) + "b" 5 | else: 6 | return "a" * n -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest179/2_2.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def numTimesAllBlue(self, light: List[int]) -> int: 6 | answer = 0 7 | 8 | for i in range(len(light)): 9 | sorted_bulb = sorted(light[:i+1]) 10 | if sorted_bulb[0] == 1 and sorted_bulb[-1] == i + 1: 11 | answer += 1 12 | 13 | return answer 14 | 15 | # didn't test 16 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest180/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import numpy as np 3 | 4 | 5 | class Solution: 6 | def luckyNumbers(self, matrix: List[List[int]]) -> List[int]: 7 | if not matrix: 8 | return [] 9 | 10 | matrix = np.array(matrix) 11 | min_row = set(matrix.min(axis=1)) 12 | max_column = set(matrix.max(axis=0)) 13 | return list(min_row & max_column) 14 | 15 | 16 | if __name__ == "__main__": 17 | 18 | matrix = [[3, 7, 8], [9, 11, 13], [15, 16, 17]] 19 | print(Solution().luckyNumbers(matrix)) 20 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest181/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def createTargetArray(self, nums: List[int], index: List[int]) -> List[int]: 6 | answer = [-1] * len(nums) 7 | for num, idx in zip(nums, index): 8 | answer.insert(idx, num) 9 | 10 | return answer[:len(nums)] 11 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest181/4.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def longestPrefix(self, s: str) -> str: 3 | for i in reversed(range(len(s))): 4 | if s[:i] == s[-i:]: 5 | return s[:i] 6 | return '' 7 | 8 | 9 | if __name__ == "__main__": 10 | print(Solution().longestPrefix('level'), 'l') 11 | print(Solution().longestPrefix('ababab'), 'abab') 12 | print(Solution().longestPrefix('leetcodeleet'), 'leet') 13 | print(Solution().longestPrefix('a'), '') 14 | print(Solution().longestPrefix('aaaaa'), 'aaaa') 15 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest182/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from collections import Counter 3 | 4 | 5 | class Solution: 6 | def findLucky(self, arr: List[int]) -> int: 7 | max_match = -1 8 | for num, count in Counter(arr).items(): 9 | if num == count and num > max_match: 10 | max_match = num 11 | 12 | return max_match 13 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest184/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def stringMatching(self, words: List[str]) -> List[str]: 6 | answer = set() 7 | for word in words: 8 | for another_word in words: 9 | if len(word) < len(another_word): 10 | if word in another_word: 11 | answer.add(word) 12 | 13 | return list(answer) 14 | 15 | # ["leetcoder","leetcode","od","hamlet","am"] 16 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest184/2.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def processQueries(self, queries: List[int], m: int) -> List[int]: 6 | P = [i + 1 for i in range(m)] 7 | answer = [] 8 | for query in queries: 9 | index = P.index(query) 10 | answer.append(index) 11 | P.remove(query) 12 | P.insert(0, query) 13 | 14 | return answer 15 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest184/3.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | 4 | class Solution: 5 | def entityParser(self, text: str) -> str: 6 | special_characters = { 7 | '&quor;': '"', 8 | ''': "'", 9 | '&': '&', 10 | '>': '>', 11 | '<': '<', 12 | '⁄': '/' 13 | } 14 | found_possible = re.findall(r'&\w+;', text) 15 | 16 | for pattern in found_possible: 17 | if pattern in special_characters: 18 | text.replace(pattern, special_characters[pattern]) 19 | 20 | return text 21 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest186/1.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | 4 | class Solution: 5 | def maxScore(self, s: str) -> int: 6 | answer = 0 7 | for split in range(1, len(s)): 8 | answer = max(Counter(s[:split])['0'] + 9 | Counter(s[split:])['1'], answer) 10 | 11 | return answer 12 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest186/2.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def maxScore(self, cardPoints: List[int], k: int) -> int: 6 | score = 0 7 | for split in range(k + 1): 8 | # print(cardPoints[:split], cardPoints[-(k-split):]) 9 | if k != split: 10 | score = max(sum(cardPoints[:split]) + 11 | sum(cardPoints[-(k-split):]), score) 12 | else: 13 | score = max(sum(cardPoints[:split]), score) 14 | 15 | return score 16 | 17 | # TLE 18 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest187/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | # https://campus.datacamp.com/courses/python-data-science-toolbox-part-2/using-iterators-in-pythonland?ex=9 4 | 5 | 6 | class Solution: 7 | def destCity(self, paths: List[List[str]]) -> str: 8 | in_set, out_set = list(map(lambda x: set(x), zip(*paths))) 9 | answer = out_set - in_set 10 | return answer.pop() 11 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest187/2.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def kLengthApart(self, nums: List[int], k: int) -> bool: 6 | dist = -1 7 | for num in nums: 8 | if num == 1: 9 | if dist >= 0: 10 | if dist < k: 11 | return False 12 | dist = 0 13 | elif num == 0 and dist >= 0: 14 | dist += 1 15 | 16 | return True 17 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest187/3.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def longestSubarray(self, nums: List[int], limit: int) -> int: 6 | for window_size in range(len(nums), 0, -1): 7 | for start in range(len(nums) - window_size + 1): 8 | temp = nums[start:start + window_size] 9 | if max(temp) - min(temp) <= limit: 10 | return window_size 11 | 12 | return 0 13 | 14 | # TLE 15 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest187/3_2.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def longestSubarray(self, nums: List[int], limit: int) -> int: 6 | longest = 0 7 | for i in range(len(nums)): 8 | temp_min = nums[i] 9 | temp_max = nums[i] 10 | for j in range(i + 1, len(nums)): 11 | temp_max = max(temp_max, nums[j]) 12 | temp_min = min(temp_min, nums[j]) 13 | if temp_max - temp_min <= limit: 14 | longest = max(longest, j - i) 15 | 16 | return longest + 1 17 | 18 | # TLE 19 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest187/4_2.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daviddwlee84/LeetCode/ab240e071789bbc23b4b5c8d25f8af2587c1c40b/Contest/LeetCodeWeeklyContest/WeeklyContest187/4_2.py -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest188/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def buildArray(self, target: List[int], n: int) -> List[str]: 6 | array = [] 7 | answer = [] 8 | for i in range(1, n + 1): 9 | array.append(i) 10 | answer.append('Push') 11 | if array == target: 12 | return answer 13 | 14 | if i not in target: 15 | array.pop() 16 | answer.append('Pop') 17 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest189/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def busyStudent(self, startTime: List[int], endTime: List[int], queryTime: int) -> int: 6 | count = 0 7 | for start, end in zip(startTime, endTime): 8 | if start <= queryTime <= end: 9 | count += 1 10 | 11 | return count 12 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest189/3.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def peopleIndexes(self, favoriteCompanies: List[List[str]]) -> List[int]: 6 | companySets = [set(companies) for companies in favoriteCompanies] 7 | answer = [i for i, cmpSet in enumerate(companySets) if not any( 8 | [cmpSet.issubset(otherCmpSet) for otherCmpSet in companySets[:i] + companySets[i+1:]])] 9 | 10 | return answer 11 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest190/1.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isPrefixOfWord(self, sentence: str, searchWord: str) -> int: 3 | for i, word in enumerate(sentence.split()): 4 | if len(searchWord) <= len(word): 5 | if word[:len(searchWord)] == searchWord: 6 | return i + 1 # 1-indexed 7 | 8 | return -1 9 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest190/2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxVowels(self, s: str, k: int) -> int: 3 | """ cumulative sum array """ 4 | vowels = set(['a', 'e', 'i', 'o', 'u']) 5 | vowel_count = [0] 6 | max_num = 0 7 | for char in s: 8 | if char in vowels: 9 | vowel_count.append(vowel_count[-1] + 1) 10 | else: 11 | vowel_count.append(vowel_count[-1]) 12 | 13 | for i in range(len(s) - k + 1): 14 | max_num = max(max_num, vowel_count[i + k] - vowel_count[i]) 15 | 16 | return max_num 17 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest192/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def shuffle(self, nums: List[int], n: int) -> List[int]: 6 | answer = [] 7 | for i in range(len(nums) // 2): 8 | answer.append(nums[i]) 9 | if i < len(nums): 10 | answer.append(nums[i + len(nums) // 2]) 11 | 12 | return answer 13 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest192/2.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import heapq 3 | 4 | 5 | class Solution: 6 | def getStrongest(self, arr: List[int], k: int) -> List[int]: 7 | arr.sort() 8 | median = arr[(len(arr)-1)//2] 9 | candidate = [] 10 | 11 | for num in arr: 12 | score = abs(num - median) 13 | heapq.heappush(candidate, (score, num)) 14 | 15 | answer = heapq.nlargest(k, candidate) 16 | return [num for _, num in answer] 17 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest195/2.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from collections import Counter 3 | 4 | 5 | class Solution: 6 | def canArrange(self, arr: List[int], k: int) -> bool: 7 | mod_count = Counter(map(lambda x: x % k, arr)) 8 | 9 | if mod_count[0] % 2 != 0: 10 | return False 11 | 12 | for i in range(1, k // 2): 13 | if mod_count[i] != mod_count[k - i]: 14 | return False 15 | 16 | return True 17 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest196/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def canMakeArithmeticProgression(self, arr: List[int]) -> bool: 6 | arr.sort() 7 | 8 | diff = arr[1] - arr[0] 9 | for i in range(2, len(arr)): 10 | if arr[i] - arr[i - 1] != diff: 11 | return False 12 | return True 13 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest196/1_2.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def canMakeArithmeticProgression(self, arr: List[int]) -> bool: 6 | """ 7 | https://leetcode.com/problems/can-make-arithmetic-progression-from-sequence/discuss/720200/Clean-Python-3-O(N) 8 | """ 9 | min_val = min(arr) 10 | gap = (max(arr) - min_val) / (len(arr) - 1) 11 | 12 | if gap == 0: 13 | return True 14 | 15 | num_diffs = set(num - min_val for num in arr) 16 | return len(num_diffs) == len(arr) and all(diff % gap == 0 for diff in num_diffs) 17 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest197/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def numIdenticalPairs(self, nums: List[int]) -> int: 6 | count = 0 7 | for i, num in enumerate(nums): 8 | for j in range(i + 1, len(nums)): 9 | if nums[j] == num: 10 | count += 1 11 | 12 | return count 13 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest198/1.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def numWaterBottles(self, numBottles: int, numExchange: int) -> int: 3 | totalBottles = numBottles 4 | bottleLeft = 0 5 | while numBottles >= numExchange: 6 | canExchange = numBottles // numExchange 7 | bottleLeft = numBottles % numExchange 8 | totalBottles += canExchange 9 | numBottles = canExchange + bottleLeft 10 | 11 | return totalBottles 12 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest198/4.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def closestToTarget(self, arr: List[int], target: int) -> int: 6 | """ 7 | William's answer 8 | """ 9 | candidate_set = set() # all possible values you can get 10 | ans = float('inf') 11 | for num in arr: 12 | new_set = set([num]) 13 | for item in candidate_set: 14 | new_set.add(num & item) 15 | for item in new_set: 16 | ans = min(ans, abs(item - target)) 17 | candidate_set = new_set 18 | return ans 19 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest199/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def restoreString(self, s: str, indices: List[int]) -> str: 6 | answer = [None] * len(indices) 7 | 8 | for i, index in enumerate(indices): 9 | answer[index] = s[i] 10 | 11 | return ''.join(answer) 12 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest199/2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def minFlips(self, target: str) -> int: 3 | i = 0 4 | n = len(target) 5 | while i < n: 6 | if target[i] == "1": 7 | break 8 | i += 1 9 | 10 | count = 0 11 | curr = "1" 12 | while i < n: 13 | if target[i] == curr: 14 | count += 1 15 | if curr == "1": 16 | curr = "0" 17 | elif curr == "0": 18 | curr = "1" 19 | i += 1 20 | 21 | return count 22 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest200/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def countGoodTriplets(self, arr: List[int], a: int, b: int, c: int) -> int: 6 | n = len(arr) 7 | count = 0 8 | 9 | for i in range(n-2): 10 | for j in range(i+1, n-1): 11 | for k in range(j+1, n): 12 | if abs(arr[i] - arr[j]) <= a and abs(arr[j] - arr[k]) <= b and abs(arr[i] - arr[k]) <= c: 13 | count += 1 14 | 15 | return count 16 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest200/2.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def getWinner(self, arr: List[int], k: int) -> int: 6 | winner = 0 7 | challenger = 1 8 | win_count = 0 9 | while win_count < k and challenger < len(arr): 10 | if arr[winner] < arr[challenger]: 11 | arr[winner], arr[challenger] = arr[challenger], arr[winner] 12 | win_count = 1 13 | else: 14 | win_count += 1 15 | challenger += 1 16 | 17 | return arr[winner] 18 | 19 | # [1,25,35,42,68,70] 20 | # 1 21 | # 25 22 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest201/1.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def makeGood(self, s: str) -> str: 3 | for i in range(len(s) - 1): 4 | if s[i] != s[i + 1] and (s[i] == s[i + 1].upper() or s[i] == s[i + 1].lower()): 5 | s = self.makeGood(s[:i] + s[i+2:]) 6 | break 7 | 8 | return s 9 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest201/2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def findKthBit(self, n: int, k: int) -> str: 3 | s = '0' 4 | while n > 0: 5 | s = s + '1' + self.reverse(self.invert(s)) 6 | n -= 1 7 | 8 | return s[k-1] 9 | 10 | def reverse(self, s): 11 | return ''.join(reversed(s)) 12 | 13 | def invert(self, s): 14 | invert_s = [] 15 | for c in s: 16 | if c == '0': 17 | invert_s.append('1') 18 | else: 19 | invert_s.append('0') 20 | return ''.join(invert_s) 21 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest202/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def threeConsecutiveOdds(self, arr: List[int]) -> bool: 6 | count = 0 7 | for num in arr: 8 | if num % 2 == 1: 9 | count += 1 10 | else: 11 | count = 0 12 | if count >= 3: 13 | return True 14 | 15 | return False 16 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest202/2_other.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def minOperations(self, n: int) -> int: 3 | """ 4 | Alex Wice's Solution 5 | 6 | [1 3 5] 7 | 2 4 8 | 3 3 9 | 10 | [1 3 5 7] 11 | 2 4 4 6 12 | 3 5 13 | 4 4 14 | """ 15 | ans = 0 16 | 17 | for x in range(1, 2 * n, 2): 18 | ans += abs(x - n) 19 | 20 | return ans >> 1 21 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest204/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def containsPattern(self, arr: List[int], m: int, k: int) -> bool: 6 | if m * k > len(arr): 7 | return False 8 | 9 | for start in range(len(arr) - k * m + 1): 10 | pattern = arr[start:start + m] * k 11 | if arr[start:start + m * k] == pattern: 12 | return True 13 | 14 | return False 15 | 16 | 17 | # [2,2] 18 | # 1 19 | # 2 20 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest205/3.py: -------------------------------------------------------------------------------- 1 | from itertools import groupby 2 | 3 | 4 | class Solution: 5 | def minCost(self, s: str, cost: List[int]) -> int: 6 | i = 0 7 | ans = 0 8 | for char, groups in groupby(s): 9 | groups = list(groups) 10 | if len(groups) > 1: 11 | ans += sum(cost[i:i + len(groups)]) - \ 12 | max(cost[i:i + len(groups)]) 13 | i += len(groups) 14 | 15 | return ans 16 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest206/1_other.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def numSpecial(self, mat: List[List[int]]) -> int: 6 | """ 7 | Alex Wice's Answer 8 | """ 9 | 10 | ans = 0 11 | for r, row in enumerate(mat): 12 | if sum(row) == 1: 13 | c = row.index(1) 14 | if sum(mat[r0][c] for r0 in range(len(mat))) == 1: 15 | ans += 1 16 | 17 | return ans -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest207/1.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def reorderSpaces(self, text: str) -> str: 3 | words = text.split() 4 | spaces = text.count(' ') 5 | if len(words) < 1: 6 | return text 7 | elif len(words) == 1: 8 | # " hello" 9 | return words[0] + spaces * ' ' 10 | max_space = spaces // (len(words) - 1) 11 | space_left = spaces % (len(words) - 1) 12 | 13 | return (' ' * max_space).join(words) + space_left * ' ' 14 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest210/1.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxDepth(self, s: str) -> int: 3 | """ 4 | It is guaranteed that parentheses expression s is a VPS. 5 | """ 6 | count = 0 7 | maximum = 0 8 | for c in s: 9 | maximum = max(maximum, count) 10 | if c == '(': 11 | count += 1 12 | elif c == ')': 13 | count -= 1 14 | return maximum 15 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest210/2.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from itertools import combinations 3 | from collections import defaultdict 4 | 5 | 6 | class Solution: 7 | def maximalNetworkRank(self, n: int, roads: List[List[int]]) -> int: 8 | edges = defaultdict(set) 9 | for a, b in roads: 10 | edges[a].add(b) 11 | edges[b].add(a) 12 | 13 | answer = 0 14 | for city_i, city_j in combinations(range(n), 2): 15 | answer = max(answer, len( 16 | edges[city_i]) + len(edges[city_j]) - int(city_i in edges[city_j])) 17 | 18 | return answer 19 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest211/1.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | 4 | class Solution: 5 | def maxLengthBetweenEqualCharacters(self, s: str) -> int: 6 | char_indices = defaultdict(list) 7 | for i, c in enumerate(s): 8 | char_indices[c].append(i) 9 | 10 | answer = -1 11 | 12 | for indices in char_indices.values(): 13 | if len(indices) < 2: 14 | continue 15 | 16 | answer = max(answer, indices[-1] - indices[0] - 1) 17 | 18 | return answer 19 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest212/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def slowestKey(self, releaseTimes: List[int], keysPressed: str) -> str: 6 | diff = 0 7 | last_release = 0 8 | answer = None 9 | for key, t in enumerate(releaseTimes): 10 | duration = t - last_release 11 | if duration > diff: 12 | diff = duration 13 | answer = keysPressed[key] 14 | elif duration == diff: 15 | answer = max(answer, keysPressed[key]) 16 | last_release = t 17 | 18 | return answer 19 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest213/2.py: -------------------------------------------------------------------------------- 1 | from functools import lru_cache 2 | 3 | 4 | class Solution: 5 | def countVowelStrings(self, n: int) -> int: 6 | # vowels = ['a', 'e', 'i', 'o', 'u'] 7 | @lru_cache(None) 8 | def start_with(cid: int, left: int): 9 | if left == 0: 10 | return 1 11 | 12 | return sum(start_with(i, left - 1) for i in range(cid, 5)) 13 | 14 | return start_with(0, n) 15 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest213/2_fail.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def countVowelStrings(self, n: int) -> int: 3 | vowels = ['a', 'e', 'i', 'o', 'u'] 4 | 5 | def start_with(cid: int, left: int): 6 | if left == 0: 7 | return 1 8 | 9 | return sum(start_with(i, left - 1) for i in range(cid, len(vowels))) 10 | 11 | return start_with(0, n) 12 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest224/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from collections import Counter 3 | 4 | 5 | class Solution: 6 | def countGoodRectangles(self, rectangles: List[List[int]]) -> int: 7 | min_edge_count = Counter([min(rect_edge) for rect_edge in rectangles]) 8 | max_key = max(min_edge_count) 9 | return min_edge_count[max_key] 10 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest225/4_fail.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def minimumBoxes(self, n: int) -> int: 3 | total = 0 4 | floor = 0 5 | i = 1 6 | while total < n: 7 | floor += i 8 | total += floor 9 | i += 1 10 | 11 | return floor 12 | 13 | # WA 14 | # 15 15 | # 9 16 | # count too much 17 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest236/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | class Solution: 3 | def arraySign(self, nums: List[int]) -> int: 4 | 5 | def signFunc(x: int): 6 | if x > 0: 7 | return 1 8 | elif x < 0: 9 | return -1 10 | else: 11 | return 0 12 | 13 | neg_one_count = 0 14 | for num in nums: 15 | res = signFunc(num) 16 | if res == 0: 17 | return 0 18 | 19 | if res == -1: 20 | neg_one_count += 1 21 | 22 | return 1 if neg_one_count % 2 == 0 else -1 23 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest236/2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def findTheWinner(self, n: int, k: int) -> int: 3 | line = [i + 1 for i in range(n)] 4 | 5 | i = -1 6 | 7 | while len(line) > 1: 8 | i += k 9 | if i >= len(line): 10 | i %= len(line) 11 | line.pop(i) 12 | i -= 1 13 | 14 | return line[0] 15 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest239/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def getMinDistance(self, nums: List[int], target: int, start: int) -> int: 6 | shift = 0 7 | while True: 8 | if start + shift < len(nums) and nums[start + shift] == target: 9 | return shift 10 | elif start - shift >= 0 and nums[start - shift] == target: 11 | return shift 12 | shift += 1 13 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest243/1.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isSumEqual(self, firstWord: str, secondWord: str, targetWord: str) -> bool: 3 | table = { 4 | chr(ord('a') + i): str(i) 5 | for i in range(26) 6 | } 7 | 8 | firstNum = int(''.join([table[char] for char in firstWord])) 9 | secondNum = int(''.join([table[char] for char in secondWord])) 10 | 11 | targetNum = int(''.join([table[char] for char in targetWord])) 12 | 13 | return firstNum + secondNum == targetNum 14 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest243/2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxValue(self, n: str, x: int) -> str: 3 | str_x = str(x) 4 | if n.startswith('-'): 5 | # negative 6 | for i in range(1, len(n)): 7 | if n[i] > str_x: 8 | return n[:i] + str_x + n[i:] 9 | else: 10 | # positive 11 | for i in range(len(n)): 12 | if n[i] < str_x: 13 | return n[:i] + str_x + n[i:] 14 | return n + str_x 15 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest245/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from collections import Counter 3 | 4 | 5 | class Solution: 6 | def makeEqual(self, words: List[str]) -> bool: 7 | 8 | total_count = Counter() 9 | for word in words: 10 | total_count += Counter(word) 11 | 12 | for count in total_count.values(): 13 | if count % len(words) != 0: 14 | return False 15 | 16 | return True 17 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest247/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def maxProductDifference(self, nums: List[int]) -> int: 6 | nums.sort() 7 | return nums[-1] * nums[-2] - nums[0] * nums[1] 8 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest248/1.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def buildArray(self, nums: List[int]) -> List[int]: 6 | ans = [] 7 | for num in nums: 8 | ans.append(nums[num]) 9 | return ans 10 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest248/2.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def eliminateMaximum(self, dist: List[int], speed: List[int]) -> int: 6 | if any(d <= 0 for d in dist): 7 | return 0 8 | 9 | dist_speed = sorted([((d / s), i) 10 | for i, (d, s) in enumerate(zip(dist, speed))]) 11 | 12 | for j, (_, i) in enumerate(dist_speed): 13 | 14 | if dist[i] - speed[i] * j <= 0: 15 | return j 16 | 17 | return len(dist) 18 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest248/3.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def countGoodNumbers(self, n: int) -> int: 3 | """ 4 | even = 0, 2, 4, 6, 8 5 | prime = 2, 3, 5, 7 6 | """ 7 | MOD = 10 ** 9 + 7 8 | ans = 1 9 | ans *= pow(5, (n - n // 2), MOD) 10 | ans *= pow(4, (n // 2), MOD) 11 | ans %= MOD 12 | return ans 13 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest248/3_fail.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | class Solution 3 | { 4 | public: 5 | int countGoodNumbers(long long n) 6 | { 7 | long long MOD = pow(10, 9) + 7; 8 | long long ans = 1; 9 | for (long long i = 0; i < n; i++) 10 | { 11 | if (i % 2 == 0) 12 | { 13 | ans *= 5; 14 | } 15 | else 16 | { 17 | ans *= 4; 18 | } 19 | ans %= MOD; 20 | } 21 | 22 | return ans; 23 | } 24 | }; 25 | 26 | // TLE 27 | // 806166225460393 28 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest248/3_fail.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def countGoodNumbers(self, n: int) -> int: 3 | """ 4 | even = 0, 2, 4, 6, 8 5 | prime = 2, 3, 5, 7 6 | """ 7 | MOD = 10 ** 9 + 7 8 | ans = 1 9 | for i in range(n): 10 | if i % 2 == 0: 11 | ans *= 5 12 | else: 13 | ans *= 4 14 | ans %= MOD 15 | return ans 16 | 17 | # TLE 18 | # 806166225460393 19 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest248/3_fail2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | class Solution 3 | { 4 | public: 5 | int countGoodNumbers(long long n) 6 | { 7 | long long MOD = pow(10, 9) + 7; 8 | long long ans = 1; 9 | ans *= (long long)pow(5, n - n / 2) % MOD; 10 | ans %= MOD; 11 | ans *= (long long)pow(4, n / 2) % MOD; 12 | ans %= MOD; 13 | return ans; 14 | }; 15 | }; 16 | 17 | // WA 18 | // 50 19 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest248/3_fail2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def countGoodNumbers(self, n: int) -> int: 3 | """ 4 | even = 0, 2, 4, 6, 8 5 | prime = 2, 3, 5, 7 6 | """ 7 | MOD = 10 ** 9 + 7 8 | ans = 1 9 | ans *= 5 ** (n - n // 2) 10 | ans *= 4 ** (n // 2) 11 | ans %= MOD 12 | return ans 13 | 14 | # TLE 15 | # 806166225460393 16 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest248/3_fail4.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | memory = {1: 5} 3 | MOD = 10 ** 9 + 7 4 | 5 | def countGoodNumbers(self, n: int) -> int: 6 | """ 7 | even = 0, 2, 4, 6, 8 8 | prime = 2, 3, 5, 7 9 | """ 10 | 11 | max_mem = max(self.memory) 12 | for i in range(max_mem + 1, n + 1): 13 | if i % 2 == 0: 14 | self.memory[i] = self.memory[i - 1] * 4 % self.MOD 15 | else: 16 | self.memory[i] = self.memory[i - 1] * 5 % self.MOD 17 | 18 | return self.memory[n] 19 | 20 | # MLE 21 | # 806166225460393 22 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest325/1/test_325_1.py: -------------------------------------------------------------------------------- 1 | from Naive import Solution as Naive 2 | 3 | testcases = [ 4 | (["hello", "i", "am", "leetcode", "hello"], "hello", 1, 1), 5 | (["a", "b", "leetcode"], "leetcode", 0, 1), 6 | (["i", "eat", "leetcode"], "ate", 0, -1), 7 | (["odjrjznxpn", "cyulttuabe", "zqxkdoeszk", "yeewpgriok", "odjrjznxpn", "btqpvxpjzv", 8 | "ukyudladhk", "ukyudladhk", "odjrjznxpn", "yeewpgriok"], "odjrjznxpn", 5, 1), 9 | ] 10 | 11 | 12 | def test_naive(): 13 | for words, target, startIndex, ans in testcases: 14 | assert Naive().closetTarget(words, target, startIndex) == ans 15 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest334/1/Naive.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def leftRigthDifference(self, nums: List[int]) -> List[int]: 6 | left_sum = [0] 7 | right_sum = [0] 8 | for num in nums[:-1]: 9 | left_sum.append(left_sum[-1] + num) 10 | for num in nums[len(nums) - 1:0:-1]: 11 | right_sum.append(right_sum[-1] + num) 12 | 13 | return [abs(r - l) for r, l in zip(reversed(right_sum), left_sum)] 14 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest337/1/Naive.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def evenOddBit(self, n: int) -> List[int]: 6 | answer = [0, 0] 7 | for i, val in enumerate(reversed(bin(n)[2:])): 8 | if val == '1': 9 | if i % 2 == 0: 10 | answer[0] += 1 11 | else: 12 | answer[1] += 1 13 | 14 | return answer 15 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest337/3/test_2597.py: -------------------------------------------------------------------------------- 1 | from DFS import Solution 2 | 3 | testcases = [ 4 | ([2, 4, 6], 2, 4), 5 | ([1], 1, 1), 6 | ([1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 7 | 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000], 1), 8 | ] 9 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest338/1/Better.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def kItemsWithMaximumSum(self, numOnes: int, numZeros: int, numNegOnes: int, k: int) -> int: 3 | return min(numOnes, k) - max(k - numOnes - numZeros, 0) 4 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest338/3/Math.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def minOperations(self, nums: List[int], queries: List[int]) -> List[int]: 6 | num_sum = sum(nums) / 4 7 | answer = [] 8 | for q in queries: 9 | answer.append(num_sum - q * len(nums)) 10 | return answer 11 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest339/3/Greedy.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def miceAndCheese(self, reward1: List[int], reward2: List[int], k: int) -> int: 6 | diff = sorted([(r1 - r2, i) for i, (r1, r2) in enumerate(zip(reward1, reward2))], reverse=True) 7 | mouse1 = set([i for _, i in diff[:k]]) 8 | 9 | answer = 0 10 | for i in range(len(reward1)): 11 | if i in mouse1: 12 | answer += reward1[i] 13 | else: 14 | answer += reward2[i] 15 | return answer 16 | 17 | -------------------------------------------------------------------------------- /Contest/LeetCodeWeeklyContest/WeeklyContest340/2/Naive.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from collections import defaultdict 3 | 4 | 5 | class Solution: 6 | def distance(self, nums: List[int]) -> List[int]: 7 | num_idx = defaultdict(set) 8 | for i, num in enumerate(nums): 9 | num_idx[num].add(i) 10 | 11 | ans = [0] * len(nums) 12 | for i, num in enumerate(nums): 13 | for j in num_idx[num]: 14 | ans[i] += abs(i - j) 15 | return ans 16 | -------------------------------------------------------------------------------- /Learn/Algorithm/Graph/BellmanFord/README.md: -------------------------------------------------------------------------------- 1 | # Bellman–Ford Algorithm 2 | 3 | * [Bellman–Ford Algorithm | DP-23 - GeeksforGeeks](https://www.geeksforgeeks.org/bellman-ford-algorithm-dp-23/) 4 | -------------------------------------------------------------------------------- /Learn/Algorithm/Graph/DijkstraShortestPath/README.md: -------------------------------------------------------------------------------- 1 | # Dijkstra's Shortest Path Algorithm 2 | 3 | * [Dijkstra's algorithm - Wikipedia](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm) 4 | * [Dijsktra's algorithm](https://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-greedy-algo-7/) 5 | -------------------------------------------------------------------------------- /Learn/Algorithm/Graph/Prim/README.md: -------------------------------------------------------------------------------- 1 | # Prim's Minimum Spanning Tree (MST) 2 | 3 | * [Prim’s Minimum Spanning Tree (MST) | Greedy Algo-5 - GeeksforGeeks](https://www.geeksforgeeks.org/prims-minimum-spanning-tree-mst-greedy-algo-5/) 4 | -------------------------------------------------------------------------------- /Notes/Algorithm/Backtracking.md: -------------------------------------------------------------------------------- 1 | # Backtracking 2 | 3 | > Kind of like brute force 4 | 5 | ## Examples 6 | 7 | ### Power Set 8 | 9 | * [Power Set - GeeksforGeeks](https://www.geeksforgeeks.org/power-set/) 10 | * [python - How to get all subsets of a set? (powerset) - Stack Overflow](https://stackoverflow.com/questions/1482308/how-to-get-all-subsets-of-a-set-powerset) 11 | -------------------------------------------------------------------------------- /Notes/Algorithm/SweepLine.md: -------------------------------------------------------------------------------- 1 | # Sweep Line 2 | 3 | ## Resources 4 | 5 | * [一文读懂扫描线算法 - 知乎](https://zhuanlan.zhihu.com/p/103616664) 6 | * [基础算法(一) -- 扫描线 - YouTube](https://www.youtube.com/watch?v=ihf8JjQdta0) 7 | -------------------------------------------------------------------------------- /Notes/Algorithm/TopologicalSort.md: -------------------------------------------------------------------------------- 1 | # Topological Sort 2 | 3 | ## Overview 4 | 5 | Property 6 | 7 | * There can be multiple possible result 8 | 9 | ## Resources 10 | 11 | * [Topological sorting - Wikipedia](https://en.wikipedia.org/wiki/Topological_sorting#:~:text=In%20computer%20science%2C%20a%20topological,before%20v%20in%20the%20ordering.) 12 | * [Topological Sorting - GeeksforGeeks](https://www.geeksforgeeks.org/topological-sorting/) 13 | * [Topological Sorting | GeeksforGeeks - YouTube](https://www.youtube.com/watch?v=Q9PIxaNGnig) 14 | -------------------------------------------------------------------------------- /Notes/DataStructure/Graph.md: -------------------------------------------------------------------------------- 1 | # Graph 2 | 3 | ## Representation of Graph 4 | 5 | * [Representing graphs (article) | Algorithms | Khan Academy](https://www.khanacademy.org/computing/computer-science/algorithms/graph-representation/a/representing-graphs) 6 | 7 | ## Minimum Spanning Tree (MST) 8 | 9 | ### Kruskal's Algorithm 10 | 11 | * [Kruskal's algorithm - Wikipedia](https://en.wikipedia.org/wiki/Kruskal%27s_algorithm) 12 | 13 | ### Prim's Algorithm 14 | 15 | * [Prim’s Minimum Spanning Tree (MST) | Greedy Algo-5 - GeeksforGeeks](https://www.geeksforgeeks.org/prims-minimum-spanning-tree-mst-greedy-algo-5/) 16 | -------------------------------------------------------------------------------- /Notes/DataStructure/MoreTree.md: -------------------------------------------------------------------------------- 1 | # More Things about Tree 2 | 3 | ## Lowest Common Ancestor (LCA) 4 | 5 | * [Lowest Common Ancestor in a Binary Tree | Set 1 - GeeksforGeeks](https://www.geeksforgeeks.org/lowest-common-ancestor-binary-tree-set-1/) 6 | * [Lowest Common Ancestor in a Binary Search Tree. - GeeksforGeeks](https://www.geeksforgeeks.org/lowest-common-ancestor-in-a-binary-search-tree/) 7 | -------------------------------------------------------------------------------- /Notes/DataStructure/README.md: -------------------------------------------------------------------------------- 1 | # Data Structure 2 | 3 | ## Resources 4 | 5 | * [Problem Solving with Algorithms and Data Structures using Python — Problem Solving with Algorithms and Data Structures](https://runestone.academy/ns/books/published/pythonds/index.html) 6 | * [1: CS22 - Python Data Structures/Algorithms Class - Introduction - YouTube](https://www.youtube.com/playlist?list=PLtbC5OfOR8aqA6CJwWTRUITgGpUy1Umr3) 7 | * [PDF](https://www.cs.auckland.ac.nz/courses/compsci105ssc/resources/ProblemSolvingwithAlgorithmsandDataStructures.pdf) 8 | -------------------------------------------------------------------------------- /Notes/DataStructure/SizeBalancedTree.md: -------------------------------------------------------------------------------- 1 | # Size Balanced Tree 2 | -------------------------------------------------------------------------------- /Notes/PracticeOrder/Order1.md: -------------------------------------------------------------------------------- 1 | # Practice Order - By 胖頭龍 2 | 3 | * [胖头龙的咸鱼刷题笔记-算法篇|一亩三分地刷题版](https://www.1point3acres.com/bbs/thread-678970-1-1.html) 4 | 5 | ## 1. Methodology 6 | 7 | ## 2. How good should we be to be able to handle job interview 8 | 9 | ## 3. List 10 | -------------------------------------------------------------------------------- /Notes/Trick/BitManipulation.md: -------------------------------------------------------------------------------- 1 | # Bit Manipulation Trick 2 | 3 | ## Shift for multiply and divide 4 | 5 | * `a // 2` is equivalent to `a >> 1` 6 | * `a * 2` is equivalent to `a << 1` 7 | * `a ** n` is equivalent to `a << n` 8 | 9 | Example: 10 | 11 | Binary search find mid `low + high >> 1` (you can save time of typing the bracket) 12 | 13 | ## Determine even or odds 14 | 15 | * `a % 2` is equivalent to `a & 1` 16 | 17 | ## Exist 18 | 19 | > TODO 20 | 21 | `^` 22 | -------------------------------------------------------------------------------- /Python3/Array/3SumClosest/test_016.py: -------------------------------------------------------------------------------- 1 | from TwoPointer016 import Solution as twoPointer 2 | 3 | nums = [] 4 | nums.append([-1, 2, 1, -4]) 5 | nums.append([0, 1, 2]) 6 | nums.append([-3, -2, -5, 3, -4]) 7 | nums.append([4, 0, 5, -5, 3, 3, 0, -4, -5]) 8 | 9 | targets = [] 10 | targets.append(1) 11 | targets.append(3) 12 | targets.append(-1) 13 | targets.append(-2) 14 | 15 | ans = [] 16 | ans.append(2) 17 | ans.append(3) 18 | ans.append(-2) 19 | ans.append(-2) 20 | 21 | def test_twoPointer(): 22 | for i in range(len(ans)): 23 | assert twoPointer().threeSumClosest(nums[i], targets[i]) == ans[i] 24 | -------------------------------------------------------------------------------- /Python3/Array/4Sum/test_018.py: -------------------------------------------------------------------------------- 1 | from GeneralizedTwoPointer018 import Solution as GeneralizedTwoPointer 2 | 3 | Nums = [] 4 | Nums.append([1, 0, -1, 0, -2, 2]) 5 | 6 | targets = [] 7 | targets.append(0) 8 | 9 | solution = [] 10 | solution.append( 11 | [ 12 | [-1, 0, 0, 1], 13 | [-2, -1, 1, 2], 14 | [-2, 0, 0, 2] 15 | ] 16 | ) 17 | 18 | def test_GeneralizedTwoPointer(): 19 | for i, nums in enumerate(Nums): 20 | assert sorted(GeneralizedTwoPointer().fourSum(nums, targets[i])) == sorted(solution[i]) 21 | -------------------------------------------------------------------------------- /Python3/Array/AddDigits/Iterative258.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def addDigits(self, num: int) -> int: 3 | while num >= 10: 4 | temp = num 5 | new_num = 0 6 | while temp > 0: 7 | new_num += temp % 10 8 | temp //= 10 9 | num = new_num 10 | return num 11 | -------------------------------------------------------------------------------- /Python3/Array/AddDigits/Naive258.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def addDigits(self, num: int) -> int: 3 | if num < 10: 4 | return num 5 | 6 | new_num = 0 7 | while num > 0: 8 | new_num += num % 10 9 | num //= 10 10 | 11 | return self.addDigits(new_num) 12 | -------------------------------------------------------------------------------- /Python3/Array/AddDigits/NoLoop258.py: -------------------------------------------------------------------------------- 1 | # Digit Root 2 | # congruence formula 3 | # https://en.wikipedia.org/wiki/Digital_root#Congruence_formula 4 | 5 | 6 | class Solution: 7 | def addDigits(self, num: int) -> int: 8 | return 1 + (num - 1) % 9 9 | -------------------------------------------------------------------------------- /Python3/Array/AddDigits/test_258.py: -------------------------------------------------------------------------------- 1 | from Naive258 import Solution as naive 2 | from NoLoop258 import Solution as no_loop 3 | from Iterative258 import Solution as iterative 4 | 5 | testcase = [ 6 | (38, 2), 7 | (11, 2), 8 | (2, 2), 9 | (10, 1) 10 | ] 11 | 12 | 13 | def test_naive(): 14 | for num, ans in testcase: 15 | assert naive().addDigits(num) == ans 16 | 17 | 18 | def test_no_loop(): 19 | for num, ans in testcase: 20 | assert no_loop().addDigits(num) == ans 21 | 22 | 23 | def test_iterative(): 24 | for num, ans in testcase: 25 | assert iterative().addDigits(num) == ans 26 | -------------------------------------------------------------------------------- /Python3/Array/AddToArrayFormOfInteger/Python989.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def addToArrayForm(self, num: List[int], k: int) -> List[int]: 6 | return [int(c) for c in str(int(''.join(str(n) for n in num)) + k)] 7 | -------------------------------------------------------------------------------- /Python3/Array/AddToArrayFormOfInteger/test_989.py: -------------------------------------------------------------------------------- 1 | from Naive989 import Solution as Naive 2 | from Python989 import Solution as Python 3 | 4 | testcases = [ 5 | ({'num': [1, 2, 0, 0], 'k': 34}, [1, 2, 3, 4]), 6 | ({'num': [2, 7, 4], 'k': 181}, [4, 5, 5]), 7 | ({'num': [2, 1, 5], 'k': 806}, [1, 0, 2, 1]), 8 | ] 9 | 10 | 11 | def test_Naive(): 12 | for testcase, ans in testcases: 13 | assert Naive().addToArrayForm(**testcase) == ans 14 | 15 | 16 | def test_Python(): 17 | for testcase, ans in testcases: 18 | assert Python().addToArrayForm(**testcase) == ans 19 | -------------------------------------------------------------------------------- /Python3/Array/AverageSalaryExcludingtheMinimumAndMaximumSalary/test_1491.py: -------------------------------------------------------------------------------- 1 | from Naive1491 import Solution as Naive 2 | 3 | testcases = [ 4 | ([4000, 3000, 1000, 2000], 2500.0), 5 | ([1000, 2000, 3000], 2000.0), 6 | ] 7 | 8 | # Answers within 10-5 of the actual answer will be accepted. 9 | 10 | 11 | def test_Naive(): 12 | for salary, ans in testcases: 13 | assert Naive().average(salary) == ans 14 | -------------------------------------------------------------------------------- /Python3/Array/BeautifulArrangement/BruteForce526.py: -------------------------------------------------------------------------------- 1 | from itertools import permutations 2 | 3 | 4 | class Solution: 5 | def countArrangement(self, n: int) -> int: 6 | ans = [] 7 | for perm in permutations(range(1, n+1)): 8 | found = True 9 | for i, perm_i in enumerate(perm): 10 | if (i+1) % perm_i != 0 and perm_i % (i+1) != 0: 11 | found = False 12 | break 13 | if found: 14 | ans.append(perm) 15 | return len(ans) 16 | 17 | # TLE at n = 11 18 | -------------------------------------------------------------------------------- /Python3/Array/BestTimetoBuyandSellStock/BruteForce121.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def maxProfit(self, prices: List[int]) -> int: 6 | """ 7 | This will TLE 8 | """ 9 | max_profit = 0 10 | for i, buy in enumerate(prices): 11 | for sell in prices[i + 1:]: 12 | max_profit = max(max_profit, sell - buy) 13 | 14 | return max_profit 15 | -------------------------------------------------------------------------------- /Python3/Array/BestTimetoBuyandSellStock/Naive121.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def maxProfit(self, prices: List[int]) -> int: 6 | cur_min = float('inf') 7 | answer = 0 8 | 9 | for price in prices: 10 | if price < cur_min: 11 | cur_min = price 12 | 13 | answer = max(price - cur_min, answer) 14 | 15 | return answer 16 | -------------------------------------------------------------------------------- /Python3/Array/BestTimetoBuyandSellStockII/Greedy2_122.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def maxProfit(self, prices: List[int]) -> int: 6 | # if not prices: 7 | # return 0 8 | 9 | max_profit = 0 10 | previous = prices[0] 11 | for price in prices: 12 | if price - previous > 0: 13 | max_profit += price - previous 14 | previous = price 15 | 16 | return max_profit 17 | -------------------------------------------------------------------------------- /Python3/Array/BestTimetoBuyandSellStockII/Max122.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def maxProfit(self, prices: List[int]) -> int: 6 | best_without_stock = 0 7 | best_with_stock = -float('inf') 8 | 9 | for price in prices: 10 | best_with_stock = max(best_with_stock, best_without_stock - price) 11 | best_without_stock = max( 12 | best_without_stock, best_with_stock + price) 13 | 14 | return best_without_stock 15 | -------------------------------------------------------------------------------- /Python3/Array/BestTimetoBuyandSellStockII/Tricky122.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxProfit(self, prices): 3 | """ 4 | :type prices: List[int] 5 | :rtype: int 6 | """ 7 | 8 | profit = 0 9 | 10 | for i in range(len(prices)-1): 11 | if prices[i+1] > prices[i]: 12 | profit += prices[i+1] - prices[i] 13 | 14 | return profit 15 | -------------------------------------------------------------------------------- /Python3/Array/BinarySearch/Bisect704.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import bisect 3 | 4 | 5 | class Solution: 6 | def search(self, nums: List[int], target: int) -> int: 7 | idx = bisect.bisect_left(nums, target) 8 | if idx < len(nums) and nums[idx] == target: 9 | return idx 10 | return -1 11 | -------------------------------------------------------------------------------- /Python3/Array/BoatsToSavePeople/test_881.py: -------------------------------------------------------------------------------- 1 | from Greedy881 import Solution as Greedy 2 | 3 | testcases = [ 4 | ([1, 2], 3, 1), 5 | ([3, 2, 2, 1], 3, 3), 6 | ([3, 5, 3, 4], 5, 4), 7 | ] 8 | 9 | 10 | def test_Greedy(): 11 | for people, limit, ans in testcases: 12 | assert Greedy().numRescueBoats(people, limit) == ans 13 | -------------------------------------------------------------------------------- /Python3/Array/CanPlaceFlowers/test_605.py: -------------------------------------------------------------------------------- 1 | from Naive605 import Solution as Naive 2 | 3 | testcases = [ 4 | ([1, 0, 0, 0, 1], 1, True), 5 | ([1, 0, 0, 0, 1], 2, False), 6 | ([1, 0, 0, 0, 0, 1], 2, False), 7 | ([1, 0, 0, 0, 0, 0, 1], 2, True), 8 | ([1, 0, 0, 0, 1, 0, 0], 2, True), 9 | ([0, 0, 0, 0, 0, 1, 0, 0], 0, True), 10 | ] 11 | 12 | 13 | def test_Naive(): 14 | for flowerbed, n, ans in testcases: 15 | assert Naive().canPlaceFlowers(flowerbed, n) == ans 16 | -------------------------------------------------------------------------------- /Python3/Array/Candy/test_135.py: -------------------------------------------------------------------------------- 1 | from BruteForce135 import Solution as BruteForce 2 | from TwoArrays135 import Solution as TwoArrays 3 | 4 | testcases = [ 5 | ([1, 0, 2], 5), 6 | ([1, 2, 2], 4), 7 | ([29, 51, 87, 87, 72, 12], 12), 8 | ] 9 | 10 | 11 | def test_BruteForce(): 12 | for ratings, ans in testcases: 13 | assert BruteForce().candy(ratings) == ans 14 | 15 | 16 | def test_TwoArrays(): 17 | for ratings, ans in testcases: 18 | assert TwoArrays().candy(ratings) == ans 19 | -------------------------------------------------------------------------------- /Python3/Array/CarPooling/Naive1094.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | class Solution: 5 | def carPooling(self, trips: List[List[int]], capacity: int) -> bool: 6 | """ 7 | Actually this is kind of a "bucket sort" 8 | """ 9 | max_passenger = np.zeros((1000, )) 10 | for n, s, e in trips: 11 | max_passenger[s:e] += n 12 | return max(max_passenger) <= capacity 13 | -------------------------------------------------------------------------------- /Python3/Array/CheckArrayFormationThroughConcatenation/HT1640.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def canFormArray(self, arr: List[int], pieces: List[List[int]]) -> bool: 6 | """ 7 | https://leetcode.com/problems/check-array-formation-through-concatenation/discuss/918408/Python-5-lines-hashmap 8 | """ 9 | first_item_to_piece = {piece[0]: piece for piece in pieces} 10 | concat = [] 11 | for num in arr: 12 | concat += first_item_to_piece.get(num, []) 13 | 14 | return arr == concat -------------------------------------------------------------------------------- /Python3/Array/ClimbingStairs/DP070.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def climbStairs(self, n): 3 | """ 4 | :type n: int 5 | :rtype: int 6 | """ 7 | if n == 1: 8 | return 1 9 | if n == 2: 10 | return 2 11 | 12 | waysToStair = [1, 2] # Initial value of stair 1 and 2 13 | for stair in range(2, n): # Calculate stair 3 to n 14 | waysToStair.append(waysToStair[stair-1] + waysToStair[stair-2]) 15 | 16 | return waysToStair[n-1] 17 | -------------------------------------------------------------------------------- /Python3/Array/ClimbingStairs/Naive070.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def climbStairs(self, n: int) -> int: 3 | dp = [0] * (n + 1) 4 | dp[0] = 1 5 | dp[1] = 1 6 | for i in range(2, n + 1): 7 | dp[i] = dp[i-1] + dp[i-2] 8 | 9 | return dp[n] 10 | 11 | # Runtime: 28 ms, faster than 80.72% of Python3 online submissions for Climbing Stairs. 12 | # Memory Usage: 13.9 MB, less than 28.53% of Python3 online submissions for Climbing Stairs. 13 | -------------------------------------------------------------------------------- /Python3/Array/CoinChange2/test_518.py: -------------------------------------------------------------------------------- 1 | from Naive518 import Solution as naive 2 | from DP518 import Solution as DP 3 | 4 | testcase = [ 5 | (5, [1, 2, 5], 4), 6 | (3, [2], 0), 7 | (10, [10], 1), 8 | (0, [], 1), 9 | # (500, [3, 5, 7, 8, 9, 10, 11], 87) 10 | ] 11 | 12 | 13 | def test_naive(): 14 | for amount, coins, ans in testcase: 15 | assert naive().change(amount, coins) == ans 16 | 17 | 18 | def test_DP(): 19 | for amount, coins, ans in testcase: 20 | assert DP().change(amount, coins) == ans 21 | -------------------------------------------------------------------------------- /Python3/Array/ContainerWithMostWater/Naive011.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxArea(self, height): 3 | """ 4 | :type height: List[int] 5 | :rtype: int 6 | """ 7 | self.height = height 8 | 9 | maxAreaTemp = 0 10 | 11 | for i in range(len(height)): 12 | for j in range(i+1, len(height)): 13 | if self.calcArea(i, j) > maxAreaTemp: 14 | maxAreaTemp = self.calcArea(i, j) 15 | return maxAreaTemp 16 | 17 | 18 | def calcArea(self, idx1, idx2): 19 | return abs(idx2 - idx1) * min(self.height[idx1], self.height[idx2]) -------------------------------------------------------------------------------- /Python3/Array/ContainerWithMostWater/Naive2_011.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from itertools import combinations 3 | 4 | 5 | class Solution: 6 | def maxArea(self, height: List[int]) -> int: 7 | height_with_idx = [(i, h) for i, h in enumerate(height)] 8 | max_area = 0 9 | for left, right in combinations(height_with_idx, 2): 10 | max_area = max(max_area, 11 | (right[0] - left[0]) * min(left[1], right[1])) 12 | 13 | return max_area 14 | 15 | # TLE 16 | -------------------------------------------------------------------------------- /Python3/Array/ContiguousArray/test_525.py: -------------------------------------------------------------------------------- 1 | from Naive525 import Solution as naive 2 | from HT525 import Solution as ht 3 | 4 | testcase = [ 5 | ([0, 1], 2), 6 | ([0, 1, 0], 2), 7 | ([0, 1, 0, 1], 4) 8 | ] 9 | 10 | 11 | def test_naive(): 12 | for nums, ans in testcase: 13 | assert naive().findMaxLength(nums) == ans 14 | 15 | 16 | def test_ht(): 17 | for nums, ans in testcase: 18 | assert ht().findMaxLength(nums) == ans 19 | -------------------------------------------------------------------------------- /Python3/Array/CountOfSmallerNumbersAfterSelf/MergeSort315.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def countSmaller(self, nums: List[int]) -> List[int]: 6 | pass 7 | -------------------------------------------------------------------------------- /Python3/Array/CountOfSmallerNumbersAfterSelf/test_315.py: -------------------------------------------------------------------------------- 1 | from BinaryIndexedTree315 import Solution as FenwickTree 2 | 3 | testcases = [ 4 | ([5, 2, 6, 1], [2, 1, 1, 0]), 5 | ([-1], [0]), 6 | ([-1, -1], [0, 0]), 7 | ([2, 0, 1], [2, 0, 0]), 8 | ([2, 1, 1], [2, 0, 0]), 9 | ] 10 | 11 | 12 | def test_FenwickTree(): 13 | for nums, ans in testcases: 14 | assert list(FenwickTree().countSmaller(nums)) == ans, f'Failed at Case: {nums}' 15 | -------------------------------------------------------------------------------- /Python3/Array/CountingElements/SinglePass.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from collections import defaultdict 3 | 4 | 5 | class Solution: 6 | def countElements(self, arr: List[int]) -> int: 7 | hash_table = defaultdict(int) 8 | 9 | result = 0 10 | for a in arr: 11 | if a + 1 in hash_table: 12 | result += 1 13 | if a not in hash_table and a - 1 in hash_table: 14 | result += hash_table[a - 1] 15 | 16 | hash_table[a] += 1 17 | 18 | return result 19 | -------------------------------------------------------------------------------- /Python3/Array/CourseScheduleIII/Naive630.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def scheduleCourse(self, courses: List[List[int]]) -> int: 6 | """ 7 | Try all the possibility 8 | Obvious not working so I don't do it = = 9 | """ 10 | pass 11 | -------------------------------------------------------------------------------- /Python3/Array/CourseScheduleIII/test_630.py: -------------------------------------------------------------------------------- 1 | from PriorityQueue630 import Solution as PQ 2 | from TopDownDP630 import Solution as TDDP 3 | 4 | testcases = [ 5 | ([[100, 200], [200, 1300], [1000, 1250], [2000, 3200]], 3), 6 | ([[1, 2]], 1), 7 | ([[3, 2], [4, 3]], 0), 8 | ([[7, 17], [3, 12], [10, 20], [9, 10], [5, 20], [10, 19], [4, 18]], 4), 9 | ] 10 | 11 | 12 | def test_TDDP(): 13 | for courses, ans in testcases: 14 | assert TDDP().scheduleCourse(courses) == ans 15 | 16 | 17 | def test_PQ(): 18 | for courses, ans in testcases: 19 | assert PQ().scheduleCourse(courses) == ans 20 | -------------------------------------------------------------------------------- /Python3/Array/DecodeWays/test_91.py: -------------------------------------------------------------------------------- 1 | from Naive91 import Solution as naive 2 | 3 | testcase = [ 4 | ('12', 2), 5 | ('226', 3), 6 | ('0', 0), 7 | ('10', 1), 8 | ('01', 0), 9 | ('301', 0), 10 | ('27', 1), 11 | ('101', 1), 12 | ('12120', 3), 13 | ] 14 | 15 | 16 | def test_naive(): 17 | for s, ans in testcase: 18 | assert naive().numDecodings(s) == ans 19 | -------------------------------------------------------------------------------- /Python3/Array/DungeonGame/test_174.py: -------------------------------------------------------------------------------- 1 | from DP174 import Solution as dp 2 | 3 | testcase = [ 4 | ([[-2, -3, 3], 5 | [-5, -10, 1], 6 | [10, 30, -5]], 7), 7 | ([[0]], 1), 8 | ([[-10]], 11), 9 | ([[10]], 1), 10 | ([[0, 5], 11 | [-2, -3]], 1) 12 | ] 13 | 14 | 15 | def test_dp(): 16 | for dungeon, ans in testcase: 17 | assert dp().calculateMinimumHP(dungeon) == ans 18 | -------------------------------------------------------------------------------- /Python3/Array/EvaluateReversePolishNotation/test_150.py: -------------------------------------------------------------------------------- 1 | from Stack150 import Solution as stack 2 | 3 | testcase = [ 4 | (["2", "1", "+", "3", "*"], 9), 5 | (["4", "13", "5", "/", "+"], 6), 6 | (["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"], 22) 7 | ] 8 | 9 | 10 | def test_stack(): 11 | for tokens, output in testcase: 12 | assert stack().evalRPN(tokens) == output 13 | -------------------------------------------------------------------------------- /Python3/Array/FinalPricesWithASpecialDiscountInAShop/Stack1475.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def finalPrices(self, prices: List[int]) -> List[int]: 6 | """ 7 | https://leetcode.com/problems/final-prices-with-a-special-discount-in-a-shop/discuss/685390/JavaC%2B%2BPython-Stack-One-Pass 8 | """ 9 | stack = [] 10 | 11 | for i in range(len(prices)): 12 | while stack and prices[stack[-1]] >= prices[i]: 13 | prices[stack.pop()] -= prices[i] 14 | stack.append(i) 15 | 16 | return prices 17 | -------------------------------------------------------------------------------- /Python3/Array/FindMinimumInRotatedSortedArray/test_153.py: -------------------------------------------------------------------------------- 1 | from Naive153 import Solution as naive 2 | from Simpler153 import Solution as simpler 3 | 4 | testcase = [ 5 | ([3, 4, 5, 1, 2], 1), 6 | ([4, 5, 6, 7, 0, 1, 2], 0), 7 | ([1], 1), 8 | ([2, 1], 1), 9 | ([1, 2], 1), 10 | ([2, 3, 4, 5, 1], 1) 11 | ] 12 | 13 | 14 | def test_naive(): 15 | for nums, ans in testcase: 16 | assert naive().findMin(nums) == ans 17 | 18 | 19 | def test_simpler(): 20 | for nums, ans in testcase: 21 | assert simpler().findMin(nums) == ans 22 | -------------------------------------------------------------------------------- /Python3/Array/FindSubsequenceOfLengthKWithTheLargestSum/Naive2099.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def maxSubsequence(self, nums: List[int], k: int) -> List[int]: 6 | answer = [] 7 | for i, _ in sorted(sorted([(i, num) for i, num in enumerate(nums)], key=lambda x: x[1])[-k:], key=lambda x: x[0]): 8 | # print(i, nums[i]) 9 | answer.append(nums[i]) 10 | return answer 11 | -------------------------------------------------------------------------------- /Python3/Array/FindSubsequenceOfLengthKWithTheLargestSum/test_2099.py: -------------------------------------------------------------------------------- 1 | from Naive2099 import Solution as Naive 2 | 3 | testcases = [ 4 | ({'nums': [2, 1, 3, 3], 'k': 2}, [3, 3]), 5 | ({'nums': [-1, -2, 3, 4], 'k': 3}, [-1, 3, 4]), 6 | # TODO: able to test => Return "any" such subsequence as an integer array of length k. 7 | # ({'nums': [3, 4, 3, 3], 'k': 2}, [3, 4]), 8 | ({'nums': [3, 4, 3, 3], 'k': 2}, [4, 3]), 9 | ({'nums': [50, -75], 'k': 2}, [50, -75]), 10 | ] 11 | 12 | 13 | def test_Naive(): 14 | for testcase, ans in testcases: 15 | assert Naive().maxSubsequence(**testcase) == ans 16 | -------------------------------------------------------------------------------- /Python3/Array/FindTheDuplicateNumber/LinkedList287.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def findDuplicate(self, nums: List[int]) -> int: 6 | for num in nums: 7 | if nums[abs(num)] < 0: 8 | return abs(num) 9 | else: 10 | nums[abs(num)] *= -1 11 | 12 | # Runtime: 68 ms, faster than 49.62% of Python3 online submissions for Find the Duplicate Number. 13 | # Memory Usage: 16.3 MB, less than 17.96% of Python3 online submissions for Find the Duplicate Number. 14 | -------------------------------------------------------------------------------- /Python3/Array/FindTheDuplicateNumber/Naive287.py: -------------------------------------------------------------------------------- 1 | 2 | from typing import List 3 | 4 | 5 | class Solution: 6 | def findDuplicate(self, nums: List[int]) -> int: 7 | for i, num in enumerate(nums): 8 | if num in nums[i+1:]: 9 | return num 10 | 11 | # Runtime: 6228 ms, faster than 5.01% of Python3 online submissions for Find the Duplicate Number. 12 | # Memory Usage: 16.3 MB, less than 55.80% of Python3 online submissions for Find the Duplicate Number. 13 | -------------------------------------------------------------------------------- /Python3/Array/FindTheDuplicateNumber/Set287.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def findDuplicate(self, nums: List[int]) -> int: 6 | memo = set() 7 | for num in nums: 8 | if num in memo: 9 | return num 10 | memo.add(num) 11 | 12 | # Runtime: 64 ms, faster than 73.62% of Python3 online submissions for Find the Duplicate Number. 13 | # Memory Usage: 18.1 MB, less than 17.96% of Python3 online submissions for Find the Duplicate Number. 14 | -------------------------------------------------------------------------------- /Python3/Array/FindTheTownJudge/Naive2_997.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def findJudge(self, n: int, trust: List[List[int]]) -> int: 6 | # find a node that in edge is n - 1 and out edge is 0 7 | in_edges = [0] * n 8 | out_edges = [0] * n 9 | for ai, bi in trust: 10 | in_edges[bi - 1] += 1 11 | out_edges[ai - 1] += 1 12 | 13 | for i, (in_edge, out_edge) in enumerate(zip(in_edges, out_edges)): 14 | if in_edge == n - 1 and out_edge == 0: 15 | return i + 1 16 | return -1 17 | -------------------------------------------------------------------------------- /Python3/Array/H-Index/test_274.py: -------------------------------------------------------------------------------- 1 | from CumulativeSum274 import Solution as cumulativesum 2 | 3 | testcase = [ 4 | ([3, 0, 6, 1, 5], 3), 5 | ([0, 1, 3, 5, 6], 3), 6 | ([], 0), 7 | ([0], 0), 8 | ([1], 1), 9 | ([1, 1], 1), 10 | ([1, 2], 1), 11 | ] 12 | 13 | 14 | def test_cumulativesum(): 15 | for citations, ans in testcase: 16 | assert cumulativesum().hIndex(citations) == ans 17 | -------------------------------------------------------------------------------- /Python3/Array/H-IndexII/BinarySearch275.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def hIndex(self, citations: List[int]) -> int: 6 | """ 7 | https://leetcode.com/problems/h-index/discuss/693375/Short-C%2B%2B-Solution 8 | """ 9 | if not citations: 10 | return 0 11 | N = len(citations) 12 | left, right = 0, N 13 | while left < right: 14 | mid = left + (right - left) // 2 15 | if citations[mid] < N - mid: 16 | left = mid + 1 17 | else: 18 | right = mid 19 | 20 | return N - left 21 | -------------------------------------------------------------------------------- /Python3/Array/H-IndexII/Linear275.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def hIndex(self, citations: List[int]) -> int: 6 | """ 7 | https://leetcode.com/problems/h-index/discuss/693418/Java-or-Simple-one 8 | """ 9 | 10 | N = len(citations) 11 | index = 0 12 | while index < N and N - index > citations[index]: 13 | index += 1 14 | 15 | return N - index 16 | -------------------------------------------------------------------------------- /Python3/Array/H-IndexII/test_275.py: -------------------------------------------------------------------------------- 1 | from Linear275 import Solution as linear 2 | from BinarySearch275 import Solution as binarysearch 3 | 4 | testcase = [ 5 | ([0, 1, 3, 5, 6], 3), 6 | ([], 0), 7 | ([0], 0), 8 | ([1], 1), 9 | ([1, 1], 1), 10 | ([1, 2], 1), 11 | ] 12 | 13 | 14 | def test_linear(): 15 | for citations, ans in testcase: 16 | assert linear().hIndex(citations) == ans 17 | 18 | 19 | def test_binarysearch(): 20 | for citations, ans in testcase: 21 | assert binarysearch().hIndex(citations) == ans 22 | -------------------------------------------------------------------------------- /Python3/Array/JumpGame/Greedy055.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def canJump(self, nums: List[int]) -> bool: 6 | """ 7 | Track the "left-most GOOD position" 8 | (observed from the break statement) 9 | 10 | Time Complexity: O(n) 11 | Space Complexity: O(1) 12 | """ 13 | lastPos = len(nums) - 1 14 | for i in reversed(range(len(nums))): 15 | if i + nums[i] >= lastPos: 16 | lastPos = i 17 | 18 | return lastPos == 0 19 | -------------------------------------------------------------------------------- /Python3/Array/JumpGame/Greedy2_055.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def canJump(self, nums: List[int]) -> bool: 6 | max_index = 0 7 | for i, num in enumerate(nums): 8 | if i > max_index: 9 | break 10 | max_index = max(max_index, i + num) 11 | 12 | return max_index >= len(nums) - 1 13 | 14 | # Runtime: 88 ms, faster than 75.27% of Python3 online submissions for Jump Game. 15 | # Memory Usage: 15.9 MB, less than 99.99% of Python3 online submissions for Jump Game. 16 | -------------------------------------------------------------------------------- /Python3/Array/JumpGameII/Greedy2_045.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def jump(self, nums: List[int]) -> int: 6 | # Update each nums to be the index it can reach 7 | for i, num in enumerate(nums): 8 | nums[i] = num + i 9 | 10 | prev = 0 11 | curr = 0 12 | times = 0 13 | while curr < len(nums) - 1: 14 | # Try to jump to the maximum index 15 | curr, prev = max(nums[prev:curr + 1]), curr 16 | times += 1 17 | return times 18 | -------------------------------------------------------------------------------- /Python3/Array/K-diffPairsInAnArray/Naive2_532.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | class Solution: 4 | def findPairs(self, nums: List[int], k: int) -> int: 5 | pass 6 | -------------------------------------------------------------------------------- /Python3/Array/KokoEatingBananas/Naive875.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def minEatingSpeed(self, piles: List[int], H: int) -> int: 6 | """ 7 | Brute Force 8 | """ 9 | for speed in range(1, max(piles) + 1): 10 | hours_taken = 0 11 | for pile in piles: 12 | while pile > 0 and hours_taken <= H: 13 | pile -= speed 14 | hours_taken += 1 15 | 16 | if hours_taken > H: 17 | break 18 | 19 | if hours_taken == H: 20 | return speed 21 | -------------------------------------------------------------------------------- /Python3/Array/KokoEatingBananas/test_875.py: -------------------------------------------------------------------------------- 1 | from BinarySearch875 import Solution as bs 2 | from Naive875 import Solution as naive 3 | 4 | testcase = [ 5 | ([3, 6, 7, 11], 8, 4), 6 | ([30, 11, 23, 4, 20], 5, 30), 7 | ([30, 11, 23, 4, 20], 6, 23), 8 | # ([312884470], 312884469, 2) 9 | ] 10 | 11 | 12 | def test_naive(): 13 | for piles, H, ans in testcase: 14 | assert naive().minEatingSpeed(piles, H) == ans 15 | 16 | 17 | def test_bs(): 18 | for piles, H, ans in testcase: 19 | assert bs().minEatingSpeed(piles, H) == ans 20 | -------------------------------------------------------------------------------- /Python3/Array/KthLargestElementInAnArray/Heap215.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import heapq 3 | 4 | 5 | class Solution: 6 | def findKthLargest(self, nums: List[int], k: int) -> int: 7 | # heap = [] 8 | # for num in nums: 9 | # heapq.heappush(heap, -num) 10 | # for _ in range(k): 11 | # temp = heapq.heappop(heap) 12 | # return -temp 13 | 14 | # equivalent 15 | heapq._heapify_max(nums) 16 | for _ in range(k): 17 | temp = heapq._heappop_max(nums) 18 | 19 | return temp -------------------------------------------------------------------------------- /Python3/Array/KthLargestElementInAnArray/HeapCheat215.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import heapq 3 | 4 | 5 | class Solution: 6 | def findKthLargest(self, nums: List[int], k: int) -> int: 7 | # heap = [] 8 | # for num in nums: 9 | # heapq.heappush(heap, num) 10 | # return heapq.nlargest(k, heap)[-1] 11 | 12 | return heapq.nlargest(k, nums)[-1] 13 | -------------------------------------------------------------------------------- /Python3/Array/KthLargestElementInAnArray/Naive215.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def findKthLargest(self, nums: List[int], k: int) -> int: 6 | nums.sort() 7 | return nums[-k] 8 | -------------------------------------------------------------------------------- /Python3/Array/KthLargestElementInAnArray/SelectionSortLike215.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | class Solution: 4 | def findKthLargest(self, nums: List[int], k: int) -> int: 5 | for last_range in range(len(nums), len(nums)-k, -1): 6 | max_idx = 0 7 | for i in range(last_range): 8 | if nums[i] > nums[max_idx]: 9 | max_idx = i 10 | nums[max_idx], nums[last_range-1] = nums[last_range-1], nums[max_idx] 11 | return nums[-k] 12 | -------------------------------------------------------------------------------- /Python3/Array/KthMissingPositiveNumber/Bisect1539.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import bisect 3 | 4 | 5 | class Solution: 6 | def findKthPositive(self, arr: List[int], k: int) -> int: 7 | """ 8 | https://leetcode.com/problems/kth-missing-positive-number/solutions/3262163/c-java-python3-1-line-o-logn/ 9 | """ 10 | # https://docs.python.org/3.10/library/bisect.html 11 | # Changed in version 3.10: Added the key parameter. 12 | return bisect.bisect_right(range(0, len(arr)), k, key=lambda x: arr[x] - x) + k 13 | -------------------------------------------------------------------------------- /Python3/Array/KthMissingPositiveNumber/Naive1539.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def findKthPositive(self, arr: List[int], k: int) -> int: 6 | pointer = 0 7 | i = 1 8 | last_miss = 0 9 | while k and pointer < len(arr): 10 | while i < arr[pointer] and k: 11 | # print(i, arr[pointer]) 12 | last_miss = i 13 | i += 1 14 | k -= 1 15 | i += 1 16 | pointer += 1 17 | 18 | if k == 0: 19 | return last_miss + k 20 | return arr[-1] + k 21 | -------------------------------------------------------------------------------- /Python3/Array/KthMissingPositiveNumber/Naive2_1539.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def findKthPositive(self, arr: List[int], k: int) -> int: 6 | j = 0 7 | for i in range(1, arr[-1] + k + 1): 8 | if j < len(arr) and i == arr[j]: 9 | # print('match', i, k) 10 | j += 1 11 | else: 12 | # print('missing', i, k) 13 | k -= 1 14 | if k == 0: 15 | return i 16 | -------------------------------------------------------------------------------- /Python3/Array/KthSmallestElementInASortedMatrix/Naive378.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def kthSmallest(self, matrix: List[List[int]], k: int) -> int: 6 | array = [cell for row in matrix for cell in row] 7 | return sorted(array)[k - 1] 8 | 9 | # Runtime: 168 ms, faster than 80.33% of Python3 online submissions for Kth Smallest Element in a Sorted Matrix. 10 | # Memory Usage: 20.1 MB, less than 78.24% of Python3 online submissions for Kth Smallest Element in a Sorted Matrix. 11 | -------------------------------------------------------------------------------- /Python3/Array/KthSmallestElementInASortedMatrix/test_378.py: -------------------------------------------------------------------------------- 1 | from Naive378 import Solution as naive 2 | testcases = [ 3 | ([[1,5,9],[10,11,13],[12,13,15]], 8, 13), 4 | ([[-5]], 1, -5), 5 | ([[1,2],[1,3]], 2, 1), 6 | ([[1,3,5],[6,7,12],[11,14,14]], 5, 7) 7 | ] 8 | 9 | def test_naive(): 10 | for matrix, k, ans in testcases: 11 | assert naive().kthSmallest(matrix, k) == ans, f'{matrix}, {k}' 12 | -------------------------------------------------------------------------------- /Python3/Array/LargestDivisibleSubset/Note368.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daviddwlee84/LeetCode/ab240e071789bbc23b4b5c8d25f8af2587c1c40b/Python3/Array/LargestDivisibleSubset/Note368.md -------------------------------------------------------------------------------- /Python3/Array/LastStoneWeight/test_1046.py: -------------------------------------------------------------------------------- 1 | from Heap1046 import Solution as Heap 2 | from InsertionSort1046 import Solution as InsertionSort 3 | 4 | testcase = [ 5 | ([2, 7, 4, 1, 8, 1], 1), 6 | ([1], 1), 7 | ([], 0), 8 | ([2, 2], 0) 9 | ] 10 | 11 | 12 | def test_Heap(): 13 | for stones, ans in testcase: 14 | assert Heap().lastStoneWeight(stones) == ans 15 | 16 | 17 | def test_InsertionSort(): 18 | for stones, ans in testcase: 19 | assert InsertionSort().lastStoneWeight(stones) == ans 20 | -------------------------------------------------------------------------------- /Python3/Array/LongestCommonPrefix/Naive014.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def longestCommonPrefix(self, strs): 3 | """ 4 | :type strs: List[str] 5 | :rtype: str 6 | """ 7 | 8 | prefix = "" 9 | 10 | if len(strs) == 0: 11 | return prefix 12 | 13 | shortestlen = min(map(len, strs)) 14 | 15 | for i in range(shortestlen): 16 | temp = strs[0][i] 17 | for j in range(len(strs)): 18 | if strs[j][i] != temp: 19 | return prefix 20 | prefix += temp 21 | 22 | return prefix -------------------------------------------------------------------------------- /Python3/Array/LongestCommonPrefix/test_014.py: -------------------------------------------------------------------------------- 1 | from Naive014 import Solution as naive 2 | 3 | allstrs = [] 4 | allstrs.append(['flower', 'flow', 'flight']) 5 | allstrs.append(['dog', 'racecar', 'car']) 6 | 7 | ans = [] 8 | ans.append("fl") 9 | ans.append("") 10 | 11 | def test_naive(): 12 | for i, strs in enumerate(allstrs): 13 | assert naive().longestCommonPrefix(strs) == ans[i] 14 | -------------------------------------------------------------------------------- /Python3/Array/LongestConsecutiveSequence/test_128.py: -------------------------------------------------------------------------------- 1 | from Naive128 import Solution as naive 2 | 3 | testcase = [ 4 | ([100, 4, 200, 1, 3, 2], 4), 5 | ([0], 1), 6 | ([], 0) 7 | ] 8 | 9 | def test_naive(): 10 | for nums, ans in testcase: 11 | assert naive().longestConsecutive(nums) == ans 12 | -------------------------------------------------------------------------------- /Python3/Array/MajorityElement/Counter169.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from collections import Counter 3 | 4 | 5 | class Solution: 6 | def majorityElement(self, nums: List[int]) -> int: 7 | counts = Counter(nums) 8 | return max(counts.keys(), key=counts.get) 9 | -------------------------------------------------------------------------------- /Python3/Array/MajorityElement/Naive169.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from collections import defaultdict 3 | 4 | 5 | class Solution: 6 | def majorityElement(self, nums: List[int]) -> int: 7 | count = defaultdict(int) 8 | majority_count = len(nums) // 2 9 | 10 | for num in nums: 11 | count[num] += 1 12 | if count[num] > majority_count: 13 | return num 14 | 15 | # Runtime: 192 ms, faster than 23.83% of Python3 online submissions for Majority Element. 16 | # Memory Usage: 15.2 MB, less than 7.14% of Python3 online submissions for Majority Element. 17 | -------------------------------------------------------------------------------- /Python3/Array/MajorityElement/Sorting169.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def majorityElement(self, nums: List[int]) -> int: 6 | return sorted(nums)[len(nums)//2] 7 | -------------------------------------------------------------------------------- /Python3/Array/MatrixDiagonalSum/Better1572.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def diagonalSum(self, mat: List[List[int]]) -> int: 6 | ans = 0 7 | left = 0 8 | right = len(mat) - 1 9 | for row in mat: 10 | if left == right: 11 | ans += row[left] 12 | else: 13 | ans += row[left] + row[right] 14 | left += 1 15 | right -= 1 16 | return ans 17 | -------------------------------------------------------------------------------- /Python3/Array/MatrixDiagonalSum/Naive1572.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def diagonalSum(self, mat: List[List[int]]) -> int: 6 | n = len(mat) 7 | ans = 0 8 | indices = set() 9 | for i in range(n): 10 | # print(mat[i][i], mat[i][n - i - 1]) 11 | indices.add((i, i)) 12 | indices.add((i, n - i - 1)) 13 | for x, y in indices: 14 | ans += mat[x][y] 15 | return ans 16 | -------------------------------------------------------------------------------- /Python3/Array/MatrixDiagonalSum/test_1572.py: -------------------------------------------------------------------------------- 1 | from Naive1572 import Solution as Naive 2 | from Better1572 import Solution as Better 3 | 4 | testcases = [ 5 | ([[1, 2, 3], [4, 5, 6], [7, 8, 9]], 25), 6 | ([[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]], 8), 7 | ([[5]], 5), 8 | ] 9 | 10 | 11 | def test_Naive(): 12 | for mat, ans in testcases: 13 | assert Naive().diagonalSum(mat) == ans 14 | 15 | 16 | def test_Better(): 17 | for mat, ans in testcases: 18 | assert Better().diagonalSum(mat) == ans 19 | -------------------------------------------------------------------------------- /Python3/Array/MaxConsecutiveOnesIII/test_1004.py: -------------------------------------------------------------------------------- 1 | from Naive1004 import Solution as naive 2 | 3 | testcases = [ 4 | ([1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0], 2, 6), 5 | ([0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1], 3, 10), 6 | ([0, 0, 1, 1, 1, 0, 0, 1, 1], 0, 3), 7 | ] 8 | 9 | 10 | def test_naive(): 11 | for nums, k, ans in testcases: 12 | assert naive().longestOnes(nums, k) == ans 13 | -------------------------------------------------------------------------------- /Python3/Array/MaximalRectangle/Note085.md: -------------------------------------------------------------------------------- 1 | # 85. Maximal Rectangle 2 | 3 | ## Description 4 | 5 | Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area. 6 | 7 | **Example**: 8 | 9 | ```txt 10 | Input: 11 | [ 12 | ["1","0","1","0","0"], 13 | ["1","0","1","1","1"], 14 | ["1","1","1","1","1"], 15 | ["1","0","0","1","0"] 16 | ] 17 | Output: 6 18 | ``` 19 | 20 | ## Resources 21 | 22 | * [Subrectangles problems - Codeforces](https://codeforces.com/blog/entry/23613) 23 | * https://www.youtube.com/watch?v=g8bSdXCG-lA 24 | * https://www.youtube.com/watch?v=FO7VXDfS8Gk 25 | -------------------------------------------------------------------------------- /Python3/Array/MaximalSquare/Note221.md: -------------------------------------------------------------------------------- 1 | # 221. Maximal Square 2 | 3 | ## Description 4 | 5 | Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area. 6 | 7 | **Example**: 8 | 9 | ```txt 10 | Input: 11 | 12 | 1 0 1 0 0 13 | 1 0 1 1 1 14 | 1 1 1 1 1 15 | 1 0 0 1 0 16 | 17 | Output: 4 18 | ``` 19 | 20 | ## Solution 21 | 22 | ## Others' Solution 23 | 24 | * [Official](https://leetcode.com/problems/maximal-square/solution/) 25 | -------------------------------------------------------------------------------- /Python3/Array/MaximumBagsWithFullCapacityOfRocks/test_2279.py: -------------------------------------------------------------------------------- 1 | from Greedy2279 import Solution as Greedy 2 | 3 | testcases = [ 4 | ([2, 3, 4, 5], [1, 2, 4, 4], 2, 3), 5 | ([10, 2, 2], [2, 2, 0], 100, 3), 6 | ] 7 | 8 | 9 | def test_Greedy(): 10 | for capacity, rocks, additionalRocks, ans in testcases: 11 | assert Greedy().maximumBags(capacity, rocks, additionalRocks) == ans 12 | -------------------------------------------------------------------------------- /Python3/Array/MaximumDistanceInArrays/Naive624.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def maxDistance(self, arrays: List[List[int]]) -> int: 6 | max_distance = 0 7 | cur_min = float('inf') 8 | cur_max = -float('inf') 9 | 10 | for arr in arrays: 11 | max_distance = max(arr[-1] - cur_min, 12 | cur_max - arr[0], max_distance) 13 | cur_min = min(arr[0], cur_min) 14 | cur_max = max(arr[-1], cur_max) 15 | 16 | return max_distance 17 | -------------------------------------------------------------------------------- /Python3/Array/MaximumLengthOfRepeatedSubarray/test_718.py: -------------------------------------------------------------------------------- 1 | from DP718 import Solution as DP 2 | 3 | testcases = [ 4 | ([1, 2, 3, 2, 1], [3, 2, 1, 4, 7], 3), 5 | ([0, 0, 0, 0, 0], [0, 0, 0, 0, 0], 5), 6 | ([0, 1, 1, 1, 1], [1, 0, 1, 0, 1], 2), 7 | ] 8 | 9 | 10 | def test_DP(): 11 | for nums1, nums2, ans in testcases: 12 | assert DP().findLength(nums1, nums2) == ans 13 | -------------------------------------------------------------------------------- /Python3/Array/MaximumSubarray/DP053.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxSubArray(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | 8 | if not nums: 9 | return 0 10 | 11 | maxSum = curSum = nums[0] # Initialize 12 | 13 | for i in range(1, len(nums)): # Go through every elements 14 | curSum = nums[i]+curSum if curSum > 0 else nums[i] 15 | maxSum = max(maxSum, curSum) 16 | 17 | return maxSum -------------------------------------------------------------------------------- /Python3/Array/MaximumSubarray/Naive053.py: -------------------------------------------------------------------------------- 1 | # Brute force 2 | # LeetCode: Time Limit Exceeded 3 | class Solution: 4 | def maxSubArray(self, nums): 5 | """ 6 | :type nums: List[int] 7 | :rtype: int 8 | """ 9 | if not nums: 10 | return 0 11 | 12 | MAX = min(nums) 13 | for i in range(1, len(nums)+1): # i: compare length 14 | for j in range(len(nums)-i+1): # j: start position 15 | sumTemp = sum(nums[j:j+i+1]) # j to j+i+1 16 | if MAX < sumTemp: 17 | MAX = sumTemp 18 | 19 | return MAX -------------------------------------------------------------------------------- /Python3/Array/MaximumSumCircularSubarray/test_918.py: -------------------------------------------------------------------------------- 1 | from Naive918 import Solution as naive 2 | from MinSumSubarray918 import Solution as minSumSubarray 3 | 4 | testcase = [ 5 | ([1, -2, 3, -2], 3), 6 | ([5, -3, 5], 10), 7 | ([3, -1, 2, -1], 4), 8 | ([3, -2, 2, -3], 3), 9 | ([-2, -3, -1], -1) 10 | ] 11 | 12 | 13 | def test_naive(): 14 | for A, ans in testcase: 15 | assert naive().maxSubarraySumCircular(A) == ans 16 | 17 | 18 | def test_minSumSubarray(): 19 | for A, ans in testcase: 20 | assert minSumSubarray().maxSubarraySumCircular(A) == ans 21 | -------------------------------------------------------------------------------- /Python3/Array/MeetingRooms/Sorting252.py: -------------------------------------------------------------------------------- 1 | from interval import Interval 2 | from typing import List 3 | 4 | 5 | class Solution(object): 6 | def canAttendMeetings(self, intervals: List[Interval]) -> bool: 7 | """ 8 | :type intervals: List[Interval] 9 | :rtype: bool 10 | """ 11 | sortedInterval = sorted(intervals, key=lambda it: (it.start, it.end)) 12 | previuosEnd = 0 13 | for interval in sortedInterval: 14 | if previuosEnd > interval.start: 15 | return False 16 | previuosEnd = interval.end 17 | 18 | return True 19 | -------------------------------------------------------------------------------- /Python3/Array/MeetingRooms/interval.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Interval(object): 5 | def __init__(self, s=0, e=0): 6 | self.start = s 7 | self.end = e 8 | 9 | 10 | def listToInterval(lst: List[List[int]]) -> List[Interval]: 11 | return [Interval(start, end) for start, end in lst] 12 | -------------------------------------------------------------------------------- /Python3/Array/MeetingRooms/test_252.py: -------------------------------------------------------------------------------- 1 | from interval import listToInterval 2 | from Sorting252 import Solution as sorting 3 | 4 | testcase = [ 5 | (listToInterval([[0, 30], [5, 10], [15, 20]]), False), 6 | (listToInterval([[0, 5], [5, 10], [15, 20]]), True), 7 | ] 8 | 9 | 10 | def test_sorting(): 11 | for intervals, ans in testcase: 12 | assert sorting().canAttendMeetings(intervals) == ans 13 | -------------------------------------------------------------------------------- /Python3/Array/MeetingRoomsII/interval.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Interval(object): 5 | def __init__(self, s=0, e=0): 6 | self.start = s 7 | self.end = e 8 | 9 | 10 | def listToInterval(lst: List[List[int]]) -> List[Interval]: 11 | return [Interval(start, end) for start, end in lst] 12 | -------------------------------------------------------------------------------- /Python3/Array/MeetingRoomsII/test_253.py: -------------------------------------------------------------------------------- 1 | from interval import listToInterval 2 | from Sorting253 import Solution as sorting 3 | 4 | testcase = [ 5 | (listToInterval([[0, 30], [5, 10], [15, 20]]), 2), 6 | (listToInterval([[7, 10], [2, 4]]), 1), 7 | ] 8 | 9 | 10 | def test_sorting(): 11 | for intervals, ans in testcase: 12 | assert sorting().minMeetingRooms(intervals) == ans 13 | -------------------------------------------------------------------------------- /Python3/Array/MergeSortedArray/test_088.py: -------------------------------------------------------------------------------- 1 | from Naive088 import Solution as naive 2 | 3 | testcase = [ 4 | ([1, 2, 3, 0, 0, 0], 3, [2, 5, 6], 3, [1, 2, 2, 3, 5, 6]), 5 | ([4, 5, 6, 0, 0, 0], 3, [1, 2, 3], 3, [1, 2, 3, 4, 5, 6]), 6 | ([], 0, [], 0, []), 7 | ([0], 0, [87], 1, [87]), 8 | ([87], 1, [], 0, [87]) 9 | ] 10 | 11 | 12 | def test_naive(): 13 | for nums1, m, nums2, n, ans in testcase: 14 | naive().merge(nums1, m, nums2, n) # in-place 15 | assert nums1 == ans 16 | -------------------------------------------------------------------------------- /Python3/Array/MinimumNumberOfArrowsToBurstBalloons/test_452.py: -------------------------------------------------------------------------------- 1 | from Naive452 import Solution as naive 2 | 3 | testcase = [ 4 | ([[10, 16], [2, 8], [1, 6], [7, 12]], 2), 5 | ([[1, 2], [3, 4], [5, 6], [7, 8]], 4), 6 | ([[1, 2], [2, 3], [3, 4], [4, 5]], 2), 7 | ([[1, 2]], 1), 8 | ([[2, 3], [2, 3]], 1), 9 | ([[9, 12], [1, 10], [4, 11], [8, 12], [3, 9], [6, 9], [6, 7]], 2), 10 | ] 11 | 12 | 13 | def test_naive(): 14 | for points, ans in testcase: 15 | assert naive().findMinArrowShots(points) == ans 16 | -------------------------------------------------------------------------------- /Python3/Array/MinimumTimeToCompleteTrips/test_2187.py: -------------------------------------------------------------------------------- 1 | from BinarySearch2187 import Solution as BinarySearch 2 | 3 | testcases = [ 4 | ([1, 2, 3], 5, 3), 5 | ([2], 1, 2), 6 | ] 7 | 8 | 9 | def test_BinarySearch(): 10 | for time, totalTrips, ans in testcases: 11 | assert BinarySearch().minimumTime(time, totalTrips) == ans 12 | -------------------------------------------------------------------------------- /Python3/Array/MissingNumber/BitManipulation268.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def missingNumber(self, nums: List[int]) -> int: 6 | bit = 2 ** (len(nums) + 1) - 1 7 | for num in nums: 8 | bit ^= 1 << num 9 | 10 | ans = 0 11 | while bit != 1: 12 | ans += 1 13 | bit >>= 1 14 | 15 | return ans 16 | -------------------------------------------------------------------------------- /Python3/Array/MissingNumber/Naive268.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def missingNumber(self, nums: List[int]) -> int: 6 | for n in range(len(nums) + 1): 7 | if n not in nums: 8 | return n 9 | -------------------------------------------------------------------------------- /Python3/Array/MissingNumber/test_268.py: -------------------------------------------------------------------------------- 1 | from Naive268 import Solution as Naive 2 | from BitManipulation268 import Solution as BitManipulation 3 | 4 | testcases = [ 5 | ([3, 0, 1], 2), 6 | ([0, 1], 2), 7 | ([9, 6, 4, 2, 3, 5, 7, 0, 1], 8), 8 | ] 9 | 10 | 11 | def test_naive(): 12 | for nums, ans in testcases: 13 | assert Naive().missingNumber(nums) == ans 14 | 15 | 16 | def test_bit_manipulation(): 17 | for nums, ans in testcases: 18 | assert BitManipulation().missingNumber(nums) == ans 19 | -------------------------------------------------------------------------------- /Python3/Array/NextPermutation/test_031.py: -------------------------------------------------------------------------------- 1 | from SinglePass031 import Solution as SinglePass 2 | 3 | inputs = [ 4 | [1, 2, 3], 5 | [3, 2, 1], 6 | [1, 1, 5], 7 | [1], 8 | [1, 3, 2] 9 | ] 10 | 11 | answer = [ 12 | [1, 3, 2], 13 | [1, 2, 3], 14 | [1, 5, 1], 15 | [1], 16 | [2, 1, 3] 17 | ] 18 | 19 | def test_singlepass(): 20 | for i, nums in enumerate(inputs): 21 | SinglePass().nextPermutation(nums) 22 | assert nums == answer[i] 23 | -------------------------------------------------------------------------------- /Python3/Array/NumberOfWaysOfCuttingAPizza/test_1444.py: -------------------------------------------------------------------------------- 1 | from PrefixSumDP1444 import Solution as PrefixSumDP 2 | 3 | testcases = [ 4 | (["A..", "AAA", "..."], 3, 3), 5 | (["A..", "AA.", "..."], 3, 1), 6 | (["A..", "A..", "..."], 1, 1), 7 | ] 8 | 9 | 10 | def test_PrefixSumDP(): 11 | for pizza, k, ans in testcases: 12 | assert PrefixSumDP().ways(pizza, k) == ans 13 | -------------------------------------------------------------------------------- /Python3/Array/NumberOfZero-FilledSubarrays/SimplifiedMath2348.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def zeroFilledSubarray(self, nums: List[int]) -> int: 6 | ans, count = 0, 0 7 | 8 | for num in nums: 9 | if num: 10 | count = 0 11 | else: 12 | count += 1 13 | ans += count 14 | 15 | return ans 16 | -------------------------------------------------------------------------------- /Python3/Array/NumberOfZero-FilledSubarrays/test_2348.py: -------------------------------------------------------------------------------- 1 | from Math2348 import Solution as Math 2 | from SimplifiedMath2348 import Solution as SimplifiedMath 3 | 4 | testcases = [ 5 | ([1, 3, 0, 0, 2, 0, 0, 4], 6), 6 | ([0, 0, 0, 2, 0, 0], 9), 7 | ([2, 10, 2019], 0), 8 | ] 9 | 10 | 11 | def test_Math(): 12 | for nums, ans in testcases: 13 | assert Math().zeroFilledSubarray(nums) == ans 14 | 15 | 16 | def test_SimplifiedMath(): 17 | for nums, ans in testcases: 18 | assert SimplifiedMath().zeroFilledSubarray(nums) == ans 19 | -------------------------------------------------------------------------------- /Python3/Array/PairsOfSongsWithTotalDurationsDivisibleBy60/Naive1010.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from itertools import combinations 3 | 4 | 5 | class Solution: 6 | def numPairsDivisibleBy60(self, time: List[int]) -> int: 7 | count = 0 8 | for time_i, time_j in combinations(time, 2): 9 | if time_i + time_j % 60 == 0: 10 | count += 1 11 | 12 | return count 13 | -------------------------------------------------------------------------------- /Python3/Array/PalindromeNumber/Naive009.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isPalindrome(self, x): 3 | """ 4 | :type x: int 5 | :rtype: bool 6 | """ 7 | if x < 0: 8 | return False 9 | 10 | strx = str(x) 11 | 12 | for i in range(len(strx)//2): 13 | if(strx[i] != strx[len(strx)-i-1]): 14 | return False 15 | 16 | return True 17 | 18 | 19 | def main(): 20 | print(Solution().isPalindrome(123321)) 21 | 22 | if __name__ == '__main__': 23 | main() -------------------------------------------------------------------------------- /Python3/Array/PalindromeNumber/test_009.py: -------------------------------------------------------------------------------- 1 | from Naive009 import Solution as naive 2 | from NotString009 import Solution as notString 3 | 4 | def test_naive(): 5 | assert naive().isPalindrome(121) == True 6 | assert naive().isPalindrome(-121) == False 7 | assert naive().isPalindrome(10) == False 8 | assert naive().isPalindrome(123321) == True 9 | 10 | def test_notString(): 11 | assert notString().isPalindrome(121) == True 12 | assert notString().isPalindrome(-121) == False 13 | assert notString().isPalindrome(10) == False 14 | assert notString().isPalindrome(123321) == True -------------------------------------------------------------------------------- /Python3/Array/PascalsTriangle/test_118.py: -------------------------------------------------------------------------------- 1 | from Naive118 import Solution as naive 2 | 3 | PascalsTriangle = [ 4 | [1], 5 | [1,1], 6 | [1,2,1], 7 | [1,3,3,1], 8 | [1,4,6,4,1] 9 | ] 10 | 11 | def test_naive(): 12 | for numRows in range(6): 13 | assert naive().generate(numRows) == PascalsTriangle[:numRows] 14 | -------------------------------------------------------------------------------- /Python3/Array/PlusOne/FullAdder066.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | class Solution: 4 | def plusOne(self, digits: List[int]) -> List[int]: 5 | carry = 1 6 | new_digits = [] 7 | for digit in reversed(digits): 8 | carry, temp = self.fullAdder(digit, 0, carry) 9 | new_digits.append(temp) 10 | if carry: 11 | new_digits.append(1) 12 | 13 | return list(reversed(new_digits)) 14 | 15 | def fullAdder(self, A: int, B: int, Cin: int) -> List[int]: 16 | S = A + B + Cin 17 | return S // 10, S % 10 18 | -------------------------------------------------------------------------------- /Python3/Array/PlusOne/test_066.py: -------------------------------------------------------------------------------- 1 | from Naive066 import Solution as naive 2 | from FullAdder066 import Solution as fulladder 3 | 4 | testcase = [ 5 | ([1, 2, 3], [1, 2, 4]), 6 | ([4, 3, 2, 1], [4, 3, 2, 2]), 7 | ([9], [1, 0]) 8 | ] 9 | 10 | 11 | def test_naive(): 12 | for case, ans in testcase: 13 | assert naive().plusOne(case.copy()) == ans 14 | 15 | 16 | def test_fulladder(): 17 | for case, ans in testcase: 18 | assert fulladder().plusOne(case) == ans 19 | -------------------------------------------------------------------------------- /Python3/Array/ReduceArraySizeToTheHalf/Naive1338.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from collections import Counter 3 | 4 | 5 | class Solution: 6 | def minSetSize(self, arr: List[int]) -> int: 7 | counter = Counter(arr) 8 | set_size = 0 9 | total = 0 10 | for _, cnt in counter.most_common(): 11 | total += cnt 12 | set_size += 1 13 | if total >= len(arr) / 2: 14 | break 15 | return set_size 16 | -------------------------------------------------------------------------------- /Python3/Array/ReduceArraySizeToTheHalf/test_1338.py: -------------------------------------------------------------------------------- 1 | from Naive1338 import Solution as naive 2 | 3 | 4 | testcases = [ 5 | ([3, 3, 3, 3, 5, 5, 5, 2, 2, 7], 2), 6 | ([7, 7, 7, 7, 7, 7], 1), 7 | ([1, 9], 1), 8 | ([1000, 1000, 3, 7], 1), 9 | ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 5), 10 | ] 11 | 12 | 13 | def test_naive(): 14 | for arr, ans in testcases: 15 | assert naive().minSetSize(arr) == ans 16 | -------------------------------------------------------------------------------- /Python3/Array/RemoveCoveredIntervals/test_1288.py: -------------------------------------------------------------------------------- 1 | from Naive1288 import Solution as naive 2 | 3 | 4 | testcase = [ 5 | ([[1, 4], [2, 3]], 1), 6 | ([[0, 10], [5, 12]], 2), 7 | ([[3, 10], [4, 10], [5, 11]], 2), 8 | ([[1, 2], [1, 4], [3, 4]], 1), 9 | ([[34335, 39239], [15875, 91969], [29673, 66453], [53548, 69161], [40618, 93111]], 2), 10 | ] 11 | 12 | 13 | def test_naive(): 14 | for intervals, ans in testcase: 15 | assert naive().removeCoveredIntervals(intervals) == ans 16 | -------------------------------------------------------------------------------- /Python3/Array/RemoveDuplicatesfromSortedArray/Naive026.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def removeDuplicates(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | lastTemp = None 8 | for i in range(len(nums)): 9 | if nums[i] == lastTemp: 10 | lastTemp = nums[i] 11 | nums[i] = None 12 | else: 13 | lastTemp = nums[i] 14 | 15 | while None in nums: 16 | nums.remove(None) 17 | 18 | return len(nums) 19 | -------------------------------------------------------------------------------- /Python3/Array/RemoveElement/Naive027.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | class Solution: 4 | def removeElement(self, nums: List[int], val: int) -> int: 5 | startIdx = 0 6 | for i in range(len(nums)): 7 | if nums[i] != val: 8 | nums[startIdx] = nums[i] 9 | startIdx += 1 10 | return startIdx 11 | -------------------------------------------------------------------------------- /Python3/Array/RemoveElement/Naive2027.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | class Solution: 4 | def removeElement(self, nums: List[int], val: int) -> int: 5 | startIdx = 0 6 | endIdx = len(nums) 7 | 8 | while endIdx > startIdx: 9 | if nums[startIdx] == val: 10 | nums[startIdx] = nums[endIdx - 1] 11 | endIdx -= 1 # reduce array size by one 12 | else: 13 | startIdx += 1 14 | 15 | return endIdx 16 | -------------------------------------------------------------------------------- /Python3/Array/RestoreIPAddresses/Note93.md: -------------------------------------------------------------------------------- 1 | # 93. Restore IP Addresses 2 | 3 | ## Description 4 | 5 | Given a string containing only digits, restore it by returning all possible valid IP address combinations. 6 | 7 | **Example**: 8 | 9 | ```txt 10 | Input: "25525511135" 11 | Output: ["255.255.11.135", "255.255.111.35"] 12 | ``` 13 | 14 | ## Solution 15 | 16 | ### Backtracking 17 | -------------------------------------------------------------------------------- /Python3/Array/RestoreIPAddresses/test_093.py: -------------------------------------------------------------------------------- 1 | from Backtracking093 import Solution as backtracking 2 | 3 | testcase = [ 4 | ("25525511135", ["255.255.11.135", "255.255.111.35"]), 5 | ("0000", ["0.0.0.0"]), 6 | ("255255255255", ["255.255.255.255"]), 7 | ("010010", ["0.10.0.10","0.100.1.0"]), 8 | ("103574606193", []) 9 | ] 10 | 11 | def test_backtrack(): 12 | for s, ans in testcase: 13 | assert set(backtracking().restoreIpAddresses(s)) == set(ans) 14 | -------------------------------------------------------------------------------- /Python3/Array/ReverseInteger/test_007.py: -------------------------------------------------------------------------------- 1 | from Naive007 import Solution as naive 2 | 3 | def test_naive(): 4 | assert naive().reverse(123) == 321 5 | assert naive().reverse(-123) == -321 6 | assert naive().reverse(120) == 21 7 | assert naive().reverse(2**32-1) == 0 -------------------------------------------------------------------------------- /Python3/Array/RotateArray/Simplest189.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def rotate(self, nums, k): 3 | """ 4 | :type nums: List[int] 5 | :type k: int 6 | :rtype: void Do not return anything, modify nums in-place instead. 7 | """ 8 | length = len(nums) 9 | nums[:] = nums[(length-k)%length:] + nums[:(length-k)%length] 10 | 11 | -------------------------------------------------------------------------------- /Python3/Array/RotateArray/UseArray189.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def rotate(self, nums, k): 3 | """ 4 | :type nums: List[int] 5 | :type k: int 6 | :rtype: void Do not return anything, modify nums in-place instead. 7 | """ 8 | length = len(nums) 9 | tempArray = [None] * length 10 | 11 | for i in range (length): 12 | tempArray[(i+k) % length] = nums[i] 13 | 14 | for i in range(len(nums)): 15 | nums[i] = tempArray[i] 16 | -------------------------------------------------------------------------------- /Python3/Array/RunningSumOf1dArray/InPlace1480.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def runningSum(self, nums: List[int]) -> List[int]: 6 | for i in range(1, len(nums)): 7 | nums[i] += nums[i - 1] 8 | 9 | return nums 10 | -------------------------------------------------------------------------------- /Python3/Array/RunningSumOf1dArray/Naive1480.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def runningSum(self, nums: List[int]) -> List[int]: 6 | running_sum = [0] 7 | for num in nums: 8 | running_sum.append(running_sum[-1] + num) 9 | 10 | return running_sum[1:] 11 | -------------------------------------------------------------------------------- /Python3/Array/SearchInRotatedSortedArray/test_033.py: -------------------------------------------------------------------------------- 1 | from BinarySearch033 import Solution as BinarySearch 2 | 3 | input_answer = [ 4 | (([4, 5, 6, 7, 0, 1, 2], 0), 4), 5 | (([4, 5, 6, 7, 0, 1, 2], 3), -1), 6 | (([3, 1], 1), 1) 7 | ] 8 | 9 | def test_binarysearch(): 10 | for ((nums, target), answer) in input_answer: 11 | assert BinarySearch().search(nums, target) == answer 12 | -------------------------------------------------------------------------------- /Python3/Array/SingleElementInASortedArray/Naive540.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | class Solution: 4 | def singleNonDuplicate(self, nums: List[int]) -> int: 5 | stack = set() 6 | for num in nums: 7 | if num in stack: 8 | stack.remove(num) 9 | else: 10 | stack.add(num) 11 | 12 | return stack.pop() 13 | 14 | # Runtime: 80 ms, faster than 22.60% of Python3 online submissions for Single Element in a Sorted Array. 15 | # Memory Usage: 16.1 MB, less than 7.69% of Python3 online submissions for Single Element in a Sorted Array. 16 | -------------------------------------------------------------------------------- /Python3/Array/SingleElementInASortedArray/XOR540.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def singleNonDuplicate(self, nums: List[int]) -> int: 6 | bitmap = 0 7 | for num in nums: 8 | bitmap ^= num 9 | 10 | return bitmap 11 | -------------------------------------------------------------------------------- /Python3/Array/SingleNumber/BM136.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def singleNumber(self, nums: List[int]) -> int: 6 | a = 0 7 | for num in nums: 8 | # xor 9 | # the bit of the number itself will be reversed when xor 10 | a ^= num 11 | return a 12 | -------------------------------------------------------------------------------- /Python3/Array/SingleNumber/HT136.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def singleNumber(self, nums: List[int]) -> int: 6 | hashTable = {} 7 | 8 | for num in nums: 9 | if num in hashTable: 10 | # all the twice element will be pop 11 | hashTable.pop(num) 12 | else: 13 | # the first time 14 | hashTable[num] = 1 15 | 16 | return hashTable.popitem()[0] # should have only one element left 17 | -------------------------------------------------------------------------------- /Python3/Array/SingleNumber/Set136.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def singleNumber(self, nums: List[int]) -> int: 6 | temp = set() 7 | for num in nums: 8 | if num in temp: 9 | temp.remove(num) 10 | else: 11 | temp.add(num) 12 | 13 | return temp.pop() # will left only one item 14 | -------------------------------------------------------------------------------- /Python3/Array/SingleNumber/test_136.py: -------------------------------------------------------------------------------- 1 | from HT136 import Solution as HT 2 | from Set136 import Solution as Set 3 | from BM136 import Solution as BM 4 | 5 | testcase = [ 6 | ([2, 2, 1], 1), 7 | ([4, 1, 2, 1, 2], 4), 8 | ([3], 3) 9 | ] 10 | 11 | 12 | def test_HT(): 13 | for nums, ans in testcase: 14 | assert HT().singleNumber(nums) == ans 15 | 16 | 17 | def test_Set(): 18 | for nums, ans in testcase: 19 | assert Set().singleNumber(nums) == ans 20 | 21 | 22 | def test_BM(): 23 | for nums, ans in testcase: 24 | assert BM().singleNumber(nums) == ans 25 | -------------------------------------------------------------------------------- /Python3/Array/SingleNumberII/Math137.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def singleNumber(self, nums: List[int]) -> int: 6 | """ 7 | https://leetcode.com/problems/single-number-ii/discuss/700780/Python-Easy-to-understand-(beats-99.85-)-simple-maths 8 | """ 9 | return (3*sum(set(nums))-sum(nums))//2 10 | -------------------------------------------------------------------------------- /Python3/Array/SingleNumberIII/Naive260.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def singleNumber(self, nums: List[int]) -> List[int]: 6 | answer = set() 7 | for num in nums: 8 | if num in answer: 9 | answer.remove(num) 10 | else: 11 | answer.add(num) 12 | 13 | return list(answer) 14 | 15 | # Runtime: 56 ms, faster than 88.47% of Python3 online submissions for Single Number III. 16 | # Memory Usage: 15.7 MB, less than 11.45% of Python3 online submissions for Single Number III. 17 | -------------------------------------------------------------------------------- /Python3/Array/SingleNumberIII/test_260.py: -------------------------------------------------------------------------------- 1 | from Naive260 import Solution as naive 2 | from BitManipulation260 import Solution as bm 3 | 4 | testcase = [ 5 | ([1, 2, 1, 3, 2, 5], [3, 5]) 6 | ] 7 | 8 | 9 | def test_naive(): 10 | for nums, ans in testcase: 11 | assert sorted(naive().singleNumber(nums)) == sorted(ans) 12 | 13 | 14 | def test_bm(): 15 | for nums, ans in testcase: 16 | assert sorted(bm().singleNumber(nums)) == sorted(ans) 17 | -------------------------------------------------------------------------------- /Python3/Array/SortAnArray/HeapSort2_912.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def sortArray(self, nums: List[int]) -> List[int]: 6 | """ 7 | https://www.educative.io/answers/heap-implementation-in-python 8 | https://www.geeksforgeeks.org/min-heap-in-python/ 9 | https://medium.com/@hs_pedro/implementing-a-heap-in-python-1036e759e0eb 10 | """ 11 | pass -------------------------------------------------------------------------------- /Python3/Array/SortAnArray/HeapSort912.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import heapq 3 | 4 | 5 | class Solution: 6 | def sortArray(self, nums: List[int]) -> List[int]: 7 | heapq.heapify(nums) 8 | 9 | answer = [] 10 | 11 | while nums: 12 | answer.append(heapq.heappop(nums)) 13 | 14 | return answer 15 | -------------------------------------------------------------------------------- /Python3/Array/SortAnArray/MergeSort912.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def sortArray(self, nums: List[int]) -> List[int]: 6 | pass -------------------------------------------------------------------------------- /Python3/Array/SortAnArray/ThreeWayQuickSort912.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def sortArray(self, nums: List[int]) -> List[int]: 6 | """ 7 | https://www.geeksforgeeks.org/3-way-quicksort-dutch-national-flag/ 8 | """ 9 | pass 10 | -------------------------------------------------------------------------------- /Python3/Array/SortAnArray/test_912.py: -------------------------------------------------------------------------------- 1 | from QuickSort912 import Solution as QuickSort 2 | from HeapSort912 import Solution as HeapSort 3 | 4 | testcases = [ 5 | [5, 2, 3, 1], 6 | [5, 1, 1, 2, 0, 0], 7 | [1, 2, 3, 4], 8 | [4, 9, 4, 4, 1, 9, 4, 4, 9, 4, 4, 1, 4], 9 | ] 10 | 11 | 12 | # The worst case will TLE 13 | def test_QuickSort(): 14 | for nums in testcases: 15 | assert QuickSort().sortArray(nums.copy()) == sorted(nums) 16 | 17 | def test_HeapSort(): 18 | for nums in testcases: 19 | assert HeapSort().sortArray(nums.copy()) == sorted(nums) 20 | -------------------------------------------------------------------------------- /Python3/Array/SubarraySumEqualsK/BruteForce560.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def subarraySum(self, nums: List[int], k: int) -> int: 6 | """ 7 | Brute Force 8 | 9 | Time Complexity: O(n^3) 10 | Space Complexity: O(n) 11 | """ 12 | count = 0 13 | # Considering every possible subarray O(n^2) 14 | for start in range(len(nums)): 15 | for end in range(start + 1, len(nums) + 1): 16 | 17 | # Calculate sum O(n) 18 | if sum(nums[start:end]) == k: 19 | count += 1 20 | 21 | return count 22 | -------------------------------------------------------------------------------- /Python3/Array/SubarraySumEqualsK/WithoutSpace560.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def subarraySum(self, nums: List[int], k: int) -> int: 6 | """ 7 | Directly find the sum on the go while considering different end points 8 | 9 | Time Complexity: O(n^2) 10 | Space Complexity: O(1) 11 | """ 12 | count = 0 13 | for start in range(len(nums)): 14 | s = 0 15 | for end in range(start, len(nums)): 16 | s += nums[end] 17 | if s == k: 18 | count += 1 19 | 20 | return count 21 | -------------------------------------------------------------------------------- /Python3/Array/TaskScheduler/test_621.py: -------------------------------------------------------------------------------- 1 | from Naive621 import Solution as naive 2 | testcase = [ 3 | (["A", "A", "A", "B", "B", "B"], 2, 8), 4 | (["A", "A", "A", "B", "B", "B"], 0, 6), 5 | (["A", "A", "A", "A", "A", "A", "B", "C", "D", "E", "F", "G"], 2, 16), 6 | (["A", "A", "A", "B", "B", "B"], 3, 10), 7 | ] 8 | 9 | 10 | def test_naive(): 11 | for tasks, n, ans in testcase: 12 | assert naive().leastInterval(tasks, n) == ans 13 | -------------------------------------------------------------------------------- /Python3/Array/TopKFrequentElements/Naive347.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from collections import Counter 3 | 4 | 5 | class Solution: 6 | def topKFrequent(self, nums: List[int], k: int) -> List[int]: 7 | counts = Counter(nums) 8 | return sorted(counts, key=counts.get, reverse=True)[:k] 9 | -------------------------------------------------------------------------------- /Python3/Array/TransposeMatrix/Naive867.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def transpose(self, matrix: List[List[int]]) -> List[List[int]]: 6 | n, m = len(matrix), len(matrix[0]) 7 | new_matrix = [[0] * n for _ in range(m)] 8 | for i in range(n): 9 | for j in range(m): 10 | new_matrix[j][i] = matrix[i][j] 11 | return new_matrix 12 | -------------------------------------------------------------------------------- /Python3/Array/TransposeMatrix/Numpy867.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import numpy as np 3 | 4 | 5 | class Solution: 6 | def transpose(self, matrix: List[List[int]]) -> List[List[int]]: 7 | return np.array(matrix).T.tolist() 8 | -------------------------------------------------------------------------------- /Python3/Array/Triangle/test_120.py: -------------------------------------------------------------------------------- 1 | from Naive120 import Solution as naive 2 | 3 | testcase = [ 4 | ( 5 | [ 6 | [2], 7 | [3, 4], 8 | [6, 5, 7], 9 | [4, 1, 8, 3] 10 | ], 11 | 11 12 | ), 13 | ( 14 | [ 15 | [2], 16 | ], 17 | 2 18 | ), 19 | ] 20 | 21 | 22 | def test_naive(): 23 | for triangle, ans in testcase: 24 | assert naive().minimumTotal(triangle) == ans 25 | -------------------------------------------------------------------------------- /Python3/Array/TwoSum/Naive001.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def twoSum(self, nums, target): 3 | """ 4 | :type nums: List[int] 5 | :type target: int 6 | :rtype: List[int] 7 | """ 8 | 9 | for i in range(len(nums)): 10 | if i != len(nums): 11 | for j in range(i+1, len(nums)): 12 | if nums[i]+nums[j] == target: 13 | return [i, j] 14 | 15 | def main(): 16 | print(Solution().twoSum([2, 7, 11, 15], 9)) 17 | print(Solution().twoSum((-3, 4, 3, 90), 0)) 18 | 19 | if __name__ == "__main__": 20 | main() 21 | -------------------------------------------------------------------------------- /Python3/Array/TwoSumII/TwoPointer167.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | class Solution: 4 | def twoSum(self, numbers: List[int], target: int) -> List[int]: 5 | small = 0 6 | large = len(numbers)-1 7 | 8 | while large > small: 9 | if numbers[small] + numbers[large] > target: 10 | large -= 1 11 | elif numbers[small] + numbers[large] < target: 12 | small += 1 13 | else: 14 | break 15 | 16 | return [small+1, large+1] 17 | -------------------------------------------------------------------------------- /Python3/Array/TwoSumII/test_167.py: -------------------------------------------------------------------------------- 1 | from TwoPointer167 import Solution as twoPointer 2 | 3 | numbers = [] 4 | numbers.append([2, 7, 11, 15]) 5 | 6 | targets = [] 7 | targets.append(9) 8 | 9 | answer = [] 10 | answer.append([1, 2]) 11 | 12 | def test_twoPointer(): 13 | for nums, target, ans in zip(numbers, targets, answer): 14 | assert twoPointer().twoSum(nums, target) == ans 15 | -------------------------------------------------------------------------------- /Python3/Array/UniquePaths/Naive062.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | 4 | class Solution: 5 | def uniquePaths(self, m: int, n: int) -> int: 6 | m -= 1 7 | n -= 1 8 | # 57, 2 => 56.99999999999999 9 | return round(math.factorial(m + n) / math.factorial(n) / math.factorial(m)) 10 | 11 | # Runtime: 32 ms, faster than 57.17% of Python3 online submissions for Unique Paths. 12 | # Memory Usage: 13.7 MB, less than 85.45% of Python3 online submissions for Unique Paths. 13 | -------------------------------------------------------------------------------- /Python3/Array/UniquePaths/test_062.py: -------------------------------------------------------------------------------- 1 | from Naive062 import Solution as naive 2 | from DP062 import Solution as DP 3 | 4 | testcase = [ 5 | (3, 2, 3), 6 | (7, 3, 28), 7 | (57, 2, 57), 8 | ] 9 | 10 | 11 | def test_naive(): 12 | for m, n, ans in testcase: 13 | assert naive().uniquePaths(m, n) == ans 14 | 15 | 16 | def test_DP(): 17 | for m, n, ans in testcase: 18 | assert DP().uniquePaths(m, n) == ans 19 | -------------------------------------------------------------------------------- /Python3/Array/ValidTriangleNumber/BinarySearch2_611.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import bisect 3 | 4 | 5 | class Solution: 6 | def triangleNumber(self, nums: List[int]) -> int: 7 | nums.sort() 8 | 9 | answer = 0 10 | 11 | for i in range(len(nums) - 1): 12 | for j in range(i + 1, len(nums)): 13 | target = nums[i] + nums[j] 14 | 15 | # find the leftest edge of target 16 | left = bisect.bisect_left(nums, target, j + 1, len(nums)) 17 | length = left - j - 1 18 | 19 | answer += length 20 | 21 | return answer 22 | -------------------------------------------------------------------------------- /Python3/Array/ValidateStackSequences/test_946.py: -------------------------------------------------------------------------------- 1 | from Naive946 import Solution as Naive 2 | from Better946 import Solution as Better 3 | 4 | testcases = [ 5 | ([1, 2, 3, 4, 5], [4, 5, 3, 2, 1], True), 6 | ([1, 2, 3, 4, 5], [4, 3, 5, 1, 2], False), 7 | ([0, 2, 1], [0, 1, 2], True), 8 | ] 9 | 10 | 11 | def test_Naive(): 12 | for pushed, popped, ans in testcases: 13 | assert Naive().validateStackSequences(pushed, popped) == ans 14 | 15 | 16 | def test_Better(): 17 | for pushed, popped, ans in testcases: 18 | assert Better().validateStackSequences(pushed, popped) == ans 19 | -------------------------------------------------------------------------------- /Python3/Array/ZigZagConversion/test_006.py: -------------------------------------------------------------------------------- 1 | from Naive006 import Solution as naive 2 | 3 | def test_naive(): 4 | assert naive().convert("PAYPALISHIRING", 3) == "PAHNAPLSIIGYIR" 5 | assert naive().convert("PAYPALISHIRING", 4) == "PINALSIGYAHRPI" 6 | assert naive().convert("A", 1) == "A" 7 | assert naive().convert("", 1) == "" -------------------------------------------------------------------------------- /Python3/BinaryTree/BinaryTreeInorderTraversal/Note94.md: -------------------------------------------------------------------------------- 1 | # 94. Binary Tree Inorder Traversal 2 | 3 | ## Descripton 4 | 5 | Given a binary tree, return the *inorder* traversal of its nodes' values. 6 | 7 | **Example**: 8 | 9 | ``` 10 | Input: [1,null,2,3] 11 | 1 12 | \ 13 | 2 14 | / 15 | 3 16 | 17 | Output: [1,3,2] 18 | ``` 19 | 20 | **Follow up**: Recursive solution is trivial, could you do it iteratively? 21 | 22 | 23 | ## Solution 24 | 25 | ### Recursive 26 | 27 | 28 | ### Iterative 29 | 30 | * Stack 31 | 32 | 1. Push all left subtree into stack 33 | 2. Pop from stack and visit it 34 | 3. Go to right subtree 35 | -------------------------------------------------------------------------------- /Python3/BinaryTree/CountCompleteTreeNodes/Naive221.py: -------------------------------------------------------------------------------- 1 | from ..TreeNodeModule import TreeNode 2 | 3 | 4 | class Solution: 5 | def countNodes(self, root: TreeNode) -> int: 6 | if not root: 7 | return 0 8 | 9 | return 1 + self.countNodes(root.left) + self.countNodes(root.right) 10 | 11 | # Runtime: 92 ms, faster than 50.29% of Python3 online submissions for Count Complete Tree Nodes. 12 | # Memory Usage: 21.3 MB, less than 36.36% of Python3 online submissions for Count Complete Tree Nodes. 13 | -------------------------------------------------------------------------------- /Python3/BinaryTree/InvertBinaryTree/Recursive226.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | from BinaryTree.TreeNodeModule import TreeNode 3 | 4 | # Definition for a binary tree node. 5 | # class TreeNode: 6 | # def __init__(self, val=0, left=None, right=None): 7 | # self.val = val 8 | # self.left = left 9 | # self.right = right 10 | class Solution: 11 | def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]: 12 | if not root: 13 | return root 14 | 15 | root.left, root.right = self.invertTree(root.right), self.invertTree(root.left) 16 | 17 | return root 18 | -------------------------------------------------------------------------------- /Python3/BinaryTree/MaximumDepthofBinaryTree/BottomUp104.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxDepth(self, root): 3 | """ 4 | :type root: TreeNode 5 | :rtype: int 6 | """ 7 | 8 | if not root: 9 | return 0 10 | 11 | leftdepth = self.maxDepth(root.left) 12 | rightdepth = self.maxDepth(root.right) 13 | 14 | return max(leftdepth, rightdepth) + 1 15 | -------------------------------------------------------------------------------- /Python3/BinaryTree/PathSumII/Note113.md: -------------------------------------------------------------------------------- 1 | # 113. Path Sum II 2 | 3 | ## Description 4 | 5 | Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum. 6 | 7 | **Note**: A leaf is a node with no children. 8 | 9 | **Example**: 10 | 11 | Given the below binary tree and `sum = 22`, 12 | 13 | ```txt 14 | 5 15 | / \ 16 | 4 8 17 | / / \ 18 | 11 13 4 19 | / \ / \ 20 | 7 2 5 1 21 | ``` 22 | 23 | Return: 24 | 25 | ```txt 26 | [ 27 | [5,4,11,2], 28 | [5,8,4,5] 29 | ] 30 | ``` 31 | 32 | ## Solution 33 | 34 | ### DFS + Backtracking 35 | -------------------------------------------------------------------------------- /Python3/BinaryTree/UniqueBinarySearchTree/test_096.py: -------------------------------------------------------------------------------- 1 | from Naive096 import Solution as naive 2 | 3 | testcase = [ 4 | (3, 5), 5 | (0, 0), 6 | (1, 1), 7 | (2, 2) 8 | ] 9 | 10 | 11 | def test_naive(): 12 | for n, ans in testcase: 13 | assert naive().numTrees(n) == ans 14 | -------------------------------------------------------------------------------- /Python3/BinaryTree/__init__.py: -------------------------------------------------------------------------------- 1 | # Let unit test file can find the solutions under this directory -------------------------------------------------------------------------------- /Python3/BinaryTree/test_BinaryTreePaths.py: -------------------------------------------------------------------------------- 1 | from BinaryTree.BinaryTreePaths.Iterative257 import Solution as iterative 2 | from BinaryTree.BinaryTreePaths.Recursive257 import Solution as recursive 3 | import BinaryTree.TreeNodeModule as tn 4 | 5 | testtree = tn.stringToTreeNode("[1,2,3,null,5]") 6 | ans = ["1->2->5","1->3"] 7 | 8 | def test_iterative(): 9 | assert iterative().binaryTreePaths(testtree) == ans 10 | 11 | def test_recursive(): 12 | assert recursive().binaryTreePaths(testtree) == ans 13 | -------------------------------------------------------------------------------- /Python3/BinaryTree/test_BinaryTreeTilt.py: -------------------------------------------------------------------------------- 1 | from BinaryTree.TreeNodeModule import stringToTreeNode 2 | from BinaryTree.BinaryTreeTilt.Naive559 import Solution as naive 3 | 4 | testcase = [ 5 | ("[1,2,3]", 1), 6 | ("[1,2,3,2]", 3), 7 | ("[1,2,3,4,null,5]", 11), 8 | ] 9 | 10 | 11 | def test_naive(): 12 | for root_str, ans in testcase: 13 | assert naive().findTilt(stringToTreeNode(root_str)) == ans 14 | -------------------------------------------------------------------------------- /Python3/BinaryTree/test_FlattenBinaryTreeToLinkedList.py: -------------------------------------------------------------------------------- 1 | from BinaryTree.TreeNodeModule import stringToTreeNode, treeNodeToList 2 | from BinaryTree.FlattenBinaryTreeToLinkedList.Naive114 import Solution as naive 3 | 4 | testcase = [ 5 | (stringToTreeNode("[1,2,5,3,4,null,6]"), stringToTreeNode( 6 | "[1,null,2,null,3,null,4,null,5,null,6]")), 7 | (stringToTreeNode("[]"), stringToTreeNode("[]")), 8 | (stringToTreeNode("[1]"), stringToTreeNode("[1]")) 9 | ] 10 | 11 | 12 | def test_naive(): 13 | for root, ans in testcase: 14 | naive().flatten(root) 15 | assert treeNodeToList(root) == treeNodeToList(ans) 16 | -------------------------------------------------------------------------------- /Python3/BinaryTree/test_LCA.py: -------------------------------------------------------------------------------- 1 | from BinaryTree.LowestCommonAncestorofaBinaryTree.Naive236 import Solution as LCA_naive 2 | import BinaryTree.TreeNodeModule as tn 3 | 4 | testtree1 = tn.stringToTreeNode("[3,5,1,6,2,0,8,null,null,7,4]") 5 | p1 = tn.TreeNode(5) 6 | q1 = tn.TreeNode(1) 7 | ans1 = 3 8 | 9 | testtree2 = tn.stringToTreeNode("[3,5,1,6,2,0,8,null,null,7,4]") 10 | p2 = tn.TreeNode(5) 11 | q2 = tn.TreeNode(4) 12 | ans2 = 5 13 | 14 | def test_LCA_naive(): 15 | assert LCA_naive().lowestCommonAncestor(testtree1, p1, q1).val == ans1 16 | assert LCA_naive().lowestCommonAncestor(testtree2, p2, q2).val == ans2 -------------------------------------------------------------------------------- /Python3/BinaryTree/test_MaximumWidthOfBinaryTree.py: -------------------------------------------------------------------------------- 1 | from BinaryTree.TreeNodeModule import stringToTreeNode 2 | from BinaryTree.MaximumWidthOfBinaryTree.Naive662 import Solution as naive 3 | 4 | testcase = [ 5 | (stringToTreeNode("[1,3,2,5,3,null,9]"), 4), 6 | (stringToTreeNode("[1,1,1,1,null,null,1,1,null,null,1]"), 8), 7 | ] 8 | 9 | 10 | def test_naive(): 11 | for root, ans in testcase: 12 | assert naive().widthOfBinaryTree(root) == ans 13 | -------------------------------------------------------------------------------- /Python3/BinaryTree/test_MinimumDepthofBinaryTree.py: -------------------------------------------------------------------------------- 1 | from BinaryTree.MinimumDepthOfBinaryTree.BFS111 import Solution as BFS 2 | import BinaryTree.TreeNodeModule as tn 3 | 4 | raw_testcase = [ 5 | ("[]", 0), 6 | ("[1]", 1), 7 | ("[3,9,20,null,null,15,7]", 2) 8 | ] 9 | testcase = [(tn.stringToTreeNode(treeStr), ans) for treeStr, ans in raw_testcase] 10 | 11 | def test_BFS(): 12 | for root, ans in testcase: 13 | assert BFS().minDepth(root) == ans 14 | -------------------------------------------------------------------------------- /Python3/BinaryTree/test_PathSum.py: -------------------------------------------------------------------------------- 1 | from BinaryTree.PathSum.Naive112 import Solution as PathSum_Naive 2 | import BinaryTree.TreeNodeModule as tn 3 | 4 | testcase1 = tn.stringToTreeNode("[5,4,8,11,null,13,4,7,2,null,null,null,1]") 5 | sum1 = 22 6 | ans1 = True 7 | 8 | testcase2 = [] 9 | sum2 = 1 10 | ans2 = False 11 | 12 | testcase3 = tn.stringToTreeNode("[-2,null,-3]") 13 | sum3 = -5 14 | ans3 = True 15 | 16 | def test_PathSumNaive(): 17 | assert PathSum_Naive().hasPathSum(testcase1, sum1) == ans1 18 | assert PathSum_Naive().hasPathSum(testcase2, sum2) == ans2 19 | assert PathSum_Naive().hasPathSum(testcase3, sum3) == ans3 -------------------------------------------------------------------------------- /Python3/BitManipulation/BitwiseANDOfNumbersRange/Improve201.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | 4 | class Solution: 5 | def rangeBitwiseAnd(self, m: int, n: int) -> int: 6 | """ 7 | 2147483648 is 2^31 8 | https://leetcode.com/problems/bitwise-and-of-numbers-range/discuss/593317/Simple-3-line-Java-solution-faster-than-100 9 | """ 10 | while n > m: 11 | n &= n - 1 12 | 13 | return m & n 14 | -------------------------------------------------------------------------------- /Python3/BitManipulation/BitwiseANDOfNumbersRange/Naive201.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def rangeBitwiseAnd(self, m: int, n: int) -> int: 3 | answer = n 4 | for i in reversed(range(m, n)): 5 | answer &= i 6 | return answer 7 | 8 | # TLE 9 | -------------------------------------------------------------------------------- /Python3/BitManipulation/BitwiseANDOfNumbersRange/test_201.py: -------------------------------------------------------------------------------- 1 | from Naive201 import Solution as naive 2 | from Improve201 import Solution as improve 3 | 4 | testcase = [ 5 | (5, 7, 4), 6 | (0, 1, 0), 7 | (0, 2147483647, 0), 8 | (1, 2147483647, 0) 9 | ] 10 | 11 | 12 | # this takes too long 13 | # def test_naive(): 14 | # for m, n, ans in testcase: 15 | # assert naive().rangeBitwiseAnd(m, n) == ans 16 | 17 | 18 | def test_improve(): 19 | for m, n, ans in testcase: 20 | assert improve().rangeBitwiseAnd(m, n) == ans 21 | -------------------------------------------------------------------------------- /Python3/BitManipulation/ComplementOfBase10Integer/Pythonic1009.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def bitwiseComplement(self, N: int) -> int: 3 | # int(str, 2) => convert to base 10 from base 2 4 | # Use bin to get binary digits; Use XOR to reverse digit 5 | return int(''.join([str((int(c) ^ 1)) for c in bin(N)[2::]]), 2) 6 | 7 | # Runtime: 32 ms, faster than 49.35% of Python3 online submissions for Complement of Base 10 Integer. 8 | # Memory Usage: 14 MB, less than 15.35% of Python3 online submissions for Complement of Base 10 Integer. 9 | -------------------------------------------------------------------------------- /Python3/BitManipulation/CountingBits/Naive2_338.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def countBits(self, n: int) -> List[int]: 6 | ans = [] 7 | for i in range(n + 1): 8 | s = 0 9 | num = i 10 | while num != 0: 11 | s += num % 2 12 | num //= 2 13 | ans.append(s) 14 | 15 | return ans 16 | -------------------------------------------------------------------------------- /Python3/BitManipulation/CountingBits/Naive338.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def countBits(self, n: int) -> List[int]: 6 | ans = [] 7 | for i in range(n + 1): 8 | ans.append(str(bin(i))[2:].count('1')) 9 | return ans 10 | -------------------------------------------------------------------------------- /Python3/BitManipulation/CountingBits/test_338.py: -------------------------------------------------------------------------------- 1 | from Naive338 import Solution as Naive 2 | from Naive2_338 import Solution as Naive2 3 | 4 | testcases = [ 5 | (2, [0, 1, 1]), 6 | (5, [0, 1, 1, 2, 1, 2]), 7 | ] 8 | 9 | 10 | def test_naive(): 11 | for n, ans in testcases: 12 | assert Naive().countBits(n) == ans 13 | 14 | def test_naive2(): 15 | for n, ans in testcases: 16 | assert Naive2().countBits(n) == ans 17 | -------------------------------------------------------------------------------- /Python3/BitManipulation/HammingDistance/Naive461.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def hammingDistance(self, x: int, y: int) -> int: 3 | return sum(bit == "1" for bit in bin(x ^ y)[2:]) 4 | 5 | # Runtime: 32 ms, faster than 50.95% of Python3 online submissions for Hamming Distance. 6 | # Memory Usage: 14 MB, less than 5.44% of Python3 online submissions for Hamming Distance. 7 | 8 | # Other 9 | # https://leetcode.com/problems/hamming-distance/discuss/94697/Python-1-line-49ms 10 | 11 | # https://en.wikipedia.org/wiki/Hamming_distance 12 | # the symbols may be letters, bits, or digits, ... 13 | -------------------------------------------------------------------------------- /Python3/BitManipulation/NumberOf1Bits/Naive191.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def hammingWeight(self, n: int) -> int: 3 | s = 0 4 | while n: 5 | s += n & 1 6 | n >>= 1 7 | return s 8 | -------------------------------------------------------------------------------- /Python3/BitManipulation/ReverseBits/Naive190.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def reverseBits(self, n: int) -> int: 3 | reverse = 0 4 | bit = 32 5 | while bit: 6 | reverse <<= 1 7 | reverse |= n & 1 8 | n >>= 1 9 | bit -= 1 10 | return reverse 11 | -------------------------------------------------------------------------------- /Python3/BitManipulation/ReverseBits/String190.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def reverseBits(self, n: int) -> int: 3 | reverseStr = bin(n)[2:][::-1] 4 | reverseStr = '0b' + reverseStr + '0' * (32 - len(reverseStr)) 5 | return int(reverseStr, 2) 6 | -------------------------------------------------------------------------------- /Python3/BitManipulation/Subsets/Backtracking078.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def subsets(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: List[List[int]] 6 | """ 7 | answer = [] 8 | self.backtrack(answer, [], nums, 0) 9 | return answer 10 | 11 | def backtrack(self, answer, tempList, nums, start): 12 | answer.append(tempList.copy()) 13 | for i in range(start, len(nums)): 14 | tempList.append(nums[i]) 15 | self.backtrack(answer, tempList, nums, i + 1) 16 | tempList.remove(tempList[-1]) -------------------------------------------------------------------------------- /Python3/BitManipulation/Subsets/DFS078.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def subsets(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: List[List[int]] 6 | """ 7 | self.answer = [] 8 | self.helper([], 0, len(nums), nums) 9 | return self.answer 10 | 11 | def helper(self, currentSet, start, end, nums): 12 | if start == end: 13 | self.answer.append(currentSet) 14 | return 15 | self.helper(currentSet + [nums[start]], start+1, end, nums) # With num[start] 16 | self.helper(currentSet, start+1, end, nums) # Without num[start] 17 | -------------------------------------------------------------------------------- /Python3/BitManipulation/Subsets/Naive078.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def subsets(self, nums: List[int]) -> List[List[int]]: 6 | self.answer = [] 7 | self.nums = nums 8 | self.dfs([]) 9 | return self.answer 10 | 11 | def dfs(self, curr: List[int]): 12 | if len(curr) == len(self.nums): 13 | self.answer.append( 14 | [item for to_pick, item in zip(curr, self.nums) if to_pick]) 15 | return 16 | 17 | self.dfs(curr + [False]) 18 | self.dfs(curr + [True]) 19 | -------------------------------------------------------------------------------- /Python3/Design/DeleteColumnsToMakeSorted/Naive944.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def minDeletionSize(self, strs: List[str]) -> int: 6 | if not strs: 7 | return 0 8 | 9 | to_delete = 0 10 | n = len(strs[0]) 11 | # For each columns 12 | for i in range(n): 13 | temp = None 14 | for string in strs: 15 | if temp and ord(string[i]) < ord(temp): 16 | to_delete += 1 17 | break 18 | temp = string[i] 19 | 20 | return to_delete 21 | -------------------------------------------------------------------------------- /Python3/Design/ImplementQueueusingStacks/test_232.py: -------------------------------------------------------------------------------- 1 | from TwoStack232 import MyQueue as DoubleStack 2 | 3 | def test_DoubleStack(): 4 | obj = DoubleStack() 5 | obj.push(1) 6 | obj.push(2) 7 | assert obj.pop() == 1 8 | assert obj.peek() == 2 9 | assert obj.empty() == False 10 | -------------------------------------------------------------------------------- /Python3/Design/ImplementStackusingQueues/test_225.py: -------------------------------------------------------------------------------- 1 | from TwoQueue225 import MyStack as DoubleQueue 2 | 3 | def test_DoubleQueue(): 4 | obj = DoubleQueue() 5 | obj.push(3) 6 | obj.push(4) 7 | param_2 = obj.pop() 8 | param_3 = obj.top() 9 | param_4 = obj.empty() 10 | assert param_2 == 4 11 | assert param_3 == 3 12 | assert param_4 == False -------------------------------------------------------------------------------- /Python3/Design/ImplementTrie/test_208.py: -------------------------------------------------------------------------------- 1 | from Trie208 import Trie 2 | 3 | def test_trie(): 4 | trie = Trie() 5 | trie.insert("apple") 6 | assert trie.search("apple") == True 7 | assert trie.search("app") == False 8 | assert trie.startsWith("app") == True 9 | trie.insert("app") 10 | assert trie.search("app") == True -------------------------------------------------------------------------------- /Python3/Design/OnlineStockSpan/Naive901.py: -------------------------------------------------------------------------------- 1 | class StockSpanner: 2 | 3 | def __init__(self): 4 | self.data = [] 5 | 6 | def next(self, price: int) -> int: 7 | less_equal_than = 1 8 | for p in reversed(self.data): 9 | if p <= price: 10 | less_equal_than += 1 11 | else: 12 | break 13 | self.data.append(price) 14 | return less_equal_than 15 | 16 | 17 | # Your StockSpanner object will be instantiated and called as such: 18 | # obj = StockSpanner() 19 | # param_1 = obj.next(price) 20 | 21 | # TLE 22 | -------------------------------------------------------------------------------- /Python3/Design/RandomPickWithWeight/OnePass528.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import random 3 | 4 | 5 | class Solution: 6 | def __init__(self, w: List[int]): 7 | self.w = w 8 | 9 | def pickIndex(self) -> int: 10 | """ 11 | Constraint: You can only pass one time at each pickIndex() call 12 | """ 13 | curr_sum = 0 14 | answer = 0 15 | for i, num in enumerate(self.w): 16 | curr_sum += num 17 | if random.random() <= num / curr_sum: 18 | answer = i 19 | return answer 20 | -------------------------------------------------------------------------------- /Python3/DynamicProgramming/HouseRobber/DP198.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def rob(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | if not nums: 8 | return 0 9 | if len(nums) == 1: 10 | return nums[0] 11 | elif len(nums) == 2: 12 | return max(nums) 13 | else: 14 | houseRob = [nums[0], max(nums[:2])] # Initial status 15 | 16 | for i in range(2, len(nums)): 17 | houseRob.append(max(houseRob[i-2] + nums[i], houseRob[i-1])) 18 | 19 | return houseRob[-1] 20 | -------------------------------------------------------------------------------- /Python3/DynamicProgramming/HouseRobber/test_198.py: -------------------------------------------------------------------------------- 1 | from DP198 import Solution as DynamicProgramming 2 | 3 | testcase = [] 4 | testcase.append([1,2,3,1]) 5 | testcase.append([2,7,9,3,1]) 6 | testcase.append([2,1,1,2]) 7 | 8 | answer = [] 9 | answer.append(4) 10 | answer.append(12) 11 | answer.append(4) 12 | 13 | def test_DP(): 14 | for i, test in enumerate(testcase): 15 | assert DynamicProgramming().rob(test) == answer[i] 16 | -------------------------------------------------------------------------------- /Python3/Graph/AllPathsFromSourceToTarget/test_797.py: -------------------------------------------------------------------------------- 1 | from Naive797 import Solution as naive 2 | from Backtracking797 import Solution as backtracking 3 | 4 | testcase = [ 5 | ([[1, 2], [3], [3], []], [[0, 1, 3], [0, 2, 3]]), 6 | ([[]], [[0]]), 7 | ([[1], []], [[0, 1]]) 8 | ] 9 | 10 | 11 | def test_naive(): 12 | for graph, ans in testcase: 13 | assert sorted(naive().allPathsSourceTarget(graph)) == sorted(ans) 14 | 15 | 16 | def test_backtracking(): 17 | for graph, ans in testcase: 18 | assert sorted(backtracking().allPathsSourceTarget( 19 | graph)) == sorted(ans) 20 | -------------------------------------------------------------------------------- /Python3/Graph/ConstructQuadTree/Naive427.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | # Definition for a QuadTree node. 5 | class Node: 6 | def __init__(self, val, isLeaf, topLeft, topRight, bottomLeft, bottomRight): 7 | self.val = val 8 | self.isLeaf = isLeaf 9 | self.topLeft = topLeft 10 | self.topRight = topRight 11 | self.bottomLeft = bottomLeft 12 | self.bottomRight = bottomRight 13 | 14 | class Solution: 15 | def construct(self, grid: List[List[int]]) -> 'Node': 16 | pass 17 | 18 | -------------------------------------------------------------------------------- /Python3/Graph/IsGraphBipartite/test_785.py: -------------------------------------------------------------------------------- 1 | from Color785 import Solution as Color 2 | 3 | 4 | testcases = [ 5 | ([[1, 2, 3], [0, 2], [0, 1, 3], [0, 2]], False), 6 | ([[1, 3], [0, 2], [1, 3], [0, 2]], True), 7 | ] 8 | 9 | 10 | def test_color(): 11 | for case, ans in testcases: 12 | assert Color().isBipartite(case) == ans 13 | -------------------------------------------------------------------------------- /Python3/Graph/KeysAndRooms/DFS841.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | class Solution: 4 | def canVisitAllRooms(self, rooms: List[List[int]]) -> bool: 5 | visited = set() 6 | def dfs(room: int): 7 | visited.add(room) 8 | # print(room, visited) 9 | for neighbor in rooms[room]: 10 | if neighbor not in visited: 11 | dfs(neighbor) 12 | 13 | dfs(0) 14 | return len(visited) == len(rooms) 15 | -------------------------------------------------------------------------------- /Python3/Graph/KeysAndRooms/DFS_loop841.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def canVisitAllRooms(self, rooms: List[List[int]]) -> bool: 6 | dfs = [0] 7 | visited = set(dfs) 8 | while dfs: 9 | room = dfs.pop() 10 | visited.add(room) 11 | for neighbor in rooms[room]: 12 | if neighbor not in visited: 13 | dfs.append(neighbor) 14 | 15 | return len(visited) == len(rooms) 16 | -------------------------------------------------------------------------------- /Python3/Graph/KeysAndRooms/test_841.py: -------------------------------------------------------------------------------- 1 | from DFS841 import Solution as DFS 2 | from DFS_loop841 import Solution as DFS_loop 3 | 4 | testcases = [ 5 | ([[1], [2], [3], []], True), 6 | ([[1, 3], [3, 0, 1], [2], [0]], False), 7 | ] 8 | 9 | 10 | def test_dfs(): 11 | for rooms, ans in testcases: 12 | assert DFS().canVisitAllRooms(rooms) == ans 13 | 14 | 15 | def test_dfs_loop(): 16 | for rooms, ans in testcases: 17 | assert DFS_loop().canVisitAllRooms(rooms) == ans 18 | -------------------------------------------------------------------------------- /Python3/Graph/LongestCycleInAGraph/test_2360.py: -------------------------------------------------------------------------------- 1 | from DFSWithTime2360 import Solution as DFSWithTime 2 | 3 | testcases = [ 4 | ([3, 3, 4, 2, 3], 3), 5 | ([2, -1, 3, 1], -1), 6 | ([1, 2, 0, 4, 5, 6, 3, 8, 9, 7], 4), 7 | ] 8 | 9 | 10 | def test_DFSWithTime(): 11 | for edges, ans in testcases: 12 | assert DFSWithTime().longestCycle(edges) == ans 13 | -------------------------------------------------------------------------------- /Python3/Graph/LongestIncreasingPathInAMatrix/test_329.py: -------------------------------------------------------------------------------- 1 | from DFS329 import Solution as DFS 2 | 3 | testcase = [ 4 | ([[9,9,4],[6,6,8],[2,1,1]], 4), 5 | ([[3,4,5],[3,2,6],[2,2,1]], 4), 6 | ([[1]], 1), 7 | ] 8 | 9 | def test_DFS(): 10 | for matrix, ans in testcase: 11 | assert DFS().longestIncreasingPath(matrix) == ans 12 | -------------------------------------------------------------------------------- /Python3/Graph/MinimumScoreOfAPathBetweenTwoCities/test_2942.py: -------------------------------------------------------------------------------- 1 | from BFS2492 import Solution as BFS 2 | from UnionFind2492 import Solution as UnionFind 3 | 4 | testcases = [ 5 | (4, [[1, 2, 9], [2, 3, 6], [2, 4, 5], [1, 4, 7]], 5), 6 | (4, [[1, 2, 2], [1, 3, 4], [3, 4, 7]], 2), 7 | (4, [[1, 2, 9], [2, 3, 6], [2, 4, 5], [1, 4, 2]], 2), 8 | ] 9 | 10 | 11 | def test_BFS(): 12 | for n, roads, ans in testcases: 13 | assert BFS().minScore(n, roads) == ans 14 | 15 | 16 | def test_UnionFind(): 17 | for n, roads, ans in testcases: 18 | assert UnionFind().minScore(n, roads) == ans 19 | -------------------------------------------------------------------------------- /Python3/Graph/NumberOfEnclaves/test_1020.py: -------------------------------------------------------------------------------- 1 | from DFS1020 import Solution as DFS 2 | from SimplerDFS1020 import Solution as SimplerDFS 3 | 4 | testcases = [ 5 | ([[0, 0, 0, 0], 6 | [1, 0, 1, 0], 7 | [0, 1, 1, 0], 8 | [0, 0, 0, 0]], 3), 9 | ([[0, 1, 1, 0], 10 | [0, 0, 1, 0], 11 | [0, 0, 1, 0], 12 | [0, 0, 0, 0]], 0), 13 | ] 14 | 15 | 16 | def test_DFS(): 17 | for grid, ans in testcases: 18 | assert DFS().numEnclaves(grid) == ans 19 | 20 | 21 | def test_SimplerDFS(): 22 | for grid, ans in testcases: 23 | assert SimplerDFS().numEnclaves(grid) == ans 24 | -------------------------------------------------------------------------------- /Python3/Graph/NumberOfOperationsToMakeNetworkConnected/test_1319.py: -------------------------------------------------------------------------------- 1 | from DFS1319 import Solution as DFS 2 | 3 | testcases = [ 4 | (4, [[0, 1], [0, 2], [1, 2]], 1), 5 | (6, [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3]], 2), 6 | (6, [[0, 1], [0, 2], [0, 3], [1, 2]], -1), 7 | ] 8 | 9 | 10 | def test_DFS(): 11 | for n, connections, ans in testcases: 12 | assert DFS().makeConnected(n, connections) == ans 13 | -------------------------------------------------------------------------------- /Python3/Graph/__init__.py: -------------------------------------------------------------------------------- 1 | # Let unit test file can find the solutions under this directory -------------------------------------------------------------------------------- /Python3/LinkedList/DeleteNodeInALinkedList/Naive237.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | # class ListNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.next = None 6 | 7 | from ..ListNodeModule import ListNode 8 | 9 | class Solution: 10 | def deleteNode(self, node: ListNode) -> None: 11 | """ 12 | :type node: ListNode 13 | :rtype: void Do not return anything, modify node in-place instead. 14 | """ 15 | node.val = node.next.val 16 | node.next = node.next.next 17 | -------------------------------------------------------------------------------- /Python3/LinkedList/LinkedListCycle/Naive141.py: -------------------------------------------------------------------------------- 1 | from ..ListNodeModule import ListNode 2 | 3 | 4 | class Solution: 5 | def hasCycle(self, head: ListNode) -> bool: 6 | visited = set() 7 | while head: 8 | if head not in visited: 9 | visited.add(head) 10 | else: 11 | return True 12 | head = head.next 13 | 14 | return False 15 | 16 | # Runtime: 52 ms, faster than 58.52% of Python3 online submissions for Linked List Cycle. 17 | # Memory Usage: 16.4 MB, less than 100.00% of Python3 online submissions for Linked List Cycle. 18 | -------------------------------------------------------------------------------- /Python3/LinkedList/LinkedListCycle/TwoPointer2_141.py: -------------------------------------------------------------------------------- 1 | from ..ListNodeModule import ListNode 2 | 3 | 4 | # Definition for singly-linked list. 5 | # class ListNode: 6 | # def __init__(self, x): 7 | # self.val = x 8 | # self.next = None 9 | 10 | class Solution: 11 | def hasCycle(self, head: ListNode) -> bool: 12 | slow, fast = head, head 13 | while fast and fast.next: 14 | slow = slow.next 15 | fast = fast.next.next 16 | if slow == fast: 17 | return True 18 | return False 19 | -------------------------------------------------------------------------------- /Python3/LinkedList/LinkedListCycleII/Naive142.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from ..ListNodeModule import ListNode 3 | 4 | # Definition for singly-linked list. 5 | # class ListNode: 6 | # def __init__(self, x): 7 | # self.val = x 8 | # self.next = None 9 | 10 | class Solution: 11 | def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: 12 | visited = set() 13 | while head: 14 | visited.add(head) 15 | head = head.next 16 | if head in visited: 17 | return head 18 | return None 19 | -------------------------------------------------------------------------------- /Python3/LinkedList/MergeKSortedLists/run_heap.ps1: -------------------------------------------------------------------------------- 1 | cd ../.. 2 | python -m LinkedList.MergeKSortedLists.Heap023 3 | cd LinkedList/MergeKSortedLists -------------------------------------------------------------------------------- /Python3/LinkedList/MiddleOfTheLinkedList/Naive876.py: -------------------------------------------------------------------------------- 1 | from ..ListNodeModule import ListNode 2 | 3 | # Definition for singly-linked list. 4 | # class ListNode: 5 | # def __init__(self, x): 6 | # self.val = x 7 | # self.next = None 8 | 9 | class Solution: 10 | def middleNode(self, head: ListNode) -> ListNode: 11 | A = [head] 12 | while A[-1].next: 13 | A.append(A[-1].next) 14 | 15 | return A[len(A) // 2] 16 | -------------------------------------------------------------------------------- /Python3/LinkedList/MiddleOfTheLinkedList/TwoPointer876.py: -------------------------------------------------------------------------------- 1 | from ..ListNodeModule import ListNode 2 | 3 | # Definition for singly-linked list. 4 | # class ListNode: 5 | # def __init__(self, x): 6 | # self.val = x 7 | # self.next = None 8 | 9 | class Solution: 10 | def middleNode(self, head: ListNode) -> ListNode: 11 | slow = fast = head 12 | while fast and fast.next: 13 | slow = slow.next 14 | fast = fast.next.next 15 | 16 | return slow 17 | -------------------------------------------------------------------------------- /Python3/LinkedList/ReverseLinkedList/Iterative206.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | # class ListNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.next = None 6 | 7 | class Solution: 8 | def reverseList(self, head): 9 | """ 10 | :type head: ListNode 11 | :rtype: ListNode 12 | """ 13 | lastNode = None 14 | while head: 15 | nextNode = head.next 16 | head.next = lastNode 17 | lastNode = head 18 | head = nextNode 19 | 20 | return lastNode 21 | -------------------------------------------------------------------------------- /Python3/LinkedList/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daviddwlee84/LeetCode/ab240e071789bbc23b4b5c8d25f8af2587c1c40b/Python3/LinkedList/__init__.py -------------------------------------------------------------------------------- /Python3/LinkedList/run_AddTwoNumber.sh: -------------------------------------------------------------------------------- 1 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 2 | cd $DIR/.. 3 | python3 -m LinkedList.AddTwoNumbers.Naive002 -------------------------------------------------------------------------------- /Python3/LinkedList/test_AddTwoNumbers.py: -------------------------------------------------------------------------------- 1 | from LinkedList.ListNodeModule import listNodeConverter, compareListNode 2 | 3 | from LinkedList.AddTwoNumbers.Naive002 import Solution as naive 4 | 5 | def test_naive(): 6 | l1 = listNodeConverter([2, 4, 3]) 7 | l2 = listNodeConverter([5, 6, 4]) 8 | ans = listNodeConverter([7, 0, 8]) 9 | assert compareListNode(ans, naive().addTwoNumbers(l1, l2)) == True 10 | 11 | l1 = listNodeConverter([1, 8]) 12 | l2 = listNodeConverter([0]) 13 | ans = listNodeConverter([1, 8]) 14 | assert compareListNode(ans, naive().addTwoNumbers(l1, l2)) == True -------------------------------------------------------------------------------- /Python3/LinkedList/test_InsertionSortList.py: -------------------------------------------------------------------------------- 1 | from LinkedList.ListNodeModule import listNodeConverter, compareListNode 2 | from LinkedList.InsertionSortList.Naive147 import Solution as naive 3 | 4 | testcase = [ 5 | (listNodeConverter([4, 2, 1, 3]), listNodeConverter([1, 2, 3, 4])), 6 | (listNodeConverter([]), listNodeConverter([])), 7 | (listNodeConverter([1]), listNodeConverter([1])) 8 | ] 9 | 10 | 11 | def test_naive(): 12 | for head, ans in testcase: 13 | assert compareListNode(naive().insertionSortList(head), ans) 14 | -------------------------------------------------------------------------------- /Python3/LinkedList/test_RotateList.py: -------------------------------------------------------------------------------- 1 | from LinkedList.RotateList.Naive061 import Solution as naive 2 | from LinkedList.ListNodeModule import compareListNode, listNodeConverter 3 | 4 | testcase = [ 5 | ([1, 2, 3, 4, 5], 2, [4, 5, 1, 2, 3]), 6 | ([0, 1, 2], 4, [2, 0, 1]), 7 | ([1], 0, [1]) 8 | ] 9 | 10 | 11 | def test_naive(): 12 | for lst, k, ans in testcase: 13 | assert compareListNode(naive().rotateRight( 14 | listNodeConverter(lst), k), listNodeConverter(ans)) 15 | -------------------------------------------------------------------------------- /Python3/Math/AngleBetweenHandsOfAClock/Naive1344.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def angleClock(self, hour: int, minutes: int) -> float: 3 | hours_in_minutes = (hour % 12 + minutes / 60) * 5 4 | diff = abs(hours_in_minutes - minutes) 5 | diff = min(60 - diff, diff) 6 | return diff * 6 7 | -------------------------------------------------------------------------------- /Python3/Math/AngleBetweenHandsOfAClock/test_1344.py: -------------------------------------------------------------------------------- 1 | from Naive1344 import Solution as naive 2 | 3 | testcase = [ 4 | (12, 30, 165), 5 | (3, 30, 75), 6 | (3, 15, 7.5), 7 | (4, 50, 155), 8 | (12, 0, 0) 9 | ] 10 | 11 | 12 | def test_naive(): 13 | for hour, minutes, angle in testcase: 14 | assert round(naive().angleClock(hour, minutes), 5) == round(angle, 5) 15 | -------------------------------------------------------------------------------- /Python3/Math/ArrangingCoins/Math441.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def arrangeCoins(self, n: int) -> int: 3 | """ 4 | https://leetcode.com/problems/arranging-coins/solution/ 5 | 6 | Solve equation: 7 | 8 | k(k+1) <= 2N 9 | 10 | k = sqrt(2N + 1/4) - 1/2 11 | """ 12 | return int((2 * n + 0.25) ** 0.5 - 0.5) 13 | 14 | # Runtime: 32 ms, faster than 86.95% of Python3 online submissions for Arranging Coins. 15 | # Memory Usage: 13.6 MB, less than 96.67% of Python3 online submissions for Arranging Coins. 16 | -------------------------------------------------------------------------------- /Python3/Math/ArrangingCoins/Naive441.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def arrangeCoins(self, n: int) -> int: 3 | coins = 0 4 | layer = 0 5 | while coins < n: 6 | layer += 1 7 | coins += layer 8 | 9 | if coins > n: 10 | layer -= 1 11 | 12 | return layer 13 | 14 | # Runtime: 888 ms, faster than 42.18% of Python3 online submissions for Arranging Coins. 15 | # Memory Usage: 13.8 MB, less than 76.20% of Python3 online submissions for Arranging Coins. 16 | -------------------------------------------------------------------------------- /Python3/Math/CheckIfItIsAStraightLine/test_1232.py: -------------------------------------------------------------------------------- 1 | from Naive1232 import Solution as naive 2 | 3 | testcase = [ 4 | ([[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7]], True), 5 | ([[1, 1], [2, 2], [3, 4], [4, 5], [5, 6], [7, 7]], False), 6 | ([[-7, -3], [-7, -1], [-2, -2], [0, -8], [2, -2], [5, -6], [5, -5], [1, 7]], False), 7 | ([[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7]], True), 8 | ([[1, 2], [1, 3]], True), 9 | ([[1, 2]], False) 10 | ] 11 | 12 | 13 | def test_naive(): 14 | for coordinates, ans in testcase: 15 | assert naive().checkStraightLine(coordinates) == ans 16 | -------------------------------------------------------------------------------- /Python3/Math/NumberOfStepsToReduceANumberToZero/Naive2_1342.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def numberOfSteps(self, num: int) -> int: 3 | steps = 0 4 | while num: 5 | # https://www.geeksforgeeks.org/check-if-a-number-is-odd-or-even-using-bitwise-operators/ 6 | if num & 1: 7 | # odd 8 | num -= 1 9 | else: 10 | # even 11 | num >>= 1 12 | steps += 1 13 | return steps 14 | -------------------------------------------------------------------------------- /Python3/Math/PowXN/BitManipulation050.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def myPow(self, x: float, n: int) -> float: 3 | """ 4 | https://leetcode.com/problems/powx-n/discuss/19563/Iterative-Log(N)-solution-with-Clear-Explanation 5 | 6 | Note that 7 | if n & 1 was same as: if n % 2 8 | n >> 1 was same as : n //= 2 9 | """ 10 | ans = 1 11 | absN = abs(n) 12 | while absN > 0: 13 | if absN & 1: 14 | ans *= x 15 | absN >>= 1 16 | x *= x 17 | 18 | if n < 0: 19 | ans = 1 / ans 20 | 21 | return ans 22 | -------------------------------------------------------------------------------- /Python3/Math/PowXN/Naive050.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def myPow(self, x: float, n: int) -> float: 3 | if n < 0: 4 | n = -n 5 | x = 1/x 6 | 7 | ans = 1 8 | for _ in range(n): 9 | ans *= x 10 | 11 | return ans 12 | -------------------------------------------------------------------------------- /Python3/Math/PowerOfFour/Iterative342.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isPowerOfFour(self, n: int) -> bool: 3 | while n > 0: 4 | if n == 1: 5 | return True 6 | if n % 4 != 0: 7 | break 8 | n /= 4 9 | return False 10 | -------------------------------------------------------------------------------- /Python3/Math/PowerOfFour/Math342.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | 4 | class Solution: 5 | def isPowerOfFour(self, n: int) -> bool: 6 | if n <= 0: 7 | return False 8 | num = math.log(n, 4) 9 | return num == int(num) 10 | -------------------------------------------------------------------------------- /Python3/Math/PowerOfFour/Recursive342.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isPowerOfFour(self, n: int) -> bool: 3 | if n == 1: 4 | return True 5 | 6 | if n % 4 != 0 or n <= 0: 7 | return False 8 | 9 | return self.isPowerOfFour(n / 4) 10 | -------------------------------------------------------------------------------- /Python3/Math/PowerOfTwo/BitManipulation231.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isPowerOfTwo(self, n: int) -> bool: 3 | return (n and not (n & (n - 1))) 4 | 5 | # Runtime: 32 ms, faster than 60.00% of Python3 online submissions for Power of Two. 6 | # Memory Usage: 13.6 MB, less than 95.45% of Python3 online submissions for Power of Two. 7 | -------------------------------------------------------------------------------- /Python3/Math/PowerOfTwo/Naive231.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isPowerOfTwo(self, n: int) -> bool: 3 | reach_one = False 4 | while n: 5 | if n & 1: 6 | if not reach_one: 7 | reach_one = True 8 | else: 9 | return False 10 | n = n >> 1 11 | 12 | # 0 case, so don't direct return True 13 | return reach_one 14 | 15 | # Runtime: 40 ms, faster than 15.33% of Python3 online submissions for Power of Two. 16 | # Memory Usage: 13.7 MB, less than 77.41% of Python3 online submissions for Power of Two. 17 | -------------------------------------------------------------------------------- /Python3/Math/PowerOfTwo/String231.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isPowerOfTwo(self, n: int) -> bool: 3 | """ 4 | Bit Count 5 | """ 6 | if n < 0: 7 | return False 8 | 9 | one_count = sum(char == '1' for char in bin(n)[2:]) 10 | return one_count == 1 11 | 12 | # Runtime: 32 ms, faster than 60.00% of Python3 online submissions for Power of Two. 13 | # Memory Usage: 13.8 MB, less than 59.26% of Python3 online submissions for Power of Two. 14 | -------------------------------------------------------------------------------- /Python3/Math/PowerOfTwo/test_231.py: -------------------------------------------------------------------------------- 1 | from Naive231 import Solution as naive 2 | from String231 import Solution as string 3 | 4 | testcase = [ 5 | (0, False), 6 | (1, True), 7 | (2, True), 8 | (16, True), 9 | (218, False), 10 | (-16, False) 11 | ] 12 | 13 | 14 | def test_naive(): 15 | for n, ans in testcase: 16 | assert naive().isPowerOfTwo(n) == ans 17 | 18 | 19 | def test_string(): 20 | for n, ans in testcase: 21 | assert string().isPowerOfTwo(n) == ans 22 | -------------------------------------------------------------------------------- /Python3/Math/SignOfTheProductOfAnArray/Better1822.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def arraySign(self, nums: List[int]) -> int: 6 | negative_count = 0 7 | 8 | for num in nums: 9 | if num == 0: 10 | return 0 11 | 12 | if num < 0: 13 | negative_count += 1 14 | 15 | return 1 if negative_count % 2 == 0 else -1 16 | -------------------------------------------------------------------------------- /Python3/Math/SignOfTheProductOfAnArray/Python1822.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from functools import reduce 3 | from operator import mul 4 | 5 | 6 | class Solution: 7 | def arraySign(self, nums: List[int]) -> int: 8 | def signFunc(x: int) -> int: 9 | if x == 0: 10 | return 0 11 | elif x > 0: 12 | return 1 13 | else: 14 | return -1 15 | 16 | # Somewhat equivalent 17 | # (this can avoid overflow issue in C/C++) 18 | # return reduce(mul, map(signFunc, nums)) 19 | 20 | return signFunc(reduce(mul, nums)) 21 | -------------------------------------------------------------------------------- /Python3/Math/UglyNumber/Naive263.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isUgly(self, num: int) -> bool: 3 | if num <= 0: 4 | return False 5 | 6 | factors = [2, 3, 5] 7 | for factor in factors: 8 | while num % factor == 0: 9 | num //= factor 10 | 11 | return num == 1 12 | 13 | # Runtime: 40 ms, faster than 20.55% of Python3 online submissions for Ugly Number. 14 | # Memory Usage: 14 MB, less than 11.24% of Python3 online submissions for Ugly Number. 15 | -------------------------------------------------------------------------------- /Python3/Math/UglyNumber/test_263.py: -------------------------------------------------------------------------------- 1 | from Naive263 import Solution as naive 2 | 3 | testcase = [ 4 | (6, True), 5 | (8, True), 6 | (14, False), 7 | (-2, False), 8 | (0, False) 9 | ] 10 | 11 | 12 | def test_naive(): 13 | for num, ans in testcase: 14 | assert naive().isUgly(num) == ans 15 | -------------------------------------------------------------------------------- /Python3/Math/UglyNumberII/test_264.py: -------------------------------------------------------------------------------- 1 | from PriorityQueue264 import Solution as pq 2 | from DP264 import Solution as dp 3 | 4 | testcase = [ 5 | (11, 15), 6 | (10, 12), 7 | (9, 10), 8 | (8, 9), 9 | (7, 8), 10 | (6, 6), 11 | (5, 5), 12 | (4, 4), 13 | (3, 3), 14 | (2, 2), 15 | (1, 1) 16 | ] 17 | 18 | 19 | def test_pq(): 20 | for n, ans in testcase: 21 | assert pq().nthUglyNumber(n) == ans 22 | 23 | 24 | def test_dp(): 25 | for n, ans in testcase: 26 | assert dp().nthUglyNumber(n) == ans 27 | -------------------------------------------------------------------------------- /Python3/Math/ValidPerfectSquare/Naive367.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isPerfectSquare(self, num: int) -> bool: 3 | for i in range(1, num + 1): 4 | if i * i > num: 5 | return False 6 | elif i * i == num: 7 | return True 8 | 9 | # Runtime: 32 ms, faster than 46.70% of Python3 online submissions for Valid Perfect Square. 10 | # Memory Usage: 14 MB, less than 10.00% of Python3 online submissions for Valid Perfect Square. 11 | -------------------------------------------------------------------------------- /Python3/Search/PerfectSquares/BottomUpDP279.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | 3 | dp = [0] # dp[i]: least number of square numbers that sum to i 4 | 5 | def numSquares(self, n: int) -> int: 6 | while len(self.dp) <= n: 7 | length = len(self.dp) 8 | minimum = float('inf') 9 | for j in range(1, n + 1): 10 | if j ** 2 > length: 11 | break 12 | 13 | minimum = min(minimum, self.dp[length - j ** 2] + 1) 14 | 15 | self.dp.append(minimum) 16 | 17 | return self.dp[n] 18 | -------------------------------------------------------------------------------- /Python3/Search/Sqrt_x/BinarySearch3_069.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def mySqrt(self, x: int) -> int: 3 | left, right = 1, x 4 | while left <= right: 5 | mid = (left + right) // 2 6 | square = mid * mid 7 | if square == x: 8 | return mid 9 | elif square < x: 10 | left = mid + 1 11 | else: 12 | right = mid - 1 13 | return right 14 | 15 | # Runtime: 32 ms, faster than 79.57% of Python3 online submissions for Sqrt(x). 16 | # Memory Usage: 14 MB, less than 6.45% of Python3 online submissions for Sqrt(x). 17 | -------------------------------------------------------------------------------- /Python3/Search/Sqrt_x/test_069.py: -------------------------------------------------------------------------------- 1 | from Naive069 import Solution as Naive 2 | from BinarySearch069 import Solution as BinarySearch 3 | 4 | testcase = [ 5 | (4, 2), 6 | (8, 2), 7 | (0, 0), 8 | (1, 1), 9 | (2, 1) 10 | ] 11 | 12 | def test_naive(): 13 | for x, ans in testcase: 14 | assert Naive().mySqrt(x) == ans 15 | 16 | def test_binary_search(): 17 | for x, ans in testcase: 18 | assert BinarySearch().mySqrt(x) == ans 19 | -------------------------------------------------------------------------------- /Python3/String/AddBinary/Python067.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def addBinary(self, a: str, b: str) -> str: 3 | return bin(eval(f'0b{a}') + eval(f'0b{b}'))[2:] 4 | -------------------------------------------------------------------------------- /Python3/String/AddBinary/test_067.py: -------------------------------------------------------------------------------- 1 | from Adder067 import Solution as Adder 2 | from Iterative067 import Solution as Iterative 3 | from Python067 import Solution as Python 4 | 5 | testcase = [ 6 | ('11', '1', '100'), 7 | ('1010', '1011', '10101') 8 | ] 9 | 10 | 11 | def test_adder(): 12 | for a, b, ans in testcase: 13 | assert Adder().addBinary(a, b) == ans 14 | 15 | 16 | def test_iterative(): 17 | for a, b, ans in testcase: 18 | assert Iterative().addBinary(a, b) == ans 19 | 20 | 21 | def test_python(): 22 | for a, b, ans in testcase: 23 | assert Python().addBinary(a, b) == ans 24 | -------------------------------------------------------------------------------- /Python3/String/BackspaceStringCompare/Naive844.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def backspaceCompare(self, S: str, T: str) -> bool: 6 | return self.getString(S) == self.getString(T) 7 | 8 | def getString(self, string: str) -> List[str]: 9 | stack = [] 10 | for c in string: 11 | if len(stack) > 0 and c == '#': 12 | stack.pop() 13 | elif c != '#': 14 | stack.append(c) 15 | return stack 16 | -------------------------------------------------------------------------------- /Python3/String/BackspaceStringCompare/TwoPointer844.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | 3 | 4 | class Solution: 5 | def backspaceCompare(self, S: str, T: str) -> bool: 6 | """ https://leetcode.com/problems/backspace-string-compare/solution/ """ 7 | 8 | def F(S: str): 9 | skip = 0 10 | for x in reversed(S): 11 | if x == '#': 12 | skip += 1 13 | elif skip: 14 | skip -= 1 15 | else: 16 | yield x 17 | 18 | return all(x == y for x, y in itertools.zip_longest(F(S), F(T))) 19 | -------------------------------------------------------------------------------- /Python3/String/BackspaceStringCompare/test_844.py: -------------------------------------------------------------------------------- 1 | from Naive844 import Solution as naive 2 | from TwoPointer844 import Solution as twoPointer 3 | 4 | testcase = [ 5 | ("ab#c", "ab#c", True), 6 | ("ab##", "c#d#", True), 7 | ("a##c", "#a#c", True), 8 | ("a#c", "b", False), 9 | ("y#fo##f", "y#f#o##f", True) 10 | ] 11 | 12 | 13 | def test_naive(): 14 | for S, T, ans in testcase: 15 | assert naive().backspaceCompare(S, T) == ans 16 | 17 | 18 | def test_twoPointer(): 19 | for S, T, ans in testcase: 20 | assert twoPointer().backspaceCompare(S, T) == ans 21 | -------------------------------------------------------------------------------- /Python3/String/BuddyStrings/test_859.py: -------------------------------------------------------------------------------- 1 | from Naive859 import Solution as naive 2 | from Naive2_859 import Solution as naive2 3 | 4 | testcase = [ 5 | ('ab', 'ba', True), 6 | ('ab', 'ab', False), 7 | ('aa', 'aa', True), 8 | ('aaaaaaabc', 'aaaaaaacb', True), 9 | ('', 'aa', False), 10 | ] 11 | 12 | 13 | def test_naive(): 14 | for A, B, ans in testcase: 15 | assert naive().buddyStrings(A, B) == ans 16 | 17 | def test_naive2(): 18 | for A, B, ans in testcase: 19 | assert naive2().buddyStrings(A, B) == ans 20 | -------------------------------------------------------------------------------- /Python3/String/CountAndSay/test_038.py: -------------------------------------------------------------------------------- 1 | from Naive038 import Solution as Naive 2 | 3 | answer = [ 4 | "1", 5 | "11", 6 | "21", 7 | "1211", 8 | "111221", 9 | "312211" 10 | ] 11 | 12 | 13 | def test_naive(): 14 | for i, ans in enumerate(answer): 15 | assert Naive().countAndSay(i+1) == ans 16 | -------------------------------------------------------------------------------- /Python3/String/DetectCapital/CapitalCount520.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def detectCapitalUse(self, word: str) -> bool: 3 | caps = 0 4 | for char in word: 5 | caps += int(char.isupper()) 6 | 7 | return (word[0].isupper() and caps == 1) or len(word) == caps or caps == 0 8 | -------------------------------------------------------------------------------- /Python3/String/DetectCapital/RegEx520.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | 4 | class Solution: 5 | def detectCapitalUse(self, word: str) -> bool: 6 | return re.fullmatch(r"[A-Z]*|.[a-z]*", word) is not None 7 | -------------------------------------------------------------------------------- /Python3/String/GenerateParentheses/Note022.md: -------------------------------------------------------------------------------- 1 | # 22. Generate Parentheses 2 | 3 | ## Description 4 | 5 | Given *n* pairs of parentheses, write a function to generate all combinations of well-formed parentheses. 6 | 7 | For example, given *n* = 3, a solution set is: 8 | 9 | ```txt 10 | [ 11 | "((()))", 12 | "(()())", 13 | "(())()", 14 | "()(())", 15 | "()()()" 16 | ] 17 | ``` 18 | 19 | ## Solution 20 | 21 | ### Brute Force 22 | 23 | * Find all permutaiton 24 | * Delete all invalid 25 | 26 | ### Backtracking 27 | -------------------------------------------------------------------------------- /Python3/String/GenerateParentheses/test_022.py: -------------------------------------------------------------------------------- 1 | from Backtracking022 import Solution as Backtracking 2 | 3 | ns = [] 4 | ns.append(3) 5 | 6 | answer = [] 7 | answer.append([ 8 | "((()))", 9 | "(()())", 10 | "(())()", 11 | "()(())", 12 | "()()()" 13 | ]) 14 | 15 | def test_backtracking(): 16 | for i, n in enumerate(ns): 17 | assert sorted(Backtracking().generateParenthesis(n)) == sorted(answer[i]) 18 | -------------------------------------------------------------------------------- /Python3/String/GreatestCommonDivisorOfStrings/Naive1071.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | 4 | class Solution: 5 | def gcdOfStrings(self, str1: str, str2: str) -> str: 6 | gcd = math.gcd(len(str1), len(str2)) 7 | 8 | while gcd: 9 | if len(str1) % gcd != 0 or len(str2) % gcd != 0: 10 | gcd -= 1 11 | continue 12 | 13 | pattern = str1[:gcd] 14 | 15 | if pattern * (len(str1) // gcd) == str1 and pattern * (len(str2) // gcd) == str2: 16 | return pattern 17 | 18 | gcd -= 1 19 | 20 | return '' 21 | -------------------------------------------------------------------------------- /Python3/String/GreatestCommonDivisorOfStrings/test_1071.py: -------------------------------------------------------------------------------- 1 | from Naive1071 import Solution as Naive 2 | 3 | 4 | testcases = [ 5 | ('ABCABC', 'ABC', 'ABC'), 6 | ('ABABAB', 'ABAB', 'AB'), 7 | ('LEET', 'CODE', ''), 8 | ('TAUXXTAUXXTAUXXTAUXXTAUXX', 'TAUXXTAUXXTAUXXTAUXXTAUXXTAUXXTAUXXTAUXXTAUXX', 'TAUXX'), 9 | ] 10 | 11 | 12 | def test_naive(): 13 | for str1, str2, ans in testcases: 14 | assert Naive().gcdOfStrings(str1, str2) == ans 15 | -------------------------------------------------------------------------------- /Python3/String/GroupAnagrams/Counter049.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | from collections import defaultdict 4 | 5 | class Solution: 6 | def groupAnagrams(self, strs: List[str]) -> List[List[str]]: 7 | group_counter = defaultdict(list) 8 | for string in strs: 9 | # counter for each English letter 10 | count = [0] * 26 11 | for char in string: 12 | count[ord(char) - ord('a')] += 1 13 | group_counter[tuple(count)].append(string) 14 | return group_counter.values() 15 | -------------------------------------------------------------------------------- /Python3/String/GroupAnagrams/Sorting049.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | from collections import defaultdict 4 | 5 | class Solution: 6 | def groupAnagrams(self, strs: List[str]) -> List[List[str]]: 7 | ans = defaultdict(list) 8 | for string in strs: 9 | ans[tuple(sorted(string))].append(string) 10 | return ans.values() 11 | -------------------------------------------------------------------------------- /Python3/String/Implement_strStr/Naive028.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def strStr(self, haystack: str, needle: str) -> int: 3 | index = -1 4 | if haystack == needle: 5 | index = 0 6 | else: 7 | for i in range(len(haystack)): 8 | if haystack[i:i+len(needle)] == needle: 9 | index = i 10 | break 11 | return index 12 | -------------------------------------------------------------------------------- /Python3/String/Implement_strStr/test_028.py: -------------------------------------------------------------------------------- 1 | from Naive028 import Solution as naive 2 | 3 | haystacks = [] 4 | haystacks.append("hello") 5 | haystacks.append("aaaaa") 6 | haystacks.append("") 7 | haystacks.append("aaa") 8 | 9 | needles = [] 10 | needles.append("ll") 11 | needles.append("bba") 12 | needles.append("") 13 | haystacks.append("a") 14 | 15 | answers = [] 16 | answers.append(2) 17 | answers.append(-1) 18 | answers.append(0) 19 | answers.append(0) 20 | 21 | 22 | def test_naive(): 23 | for haystack, needle, answer in zip(haystacks, needles, answers): 24 | assert naive().strStr(haystack, needle) == answer 25 | -------------------------------------------------------------------------------- /Python3/String/IntegerToRoman/Naive012.py: -------------------------------------------------------------------------------- 1 | """ 2 | I 1 3 | V 5 4 | X 10 5 | L 50 6 | C 100 7 | D 500 8 | M 1000 9 | """ 10 | 11 | class Solution: 12 | def intToRoman(self, num): 13 | """ 14 | :type num: int 15 | :rtype: str 16 | """ 17 | Value = {1:'I', 5:'V', 10:'X', 50:'L', 100:'C', 500:'D', 1000:'M'} 18 | MinusValue = {4:'IV', 9:'IX', 40:'XL', 90:'XC', 400:'CD', 900:'CM'} 19 | 20 | 21 | def main(): 22 | Solution().intToRoman(10) 23 | 24 | if __name__ == "__main__": 25 | main() 26 | -------------------------------------------------------------------------------- /Python3/String/IsSubsequence/Naive392.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isSubsequence(self, s: str, t: str) -> bool: 3 | if len(t) < len(s): 4 | return False 5 | 6 | i, j = 0, 0 7 | 8 | while i < len(s) and j < len(t): 9 | while s[i] != t[j]: 10 | j += 1 11 | if j >= len(t): 12 | break 13 | 14 | if j >= len(t): 15 | break 16 | 17 | # s[i] == t[j] 18 | i += 1 19 | j += 1 20 | 21 | if i == len(s): 22 | return True 23 | else: 24 | return False 25 | -------------------------------------------------------------------------------- /Python3/String/IsSubsequence/test_IsSubsequence.py: -------------------------------------------------------------------------------- 1 | from Naive392 import Solution as naive 2 | 3 | testcase = [ 4 | ("b", "c", False), 5 | ("abc", "ahbgdc", True), 6 | ("axc", "ahbgdc", False), 7 | ("aaaaaa", "bbaaaa", False), 8 | ] 9 | 10 | 11 | def test_naive(): 12 | for s, t, ans in testcase: 13 | assert naive().isSubsequence(s, t) == ans 14 | -------------------------------------------------------------------------------- /Python3/String/JewelsAndStones/Naive2_771.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def numJewelsInStones(self, J: str, S: str) -> int: 3 | jewels = set(J) 4 | answer = 0 5 | for s in S: 6 | if s in jewels: 7 | answer += 1 8 | 9 | return answer 10 | 11 | # Runtime: 32 ms, faster than 39.24% of Python3 online submissions for Jewels and Stones. 12 | # Memory Usage: 13.6 MB, less than 5.39% of Python3 online submissions for Jewels and Stones. 13 | -------------------------------------------------------------------------------- /Python3/String/JewelsAndStones/Naive771.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | 3 | class Solution: 4 | def numJewelsInStones(self, J: str, S: str) -> int: 5 | stones_count = defaultdict(int) 6 | answer = 0 7 | for s in S: 8 | stones_count[s] += 1 9 | 10 | for j in J: 11 | answer += stones_count[j] 12 | 13 | return answer 14 | 15 | # Runtime: 32 ms, faster than 39.24% of Python3 online submissions for Jewels and Stones. 16 | # Memory Usage: 13.8 MB, less than 5.39% of Python3 online submissions for Jewels and Stones. 17 | -------------------------------------------------------------------------------- /Python3/String/LetterCombinationsOfAPhoneNumber/test_017.py: -------------------------------------------------------------------------------- 1 | from Backtracking017 import Solution as Backtracking 2 | 3 | numbers = [] 4 | numbers.append("23") 5 | numbers.append("") 6 | 7 | answer = [] 8 | answer.append(["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]) 9 | answer.append([]) 10 | 11 | 12 | def test_backtracking(): 13 | for i, nums in enumerate(numbers): 14 | assert Backtracking().letterCombinations(nums) == answer[i] 15 | -------------------------------------------------------------------------------- /Python3/String/LongestCommonSubsequence/test_nc92.py: -------------------------------------------------------------------------------- 1 | from DP_ReturnSubsequence import Solution as DP 2 | 3 | # https://www.nowcoder.com/practice/6d29638c85bb4ffd80c020fe244baf11?tpId=196&tqId=37131&ru=/exam/oj 4 | testcases = [ 5 | ("1A2C3D4B56", "B1D23A456A", "123456"), 6 | ("abc", "def", "-1"), 7 | ("abc", "abc", "abc"), 8 | ("ab", "", "-1"), 9 | ] 10 | 11 | 12 | def test_DP(): 13 | for s1, s2, ans in testcases: 14 | assert DP().LCS(s1, s2) == ans 15 | -------------------------------------------------------------------------------- /Python3/String/LongestPalindromicSubsequence/test_516.py: -------------------------------------------------------------------------------- 1 | from TopDownDP516 import Solution as TopDownDP 2 | from BottomUpDP516 import Solution as BottomUpDP 3 | 4 | testcases = [ 5 | ('bbbab', 4), 6 | ('cbbd', 2), 7 | ] 8 | 9 | 10 | def test_TopDownDP(): 11 | for s, ans in testcases: 12 | assert TopDownDP().longestPalindromeSubseq(s) == ans 13 | 14 | 15 | def test_BottomUpDP(): 16 | for s, ans in testcases: 17 | assert BottomUpDP().longestPalindromeSubseq(s) == ans 18 | -------------------------------------------------------------------------------- /Python3/String/MergeStringsAlternatively/Naive1768.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def mergeAlternately(self, word1: str, word2: str) -> str: 3 | i = 0 4 | j = 0 5 | put_one = True 6 | answer = [] 7 | while i < len(word1) or j < len(word2): 8 | if put_one and i < len(word1): 9 | answer.append(word1[i]) 10 | i += 1 11 | elif not put_one and j < len(word2): 12 | answer.append(word2[j]) 13 | j += 1 14 | put_one = not put_one 15 | 16 | return ''.join(answer) 17 | -------------------------------------------------------------------------------- /Python3/String/MergeStringsAlternatively/test_1768.py: -------------------------------------------------------------------------------- 1 | from Naive1768 import Solution as Naive 2 | 3 | testcases = [ 4 | ('abc', 'pqr', 'apbqcr'), 5 | ('ab', 'pqrs', 'apbqrs'), 6 | ('abcd', 'pq', 'apbqcd'), 7 | ] 8 | 9 | 10 | def test_Naive(): 11 | for word1, word2, ans in testcases: 12 | assert Naive().mergeAlternately(word1, word2) == ans 13 | -------------------------------------------------------------------------------- /Python3/String/MinimumInsertionStepsToMakeAStringPalindrome/TopDownDP1312.py: -------------------------------------------------------------------------------- 1 | from functools import lru_cache 2 | 3 | 4 | class Solution: 5 | @lru_cache(None) 6 | def minInsertions(self, s: str) -> int: 7 | if len(s) == 0 or len(s) == 1: 8 | return 0 9 | 10 | if s[0] == s[-1]: 11 | return self.minInsertions(s[1:-1]) 12 | 13 | return 1 + min(self.minInsertions(s[:-1]), self.minInsertions(s[1:])) 14 | -------------------------------------------------------------------------------- /Python3/String/MinimumInsertionStepsToMakeAStringPalindrome/test_1312.py: -------------------------------------------------------------------------------- 1 | from TopDownDP1312 import Solution as TopDownDP 2 | 3 | testcases = [ 4 | ('zzazz', 0), 5 | ('mbadm', 2), 6 | ('leetcode', 5), 7 | ] 8 | 9 | 10 | def test_TopDownDP(): 11 | for s, ans in testcases: 12 | assert TopDownDP().minInsertions(s) == ans 13 | -------------------------------------------------------------------------------- /Python3/String/MinimumRemoveToMakeValidParentheses/test_1249.py: -------------------------------------------------------------------------------- 1 | from Naive1249 import Solution as Naive 2 | from Naive2_1249 import Solution as Naive2 3 | testcase = [ 4 | ("lee(t(c)o)de)", {"lee(t(c)o)de", "lee(t(c)ode)", "lee(t(co)de)"}), 5 | ("a)b(c)d", {"ab(c)d"}), 6 | ("))((", {""}), 7 | ("(a(b(c)d)", {"a(b(c)d)", "(a(bc)d)", "(ab(c)d)"}), 8 | ] 9 | 10 | 11 | def test_naive(): 12 | for s, answers in testcase: 13 | assert Naive().minRemoveToMakeValid(s) in answers 14 | 15 | 16 | def test_naive2(): 17 | for s, answers in testcase: 18 | assert Naive2().minRemoveToMakeValid(s) in answers 19 | -------------------------------------------------------------------------------- /Python3/String/OptimalPartitionOfString/Greedy2405.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def partitionString(self, s: str) -> int: 3 | curr = set() 4 | ans = 0 5 | for c in s: 6 | if c not in curr: 7 | curr.add(c) 8 | else: 9 | curr = set([c]) 10 | ans += 1 11 | if curr: 12 | ans += 1 13 | return ans 14 | -------------------------------------------------------------------------------- /Python3/String/OptimalPartitionOfString/test_2405.py: -------------------------------------------------------------------------------- 1 | from Greedy2405 import Solution as Greedy 2 | 3 | testcases = [ 4 | ("abacaba", 4), 5 | ("ssssss", 6), 6 | ] 7 | 8 | 9 | def test_Greedy(): 10 | for s, ans in testcases: 11 | assert Greedy().partitionString(s) == ans 12 | -------------------------------------------------------------------------------- /Python3/String/PermutationSequence/Naive060.py: -------------------------------------------------------------------------------- 1 | from itertools import permutations 2 | 3 | 4 | class Solution: 5 | def getPermutation(self, n: int, k: int) -> str: 6 | return ''.join(list(permutations('123456789'[:n]))[k-1]) 7 | 8 | # Runtime: 2220 ms, faster than 10.20% of Python3 online submissions for Permutation Sequence. 9 | # Memory Usage: 57.4 MB, less than 5.04% of Python3 online submissions for Permutation Sequence. 10 | -------------------------------------------------------------------------------- /Python3/String/RansomNote/test_383.py: -------------------------------------------------------------------------------- 1 | from Naive383 import Solution as Naive 2 | from Better383 import Solution as Better 3 | 4 | testcases = [ 5 | ("a", "b", False), 6 | ("aa", "ab", False), 7 | ("aa", "aab", True), 8 | ] 9 | 10 | 11 | def test_Naive(): 12 | for ransomNote, magazine, ans in testcases: 13 | assert Naive().canConstruct(ransomNote, magazine) == ans 14 | 15 | 16 | def test_Better(): 17 | for ransomNote, magazine, ans in testcases: 18 | assert Better().canConstruct(ransomNote, magazine) == ans 19 | -------------------------------------------------------------------------------- /Python3/String/RemoveDuplicateLetters/Greedy316.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def removeDuplicateLetters(self, s): 3 | """ 4 | https://leetcode.com/problems/remove-duplicate-letters/discuss/76768/A-short-O(n)-recursive-greedy-solution 5 | """ 6 | for c in sorted(set(s)): 7 | suffix = s[s.index(c):] 8 | if set(suffix) == set(s): 9 | return c + self.removeDuplicateLetters(suffix.replace(c, '')) 10 | return '' 11 | -------------------------------------------------------------------------------- /Python3/String/RemovingStarsFromAString/Stack2390.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def removeStars(self, s: str) -> str: 3 | stack = [] 4 | for c in s: 5 | if c == '*': 6 | stack.pop() 7 | else: 8 | stack.append(c) 9 | 10 | return ''.join(stack) 11 | -------------------------------------------------------------------------------- /Python3/String/RemovingStarsFromAString/test_2390.py: -------------------------------------------------------------------------------- 1 | from Stack2390 import Solution as Stack 2 | 3 | testcases = [ 4 | ('leet**cod*e', 'lecoe'), 5 | ('erase*****', ''), 6 | ] 7 | 8 | 9 | def test_Stack(): 10 | for s, ans in testcases: 11 | assert Stack().removeStars(s) == ans 12 | -------------------------------------------------------------------------------- /Python3/String/ReverseString/Naive344.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def reverseString(self, s: List[str]) -> None: 6 | """ 7 | Do not return anything, modify s in-place instead. 8 | """ 9 | for i in range(len(s) // 2): 10 | s[i], s[len(s) - i - 1] = s[len(s) - i - 1], s[i] 11 | 12 | 13 | # Runtime: 216 ms, faster than 53.27 % of Python3 online submissions for Reverse String. 14 | # Memory Usage: 18.4 MB, less than 5.81 % of Python3 online submissions for Reverse String. 15 | -------------------------------------------------------------------------------- /Python3/String/ReverseString/Recursive344.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | class Solution: 4 | def reverseString(self, s: List[str]) -> None: 5 | """ 6 | Do not return anything, modify s in-place instead. 7 | """ 8 | def helper(left, right): 9 | if left < right: 10 | s[left], s[right] = s[right], s[left] 11 | helper(left+1, right-1) 12 | 13 | helper(0, len(s)-1) 14 | -------------------------------------------------------------------------------- /Python3/String/ReverseWordsInAString/Naive151.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def reverseWords(self, s: str) -> str: 3 | return ' '.join(reversed(s.split())) 4 | -------------------------------------------------------------------------------- /Python3/String/RomanToInteger/Naive013.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def romanToInt(self, s): 3 | """ 4 | :type s: str 5 | :rtype: int 6 | """ 7 | Value = {'I':1, 'V':5, 'X':10, 'L': 50, 'C':100, 'D':500, 'M':1000} 8 | prev_val = 5000 9 | ans = 0 10 | for c in s: 11 | if prev_val >= Value[c]: 12 | ans += Value[c] 13 | else: 14 | ans = ans + Value[c] - 2*prev_val 15 | prev_val = Value[c] 16 | return ans 17 | 18 | -------------------------------------------------------------------------------- /Python3/String/RomanToInteger/test_013.py: -------------------------------------------------------------------------------- 1 | from Naive013 import Solution as naive 2 | 3 | Romans = [] 4 | Romans.append("III") 5 | Romans.append("IV") 6 | Romans.append("IX") 7 | Romans.append("LVIII") 8 | Romans.append("MCMXCIV") 9 | 10 | Answers = [] 11 | Answers.append(3) 12 | Answers.append(4) 13 | Answers.append(9) 14 | Answers.append(58) 15 | Answers.append(1994) 16 | 17 | def test_naive(): 18 | for i, roman, in enumerate(Romans): 19 | assert naive().romanToInt(roman) == Answers[i] -------------------------------------------------------------------------------- /Python3/String/SimplifyPath/Naive071.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def simplifyPath(self, path: str) -> str: 3 | stack = [] 4 | for item in path.split('/'): 5 | if item in ['.', '']: 6 | continue 7 | elif item == '..': 8 | if stack: 9 | # "/../" 10 | stack.pop() 11 | else: 12 | stack.append(item) 13 | 14 | return '/' + '/'.join(stack) 15 | -------------------------------------------------------------------------------- /Python3/String/SimplifyPath/Stack2_071.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def simplifyPath(self, path: str) -> str: 3 | stack = [] 4 | 5 | for item in path.split('/'): 6 | if item == '' or item == '.': 7 | continue 8 | elif item == '..': 9 | if stack: 10 | stack.pop() 11 | else: 12 | stack.append(item) 13 | 14 | if not stack: 15 | return '/' 16 | 17 | ans = '' 18 | for item in stack: 19 | ans += f'/{item}' 20 | return ans 21 | -------------------------------------------------------------------------------- /Python3/String/StringToInteger/test_008.py: -------------------------------------------------------------------------------- 1 | from Naive008 import Solution as naive 2 | 3 | string = [] 4 | string.append("42") 5 | string.append(" -42") 6 | string.append("4193 with words") 7 | string.append("words and 987") 8 | string.append("-91283472332") 9 | string.append("2147483648") 10 | 11 | answer = [] 12 | answer.append(42) 13 | answer.append(-42) 14 | answer.append(4193) 15 | answer.append(0) 16 | answer.append(-2147483648) 17 | answer.append(2147483647) 18 | 19 | def test_naive(): 20 | for i, s in enumerate(string): 21 | assert naive().myAtoi(s) == answer[i] -------------------------------------------------------------------------------- /Python3/String/ValidAnagram/Naive242.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | 4 | class Solution: 5 | def isAnagram(self, s: str, t: str) -> bool: 6 | return Counter(s) == Counter(t) 7 | -------------------------------------------------------------------------------- /Python3/String/ValidPalindrome/Naive125.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | 4 | class Solution: 5 | def isPalindrome(self, s: str) -> bool: 6 | s = ''.join(re.findall(r'[A-Za-z0-9]+', s)) 7 | s = s.lower() 8 | 9 | print(s) 10 | 11 | for i in range(len(s)//2): 12 | if s[i] != s[len(s)-i-1]: 13 | return False 14 | return True 15 | 16 | # Runtime: 28 ms, faster than 99.53% of Python3 online submissions for Valid Palindrome. 17 | # Memory Usage: 13.9 MB, less than 54.76% of Python3 online submissions for Valid Palindrome. 18 | -------------------------------------------------------------------------------- /Python3/String/ValidPalindrome/test_125.py: -------------------------------------------------------------------------------- 1 | from Naive125 import Solution as naive 2 | from Naive2_125 import Solution as two_pointer 3 | 4 | testcase = [ 5 | ("A man, a plan, a canal: Panama", True), 6 | ("race a car", False), 7 | ("", True), 8 | (" ", True), 9 | ("0P", False) 10 | ] 11 | 12 | 13 | def test_naive(): 14 | for s, ans in testcase: 15 | assert naive().isPalindrome(s) == ans 16 | 17 | 18 | def test_two_pointer(): 19 | for s, ans in testcase: 20 | assert two_pointer().isPalindrome(s) == ans 21 | -------------------------------------------------------------------------------- /Python3/String/ValidParentheses/Dict020.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isValid(self, s): 3 | """ 4 | :type s: str 5 | :rtype: bool 6 | """ 7 | 8 | stack = [] 9 | dic = {'(': ')', '[': ']', '{': '}'} 10 | for char in s: 11 | if char in dic: 12 | stack.append(char) 13 | elif not stack or dic[stack.pop()] != char: 14 | return False 15 | return not stack -------------------------------------------------------------------------------- /Python3/String/ValidParentheses/test_020.py: -------------------------------------------------------------------------------- 1 | from Naive020 import Solution as naive 2 | from Stack020 import Solution as stack 3 | from Dict020 import Solution as hashtable 4 | 5 | strings = ["()", "()[]{}", "(]", "([)]", "{[]}"] 6 | answers = [True, True, False, False, True] 7 | 8 | def test_naive(): 9 | for i, s in enumerate(strings): 10 | assert naive().isValid(s) == answers[i] 11 | 12 | def test_stack(): 13 | for i, s in enumerate(strings): 14 | assert stack().isValid(s) == answers[i] 15 | 16 | def test_hashtable(): 17 | for i, s in enumerate(strings): 18 | assert hashtable().isValid(s) == answers[i] 19 | -------------------------------------------------------------------------------- /Python3/String/ValidParenthesisString/Greedy678.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def checkValidString(self, s: str) -> bool: 3 | minOpen = 0 4 | maxOpen = 0 5 | for c in s: 6 | if c == '(': 7 | minOpen += 1 8 | maxOpen += 1 9 | elif c == ')': 10 | minOpen -= 1 11 | maxOpen -= 1 12 | else: 13 | minOpen -= 1 14 | maxOpen += 1 15 | 16 | if maxOpen < 0: 17 | return False 18 | 19 | minOpen = max(minOpen, 0) 20 | 21 | return minOpen == 0 22 | -------------------------------------------------------------------------------- /Python3/String/WordBreak/test_139.py: -------------------------------------------------------------------------------- 1 | from Recursive139 import Solution as recursive_with_memory 2 | from DP139 import Solution as dp 3 | 4 | testcase = [ 5 | ("leetcode", ["leet", "code"], True), 6 | ("applepenapple", ["apple", "pen"], True), 7 | ("catsandog", ["cats", "dog", "sand", "and", "cat"], False) 8 | ] 9 | 10 | 11 | def test_recursive(): 12 | for s, wordDict, ans in testcase: 13 | assert recursive_with_memory().wordBreak(s, wordDict) == ans 14 | 15 | 16 | def test_dp(): 17 | for s, wordDict, ans in testcase: 18 | assert dp().wordBreak(s, wordDict) == ans 19 | -------------------------------------------------------------------------------- /Python3/String/WordPattern/test_290.py: -------------------------------------------------------------------------------- 1 | from HashMap290 import Solution as HashMap 2 | 3 | testcases = [ 4 | ("abba", "dog cat cat dog", True), 5 | ("abba", "dog cat cat fish", False), 6 | ("aaaa", "dog cat cat dog", False), 7 | ("abba", "dog dog dog dog", False), 8 | ("aaa", "aa aa aa aa", False), 9 | ] 10 | 11 | 12 | def test_hashmap(): 13 | for pattern, s, ans in testcases: 14 | assert HashMap().wordPattern(pattern, s) == ans 15 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pytest 2 | pytest-cov 3 | coverage 4 | numpy --------------------------------------------------------------------------------