Repository: mission-peace/interview
Branch: master
Commit: 94be5deb0c0d
Files: 646
Total size: 1.2 MB
Directory structure:
gitextract_ew93x48r/
├── .gitignore
├── .idea/
│ ├── misc.xml
│ └── vcs.xml
├── C++/
│ ├── Arrays/
│ │ └── Trapping the rain water.cpp
│ ├── Bit Manipulation/
│ │ ├── Checking Whether K-th Bit is Set or Not.cpp
│ │ ├── Clearing the K-th bit of a number.cpp
│ │ ├── Setting the K-th bit of a number.cpp
│ │ ├── Toggling Rightmost Set Bit of a number.cpp
│ │ └── Toggling the K-th bit of a number.cpp
│ ├── Dynamic Programming/
│ │ ├── Edit Distance.cpp
│ │ ├── Longest Common Subsequence.cpp
│ │ ├── Longest Common Substring.cpp
│ │ ├── Longest Increasing Subsequence.cpp
│ │ ├── Longest palindromic Subsequence.cpp
│ │ └── Matrix Chain Multiplication.cpp
│ ├── Graph Algorithms/
│ │ ├── All Pair Shortest Path Problem.cpp
│ │ ├── Breadth First Search.cpp
│ │ ├── Connected Components Algorithm DFS.cpp
│ │ ├── Depth First Search.cpp
│ │ ├── Kruskal's Minimum Spanning Tree Algorithm.cpp
│ │ ├── Prims Minimum Spanning Tree Algorithm.cpp
│ │ ├── Recursive Depth First Search.cpp
│ │ ├── Single Shortest Path Bellman Ford Algorithm.cpp
│ │ ├── Single Source Shortest Path Dijkstra Algorithm.cpp
│ │ └── Topological Sorting.cpp
│ ├── Heaps - Priority Queues/
│ │ └── K-th Largest element of the stream.cpp
│ ├── Linked List/
│ │ └── Reverse a linked list recursively.cpp
│ ├── Number Theory Algorithms/
│ │ ├── Divisors.cpp
│ │ └── Sieve of Eratosthenes.cpp
│ ├── Recursion/
│ │ ├── Partition of array on the pivot.cpp
│ │ └── Permutation of a string.cpp
│ ├── Segment Tree/
│ │ └── Segment Tree.cpp
│ ├── Stacks - Queue/
│ │ └── CircularQueue.cpp
│ ├── String Algorithms/
│ │ ├── KMP.cpp
│ │ └── Trie.cpp
│ └── Union Find/
│ └── Union Find.cpp
├── LICENSE
├── README.md
├── build.gradle
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── python/
│ ├── array/
│ │ ├── arrayaddition.py
│ │ ├── commonthreesortedarray.py
│ │ ├── countinversionofsize3.py
│ │ ├── flip0smaximum1s.py
│ │ ├── longestsamesumspan.py
│ │ ├── maximumsumpathtwoarrays.py
│ │ ├── maxproductsubarray.py
│ │ ├── numberoftrianglesunsortedarray.py
│ │ ├── positiveandnegativealternativelymaintainingorder.py
│ │ ├── rearrangearrayperindex.py
│ │ ├── reorderarraybyindex.py
│ │ ├── rotationwithmaxsum.py
│ │ ├── smallestintegernotrepresentedbysubsetsum.py
│ │ ├── tripletsumlessthantotal.py
│ │ └── zigzagarrangement.py
│ ├── dynamic/
│ │ ├── bitonicsequence.py
│ │ ├── boxstacking.py
│ │ ├── breakword.py
│ │ ├── coin_change_num_ways.py
│ │ ├── coinchangingmincoins.py
│ │ ├── count_num_A.py
│ │ ├── count_num_binary_without_consec_1.py
│ │ ├── cutting_rod.py
│ │ ├── dice_throw_ways.py
│ │ ├── editdistance.py
│ │ ├── egg_drop.py
│ │ ├── knapsack_01.py
│ │ ├── kth_ugly_number.py
│ │ ├── longest_common_subsequence.py
│ │ ├── longest_common_substring.py
│ │ ├── longest_increasing_subsequence.py
│ │ ├── longest_palindromic_subsequence.py
│ │ ├── matrix_chain_order.py
│ │ ├── maximum_increasing_subsequence.py
│ │ ├── nth_fibonacci.py
│ │ ├── num_bst.py
│ │ ├── num_paths_nm_matrix.py
│ │ ├── num_trees_preorder.py
│ │ ├── optimal_bst.py
│ │ ├── stockbuysellktransactions.py
│ │ ├── string_interleaving.py
│ │ ├── sub_rectangular_maximum_sum.py
│ │ ├── subset_sum.py
│ │ ├── symbolexpressionevaluation.py
│ │ └── weighted_job_scheduling_max_profit.py
│ ├── geometry/
│ │ └── skylinedrawing.py
│ ├── graph/
│ │ ├── cycledirectedgraph.py
│ │ ├── cycleundirectedgraph.py
│ │ ├── dijkstrashortestpath.py
│ │ ├── disjointset.py
│ │ ├── floydwarshall.py
│ │ ├── fordfulkerson.py
│ │ ├── graph.py
│ │ ├── graphtraversal.py
│ │ ├── kruskalmst.py
│ │ ├── primmst.py
│ │ ├── priorityqueue.py
│ │ └── topologicalsort.py
│ ├── recursion/
│ │ ├── setpairtogether.py
│ │ └── stringpermutation.py
│ ├── string/
│ │ ├── Z_Algorithm.py
│ │ ├── knuthmorrispratt.py
│ │ └── rabinkarp.py
│ └── tree/
│ ├── binary_tree.py
│ ├── construct_tree_from_inorder_preorder.py
│ ├── fenwick_tree.py
│ ├── largest_bst_in_binary_tree.py
│ ├── max_depth_binary_tree.py
│ ├── morris_traversal.py
│ └── segmenttreesum.py
├── src/
│ └── com/
│ └── interview/
│ ├── array/
│ │ ├── AdditiveNumber.java
│ │ ├── ArrayAddition.java
│ │ ├── BestMeetingPoint.java
│ │ ├── BuySellStockProfit.java
│ │ ├── CheckIfArrayElementsAreConsecutive.java
│ │ ├── ChunkMerge.java
│ │ ├── CommonThreeSortedArray.java
│ │ ├── ConvertAnArrayIntoDecreaseIncreaseFashion.java
│ │ ├── CountInversionOfSize3.java
│ │ ├── CountSmallerOnRight.java
│ │ ├── DivideNumbersInEqualGroupWithClosestSum.java
│ │ ├── DuplicateNumberDetection.java
│ │ ├── DuplicateWithinkIndices.java
│ │ ├── FindElementsOccurringNByKTimesTetris.java
│ │ ├── FirstPositiveMissing.java
│ │ ├── Flip0sMaximum1s.java
│ │ ├── FourSum.java
│ │ ├── GasStationCircle.java
│ │ ├── GreedyTextJustification.java
│ │ ├── GroupElementsInSizeM.java
│ │ ├── HIndex.java
│ │ ├── IncreasingSubsequnceOfLength3WithMaxProduct.java
│ │ ├── IncreasingTripletSubsequence.java
│ │ ├── JumpGame.java
│ │ ├── KadaneWrapArray.java
│ │ ├── KthElementInArray.java
│ │ ├── KthLargestInTwoSortedArray.java
│ │ ├── LargerElementOnRight.java
│ │ ├── LargestMountain.java
│ │ ├── LargestSubArrayWithEqual0sAnd1s.java
│ │ ├── LeetCodeCandy.java
│ │ ├── LongestConsecutiveSubsequence.java
│ │ ├── LongestIncreasingSubSequenceOlogNMethod.java
│ │ ├── LongestSameSumSpan.java
│ │ ├── LongestSubstringWithAtMost2Char.java
│ │ ├── MaxNumberFromTwoArray.java
│ │ ├── MaxProductSubarray.java
│ │ ├── MaxRepeatingNumber.java
│ │ ├── MaximumGap.java
│ │ ├── MaximumIminusJSuchThatAiGTAj.java
│ │ ├── MaximumMinimumArrangement.java
│ │ ├── MaximumOfSubarrayOfSizeK.java
│ │ ├── MaximumSumPathTwoArrays.java
│ │ ├── MaximumSumThreeNonOverlappingSubarray.java
│ │ ├── MeetingRooms.java
│ │ ├── MinimumDistanceBetweenTwoNumbers.java
│ │ ├── MinimumNumberFromSequence.java
│ │ ├── MinimumSortedWhichSortsEntireArray.java
│ │ ├── MissingRanges.java
│ │ ├── MoveAllZerosToEnd.java
│ │ ├── MultiplyAllFieldsExceptOwnPosition.java
│ │ ├── NthElementOfCountNumberSequence.java
│ │ ├── NumberOfTrianglesInUnsortedArray.java
│ │ ├── PositiveAndNegativeNumberAlternatively.java
│ │ ├── PositiveAndNegativeNumberAlternativelyMaintainingOrder.java
│ │ ├── RearrangeArrayPerIndex.java
│ │ ├── RearrangeSuchThatArriBecomesArrArri.java
│ │ ├── ReorderArrayByIndex.java
│ │ ├── RepeatingAndMissingNumber.java
│ │ ├── RotationWithMaxSum.java
│ │ ├── SelfCrossing.java
│ │ ├── ShortestPalindrome.java
│ │ ├── SmallestIntegerNotRepresentedBySubsetSum.java
│ │ ├── SmallestSubarrayWithAtleastKSum.java
│ │ ├── SortedArrayTransformation.java
│ │ ├── StableMarriageProblem.java
│ │ ├── SubarrayWithGivenSum.java
│ │ ├── SummaryRanges.java
│ │ ├── ThreeSumSmallerThanTarget.java
│ │ ├── TrappingWater.java
│ │ ├── TripletInArray.java
│ │ ├── TripletSumLessThanTotal.java
│ │ ├── TugOfWar.java
│ │ ├── WaterContainer.java
│ │ ├── WiggleSort.java
│ │ └── ZigZagArrangement.java
│ ├── binarysearch/
│ │ ├── ArithmeticProgressionSearch.java
│ │ ├── BinarySearch.java
│ │ ├── CircularBinarySearch.java
│ │ ├── CountNDistinctPairsWithDifferenceK.java
│ │ ├── FirstOccurrenceOfNumberInSortedArray.java
│ │ ├── FloorAndCeilingSortedArray.java
│ │ ├── MedianOfTwoSortedArray.java
│ │ ├── MedianOfTwoSortedArrayOfDifferentLength.java
│ │ ├── MinimumInSortedRotatedArray.java
│ │ ├── MissingNumberInConsecutiveNumbers.java
│ │ ├── MonotonicallyIncreasingFunctionBecomesPositive.java
│ │ ├── NumberOfPairWithXPowerYGreaterThanYPowerX.java
│ │ ├── PeakElement.java
│ │ ├── SearchForRange.java
│ │ ├── SearchInsertPosition.java
│ │ ├── SortedAndRotatedArraySearch.java
│ │ └── SquareRootOfNumber.java
│ ├── bits/
│ │ ├── AddTwoNumberInBinaryRepresentation.java
│ │ ├── BitRotation.java
│ │ ├── ByteAsStorage.java
│ │ ├── CountBits.java
│ │ ├── CountingBitsTillNum.java
│ │ ├── DrawHorizontalLine.java
│ │ ├── FindNumberOccurringOnceOtherNumbers3Times.java
│ │ ├── GrayCode.java
│ │ ├── InsertMintoNiTojBits.java
│ │ ├── MaxProductWordLength.java
│ │ ├── MissingNumbers.java
│ │ ├── NextHigherAndNextLowerWithSameNumberBits.java
│ │ ├── NextPowerOf2.java
│ │ ├── NumberOccuringOddTimes.java
│ │ ├── NumberOfBitsFlipToConvertNToM.java
│ │ ├── RealNumberToBinary.java
│ │ ├── RepeatedDnaSequence.java
│ │ ├── ReverseBits.java
│ │ ├── SquareOfNumber.java
│ │ ├── SwapOddEvenBits.java
│ │ ├── SwapTwoBits.java
│ │ └── WinnerWithBeautifulNumber.java
│ ├── dynamic/
│ │ ├── BitonicSequence.java
│ │ ├── BoxStacking.java
│ │ ├── BreakMultipleWordsWithNoSpaceIntoSpace.java
│ │ ├── BurstBalloons.java
│ │ ├── CoinChanging.java
│ │ ├── CoinChangingMinimumCoin.java
│ │ ├── CountAs.java
│ │ ├── CountNumberOfBinaryWithoutConsecutive1s.java
│ │ ├── CountNumberOfTreePreorder.java
│ │ ├── CountNumberOfTreesInBST.java
│ │ ├── CutRodToMinimizeCost.java
│ │ ├── CuttingRod.java
│ │ ├── DecodeWays.java
│ │ ├── DiceThrowWays.java
│ │ ├── DistinctSubsequence.java
│ │ ├── DungeonGame.java
│ │ ├── EditDistance.java
│ │ ├── EggDropping.java
│ │ ├── ExpressionEvaluation.java
│ │ ├── FibonacciSeries.java
│ │ ├── Immutable2DSumRangeQuery.java
│ │ ├── Knapsack01.java
│ │ ├── LongestCommonSubsequence.java
│ │ ├── LongestCommonSubstring.java
│ │ ├── LongestEvenLengthSubstringOfEqualHalf.java
│ │ ├── LongestIncreasingPath.java
│ │ ├── LongestIncreasingSubsequence.java
│ │ ├── LongestPalindromicSubsequence.java
│ │ ├── MatrixMultiplicationCost.java
│ │ ├── MaxSumForNonAdjacentElements.java
│ │ ├── MaximizeSkiGates.java
│ │ ├── MaximumLengthChainPair.java
│ │ ├── MaximumProductCutting.java
│ │ ├── MaximumRectangularSubmatrixOf1s.java
│ │ ├── MaximumSizeSubMatrix.java
│ │ ├── MaximumSumSubsequence.java
│ │ ├── MinCostPath.java
│ │ ├── MinJumpToReachEnd.java
│ │ ├── MinimumCostTrainTicket.java
│ │ ├── MinimumNumberOfPerfectSquares.java
│ │ ├── MinimumTriangleSum.java
│ │ ├── NPotGold.java
│ │ ├── NumberOfPathsInMxNMatrix.java
│ │ ├── NumberOfWaysToScorePoints.java
│ │ ├── OptimalTreeSearch.java
│ │ ├── PaintHouse.java
│ │ ├── PalindromePartition.java
│ │ ├── PhoneDialNumberOfCombinationOfSizeK.java
│ │ ├── RegexMatching.java
│ │ ├── RemoveFromEndToMake2IntoMinGreaterThanMax.java
│ │ ├── ScrambledString.java
│ │ ├── StockBuySellKTransactions.java
│ │ ├── SubRectangularMatrixWithMaximumSum.java
│ │ ├── SubsetSum.java
│ │ ├── SubsquareSurrounedByXs.java
│ │ ├── SymbolExpressionEvaluation.java
│ │ ├── TextJustification.java
│ │ ├── TwoStringInterleavingToFormThird.java
│ │ ├── UglyNumbers.java
│ │ ├── WeightedJobSchedulingMaximumProfit.java
│ │ └── WildCardMatching.java
│ ├── geometry/
│ │ ├── ClosestPairOfPoints.java
│ │ ├── GrahamScanConvexHull.java
│ │ ├── JarvisMarchConvexHull.java
│ │ ├── MaximumPointsOnSameLine.java
│ │ └── SkylineDrawing.java
│ ├── graph/
│ │ ├── AlientDictionary.java
│ │ ├── AllCyclesInDirectedGraphJohnson.java
│ │ ├── AllCyclesInDirectedGraphTarjan.java
│ │ ├── ArticulationPoint.java
│ │ ├── BellmanFordShortestPath.java
│ │ ├── BinaryMaxHeap.java
│ │ ├── BinaryMinHeap.java
│ │ ├── BiparteGraph.java
│ │ ├── Boggle.java
│ │ ├── Bridge.java
│ │ ├── CloneDirectedGraph.java
│ │ ├── CloneGraph.java
│ │ ├── ConvertOneWordToAnother.java
│ │ ├── CourseSchedule.java
│ │ ├── CycleInDirectedGraph.java
│ │ ├── CycleUndirectedGraph.java
│ │ ├── DAGShortestPathTopological.java
│ │ ├── DijkstraShortestPath.java
│ │ ├── DirectedGraphConnectivity.java
│ │ ├── DisjointSet.java
│ │ ├── EulerianPathAndCircuit.java
│ │ ├── EvaluateDivison.java
│ │ ├── FillOsWIthXsIfSurroundedByXs.java
│ │ ├── FloodFillAlgorithm.java
│ │ ├── FloydWarshallAllPairShortestPath.java
│ │ ├── FordFulkerson.java
│ │ ├── Graph.java
│ │ ├── GraphColoring.java
│ │ ├── GraphTraversal.java
│ │ ├── HamiltonianCycle.java
│ │ ├── KruskalMST.java
│ │ ├── MaximumBiparteMatching.java
│ │ ├── MinimumHeightTree.java
│ │ ├── NumberOfIsland.java
│ │ ├── NumberOfIslandDynamic.java
│ │ ├── NumberofTriangles.java
│ │ ├── PrimMST.java
│ │ ├── PrintAllPathFromSourceToDestination.java
│ │ ├── ShortestDistanceFromExit.java
│ │ ├── StronglyConnectedComponent.java
│ │ ├── TarjanStronglyConnectedComponent.java
│ │ ├── TopologicalSort.java
│ │ ├── TransitiveClosure.java
│ │ ├── TravelingSalesmanHeldKarp.java
│ │ ├── ValidTree.java
│ │ ├── WallsAndGates.java
│ │ └── WordLadder.java
│ ├── linklist/
│ │ ├── AddNumberRepresentedByLinkList.java
│ │ ├── CopyLinkListWIthArbitPointer.java
│ │ ├── DeleteDuplicateNodes.java
│ │ ├── DeleteNAfterMNodes.java
│ │ ├── DeleteNodeWithGreaterValueOnRight.java
│ │ ├── DoubleLinkList.java
│ │ ├── Flatten2DList.java
│ │ ├── FlattenLinkList.java
│ │ ├── InsertionSortLinkList.java
│ │ ├── LRUCache.java
│ │ ├── LRUCacheLeetCode.java
│ │ ├── LinkList.java
│ │ ├── LinkListIsPalindrome.java
│ │ ├── LinkListToCompleteBinaryTree.java
│ │ ├── LoopInLinkList.java
│ │ ├── MergeForLargestSum.java
│ │ ├── MergeSortLinkList.java
│ │ ├── MiddleElementOfLinkList.java
│ │ ├── MultiplyTwoNumbersLinkList.java
│ │ ├── QuickSortSingleLinkList.java
│ │ ├── RemoveDuplicatesSortedList.java
│ │ ├── RemoveMiddleElementsOfLineSegment.java
│ │ ├── ReorderList.java
│ │ ├── ReverseAlternateKNodes.java
│ │ ├── ReverseAlternateNodeAndAppendAtEnd.java
│ │ ├── ReverseKNodes.java
│ │ ├── RotateList.java
│ │ ├── ShuffleMerge.java
│ │ ├── SortNearlySortedList.java
│ │ ├── SortedCircularLinkList.java
│ │ ├── SortedLLToBalancedBST.java
│ │ ├── StackWithLinkListMiddleOperation.java
│ │ ├── SwapTwoNodesInDoubleLL.java
│ │ └── TripletToSumInLinkList.java
│ ├── misc/
│ │ ├── AddingTwoSetOfIntervals.java
│ │ ├── AngleBetweenHourAndMinuteHand.java
│ │ ├── BulbSwitcher.java
│ │ ├── CandiesProblem.java
│ │ ├── ContainsNumberWithinKDistance.java
│ │ ├── ConvertNumberIntoBase26.java
│ │ ├── CountRanges.java
│ │ ├── DayDifferenceBetweenTwoDates.java
│ │ ├── DifferenceBetweenTwoTime.java
│ │ ├── FindingCelebrity.java
│ │ ├── FloatPointConversion.java
│ │ ├── FourPointsFormSquare.java
│ │ ├── GetKthPermutation.java
│ │ ├── HammingDistanceBetweenPair.java
│ │ ├── InsertInterval.java
│ │ ├── IntegerListParser.java
│ │ ├── KthLargestInRowiseColumnWiseSorted2DArray.java
│ │ ├── LoadBalancers.java
│ │ ├── NestedIterator.java
│ │ ├── NumberToWord.java
│ │ ├── PrimeNumbersBeforeN.java
│ │ ├── Read4Function.java
│ │ ├── RomanNumberToDecimal.java
│ │ └── SparseTableRangeMinimumQuery.java
│ ├── multiarray/
│ │ ├── Fill2DMatrixWith1.java
│ │ ├── GameOfLife.java
│ │ ├── LongestConsecutiveIntegerInUnsorted2DArray.java
│ │ ├── MatrixCalculation.java
│ │ ├── MatrixFindAllSubSquareRectangleMatrix.java
│ │ ├── MatrixInDiagonalOrder.java
│ │ ├── MatrixOf0sAnd1s.java
│ │ ├── MoveCellPerCellValue.java
│ │ ├── Mutable2DSumRangeQuery.java
│ │ ├── RotateImage.java
│ │ ├── ShortestDistanceFromAllBuildings.java
│ │ ├── SmallestRectangleBlackPixel.java
│ │ ├── SpiralGeneration.java
│ │ ├── SpiralPrinting.java
│ │ └── TilingProblem.java
│ ├── multithreaded/
│ │ ├── BoundedBlockingQueue.java
│ │ ├── CountingWord.java
│ │ ├── DependencyTaskExecutor.java
│ │ ├── FillupMatrix.java
│ │ ├── MinMaxKeeper.java
│ │ ├── PrintInSequence.java
│ │ ├── RealTimeCounter.java
│ │ ├── SingleQueueDomainTableUpdate.java
│ │ ├── SpinLockMutex.java
│ │ ├── ThreadPoolExample.java
│ │ └── ThreadPoolImpl.java
│ ├── number/
│ │ ├── AggregateNumber.java
│ │ ├── AllStrobogrammaticNumber.java
│ │ ├── ArithemeticProgressionExists.java
│ │ ├── ArrayMultiplication.java
│ │ ├── BasicCalculator.java
│ │ ├── BinomialCoefficient.java
│ │ ├── ConvertToBaseN.java
│ │ ├── CountNoOf2s.java
│ │ ├── CountNumbersNotIncluding4.java
│ │ ├── DivisionWithoutDivisionOperator.java
│ │ ├── EuclideanAlgoForGCD.java
│ │ ├── FactorialOfLargeNumber.java
│ │ ├── GenerateSignature.java
│ │ ├── LargestMultipleOf3inArray.java
│ │ ├── LuckyNumbers.java
│ │ ├── MedianOf3Number.java
│ │ ├── MthNumberInNSizeArray.java
│ │ ├── NBy2PairSumToK.java
│ │ ├── NextLargestPalindrome.java
│ │ ├── NotIncluding4.java
│ │ ├── NumberOfCombinationsForStairs.java
│ │ ├── PermutationBiggerThanNumber.java
│ │ ├── PermutationLargerThanGivenArray.java
│ │ ├── PowerFunction.java
│ │ ├── RearrangeNumberInArrayToFormLargestNumber.java
│ │ ├── RussianPeasantMultiplication.java
│ │ ├── SmallestNumberGreaterThanGiveNumberIncreasingSequence.java
│ │ ├── SquareRoot.java
│ │ ├── StrobogrammaticNumber.java
│ │ ├── Trailing0sinFactorial.java
│ │ └── UniquePartitionOfInteger.java
│ ├── playground/
│ │ └── TestInnerClass.java
│ ├── random/
│ │ ├── Rand7UsingRand5.java
│ │ ├── RandomCountrySelectionByPopluation.java
│ │ ├── SelectMRandomNumbersInStream.java
│ │ └── ShuffleArray.java
│ ├── recursion/
│ │ ├── AllAdjacentCombination.java
│ │ ├── Bracketology.java
│ │ ├── ChainWordsToFormCircle.java
│ │ ├── Combination.java
│ │ ├── CombinationOfSizeK.java
│ │ ├── CombinationWithStar.java
│ │ ├── DifferentWaysToAddParentheses.java
│ │ ├── FancyShuffle.java
│ │ ├── InterpretationOfArray.java
│ │ ├── KeyPadPermutation.java
│ │ ├── LongestAbsolutePath.java
│ │ ├── MinimumEditForReversePolishNotation.java
│ │ ├── NQueenProblem.java
│ │ ├── OneEditApart.java
│ │ ├── OperatorAdditionForTarget.java
│ │ ├── OptimalDivision.java
│ │ ├── PrintAllPathFromTopLeftToBottomRight.java
│ │ ├── PrintAllSubsequence.java
│ │ ├── PrintArrayInAdjacentWay.java
│ │ ├── PrintArrayInCustomizedFormat.java
│ │ ├── PrintSumCombination.java
│ │ ├── ReconstructItinerary.java
│ │ ├── RemoveInvalidParenthesis.java
│ │ ├── RestoreIPAddresses.java
│ │ ├── SetPairTogether.java
│ │ ├── StringInterleaving.java
│ │ ├── StringPermutation.java
│ │ ├── StringPermutationRotation.java
│ │ ├── SudokuSolver.java
│ │ ├── WordCombination.java
│ │ └── WordPattern.java
│ ├── regex/
│ │ └── MultiSpaceReplacement.java
│ ├── sort/
│ │ ├── CountingSort.java
│ │ ├── HeapSort.java
│ │ ├── IterativeQuickSort.java
│ │ ├── MergeSort.java
│ │ ├── PanCakeSorting.java
│ │ ├── QuickSort.java
│ │ ├── RadixSort.java
│ │ ├── Sort0toN3.java
│ │ └── SortArrayByFrequence.java
│ ├── stackqueue/
│ │ ├── CircularQueue.java
│ │ ├── MaximumHistogram.java
│ │ ├── MedianFinder.java
│ │ ├── RealTimeCounter.java
│ │ ├── RealTimeCounterUsingCircularQueue.java
│ │ ├── RemoveDuplicateMaintainingOrder.java
│ │ ├── RemoveExtraBrackets.java
│ │ ├── ReverseStackUsingRecursion.java
│ │ ├── SimplyPath.java
│ │ └── StockSpanProblem.java
│ ├── string/
│ │ ├── AnagramOfFirstAsSubstring.java
│ │ ├── CycleLeaderIteration.java
│ │ ├── GroupAnagramsTogether.java
│ │ ├── InPlaceTransformationOfString.java
│ │ ├── LexicographicRankInPermutation.java
│ │ ├── LongestPalindromeSubstring.java
│ │ ├── LongestSubstringWithKDistinctCharacters.java
│ │ ├── LongestSubstringWithoutRepetingCharacter.java
│ │ ├── MultiplyStrings.java
│ │ ├── NTMatch.java
│ │ ├── PalindromePair.java
│ │ ├── PrintAnagramTogether.java
│ │ ├── RabinKarpSearch.java
│ │ ├── RearrangeDuplicateCharsdDistanceAway.java
│ │ ├── RemoveConsecutiveDuplicate.java
│ │ ├── RunLengthEncoding.java
│ │ ├── SmallestWindowContaingAllCharacters.java
│ │ ├── StringEncoderDecoder.java
│ │ ├── SubstringSearch.java
│ │ ├── SubtringWithConcatentationOfWords.java
│ │ ├── ValidPalindrome.java
│ │ ├── ValidWordAbbreviation.java
│ │ ├── WordAbbreviationCombination.java
│ │ └── ZAlgorithm.java
│ ├── suffixprefix/
│ │ ├── SuffixArray.java
│ │ ├── SuffixTree.java
│ │ ├── TernaryTree.java
│ │ └── Trie.java
│ └── tree/
│ ├── AVLTree.java
│ ├── AddGreaterValueNodeToEveryNode.java
│ ├── ArbitaryTreeToChildSumTree.java
│ ├── BSTOneChildPreOrderTraversal.java
│ ├── BSTSearch.java
│ ├── BTree.java
│ ├── BinaryTree.java
│ ├── BinaryTreeFromParentRepresentation.java
│ ├── BinaryTreeMaximumPathSum.java
│ ├── BinaryTreeToCircularLinkList.java
│ ├── BinaryTreeToDoubleLinkList.java
│ ├── BinaryTreeToSortedLinkList.java
│ ├── BoundaryTraversal.java
│ ├── ClosestValueBinaryTree.java
│ ├── ConnectNodesAtSameLevel.java
│ ├── ConstructAllBinaryTreeFromInorderTraversal.java
│ ├── ConstructBSTFromPreOrderArray.java
│ ├── ConstructFullTreeFromPreOrderPostOrder.java
│ ├── ConstructTreeFromInOrderPreOrder.java
│ ├── ConstructTreeFromLevelOrderInOrder.java
│ ├── ConstructTreeFromPreOrderTraversalWith0or2Child.java
│ ├── ContructTreeFromInOrderTraversalRootGreaterThanChild.java
│ ├── ContructTreeFromInorderPostOrder.java
│ ├── CountNodesCompleteTree.java
│ ├── CountNumberOfSmallerElementOnRight.java
│ ├── CountPathSum.java
│ ├── CountUnivalueTree.java
│ ├── CousinNodes.java
│ ├── DegenerateBinaryTreeToSortedLL.java
│ ├── DiameterOfTree.java
│ ├── FenwickTree.java
│ ├── FlattenLinkListToBinaryTreePreorder.java
│ ├── HeightBalanced.java
│ ├── HuffmanEncoding.java
│ ├── IdenticalTrees.java
│ ├── InorderSuccessor.java
│ ├── IntervalTree.java
│ ├── IsBST.java
│ ├── IsCompleteBinaryTree.java
│ ├── IsPreOrderArrayBST.java
│ ├── KClosestValueInBinaryTree.java
│ ├── LargestBSTInBinaryTree.java
│ ├── LargestIndependentSetInTree.java
│ ├── LeavesOfBinaryTree.java
│ ├── LevelOrderTraversal.java
│ ├── LevelOrderTraversalInReverse.java
│ ├── LongestConsecutiveSequence.java
│ ├── LowestCommonAncestorInBinaryTree.java
│ ├── LowestCommonAncestoryBinarySearchTree.java
│ ├── MorrisTraversal.java
│ ├── NextInorderSuccessorIterator.java
│ ├── NextInorderSuccessorOfTwoTree.java
│ ├── NodesAtDistanceK.java
│ ├── NodesWithNoSibling.java
│ ├── PathSum.java
│ ├── PopulateInOrderSuccessor.java
│ ├── PrintPostOrderFromPreOrderInOrder.java
│ ├── PrintTwoBSTInSortedForm.java
│ ├── RedBlackTree.java
│ ├── RootToLeafToSum.java
│ ├── SameTree.java
│ ├── SegmentTree.java
│ ├── SegmentTreeMinimumRangeQuery.java
│ ├── SerializeDeserializeBinaryTree.java
│ ├── SinkNegativeToBottom.java
│ ├── SizeOfBinaryTree.java
│ ├── SortedArrayToBST.java
│ ├── SortedOrderPrintCompleteTreeArray.java
│ ├── SuccinctTree.java
│ ├── SumTree.java
│ ├── TreeIsomorphism.java
│ ├── TreeTraversalInSpiralOrder.java
│ ├── TreeTraversalLevelByLevel.java
│ ├── TreeTraversals.java
│ ├── UpsidedownBinaryTree.java
│ ├── VertexCoverBinaryTreeDP.java
│ ├── VerticalOrder.java
│ └── VerticalTreePrinting.java
└── test/
└── com/
└── interview/
├── TestUtil.java
├── array/
│ ├── AdditiveNumberTest.java
│ ├── ArrayAdditionTest.java
│ ├── MaximumMinimumArrangementTest.java
│ ├── MeetingRoomsTest.java
│ ├── MultiplyAllFieldsExceptOwnPositionTest.java
│ ├── NumberOfTriangledInUnsortedArrayTest.java
│ └── ThreeSumSmallerThanTargetTest.java
├── bits/
│ ├── CountingBitsTillNumTest.java
│ └── MaxProductWordLengthTest.java
├── dynamic/
│ ├── DecodeWaysTest.java
│ └── PalindromePartitionTest.java
├── graph/
│ ├── CourseScheduleTest.java
│ ├── TravelingSalesmanHeldKarpTest.java
│ └── WallsAndGatesTest.java
├── linklist/
│ └── DeleteDuplicateNodesTest.java
├── misc/
│ └── IntegerListParserTest.java
├── multiarray/
│ └── Mutable2DSumRangeQueryTest.java
├── number/
│ ├── AllStrobogrammaticNumberTest.java
│ └── BasicCalculatorTest.java
├── recursion/
│ └── RestoreIPAddressesTest.java
├── string/
│ ├── LongestSubstringWithKDistinctCharactersTest.java
│ ├── PalindromePairTest.java
│ ├── StringEncoderDecoderTest.java
│ ├── ValidPalindromeTest.java
│ └── ValidWordAbbreviationTest.java
├── suffixprefix/
│ └── TrieTest.java
└── tree/
├── KClosestValueInBinaryTreeTest.java
└── VerticalOrderTest.java
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
interview.iml
interview.ipr
interview.iws
build/
.gradle/
.classpath
.project
.settings/
/bin/
/out
.DS_Store
python/graph/__pycache__/
python/.idea
target/
================================================
FILE: .idea/misc.xml
================================================
================================================
FILE: .idea/vcs.xml
================================================
================================================
FILE: C++/Arrays/Trapping the rain water.cpp
================================================
#include
using namespace std;
int trapped_water(int array[],int size){
int amount = 0;
int left[size],right[size];
left[0] = array[0]; right[size-1] = array[size-1];
for(int i = 1; i < size; i++){
left[i] = max(left[i-1],array[i]);
}
for(int i = size-2; i >=0; i--){
right[i] = max(right[i+1],array[i]);
}
for(int i = 0 ; i < size;i++){
amount += min(left[i],right[i]) - array[i];
}
return amount;
}
int main(){
int array[] = {1,0,3,4,5,0,5,7,7,8,9,0};
int size = sizeof(array) / sizeof(int);
cout << trapped_water(array,size);
return 0;
}
================================================
FILE: C++/Bit Manipulation/Checking Whether K-th Bit is Set or Not.cpp
================================================
#include
using namespace std;
int main(){
int n,k;
cout << "Enter the number and the value of K : ";
cin >> n >> k;
int mask = 1 << (k-1);
if(n & mask){
cout << "Yes K-th bit is set" << endl;
}
else{
cout << "No K-th bit is not set" << endl;
}
return 0;
}
================================================
FILE: C++/Bit Manipulation/Clearing the K-th bit of a number.cpp
================================================
#include
using namespace std;
int main(){
int n,k,mask;
cout << "Enter the number and the value of K : ";
cin >> n >> k;
mask = ~(1 << (k-1));
n = n&mask;
cout << "The number after clearing the K-th bit is : " << n << endl;
return 0;
}
================================================
FILE: C++/Bit Manipulation/Setting the K-th bit of a number.cpp
================================================
#include
using namespace std;
int main(){
int n,k;
cout << "Enter the number and the value of K :";
cin >> n >> k;
int mask = 1 << (k - 1);
n = n | mask;
cout << "The number after setting the K-th bit is:" << n;
return 0;
}
================================================
FILE: C++/Bit Manipulation/Toggling Rightmost Set Bit of a number.cpp
================================================
#include
using namespace std;
int main(){
int n;
cout << "Enter the number : ";
cin >> n ;
n = n & (n-1);
cout << "The number after toggling right most set bit : " << n << endl;
return 0;
}
================================================
FILE: C++/Bit Manipulation/Toggling the K-th bit of a number.cpp
================================================
#include
using namespace std;
int main(){
int n,k,mask;
cout << "Enter the number and the value of K : ";
cin >> n >> k;
mask = 1 << (k-1);
n = n ^ mask;
cout << "The number after toggling the K-th bit is : " << n << endl;
return 0;
}
================================================
FILE: C++/Dynamic Programming/Edit Distance.cpp
================================================
int editDistance(string s1, string s2){
int m = s1.length();
int n = s2.length();
int dp[m+1][n+1];
for (int i = 0; i <= m; i++) {
dp[i][0] = i;
}
for (int j = 0; j <= n; j++) {
dp[0][j] = j;
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (s1[i-1] == s2[j-1]) dp[i][j] = dp[i-1][j-1];
else dp[i][j] = 1 + min(min(dp[i][j-1],dp[i-1][j]),dp[i-1][j-1]);
}
}
return dp[m][n];
}
================================================
FILE: C++/Dynamic Programming/Longest Common Subsequence.cpp
================================================
int lcs(string x,string y){
int m = x.size(),n = y.size();
int dp[m+1][n+1];
for(int i=0;i<=m;i++){
dp[i][0] = 0;
}
for(int j=0;j<=m;j++){
dp[0][j] = 0;
}
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(x[i-1] == y[j-1]){
dp[i][j] = dp[i-1][j-1]+1;
}
else{
dp[i][j] = max(dp[i][j-1],dp[i-1][j]);
}
}
}
return dp[m][n];
}
================================================
FILE: C++/Dynamic Programming/Longest Common Substring.cpp
================================================
#include
using namespace std;
int longest_common_substring(string x,string y){
int m = x.size();
int n = y.size();
int lcs[m+1][n+1];
for(int i = 0 ; i < m; i++){
lcs[i][0] = 0;
}
for(int j = 0; j < n; j++){
lcs[0][j] = 0;
}
for(int i = 1; i <= m; i++){
for(int j = 1; j <=n; j++){
if(x[i-1] == y[j-1]){
lcs[i][j] = 1 + lcs[i-1][j-1];
}
else{
lcs[i][j] = 0;
}
}
}
return lcs[m][n];
}
int main(){
string x,y;
cin >> x >> y;
cout << longest_common_substring(x,y);
return 0;
}
================================================
FILE: C++/Dynamic Programming/Longest Increasing Subsequence.cpp
================================================
int lis(int array[],int n){
int dp[n],lis_value = -1;
for(int i=0;i array[j] and dp[i] < dp[j]+1){
dp[i] = dp[j] + 1;
}
}
}
for(int i=0;i
using namespace std;
int longest_palindromic_subsequence(string str){
int table[str.size()][str.size()];
for(int i = 0 ; i < str.size(); i++){
table[i][i] = 1;
}
for(int l = 1 ; l < str.size() ; l++){
int i = 0, j = l;
while(j != str.size()){
if(str[i] == str[j]){
table[i][j] = 2 + table[i+1][j-1];
}
else{
table[i][j] = max(table[i+1][j],table[i][j-1]);
}
i++;j++;
}
}
return table[0][str.size()-1];
}
int main(){
string str;
cin >> str;
cout << longest_palindromic_subsequence(str);
return 0;
}
================================================
FILE: C++/Dynamic Programming/Matrix Chain Multiplication.cpp
================================================
int mcm(int p[], int n){
int m[n][n];
int i, j, k, L, q;
for (i = 1; i < n; i++)
m[i][i] = 0;
for (L=2; L
#include
using namespace std;
void floydWarshall(vector> &graph){
for (int k=0; k> graph;
int v,e,src,des,weight;
cin >> v >> e;
graph.resize(v,vector(v,0));
while(e--){
cin >> src >> des >> weight;
graph[src][des] = weight;
}
floydWarshall(graph);
for(int i=0;i
#include
#include
#include
using namespace std;
void breadth_first_search(vector> graph,int src){
vectorvisited(graph.size(),false);
queueQ;
Q.push(src);
visited[src] = true;
while(!Q.empty()){
int vertex = Q.front(); Q.pop();
cout << vertex << " ";
for(list::iterator itr = graph[vertex].begin();itr!=graph[vertex].end();itr++){
if(!visited[*itr])
Q.push(*itr);
visited[*itr] = true;
}
}
}
int main(){
vector> graph;
int v,e,src,des;
cin >> v >> e;
graph.resize(v);
while(e--){
cin >> src >> des;
graph[src].push_back(des);
graph[des].push_back(src);
}
cin >> src;
breadth_first_search(graph,src);
return 0;
}
================================================
FILE: C++/Graph Algorithms/Connected Components Algorithm DFS.cpp
================================================
#include
#include
#include
using namespace std;
void connectedComponentsDFS(vector> graph,int src,vector &visited){
if(!visited[src]){
visited[src] = true;
for(list::iterator itr = graph[src].begin();itr != graph[src].end();itr++){
connectedComponentsDFS(graph,*itr,visited);
}
}
}
int connectedComponents(vector> graph){
int components = 0;
vector visited(graph.size(),false);
for(int src = 0; src < graph.size();src++){
if(!visited[src]){
components++;
connectedComponentsDFS(graph,src,visited);
}
}
return components;
}
int main(){
vector> graph;
int v,e,src,des;
cin >> v >> e;
graph.resize(v);
while(e--){
cin >> src >> des;
graph[src].push_back(des);
}
cout << connectedComponents(graph);
return 0;
}
================================================
FILE: C++/Graph Algorithms/Depth First Search.cpp
================================================
#include
#include
#include
#include
using namespace std;
void depth_first_search(vector> graph,int src){
vectorvisited(graph.size(),false);
stackS;
S.push(src);
visited[src] = true;
while(!S.empty()){
int vertex = S.top(); S.pop();
cout << vertex << " ";
for(list::iterator itr = graph[vertex].begin();itr!=graph[vertex].end();itr++){
if(!visited[*itr])
S.push(*itr);
visited[*itr] = true;
}
}
}
int main(){
vector> graph;
int v,e,src,des;
cin >> v >> e;
graph.resize(v);
while(e--){
cin >> src >> des;
graph[src].push_back(des);
graph[des].push_back(src);
}
cin >> src;
depth_first_search(graph,src);
return 0;
}
================================================
FILE: C++/Graph Algorithms/Kruskal's Minimum Spanning Tree Algorithm.cpp
================================================
#include
#include
#include
using namespace std;
struct edge{int src,des,weight;};
class UnionFind {
int *parent, *ranks, _size;
public:
UnionFind(){
}
UnionFind(int size){
parent = new int[size]; ranks = new int[size];
for(int element = 0 ; element < size ; element++){
parent[element] = element , ranks[element] = 0 ;
}
_size = size;
}
void resize(int size){
parent = new int[size]; ranks = new int[size];
for(int element = 0 ; element < size ; element++){
parent[element] = element , ranks[element] = 0 ;
}
_size = size;
}
int find(int element){
if(parent[element] == element){
return element;
}
else{
return parent[element] = find(parent[element]); // Path Compression algorithm
}
}
bool connected(int x,int y){
if(find(x) == find(y)){
return true;
}
else{
return false;
}
}
void merge(int x,int y){
x = find(x);
y = find(y);
if(x != y){ // Union by Rank algorithm
if(ranks[x] > ranks[y]){
parent[y] = x;
}
else if(ranks[x] < ranks[y]){
parent[x] = y;
}
else{
parent[x] = y; ranks[y] ++ ;
}
_size--;
}
}
void clear(){
delete [] parent; delete [] ranks;
}
int size(){
return _size;
}
};
bool comparator(const edge &a,const edge &b){
return a.weight < b.weight;
}
vector kruskalsAlgorithm(vectorgraph,int vertices){
UnionFind uf(vertices);
vectorspanningTree;
sort(graph.begin(),graph.end(),comparator);
spanningTree.push_back(graph[0]);
uf.merge(graph[0].src,graph[0].des);
for(int i=1;igraph;
int e,v;
cin >> e >> v;
graph.resize(e);
for(int i=0;i> graph[i].src >> graph[i].des >> graph[i].weight;
}
vector spanningTree = kruskalsAlgorithm(graph,v);
for(edge x : spanningTree){
cout << x.src << " " << x.des << " " << x.weight << endl;
}
return 0;
}
================================================
FILE: C++/Graph Algorithms/Prims Minimum Spanning Tree Algorithm.cpp
================================================
#include
#include
#include
#include
#include
using namespace std;
const int INF = INT_MAX;
class edge{ public: int src,des,weight; edge(){}edge(int s,int d,int w): src(s),des(d),weight(w){}};
class compare { public: bool operator()(const edge &a,const edge &b){ return a.weight < b.weight; }};
vector primsAlgorithm(vector>> graph,edge minEdge){
vectorspanningTree;
priority_queue,compare> Q;
while(spanningTree.size() == graph.size()-1){
spanningTree.push_back(minEdge);
for(list>::iterator it = graph[minEdge.src].begin();it!=graph[minEdge.src].end();it++){
Q.push(edge(minEdge.src,it->first,it->second));
}
for(list>::iterator it = graph[minEdge.des].begin();it!=graph[minEdge.des].end();it++){
Q.push(edge(minEdge.des,it->first,it->second));
}
minEdge = Q.top(); Q.pop();
}
return spanningTree;
}
int main(){
vector>>graph;
int v,e,src,des,weight;
cin >> v >> e;
graph.resize(v);
edge minEdge;
minEdge.weight = INF;
while(e--){
cin >> src >> des >> weight;
graph[src].push_back(make_pair(des,weight));
graph[des].push_back(make_pair(src,weight));
if(weight < minEdge.weight){
minEdge.src = src, minEdge.des = des, minEdge.weight = weight;
}
}
vector spanningTree = primsAlgorithm(graph,minEdge);
for(edge x : spanningTree){
cout << x.src << " " << x.des << " " << x.weight << endl;
}
return 0;
}
================================================
FILE: C++/Graph Algorithms/Recursive Depth First Search.cpp
================================================
#include
#include
#include
using namespace std;
void depth_first_search(vector> graph,int src,vector &visited){
if(!visited[src]){
cout << src << " ";
visited[src] = true;
for(list::iterator itr = graph[src].begin();itr != graph[src].end();itr++){
depth_first_search(graph,*itr,visited);
}
}
}
int main(){
vector> graph;
vector visited;
int v,e,src,des;
cin >> v >> e;
graph.resize(v);
visited.resize(v,false);
while(e--){
cin >> src >> des;
graph[src].push_back(des);
}
cin >> src;
depth_first_search(graph,src,visited);
return 0;
}
================================================
FILE: C++/Graph Algorithms/Single Shortest Path Bellman Ford Algorithm.cpp
================================================
#include
#include
#include
using namespace std;
struct edge {int src, des, weight;};
pair> bellmanFord(vector graph,int vertex,int source){
vector distances(vertex,INT_MAX);
distances[source] = 0;
for(int i=0;i distances[graph[j].src] + graph[j].weight){
distances[graph[j].des] = distances[graph[j].src] + graph[j].weight;
}
}
}
for(int j=0;j distances[graph[j].src] + graph[j].weight){
return make_pair(false,vector());
}
}
return make_pair(true,distances);
}
int main(){
int edges,source,vertex;
vector graph;
cin >> edges >> vertex;
for(int i = 0; i < edges; i++){
cin >> graph[i].src >> graph[i].des >> graph[i].weight;
}
cin >> source;
pair> result = bellmanFord(graph,vertex,source);
if(result.first == true){
cout << "No Cycle Exist ! " << endl;
for(vector::iterator itr = (result.second).begin();itr!=(result.second).end();itr++){
cout << *itr << " ";
}
}
else{
cout << "Graph Has Negative Weight Cycle" << endl;
}
return 0;
}
================================================
FILE: C++/Graph Algorithms/Single Source Shortest Path Dijkstra Algorithm.cpp
================================================
#include
#include
#include
#include
#include
using namespace std;
struct compare{
bool operator()(const pair &a,const pair &b){
return a.second > b.second;
}
};
vector dijkshtra(vector>> graph,int src){
priority_queue,vector>,compare> Q;
vector distances(graph.size(),INT_MAX);
vector visited(graph.size(),false);
distances[src] = 0;
Q.push(make_pair(src,0));
while(!Q.empty()){
pair current = Q.top(); Q.pop();
cout << "Currently at" << current.first << endl;
if(!visited[current.first]){
visited[current.first] = true;
for(list> :: iterator vertex = graph[current.first].begin();vertex != graph[current.first].end();vertex++){
if(current.second + vertex->second < distances[vertex->first]){
distances[vertex->first] = current.second + vertex->second;
Q.push(make_pair(vertex->first,distances[vertex->first]));
}
}
}
}
return distances;
}
int main(){
vector>> graph;
int v,e,src,des,weight;
cin >> v >> e;
graph.resize(v);
while(e--){
cin >> src >> des >> weight;
graph[src].push_back(make_pair(des,weight));
}
cin >> src;
vector distances = dijkshtra(graph,src);
for(vector :: iterator itr = distances.begin();itr != distances.end();itr++){
cout << *itr << " ";
}
return 0;
}
================================================
FILE: C++/Graph Algorithms/Topological Sorting.cpp
================================================
#include
#include
#include
using namespace std;
void topologicalSortDFS(vector> graph,int src,vector &visited,list &topologicalSortedList){
if(!visited[src]){
visited[src] = true;
for(list::iterator itr = graph[src].begin();itr != graph[src].end();itr++){
topologicalSortDFS(graph,*itr,visited,topologicalSortedList);
}
topologicalSortedList.push_front(src);
}
}
list topologicalSort(vector> graph){
list topologicalSortedList;
vector visited(graph.size(),false);
for(int src = 0; src < graph.size();src++){
topologicalSortDFS(graph,src,visited,topologicalSortedList);
}
return topologicalSortedList;
}
int main(){
vector> graph;
int v,e,src,des;
cin >> v >> e;
graph.resize(v);
while(e--){
cin >> src >> des;
graph[src].push_back(des);
}
list topologicalSortedList = topologicalSort(graph);
for(list::iterator itr = topologicalSortedList.begin();itr!=topologicalSortedList.end();itr++){
cout << *itr << " ";
}
return 0;
}
================================================
FILE: C++/Heaps - Priority Queues/K-th Largest element of the stream.cpp
================================================
#include
#include
using namespace std;
int main(){
int n,k;
priority_queue,greater>Q;
cout << "Enter the the value of K : ";
cin >> k;
while(cin >> n){
cout << k << "-th largest element of the stream : ";
if(Q.size() < k){
Q.push(n);
if(Q.size() == k){
cout << Q.top() 3<< endl;
}
else{
cout << "NULL" << endl;
}
}
else{
if(Q.top() < n){
Q.pop();
Q.push(n);
}
cout << Q.top() << endl;
}
cout << "Enter next element of the stream : ";
}
return 0;
}
================================================
FILE: C++/Linked List/Reverse a linked list recursively.cpp
================================================
void reverse_list(list_node *head){
list_node *
}
================================================
FILE: C++/Number Theory Algorithms/Divisors.cpp
================================================
#include
#include
using namespace std;
set generateDivisors(long long int num){
set divisors;
for(int i = 1 ; i*i <= num; i++ ){
if(num % i == 0){
divisors.insert(i);
if( i != num/i ){
divisors.insert(num/i);
}
}
}
return divisors;
}
int main(){
set d = generateDivisors(23);
for(int x : d){
cout << x << " ";
}
return 0;
}
================================================
FILE: C++/Number Theory Algorithms/Sieve of Eratosthenes.cpp
================================================
#include
#include
#include
using namespace std;
const int MAX = 1000*1000;
const int LMT = 1000;
vector prime(MAX+1,true);
int seiveEratosthenes(){
prime[0] = prime[1] = false;
for(int i = 2; i <= LMT; i++){
if(prime[i]){
for(int j = i + i; j <= MAX ; j += i){
prime[j] = false;
}
}
}
return count_if(prime.begin(),prime.end(),[](bool p){ return p == true;});
}
int main(){
cout << seiveEratosthenes();
return 0;
}
================================================
FILE: C++/Recursion/Partition of array on the pivot.cpp
================================================
#include
using namespace std;
void partition(int array[],int low,int high){
int i = low-1, pivot = array[high-1];
for(int j = low ; j < high ; j++){
if(array[j] <= pivot){
i++;
swap(array[i],array[j]);
}
}
swap(array[i+1],array[high-1]);
}
int main(){
int n;
cin >> n;
int array[n];
partition(array,0,n);
return 0;
}
================================================
FILE: C++/Recursion/Permutation of a string.cpp
================================================
#include
using namespace std;
void permutation(char str[],int k,int n){
if(k == n){
for(int j = 0; j < n; j++){
cout << str[j];
}
cout << endl;
}
else{
for(int i = k ; i < n; i++){
swap(str[i],str[k]);
permutation(str,k+1,n);
swap(str[i],str[k]);
}
}
}
int main(){
char str[] = {'A','B','C','D'};
permutation(str,0,4);
return 0;
}
================================================
FILE: C++/Segment Tree/Segment Tree.cpp
================================================
void buildTree (int tree[],int array[], int index, int low, int high) {
if (low == high)
tree[index] = array[low];
else {
int mid = (low + high) >> 1;
buildTree (tree,array, index*2, low, mid);
buildTree (tree,array, index*2+1, mid+1, high);
tree[index] = tree[index*2] + tree[index*2+1];
}
}
int rangeQuery (int tree[],int index, int low, int high, int l, int r) {
if (l > r)
return 0;
if (l == low && r == high)
return tree[index];
int mid = (low + high) >> 1;
return rangeQuery (tree,index*2, low, mid, l, min(r,mid))
+ rangeQuery (tree,index*2+1, mid+1, high, max(l,mid+1), r);
}
void updateQuery (int tree[],int index, int low, int high, int pos, int delta) {
if (low == high)
tree[index] = delta;
else {
int mid = (low + high) >> 1;
if (pos <= mid)
updateQuery (tree,index*2, low, mid, pos, delta);
else
updateQuery (tree,index*2+1, mid+1, high, pos, delta);
tree[index] = tree[index*2] + tree[index*2+1];
}
}
================================================
FILE: C++/Stacks - Queue/CircularQueue.cpp
================================================
#include
using namespace std;
class circular_queue
{
private :
int *array ;
int front, back ;
int MAX;
public :
circular_queue( int maxsize = 10 ) ;
void enqueue ( int item ) ;
int dequeue( ) ;
void display( ) ;
} ;
circular_queue :: circular_queue( int maxsize )
{
MAX = maxsize ;
array = new int [ MAX ];
front = back = -1 ;
for ( int i = 0 ; i < MAX ; i++ )
array[i] = 0 ;
}
void circular_queue :: enqueue(int item){
if((back+1)%MAX == front){
cout << "Queue is full" << endl;
return ;
}
back = ( back + 1 ) % MAX;
array[back] = item ;
if ( front == -1 )
front = 0 ;
}
int circular_queue :: dequeue(){
int data ;
if ( front == -1 )
{
cout << "\nQueue is empty" ;
return NULL ;
}
data = array[front] ;
array[front] = 0 ;
if ( front == back )
{
front = -1 ;
back = -1 ;
}
else
front = ( front + 1 ) % MAX;
return data ;
}
void circular_queue :: display()
{
cout << endl ;
for ( int i = 0 ; i < MAX ; i++ )
cout << array[i] << " " ;
cout << endl ;
}
int main(){
circular_queue cq(10) ;
cq.enqueue(14);
cq.enqueue(22);
cq.enqueue(13);
cq.enqueue(-6);
cq.enqueue(25);
cout << "\nElements in the circular queue: " ;
cq.display();
int i = cq.dequeue() ;
cout << "Item deleted: " << i ;
i = cq.dequeue();
cout << "\nItem deleted: " << i ;
cout << "\nElements in the circular queue after deletion: " ;
cq.display();
cq.enqueue(21);
cq.enqueue(17);
cq.enqueue(18);
cq.enqueue(9);
cq.enqueue(20);
cout << "Elements in the circular queue after addition: " ;
cq.display();
cq.enqueue(32);
cout << "Elements in the circular queue after addition: " ;
cq.display();
return 0;
}
================================================
FILE: C++/String Algorithms/KMP.cpp
================================================
vector computePrefix(string pat){
int m = pat.size();
vector longestPrefix(m);
for(int i = 1, k = 0; i < m; i++){
while(k > 0 && pat[k] != pat[i]){
k = longestPrefix[k - 1];
}
if(pat[i] == pat[k]){
longestPrefix[i] = ++k;
}
else{
longestPrefix[i] = k;
}
}
return longestPrefix;
}
void KMP(string str,string pat){
int n = str.size();
int m = pat.size();
vector longestPrefix = computePrefix(pat);
for(int i = 0, k = 0; i < n; i++){
while(k > 0 && pat[k] != str[i]){
k = longestPrefix[k - 1];
}
if(str[i] == pat[k]){
k++;
}
if(k == m){
cout << i - m + 1 << "\n";
k = longestPrefix[k - 1];
}
}
}
================================================
FILE: C++/String Algorithms/Trie.cpp
================================================
struct Trie {
Trie* child[26];
bool isLeaf;
Trie() {
memset(child, 0, sizeof(child));
isLeaf = 0;
}
void pushWord(char *str) {
if(*str == '\0')
isLeaf = 1;
else {
int cur = *str - 'a';
if(child[cur] == 0 )
child[cur] = new Trie();
child[cur]->pushWord(str+1);
}
}
bool wordExist(char* str) {
if(*str == '\0')
return isLeaf;
int cur = *str - 'a';
if(child[cur] == 0 )
return false;
return child[cur]->wordExist(str+1);
}
bool prefixExist(char* str) {
if(*str == '\0')
return true;
int cur = *str - 'a';
if(child[cur] == 0 )
return false;
return child[cur]->prefixExist(str+1);
}
};
================================================
FILE: C++/Union Find/Union Find.cpp
================================================
#include
using namespace std;
class UnionFind {
int *parent, *ranks, _size;
public:
UnionFind(){
}
UnionFind(int size){
parent = new int[size]; ranks = new int[size];
for(int element = 0 ; element < size ; element++){
parent[element] = element , ranks[element] = 0 ;
}
_size = size;
}
void resize(int size){
parent = new int[size]; ranks = new int[size];
for(int element = 0 ; element < size ; element++){
parent[element] = element , ranks[element] = 0 ;
}
_size = size;
}
int find(int element){
if(parent[element] == element){
return element;
}
else{
return parent[element] = find(parent[element]); // Path Compression algorithm
}
}
bool connected(int x,int y){
if(find(x) == find(y)){
return true;
}
else{
return false;
}
}
void merge(int x,int y){
x = find(x);
y = find(y);
if(x != y){ // Union by Rank algorithm
if(ranks[x] > ranks[y]){
parent[y] = x;
}
else if(ranks[x] < ranks[y]){
parent[x] = y;
}
else{
parent[x] = y; ranks[y] ++ ;
}
_size--;
}
}
void clear(){
delete [] parent; delete [] ranks;
}
int size(){
return _size;
}
};
int main(){
UnionFind uf(5);
cout << uf.size() << endl; // 5 disjoint sets are there
uf.merge(0,1);
cout << uf.size() << endl; // 4 disjoint sets are there
uf.merge(0,2);
cout << uf.size() << endl; // 3 disjoint sets are there
uf.merge(1,2);
cout << uf.size() << endl; // 3 disjoint sets are there
uf.clear();
return 0;
}
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
Please visit my wiki link for full list of questions
https://github.com/mission-peace/interview/wiki
Like my facebook page for latest updates on my youtube channel
https://www.facebook.com/tusharroy25
Contribution
Please contribute to this repository to help it make better. Any change like new question, code improvement, doc improvement etc. is very welcome. Just send me a pull request and I will review the request and approve it if it looks good.
How to use this repository
Softwares to install
* Install JDK8 https://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html
* Install Git https://git-scm.com/book/en/v2/Getting-Started-Installing-Git
* Install either Intellij https://www.jetbrains.com/idea/download/
* If you like eclipse instead of intellij install eclipse https://eclipse.org/downloads/
Set up your desktop
* Pull the git repository. Go to command line and type git clone https://github.com/mission-peace/interview.git
* Go to root directory of checked out project.
* Run ./gradlew idea to generate idea related classes
* Fire up intellij. Go to Open. Go to git repo folder and open interview.ipr . On file menu go to project structure. Update language level support to 8
* If you use eclipse, do ./gradlew eclipse . This will generate eclipse related files. Go to eclipse and open up folder containing this repo.
* Go to any program and run that program
* Go to any test and run the junit test.
* Run ./gradlew build to create classes, run tests and create jar.
================================================
FILE: build.gradle
================================================
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'eclipse'
apply plugin: "jacoco"
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
testCompile 'junit:junit:4.12'
}
sourceSets {
main {
java {
srcDir 'src'
}
}
test {
java {
srcDir 'test'
}
}
}
jacocoTestReport {
reports {
xml.enabled false
csv.enabled false
html.destination "${buildDir}/jacocoHtml"
}
}
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Sat Apr 02 16:59:09 PDT 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.11-bin.zip
================================================
FILE: gradlew
================================================
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
================================================
FILE: python/array/arrayaddition.py
================================================
def add(arr1, arr2):
l = max(len(arr1), len(arr2))
result = [0 for j in range(l)]
c = 0
i = len(arr1) - 1
j = len(arr2) - 1
r = 0
l -= 1
while i >= 0 and j >= 0:
r = arr1[i] + arr2[j] + c
i -= 1
j -= 1
c = r // 10
result[l] = r % 10
l -= 1
while i >= 0:
r = arr1[i] + c
i -= 1
c = r // 10
result[l] = r % 10
l -= 1
while j >= 0:
r = arr1[j] + c
j -= 1
c = r // 10
result[l] = r % 10
l -= 1
if c != 0:
new_result = [0 for j in range(len(result) + 1)]
t = len(new_result) - 1
while t > 0:
new_result[t] = result[t - 1]
t -= 1
new_result[0] = c
return new_result
return result
arr1 = [9, 9, 9, 9, 9, 9, 9]
arr2 = [1, 6, 8, 2, 6, 7]
result = add(arr1, arr2)
print(result)
================================================
FILE: python/array/commonthreesortedarray.py
================================================
# http://www.geeksforgeeks.org/find-common-elements-three-sorted-arrays/
def common_elements(input1, input2, input3):
result = []
i = 0
j = 0
k = 0
while i < len(input1) and j < len(input2) and k < len(input3):
if input1[i] == input2[j] and input2[j] == input3[k]:
result.append(input1[i])
i = i + 1
j = j + 1
k = k + 1
elif input1[i] < input2[j]:
i = i + 1
elif input2[j] < input3[k]:
j = j + 1
else:
k = k + 1
return result
if __name__ == '__main__':
input1 = [1, 5, 10, 20, 40, 80]
input2 = [6, 7, 20, 80, 100]
input3 = [3, 4, 15, 20, 30, 70, 80, 120]
print(common_elements(input1, input2, input3))
================================================
FILE: python/array/countinversionofsize3.py
================================================
# http://www.geeksforgeeks.org/count-inversions-of-size-three-in-a-give-array/
def find_inversions(input):
inversion = 0
for i in range(1, len(input) - 1):
larger = 0
for k in range(0, i):
if input[k] > input[i]:
larger = larger + 1
smaller = 0
for k in range(i+1, len(input)):
if input[k] < input[i]:
smaller = smaller + 1
inversion += larger*smaller
return inversion
if __name__ == '__main__':
input = [9, 6, 4, 5, 8]
print(find_inversions(input))
================================================
FILE: python/array/flip0smaximum1s.py
================================================
# http://www.geeksforgeeks.org/find-zeroes-to-be-flipped-so-that-number-of-consecutive-1s-is-maximized/
def flip_0s_to_maximize_consecutive_1s(input, flips_allowed):
window_start = 0
count_zero = 0
result = 0
for i in range(len(input)):
if input[i] == 1:
result = max(result, i - window_start + 1)
else:
if count_zero < flips_allowed:
count_zero = count_zero + 1
result = max(result, i - window_start + 1)
else:
while True:
if input[window_start] == 0:
window_start = window_start + 1
break
window_start = window_start + 1
return result
if __name__ == '__main__':
input = [0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1]
print(flip_0s_to_maximize_consecutive_1s(input, 1))
================================================
FILE: python/array/longestsamesumspan.py
================================================
# http://www.geeksforgeeks.org/longest-span-sum-two-binary-arrays/
# java code https://github.com/mission-peace/interview/blob/master/src/com/interview/array/LongestSameSumSpan.java
def longest_span(input1, input2):
if len(input1) != len(input2):
raise ValueError;
diff = {}
prefix1 = 0
prefix2 = 0
max_span = 0
diff[0] = -1
for i in range(len(input1)):
prefix1 += input1[i]
prefix2 += input2[i]
curr_diff = prefix1 - prefix2
if curr_diff in diff:
max_span = max(max_span, i - diff[curr_diff])
else:
diff[curr_diff] = i
return max_span
if __name__ == '__main__':
input1 = [1, 0, 0, 1, 1, 0]
input2 = [0, 1, 1, 0, 1, 1]
print(longest_span(input1, input2))
================================================
FILE: python/array/maximumsumpathtwoarrays.py
================================================
# http://www.geeksforgeeks.org/maximum-sum-path-across-two-arrays/
def max_sum(input1, input2):
max_sum = 0
i = 0
j = 0
sum1 = 0
sum2 = 0
while i < len(input1) and j < len(input2):
if input1[i] == input2[j]:
if sum1 > sum2:
max_sum += sum1 + input1[i]
else:
max_sum += sum2 + input2[j]
i = i + 1
j = j + 1
sum1 = 0
sum2 = 0
elif input1[i] < input2[j]:
sum1 += input1[i]
i = i + 1
else:
sum2 += input2[j]
j = j + 1
while i < len(input1):
sum1 += input1[i]
i = i + 1
while j < len(input2):
sum2 += input2[j]
j = j + 1
if sum1 > sum2:
max_sum += sum1
else:
max_sum += sum2
return max_sum
if __name__ == '__main__':
input1 = [2, 3, 7, 10, 12, 15, 30, 34]
input2 = [1, 5, 7, 8, 10, 15, 16, 19]
print(max_sum(input1, input2))
================================================
FILE: python/array/maxproductsubarray.py
================================================
# http://www.geeksforgeeks.org/maximum-product-subarray/
def max_product(input):
max_ending = 1
min_ending = 1
max_so_far = 1
for i in input:
if i > 0:
max_ending = max_ending * i
min_ending = min(min_ending*i, 1)
elif i == 0:
max_ending = 1
min_ending = 1
else:
t = max_ending
max_ending = max(min_ending*i, 1)
min_ending = t * i
if max_so_far < max_ending:
max_so_far = max_ending
return max_so_far
if __name__ == '__main__':
input = [-6,-3,8,-9,-1,-1,3,6,9,0,3,-1]
print(max_product(input))
================================================
FILE: python/array/numberoftrianglesunsortedarray.py
================================================
# http://www.geeksforgeeks.org/find-number-of-triangles-possible/
def number_of_triangles(input):
input.sort()
count = 0
for i in range(len(input)-2):
k = i + 2
for j in range(i+1, len(input)):
while k < len(input) and input[i] + input[j] > input[k]:
k = k + 1
count += k - j - 1
return count
if __name__ == '__main__':
input = [15, 9, 8, 3, 4, 5, 6]
print(number_of_triangles(input))
================================================
FILE: python/array/positiveandnegativealternativelymaintainingorder.py
================================================
# http://www.geeksforgeeks.org/rearrange-array-alternating-positive-negative-items-o1-extra-space/
def rearrange(input):
for i in range (len(input)):
if i%2 == 0 and input[i] >= 0:
index_of_next_negative = find_next(input, i+1, False)
if index_of_next_negative == -1:
return
else:
right_rotate(input, i, index_of_next_negative)
elif i % 2 != 0 and input[i] < 0:
index_of_next_positive = find_next(input, i+1, True)
if index_of_next_positive == -1:
return
else:
right_rotate(input, i, index_of_next_positive)
def find_next(input, start, isPositive):
for i in range(start, len(input)):
if (isPositive and input[i] >= 0) or (not isPositive and input[i] < 0):
return i;
return -1
def right_rotate(input, start, end):
t = input[end]
for i in range(end, start -1, -1):
input[i] = input[i-1]
input[start] = t
if __name__ == '__main__':
input = [-5, -2, 5, 2, 4, 7, 1, 8, 0, -8];
rearrange(input)
print(input)
================================================
FILE: python/array/rearrangearrayperindex.py
================================================
# http://www.geeksforgeeks.org/rearrange-array-arrj-becomes-arri-j/
def rearrange(input):
for i in range(len(input)):
input[i] += 1
for i in range(len(input)):
if input[i] > 0:
rearrange_util(input, i)
for i in range(len(input)):
input[i] = -input[i] - 1
def rearrange_util(input, start):
i = start + 1
v = input[start]
while v > 0:
t = input[v-1]
input[v-1] = -i
i = v
v = t
if __name__ == '__main__':
input = [1, 2, 0, 5, 3, 4];
rearrange(input)
print(input)
================================================
FILE: python/array/reorderarraybyindex.py
================================================
# http://www.geeksforgeeks.org/reorder-a-array-according-to-given-indexes/
def reorder(input, index):
if len(input) != len(index):
raise ValueError
for i in range(len(index)):
while index[i] != i:
s_index = index[index[i]]
s_val = input[index[i]]
index[index[i]] = index[i]
input[index[i]] = input[i]
index[i] = s_index
input[i] = s_val
if __name__ == '__main__':
input = [50, 40, 70, 60, 90]
index = [3, 0, 4, 1, 2]
reorder(input, index)
print(input)
print(index)
================================================
FILE: python/array/rotationwithmaxsum.py
================================================
# http://www.geeksforgeeks.org/find-maximum-value-of-sum-iarri-with-only-rotations-on-given-array-allowed/
def max_sum(input):
arr_sum = 0
rotation_sum = 0
for i in range(len(input)):
arr_sum += input[i]
rotation_sum += i*input[i]
max_rotation_sum = rotation_sum
for i in range(1, len(input)):
rotation_sum += len(input)*input[i-1] - arr_sum
max_rotation_sum = max(max_rotation_sum, rotation_sum)
return max_rotation_sum
if __name__ == '__main__':
input = [10, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(max_sum(input))
================================================
FILE: python/array/smallestintegernotrepresentedbysubsetsum.py
================================================
# http://www.geeksforgeeks.org/find-smallest-value-represented-sum-subset-given-array/
def find_smallest_integer(input):
result = 1
for i in range(len(input)):
if input[i] <= result:
result += input[i]
else:
break
return result
if __name__ == '__main__':
input = [1, 2, 3, 8]
print(find_smallest_integer(input))
================================================
FILE: python/array/tripletsumlessthantotal.py
================================================
# http://www.geeksforgeeks.org/count-triplets-with-sum-smaller-that-a-given-value/
def find_all_triplet(input, total):
input.sort()
result = 0
for i in range(len(input) - 2):
j = i + 1
k = len(input) - 1
while j < k:
if input[i] + input[j] + input[k] >= total:
k = k - 1
else:
result += k - j
j = j + 1
return result
if __name__ == '__main__':
input = [5, 1, 3, 4, 7]
print(find_all_triplet(input, 12))
================================================
FILE: python/array/zigzagarrangement.py
================================================
# http://www.geeksforgeeks.org/convert-array-into-zig-zag-fashion/
def rearrange(input):
is_less = True
for i in range(len(input)-1):
if is_less:
if input[i] > input[i+1]:
swap(input, i, i+1)
else:
if input[i] < input[i+1]:
swap(input, i, i+1)
is_less = not is_less
def swap(input, i, j):
t = input[i]
input[i] = input[j]
input[j] = t
if __name__ == '__main__':
input = [4, 3, 2, 6, 7, 1, 9]
rearrange(input)
print(input)
================================================
FILE: python/dynamic/bitonicsequence.py
================================================
"""
Problem Statement
=================
Find the length of the longest Bitonic Sequence in a given sequence of numbers. A Bitonic sequence is a sequence of
numbers which are increasing and then decreasing.
Video
-----
* https://youtu.be/TWHytKnOPaQ
Analysis
--------
* Runtime O(n)
Reference
---------
* http://www.geeksforgeeks.org/dynamic-programming-set-15-longest-bitonic-subsequence/
"""
def longest_bitonic(sequence):
length_of_input = len(sequence)
increasing_sequence = [1] * length_of_input
decreasing_sequence = [1] * length_of_input
for i in range(1, length_of_input):
for j in range(0, i):
if sequence[i] > sequence[j]:
increasing_sequence[i] = max(increasing_sequence[i], increasing_sequence[j] + 1)
for i in range(length_of_input - 2, -1, -1):
for j in range(length_of_input - 1, i, -1):
if sequence[i] > sequence[j]:
decreasing_sequence[i] = max(decreasing_sequence[i], decreasing_sequence[j] + 1)
max_value = 0
for i in range(len(sequence)):
bitonic_sequence_length = increasing_sequence[i] + decreasing_sequence[i] - 1
max_value = max(max_value, bitonic_sequence_length)
return max_value
if __name__ == '__main__':
max_value = longest_bitonic([1, 4, 3, 7, 2, 1, 8, 11, 13, 0])
assert 7 == max_value # 1, 4, 7, 8, 11, 13, 0
================================================
FILE: python/dynamic/boxstacking.py
================================================
"""
Problem Statement
=================
Given different dimensions and unlimited supply of boxes for each dimension, stack boxes on top of each other such that
it has maximum height but with caveat that length and width of box on top should be strictly less than length and width
of box under it. You can rotate boxes as you like.
1) Create all rotations of boxes such that length is always greater or equal to width
2) Sort boxes by base area in non increasing order (length * width). This is because box
with more area will never ever go on top of box with less area.
3) Take T[] and result[] array of same size as total boxes after all rotations are done
4) Apply longest increasing subsequence type of algorithm to get max height.
Analysis
--------
If n number of dimensions are given total boxes after rotation will be 3n.
* Space complexity is O(n)
* Time complexity - O(nlogn) to sort boxes. O(n^2) to apply DP on it So really O(n^2)
Video
-----
* https://youtu.be/9mod_xRB-O0
References
----------
* http://www.geeksforgeeks.org/dynamic-programming-set-21-box-stacking-problem/
* http://people.cs.clemson.edu/~bcdean/dp_practice/
"""
from collections import namedtuple
from itertools import permutations
dimension = namedtuple("Dimension", "height length width")
def create_rotation(given_dimensions):
"""
A rotation is an order wherein length is greater than or equal to width. Having this constraint avoids the
repetition of same order, but with width and length switched.
For e.g (height=3, width=2, length=1) is same the same box for stacking as (height=3, width=1, length=2).
:param given_dimensions: Original box dimensions
:return: All the possible rotations of the boxes with the condition that length >= height.
"""
for current_dim in given_dimensions:
for (height, length, width) in permutations((current_dim.height, current_dim.length, current_dim.width)):
if length >= width:
yield dimension(height, length, width)
def sort_by_decreasing_area(rotations):
return sorted(rotations, key=lambda dim: dim.length * dim.width, reverse=True)
def can_stack(box1, box2):
return box1.length < box2.length and box1.width < box2.width
def box_stack_max_height(dimensions):
boxes = sort_by_decreasing_area([rotation for rotation in create_rotation(dimensions)])
num_boxes = len(boxes)
T = [rotation.height for rotation in boxes]
R = [idx for idx in range(num_boxes)]
for i in range(1, num_boxes):
for j in range(0, i):
if can_stack(boxes[i], boxes[j]):
stacked_height = T[j] + boxes[i].height
if stacked_height > T[i]:
T[i] = stacked_height
R[i] = j
max_height = max(T)
start_index = T.index(max_height)
# Prints the dimensions which were stored in R list.
while True:
print boxes[start_index]
next_index = R[start_index]
if next_index == start_index:
break
start_index = next_index
return max_height
if __name__ == '__main__':
d1 = dimension(3, 2, 5)
d2 = dimension(1, 2, 4)
assert 11 == box_stack_max_height([d1, d2])
================================================
FILE: python/dynamic/breakword.py
================================================
"""
Problem Statement
=================
Given a string and a dictionary, split the string in to multiple words so that each word belongs to the dictionary.
Video
-----
* https://youtu.be/WepWFGxiwRs
Analysis
--------
* word_break_recursive: Exponential
* word_break_dp : O(n^3)
Solution
--------
if input[i..j] belongs in a dictionary:
DP[i][j] = True
else:
DP[i][j] = True if DP[i][k-1] and DP[k][j] for any k between i to j.
Multiple different implementations are given below.
"""
def word_break_recursive(given_string, dictionary):
""""Returns None if the given string cannot be broken into words, otherwise returns space separate words."""
given_string_length = len(given_string)
if given_string_length == 0:
return ""
string = ""
for i in range(given_string_length):
string += given_string[i]
if string in dictionary:
r = word_break_recursive(given_string[i + 1:], dictionary)
if r is not None:
string += " " + r
return string
return None
def word_break_dp(given_string, dictionary):
"""Returns None if the given string cannot be broken into words, otherwise returns space separated words."""
given_string_length = len(given_string)
# -1 indicates the word cannot be split.
DP = [[-1 for _ in range(given_string_length)] for _ in range(given_string_length)]
for substring_length in range(1, given_string_length + 1):
for start in range(0, given_string_length - substring_length + 1):
end = start + substring_length - 1
substring = given_string[start: end + 1]
if substring in dictionary:
DP[start][end] = start
continue
for split in range(start + 1, end + 1):
if DP[start][split - 1] != -1 and DP[split][end] != -1:
DP[start][end] = split
break
if DP[0][-1] == -1:
return None
words = []
start_index = 0
end_index = given_string_length - 1
while start_index < given_string_length:
split_index = DP[start_index][end_index]
if start_index == split_index:
words.append(given_string[start_index: end_index + 1])
break
else:
words.append(given_string[start_index: split_index])
start_index = split_index
return " ".join(words)
def is_word_break_possible(given_string, dictionary):
"""Returns if any word break is possible amongst the multiple word breaks in the sentence."""
DP = dict()
max_word_length = len(max(dictionary, key=len))
return is_word_break_possible_recursive_helper(given_string, dictionary, 0, max_word_length, DP)
def is_word_break_possible_recursive_helper(given_string, dictionary, start, max_word_length, DP):
if start == len(given_string):
return True
if start in DP:
return DP[start]
for i in range(start, start + max_word_length):
if i < len(given_string):
new_word = given_string[start: i + 1]
if new_word in dictionary:
continue
if is_word_break_possible_recursive_helper(given_string, dictionary, i + 1, max_word_length, DP):
DP[start] = True
return True
DP[start] = False
return False
def all_possible_word_break_helper(given_string, dictionary, start, max_word_length, DP):
""""Returns all possible word breaks in a given sentence."""
if start == len(given_string):
return [""]
if start in DP:
return DP[start]
words = []
for i in range(start, start + max_word_length):
if i < len(given_string):
new_word = given_string[start: i + 1]
if new_word not in dictionary:
continue
sub_words = all_possible_word_break_helper(given_string, dictionary, i + 1, max_word_length, DP)
for word in sub_words:
extra_space = "" if len(word) == 0 else " "
words.append(new_word + extra_space + word)
DP[start] = words
return words
def all_possible_word_breaks(given_string, dictionary):
DP = dict()
max_word_length = len(max(dictionary, key=len))
return all_possible_word_break_helper(given_string, dictionary, 0, max_word_length, DP)
if __name__ == '__main__':
dictionary = {"joy", "likes", "to", "play"}
given_string = "joylikestoplay"
assert True == is_word_break_possible(given_string, dictionary)
assert "joy likes to play " == word_break_recursive(given_string, dictionary)
assert "joy likes to play" == word_break_dp(given_string, dictionary)
dictionary = {"pea", "nut", "peanut", "butter"}
given_string = "peanutbutter"
assert ['pea nut butter', 'peanut butter'] == all_possible_word_breaks(given_string, dictionary)
================================================
FILE: python/dynamic/coin_change_num_ways.py
================================================
"""
Problem Statement
=================
Given a total and coins of certain denominations find number of ways total can be formed from coins assuming infinity
supply of coins.
Analysis
--------
* Runtime : O(num_of_coins * total)
Video
-----
* https://youtu.be/_fgjrs570YE
Reference
---------
* http://www.geeksforgeeks.org/dynamic-programming-set-7-coin-change/
"""
def coin_changing_num_ways(coins, total):
cols = total + 1 # 1 for value 0 in total
rows = len(coins)
T = [[1 if col == 0 else 0 for col in range(cols)] for _ in range(rows)]
for i in range(rows):
for j in range(cols):
if (i - 1) < 0:
continue
if j < coins[i]:
T[i][j] = T[i - 1][j]
else:
T[i][j] = T[i - 1][j] + T[i][j - coins[i]]
return T[rows - 1][cols - 1]
def coin_changing_num_ways2(coins, total):
cols = total + 1
num_coins = len(coins)
# Using 1-D Array instead of 2-D Array. Approach is same as coin_changing_num_ways.
T = [1 if col == 0 else 0 for col in range(cols)]
for i in range(num_coins):
for col in range(1, cols):
if col >= coins[i]:
T[col] += T[col - coins[i]]
return T[cols - 1]
def print_coin_changes_recursive(coins, total, results_stack, pos):
if total == 0:
for coin in results_stack:
print "%d " % coin,
print
for idx in range(pos, len(coins)):
if total >= coins[idx]:
results_stack.append(coins[idx])
print_coin_changes_recursive(coins, total - coins[idx], results_stack, idx)
results_stack.pop() # Remove last inserted coin from stack to use new coin with different index.
def print_coin_changes(coins, total):
print_coin_changes_recursive(coins, total, list(), 0)
if __name__ == '__main__':
coins = [1, 2, 3]
total = 5
expected = 5
assert expected == coin_changing_num_ways(coins, total)
assert expected == coin_changing_num_ways2(coins, total)
print_coin_changes(coins, total)
================================================
FILE: python/dynamic/coinchangingmincoins.py
================================================
"""
Problem Statement
=================
Given coins of certain denominations with infinite supply find minimum number of coins it takes to form given total
Video
-----
* Topdown DP - https://youtu.be/Kf_M7RdHr1M
* Bottom Up DP - https://youtu.be/Y0ZqKpToTic (Approach 1. 2D array.)
* Bottom up DP - https://youtu.be/NJuKJ8sasGk (Same as Approach 1. Uses 1D array since 2D array is not required.)
Analysis
--------
* Time complexity - O(len(coins) * total)
* Space complexity - O(len(coins) * total)
"""
def min_coins(coins, total):
cols = total + 1
rows = len(coins)
T = [[0 if col == 0 else float("inf") for col in range(cols)] for _ in range(rows)]
for i in range(rows):
for j in range(1, cols):
if j < coins[i]:
T[i][j] = T[i - 1][j]
else:
T[i][j] = min(T[i - 1][j], 1 + T[i][j - coins[i]])
return T[rows - 1][cols - 1]
def print_coins(R, coins):
start = len(R) - 1
if R[start] == -1:
print "No Solution Possible."
return
print "Coins:",
while start != 0:
coin = coins[R[start]]
print "%d " % coin,
start = start - coin
def min_coins2(coins, total):
cols = total + 1
T =[0 if idx == 0 else float("inf") for idx in range(cols)]
R = [-1 for _ in range(total + 1)]
for j in range(len(coins)):
for i in range(1, cols):
coin = coins[j]
if i >= coins[j]:
if T[i] > 1 + T[i - coin]:
T[i] = 1 + T[i - coin]
R[i] = j
print_coins(R, coins)
return T[cols - 1]
def min_coins_top_down(coins, total, memo):
if total == 0:
return 0
if total in memo:
return memo[total]
min_value = float("inf")
for i in range(len(coins)):
coin = coins[i]
if coin > total:
continue
val = min_coins_top_down(coins, total - coin, memo)
min_value = min(min_value, val)
min_value += 1
memo[total] = min_value
return min_value
if __name__ == '__main__':
coins = [1, 5, 6, 8]
total = 11
expected = 2
assert expected == min_coins(coins, total)
assert expected == min_coins2(coins, total)
assert expected == min_coins_top_down(coins, total, dict())
================================================
FILE: python/dynamic/count_num_A.py
================================================
"""
Problem Statement
=================
Imagine you have a special keyboard with the following keys:
Key 1: Prints 'A' on screen
Key 2: (Ctrl-A): Select screen
Key 3: (Ctrl-C): Copy selection to buffer
Key 4: (Ctrl-V): Print buffer on screen appending it
after what has already been printed.
If you can only press the keyboard for N times (with the above four
keys), write a program to produce maximum numbers of A's. That is to
say, the input parameter is N (No. of keys that you can press), the
output is M (No. of As that you can produce).
Complexity
----------
* Recursive Solution : Exponential > O(2^n)
* Dynamic Programming: Quadratic O(n^2)
Reference
---------
* http://www.geeksforgeeks.org/how-to-print-maximum-number-of-a-using-given-four-keys/
"""
def count_a_recursive(n_times):
if n_times < 7:
return n_times
result = float("-inf")
for sub_prob in range(n_times - 3, 0, -1):
result = max(result, (n_times - sub_prob - 1) * count_a_recursive(sub_prob))
return result
def count_a(n_times):
if n_times < 7:
return n_times
T = [0 for _ in range(n_times + 1)]
for num in range(7):
T[num] = num
for n in range(7, n_times + 1):
for sub_prob in range(n - 3, 0, -1):
T[n] = max(T[n], T[sub_prob] * (n - sub_prob - 1))
return T[n_times]
if __name__ == '__main__':
expected = 9
assert expected == count_a_recursive(7)
assert expected == count_a(7)
================================================
FILE: python/dynamic/count_num_binary_without_consec_1.py
================================================
"""
Problem Statement
=================
Given a positive integer N, count all the numbers from 1 to 2^N, whose binary representation does not have consecutive
1s.
This is a simple application of fibonacci series.
Video
-----
* https://www.youtube.com/watch?v=a9-NtLIs1Kk
Complexity
----------
* Runtime Complexity: O(n)
Reference
---------
* http://www.geeksforgeeks.org/count-number-binary-strings-without-consecutive-1s/
"""
def consec_one(num_n):
f1 = f2 = 1
for _ in range(num_n):
f1, f2 = f1 + f2, f1
return f1
if __name__ == '__main__':
assert 13 == consec_one(5)
================================================
FILE: python/dynamic/cutting_rod.py
================================================
"""
Problem Statement
=================
Given a rod of length n inches and an array of prices that contains prices of all pieces of size smaller than n.
Determine the maximum value obtainable by cutting up the rod and selling the pieces.
Video
-----
* https://youtu.be/IRwVmTmN6go
Time Complexity
---------------
1. Recursive Solution = O(2^n)
2. Dynamic Programming Solution = O(n^2)
Reference
---------
http://www.geeksforgeeks.org/dynamic-programming-set-13-cutting-a-rod/
"""
def max_profit_dp(prices, rod_length):
rod_length_values = [0 for _ in range(rod_length + 1)]
for length in range(1, rod_length + 1):
max_value = float("-inf")
for cut_length in range(1, length + 1):
max_value = max(max_value, prices[cut_length - 1] + rod_length_values[length - cut_length])
rod_length_values[length] = max_value
return rod_length_values[rod_length]
def max_profit_recursive(prices, rod_length):
if rod_length == 0:
return 0
max_price = float('-inf')
for length in range(1, rod_length + 1):
max_price = max(max_price, prices[length - 1] + max_profit_recursive(prices, rod_length - length))
return max_price
if __name__ == '__main__':
prices = [3,5,8,9,10,20,22,25]
rod_length = 8
expected_max_profit = 26
assert expected_max_profit == max_profit_recursive(prices, rod_length)
assert expected_max_profit == max_profit_dp(prices, rod_length)
================================================
FILE: python/dynamic/dice_throw_ways.py
================================================
"""
Problem Statement
=================
Given n dice each with m faces, numbered from 1 to m, find the number of ways to get sum X. X is the summation of values
on each face when all the dice are thrown.
Complexity
----------
* Run time complexity: O(m * n * x) where m is number of faces, n is number of dice and x is given sum.
References
----------
* http://www.geeksforgeeks.org/dice-throw-problem/
"""
def num_ways(faces, dices, sumX):
T = [[0 for _ in range(sumX + 1)] for _ in range(dices + 1)]
# For a single dice
for face_value in range(1, faces + 1):
if face_value <= sumX:
T[1][face_value] = 1
for dice in range(2, dices + 1):
for partial_sum in range(1, sumX + 1):
for face_value in range(1, faces + 1):
if face_value < partial_sum:
T[dice][partial_sum] += T[dice - 1][partial_sum - face_value]
return T[dices][sumX]
if __name__ == '__main__':
assert 7 == num_ways(3, 3, 6)
================================================
FILE: python/dynamic/editdistance.py
================================================
"""
Problem Statement
=================
Given two strings str1 and str2, find the minimum number of edits (edit one character to another, delete char from str1
or delete char from str2) to change str1 to str2.
Video
-----
* https://youtu.be/We3YDTzNXEk
Analysis
--------
* DP Runtime : O(len(str1) * len(str2))
* Recursive Solution: Exponential (O(3^(m+n-1)))
Reference
---------
* https://www.clear.rice.edu/comp130/12spring/editdist/
"""
def print_edits(T, str1, str2):
i = len(T) - 1
j = len(T[0]) - 1
while True:
if i == 0 or j == 0:
break
if str2[i - 1] == str1[j - 1]:
i -= 1
j -= 1
elif T[i][j] == T[i - 1][j - 1] + 1:
print "Edit %s in string1 to %s in string2." % (str1[j - 1], str2[i - 1])
i -= 1
j -= 1
elif T[i][j] == T[i - 1][j] + 1:
print "Delete %s in string2." % str2[i - 1]
i -= 1
elif T[i][j] == T[i][j - 1] + 1:
print "Delete %s in string1." % str1[j - 1]
j -= 1
def min_edit_distance(str1, str2):
rows = len(str2) + 1
cols = len(str1) + 1
T = [[0 for _ in range(cols)] for _ in range(rows)]
for j in range(cols):
T[0][j] = j
for i in range(rows):
T[i][0] = i
for i in range(1, rows):
for j in range(1, cols):
if str2[i - 1] == str1[j - 1]:
T[i][j] = T[i - 1][j - 1]
else:
T[i][j] = 1 + min(T[i - 1][j - 1], T[i - 1][j], T[i][j - 1])
print_edits(T, str1, str2)
return T[rows - 1][cols - 1]
def min_edit_distance_recursive(str1, str2):
i = len(str1)
j = len(str2)
if i == 0: return j
if j == 0: return i
return min(min_edit_distance_recursive(str1[:i - 1], str2) + 1,
min_edit_distance_recursive(str1, str2[:j - 1]) + 1,
min_edit_distance_recursive(str1[:i - 1], str2[:j - 1]) + (1 if str1[i - 1] != str2[j - 1] else 0))
if __name__ == '__main__':
str1 = "azced"
str2 = "abcdef"
expected = 3
assert expected == min_edit_distance(str1, str2)
assert expected == min_edit_distance(str2, str1)
assert expected == min_edit_distance_recursive(str1, str2)
================================================
FILE: python/dynamic/egg_drop.py
================================================
"""
Problem Statement
=================
Given a certain number of eggs and a certain number of floors, determine the minimum number of attempts required to find
the egg breaking floor.
Analysis
--------
* Dynamic Programming Time Complexity: O(eggs * num_floors^2)
* Recursive Solution: Exponential
Video
-----
* https://youtu.be/3hcaVyX00_4
Reference
---------
* http://www.geeksforgeeks.org/dynamic-programming-set-11-egg-dropping-puzzle/
"""
def min_attempts_egg_drop(eggs, floors):
num_eggs = eggs + 1
num_floors = floors + 1
T = [[floor if egg == 1 else 0 for floor in range(num_floors)] for egg in range(num_eggs)]
for egg in range(2, num_eggs):
for floor in range(1, num_floors):
T[egg][floor] = min(1 + max(T[egg - 1][k - 1], T[egg][floor - k]) for k in range(1, floor + 1))
return T[num_eggs - 1][num_floors - 1]
def min_attempts_egg_drop_recursive(eggs, floors):
if eggs == 1 or floors == 0:
return floors
min_value = float("inf")
for floor in range(1, floors + 1):
min_value = min(min_value,
1 + max(min_attempts_egg_drop_recursive(eggs - 1, floor - 1),
min_attempts_egg_drop_recursive(eggs, floors - floor)))
return min_value
if __name__ == '__main__':
eggs = 3
floors = 100
expected_attempts = 9
assert expected_attempts == min_attempts_egg_drop(eggs, floors)
eggs = 2
floors = 6
expected_attempts = 3
assert expected_attempts == min_attempts_egg_drop_recursive(eggs, floors)
================================================
FILE: python/dynamic/knapsack_01.py
================================================
"""
Problem Statement
=================
0/1 Knapsack Problem - Given items of certain weights/values and maximum allowed weight how to pick items to pick items
from this set to maximize sum of value of items such that sum of weights is less than or equal to maximum allowed
weight.
Runtime Analysis
----------------
Time complexity - O(W*total items)
Video
-----
* Topdown DP - https://youtu.be/149WSzQ4E1g
* Bottomup DP - https://youtu.be/8LusJS5-AGo
References
----------
* http://www.geeksforgeeks.org/dynamic-programming-set-10-0-1-knapsack-problem/
* https://en.wikipedia.org/wiki/Knapsack_problem
"""
def knapsack_01(values, weights, total):
total_items = len(weights)
rows = total_items + 1
cols = total + 1
T = [[0 for _ in range(cols)] for _ in range(rows)]
for i in range(1, rows):
for j in range(1, cols):
if j < weights[i - 1]:
T[i][j] = T[i - 1][j]
else:
T[i][j] = max(T[i - 1][j], values[i - 1] + T[i - 1][j - weights[i - 1]])
return T[rows - 1][cols -1]
def knapsack_01_recursive_util(values, weights, remaining_weight, total_items, current_item, memo):
if current_item >= total_items or remaining_weight <= 0:
return 0
key = (total_items - current_item - 1, remaining_weight)
if key in memo:
return memo[key]
if remaining_weight < weights[current_item]:
max_value = knapsack_01_recursive_util(values, weights, remaining_weight, total_items, current_item + 1, memo)
else:
max_value = max(values[current_item] + knapsack_01_recursive_util(values, weights, remaining_weight - weights[current_item], total_items, current_item + 1, memo),
knapsack_01_recursive_util(values, weights, remaining_weight, total_items, current_item + 1, memo))
memo[key] = max_value
return max_value
def knapsack_01_recursive(values, weights, total_weight):
memo = dict()
return knapsack_01_recursive_util(values, weights, total_weight, len(values), 0, memo)
if __name__ == '__main__':
total_weight = 7
weights = [1, 3, 4, 5]
values = [1, 4, 5, 7]
expected = 9
assert expected == knapsack_01(values, weights, total_weight)
assert expected == knapsack_01_recursive(values, weights, total_weight)
total_weight = 8
weights = [2, 2, 4, 5]
values = [2, 4, 6, 9]
expected = 13
assert expected == knapsack_01(values, weights, total_weight)
assert expected == knapsack_01_recursive(values, weights, total_weight)
================================================
FILE: python/dynamic/kth_ugly_number.py
================================================
"""
Problem Statement
=================
Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15,
shows the first 11 ugly numbers. By convention, 1 is included.
Write a program to find the kth ugly number.
Complexity
----------
* Time Complexity O(n)
* Space Complexity O(n)
Reference
---------
* http://www.geeksforgeeks.org/ugly-numbers/
"""
def ugly_number(kth):
ugly_factors = [1] # By convention 1 is included.
factor_index = {
2: 0,
3: 0,
5: 0}
for num in range(1, kth):
minimal_factor = min(min(ugly_factors[factor_index[2]] * 2, ugly_factors[factor_index[3]] * 3),
ugly_factors[factor_index[5]] * 5)
ugly_factors.append(minimal_factor)
for factor in [2, 3, 5]:
if minimal_factor % factor == 0:
factor_index[factor] += 1
return ugly_factors[kth - 1]
if __name__ == '__main__':
assert 5832 == ugly_number(150)
================================================
FILE: python/dynamic/longest_common_subsequence.py
================================================
"""
Problem Statement
=================
Given two sequences A = [A1, A2, A3,..., An] and B = [B1, B2, B3,..., Bm], find the length of the longest common
subsequence.
Video
-----
* https://youtu.be/NnD96abizww
Complexity
----------
* Recursive Solution: O(2^n) (or O(2^m) whichever of n and m is larger).
* Dynamic Programming Solution: O(n * m)
Reference
---------
* https://en.wikipedia.org/wiki/Longest_common_subsequence_problem
* http://www.geeksforgeeks.org/dynamic-programming-set-4-longest-common-subsequence/
"""
def lcs_recursive_helper(sequence1, sequence2, index1, index2):
if (index1 == len(sequence1)) or (index2 == len(sequence2)):
return 0
if sequence1[index1] == sequence2[index2]:
return 1 + lcs_recursive_helper(sequence1, sequence2, index1 + 1, index2 + 1)
return max(lcs_recursive_helper(sequence1, sequence2, index1 + 1, index2),
lcs_recursive_helper(sequence1, sequence2, index1, index2 + 1))
def longest_common_subsequence_recursive(sequence1, sequence2):
return lcs_recursive_helper(sequence1, sequence2, 0, 0)
def longest_common_subsequence(sequence1, sequence2):
cols = len(sequence1) + 1 # Add 1 to represent 0 valued column for DP
rows = len(sequence2) + 1 # Add 1 to represent 0 valued row for DP
T = [[0 for _ in range(cols)] for _ in range(rows)]
max_length = 0
for i in range(1, rows):
for j in range(1, cols):
if sequence2[i - 1] == sequence1[j - 1]:
T[i][j] = 1 + T[i - 1][j - 1]
else:
T[i][j] = max(T[i - 1][j], T[i][j - 1])
max_length = max(max_length, T[i][j])
return max_length
if __name__ == '__main__':
sequence1 = "ABCDGHLQR"
sequence2 = "AEDPHR"
expected_length = 4
assert expected_length == longest_common_subsequence_recursive(sequence1, sequence2)
assert expected_length == longest_common_subsequence_recursive(sequence2, sequence1)
assert expected_length == longest_common_subsequence(sequence1, sequence2)
assert expected_length == longest_common_subsequence(sequence2, sequence1)
================================================
FILE: python/dynamic/longest_common_substring.py
================================================
"""
Problem Statement
=================
Given two sequences A = [A1, A2, A3,..., An] and B = [B1, B2, B3,..., Bm], find the length of the longest common
substring.
Video
-----
* https://youtu.be/BysNXJHzCEs
Complexity
----------
* Recursive Solution: O(2^n) (or O(2^m) whichever of n and m is larger).
* Dynamic Programming Solution: O(n * m)
Reference
---------
* http://en.wikipedia.org/wiki/Longest_common_substring_problem
"""
def longest_common_string_recursive_helper(str1, str2, pos1, pos2, check_equal):
if pos1 == -1 or pos2 == -1:
return 0
if check_equal:
if str1[pos1] == str2[pos2]:
return 1 + longest_common_string_recursive_helper(str1, str2, pos1 - 1, pos2 - 1, True)
else:
return 0
longest = 0 # start (again) to find the longest from the current positions
if str1[pos1] == str2[pos2]:
longest = 1 + longest_common_string_recursive_helper(str1, str2, pos1 - 1, pos2 - 1, True)
return max(longest,
longest_common_string_recursive_helper(str1, str2, pos1, pos2 - 1, False),
longest_common_string_recursive_helper(str1, str2, pos1 - 1, pos2, False))
def longest_common_substring_recursive(str1, str2):
return longest_common_string_recursive_helper(str1, str2, len(str1) - 1, len(str2) - 1, False)
def longest_common_substring(str1, str2):
cols = len(str1) + 1 # Add 1 to represent 0 valued col for DP
rows = len(str2) + 1 # Add 1 to represent 0 valued row for DP
T = [[0 for _ in range(cols)] for _ in range(rows)]
max_length = 0
for i in range(1, rows):
for j in range(1, cols):
if str2[i - 1] == str1[j - 1]:
T[i][j] = T[i - 1][j - 1] + 1
max_length = max(max_length, T[i][j])
return max_length
if __name__ == '__main__':
str1 = "abcdef"
str2 = "zcdemf"
expected = 3
assert expected == longest_common_substring(str1, str2)
assert expected == longest_common_substring_recursive(str1, str2)
str1 = "abcdef"
str2 = "cde"
expected = 3
assert expected == longest_common_substring(str1, str2)
str1 = "cde"
str2 = "zcdemf"
expected = 3
assert expected == longest_common_substring(str1, str2)
================================================
FILE: python/dynamic/longest_increasing_subsequence.py
================================================
"""
Problem Statement
=================
Find a subsequence in given array in which the subsequence's elements are in sorted order, lowest to highest, and in
which the subsequence is as long as possible.
Video
-----
* https://youtu.be/CE2b_-XfVDk
Solution
--------
Dynamic Programming is used to solve this question. DP equation is.::
if(arr[i] > arr[j]) { T[i] = max(T[i], T[j] + 1) }
* Time complexity is O(n^2).
* Space complexity is O(n)
Reference
---------
* http://en.wikipedia.org/wiki/Longest_increasing_subsequence
* http://www.geeksforgeeks.org/dynamic-programming-set-3-longest-increasing-subsequence/
"""
def longest_increasing_subsequence(sequence):
sequence_length = len(sequence)
T = [1 for _ in range(sequence_length)]
solution_indices = [i for i in range(sequence_length)]
for index_i in range(1, sequence_length):
for index_j in range(0, index_i):
if (sequence[index_i] > sequence[index_j]) and (T[index_i] < T[index_j] + 1):
T[index_i] = T[index_j] + 1
solution_indices[index_i] = index_j
# find the index of the max number in T
max_value = max(T)
max_index = T.index(max_value)
# Print solution using linked values in solution_indices
next_index = max_index
while True:
print sequence[next_index],
old_index = next_index
next_index = solution_indices[next_index]
if next_index == old_index:
break
return T[max_index]
def longest_increasing_subsequence_recursive(sequence):
sequence_length = len(sequence)
longest = 0
for index in range(sequence_length - 1):
longest_so_far = longest_subsequence_recursive_helper(sequence, index + 1, sequence[index])
if longest_so_far > longest:
longest = longest_so_far
return longest + 1
def longest_subsequence_recursive_helper(sequence, next_position, current_position_value):
if next_position == len(sequence):
return 0
temp1 = 0
if sequence[next_position] > current_position_value:
temp1 = 1 + longest_subsequence_recursive_helper(sequence, next_position + 1, sequence[next_position])
temp2 = longest_subsequence_recursive_helper(sequence, next_position + 1, current_position_value)
return max(temp1, temp2)
if __name__ == '__main__':
sequence = [23, 10, 22, 5, 33, 8, 9, 21, 50, 41, 60, 80, 99, 22, 23, 24, 25, 26, 27]
assert 10 == longest_increasing_subsequence(sequence)
assert 10 == longest_increasing_subsequence_recursive(sequence)
================================================
FILE: python/dynamic/longest_palindromic_subsequence.py
================================================
"""
Problem Statement
=================
Given a string find longest palindromic subsequence in this string.
Complexity
----------
* Dynamic Programming Time Complexity: O(n^2)
* Recursive Solution Time Complexity: O(2^n)
Video
-----
* https://youtu.be/_nCsPn7_OgI
References
----------
* http://www.geeksforgeeks.org/dynamic-programming-set-12-longest-palindromic-subsequence/
"""
def longest_palindromic_subsequence(given_string):
rows = cols = string_length = len(given_string)
T = [[0 for _ in range(cols)] for _ in range(rows)]
for row in range(rows):
T[row][row] = 1
for substring_length in range(2, string_length + 1):
for row in range(0, string_length - substring_length + 1):
col = row + substring_length - 1
if given_string[row] == given_string[col]:
if string_length == 2:
T[row][col] = 2
else:
T[row][col] = 2 + T[row + 1][col - 1]
else:
T[row][col] = max(T[row + 1][col], T[row][col - 1])
return T[0][-1]
def palindromic_subsequence_recursive_helper(given_string, start_index, length):
if length == 0 or length == 1:
return length
if given_string[start_index] == given_string[length - start_index - 1]:
return 2 + palindromic_subsequence_recursive_helper(given_string, start_index + 1, length - 2)
else:
return max(palindromic_subsequence_recursive_helper(given_string, start_index, length - 1),
palindromic_subsequence_recursive_helper(given_string, start_index + 1, length - 1))
def longest_palindromic_subsequence_recursive(given_string):
return palindromic_subsequence_recursive_helper(given_string, 0, len(given_string))
if __name__ == '__main__':
given_string = "agbdba"
expected_result = 5
assert expected_result == longest_palindromic_subsequence(given_string)
assert expected_result == longest_palindromic_subsequence_recursive(given_string)
================================================
FILE: python/dynamic/matrix_chain_order.py
================================================
"""
Problem Statement
=================
Given an array p[] which represents the chain of matrices such that the ith matrix Ai is of dimension p[i-1] x p[i]. We
need to write a function matrix_chain_order() that should return the minimum number of multiplications needed to
multiply the chain.
Video
-----
* https://youtu.be/vgLJZMUfnsU
Note
----
In the code below we give matrices length as an array and each matrix takes 2 indices from the array.
For e.g. {2, 3, 4} represents two matrices (2, 3) and (3, 4) in (row, col) format.
Complexity
----------
Time Complexity: O(n^3)
Reference
---------
* http://www.geeksforgeeks.org/dynamic-programming-set-8-matrix-chain-multiplication/
"""
def matrix_chain_order(matrices):
matrices_length = len(matrices)
T = [[0 for _ in range(matrices_length)] for _ in range(matrices_length)]
for gap in range(2, matrices_length):
for index_i in range(0, matrices_length - gap):
index_j = index_i + gap
T[index_i][index_j] = 10000
for index_k in range(index_i + 1, index_j):
temp = T[index_i][index_k] + T[index_k][index_j] + matrices[index_i] * matrices[index_k] * matrices[index_j]
if temp < T[index_i][index_j]:
T[index_i][index_j] = temp
return T[0][-1]
if __name__ == '__main__':
matrices = [4, 2, 3, 5, 3]
assert 84 == matrix_chain_order(matrices)
================================================
FILE: python/dynamic/maximum_increasing_subsequence.py
================================================
"""
Problem Statement
=================
Given an array of n positive integers. Write a program to find the sum of maximum sum subsequence of the given array
such that the integers in the subsequence are in increasing order.
Complexity
----------
* Time Complexity: O(n^2)
* Space Complexity: O(n)
Video
-----
* https://youtu.be/99ssGWhLPUE
Reference
---------
* http://www.geeksforgeeks.org/dynamic-programming-set-14-maximum-sum-increasing-subsequence/
"""
def maximum_sum_subsequence(sequence):
sequence_length = len(sequence)
T = [sequence[i] for i in range(sequence_length)]
for index_i in range(1, sequence_length):
for index_j in range(0, index_i):
if sequence[index_j] < sequence[index_i]:
T[index_i] = max(T[index_i], T[index_j] + sequence[index_i])
return max(T)
if __name__ == '__main__':
sequence = [1, 101, 10, 2, 3, 100, 4]
assert 111 == maximum_sum_subsequence(sequence)
================================================
FILE: python/dynamic/nth_fibonacci.py
================================================
"""
Problem Statement
=================
Given the number n, find the nth fibanacci number.
The fibonacci series is 0, 1, 1, 2, 3 ...
And follows the formula Fn = Fn-1 + Fn-2
Complexity
----------
* Recursive Solution: O(2^n)
* Dynamic Programming: O(n)
"""
def fibonacci_recursive(n):
if n == 0 or n == 1:
return n
return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2)
def fibonacci(n):
n1, n2 = 0, 1
if n == n1 or n == n2:
return n
for i in range(2, n + 1):
n1, n2 = n2, n1 + n2
return n2
if __name__ == '__main__':
assert 610 == fibonacci_recursive(15)
assert 610 == fibonacci(15)
================================================
FILE: python/dynamic/num_bst.py
================================================
"""
Problem Statement
=================
Count number of binary search trees created for array of size n. The solution is the nth catalan number.
Complexity
----------
* Dynamic Programming: O(n^2)
* Recursive Solution: O(2^n)
Video
-----
* https://youtu.be/YDf982Lb84o
Reference
---------
* http://www.geeksforgeeks.org/program-nth-catalan-number/
"""
def num_bst(num_nodes):
T = [0 for _ in range(num_nodes + 1)]
T[0] = 1
T[1] = 1
for node in range(2, num_nodes+1):
for sub in range(0, node):
T[node] += T[sub] * T[node - sub - 1]
return T[num_nodes]
def num_bst_recursive(num_nodes):
if num_nodes == 0 or num_nodes == 1:
return 1
result = 0
for root in range(1, num_nodes + 1):
result += num_bst_recursive(root - 1) * num_bst_recursive(num_nodes - root)
return result
if __name__ == '__main__':
assert 5 == num_bst(3)
assert 5 == num_bst_recursive(3)
================================================
FILE: python/dynamic/num_paths_nm_matrix.py
================================================
"""
Problem Statement
=================
Count the number of Paths from 1,1 to N,M in an NxM matrix.
Analysis
--------
* Dynamic Programing Solution: O(rows * cols)
* Recursive: O(2^rows) if rows > cols else O(2^cols)
References
----------
* http://www.geeksforgeeks.org/count-possible-paths-top-left-bottom-right-nxm-matrix/
"""
def num_paths_matrix(rows, cols):
T = [[1 if row == 0 or col == 0 else 0 for row in range(cols)] for col in range(rows)]
for row in range(1, rows):
for col in range(1, cols):
T[row][col] = T[row - 1][col] + T[row][col - 1]
return T[rows - 1][cols - 1]
def num_paths_matrix_recursive(rows, cols):
if rows == 1 or cols == 1:
return 1
return num_paths_matrix(rows-1, cols) + num_paths_matrix(rows, cols - 1)
if __name__ == '__main__':
rows = 3
cols = 3
expected = 6
assert expected == num_paths_matrix(rows, cols)
assert expected == num_paths_matrix_recursive(rows, cols)
================================================
FILE: python/dynamic/num_trees_preorder.py
================================================
"""
Problem Statement
=================
Given the number of nodes N, in a pre-order sequence how many unique trees can be created? Number of tree is exactly
same as number of unique BST create with array of size n. The solution is a catalan number.
Complexity
----------
* Dynamic Programming: O(n^2)
* Recursive Solution: O(2^n)
Video
-----
* https://youtu.be/RUB5ZPfKcnY
"""
def num_trees(num_nodes):
T = [0 for _ in range(num_nodes + 1)]
T[0] = 1
T[1] = 1
for n in range(2, num_nodes + 1):
for j in range(0, n):
T[n] += T[j] * T[n - j - 1]
return T[num_nodes]
def num_trees_recursive(num_nodes):
if num_nodes == 0 or num_nodes == 1:
return 1
result = 0
for n in range(1, num_nodes + 1):
result += num_trees_recursive(n - 1) * num_trees_recursive(num_nodes - n)
return result
if __name__ == '__main__':
assert 5 == num_trees(3)
assert 14 == num_trees(4)
assert 42 == num_trees(5)
assert 5 == num_trees_recursive(3)
assert 14 == num_trees_recursive(4)
assert 42 == num_trees_recursive(5)
================================================
FILE: python/dynamic/optimal_bst.py
================================================
"""
Problem Statement
=================
Given a sorted array keys[0.. n-1] of search keys and an array freq[0.. n-1] of frequency counts, where freq[i] is the
number of searches to keys[i]. Construct a binary search tree of all keys such that the total cost of all the searches
is as small as possible.
Video
-----
* https://youtu.be/hgA4xxlVvfQ
Analysis
--------
* Recursive: Exponential O(n^n)
* Dynamic Programming: O(n^3)
Reference
---------
* http://www.geeksforgeeks.org/dynamic-programming-set-24-optimal-binary-search-tree/
"""
def min_cost_bst(input_array, freq):
size = rows = cols = len(input_array)
T = [[0 for _ in range(cols)] for _ in range(rows)]
for idx in range(rows):
T[idx][idx] = freq[idx]
for sub_tree_size in range(2, size + 1):
for start in range(size + 1 - sub_tree_size):
end = start + sub_tree_size - 1
T[start][end] = float("inf")
total = sum(freq[start:end + 1])
for k in range(start, end + 1):
val = total + (0 if k - 1 < 0 else T[start][k - 1]) + (0 if k + 1 > end else T[k + 1][end])
T[start][end] = min(val, T[start][end])
return T[0][-1]
def min_cost_bst_recursive_helper(input_array, freq, low_index, high_index, level):
if low_index > high_index:
return 0
min_value = float("inf")
for index in range(low_index, high_index + 1):
val = (min_cost_bst_recursive_helper(input_array, freq, low_index, index - 1, level + 1) # left tree
+ level * freq[index] # value at level
+ min_cost_bst_recursive_helper(input_array, freq, index + 1, high_index, level + 1)) # right tree
min_value = min(val, min_value)
return min_value
def min_cost_bst_recursive(input_array, freq):
return min_cost_bst_recursive_helper(input_array, freq, 0, len(input_array) - 1, 1)
if __name__ == '__main__':
input_array = [10, 12, 16, 21]
freq = [4, 2, 6, 3]
expected = 26
assert expected == min_cost_bst(input_array, freq)
assert expected == min_cost_bst_recursive(input_array, freq)
input_array = [10, 12, 20, 35, 46]
freq = [34, 8, 50, 21, 16]
expected = 232
assert expected == min_cost_bst(input_array, freq)
assert expected == min_cost_bst_recursive(input_array, freq)
================================================
FILE: python/dynamic/stockbuysellktransactions.py
================================================
""""
Problem Statement
=================
Given certain stock values over a period of days (d days) and a number K, the number of transactions allowed, find the
maximum profit that be obtained with at most K transactions.
Video
-----
* https://youtu.be/oDhu5uGq_ic
Complexity
----------
* Space Complexity O(days * transctions)
* Time Complexity: Slow Solution O (days^2 * transactions), Faster Solution O(days * transaction)
"""
def max_profit(prices, K):
if K == 0 or prices == []:
return 0
days = len(prices)
num_transactions = K + 1 # 0th transaction up to and including kth transaction is considered.
T = [[0 for _ in range(days)] for _ in range(num_transactions)]
for transaction in range(1, num_transactions):
max_diff = - prices[0]
for day in range(1, days):
T[transaction][day] = max(T[transaction][day - 1], # No transaction
prices[day] + max_diff) # price on that day with max diff
max_diff = max(max_diff,
T[transaction - 1][day] - prices[day]) # update max_diff
print_actual_solution(T, prices)
return T[-1][-1]
def max_profit_slow_solution(prices, K):
if K == 0 or prices == []:
return 0
days = len(prices)
num_transactions = K + 1
T = [[0 for _ in range(len(prices))] for _ in range(num_transactions)]
for transaction in range(1, num_transactions):
for day in range(1, days):
# This maximum value of either
# a) No Transaction on the day. We pick the value from day - 1
# b) Max profit made by selling on the day plus the cost of the previous transaction, considered over m days
T[transaction][day] = max(T[transaction][day - 1],
max([(prices[day] - prices[m] + T[transaction - 1][m]) for m in range(day)]))
print_actual_solution(T, prices)
return T[-1][-1]
def print_actual_solution(T, prices):
transaction = len(T) - 1
day = len(T[0]) - 1
stack = []
while True:
if transaction == 0 or day == 0:
break
if T[transaction][day] == T[transaction][day - 1]: # Didn't sell
day -= 1
else:
stack.append(day) # sold
max_diff = T[transaction][day] - prices[day]
for k in range(day - 1, -1, -1):
if T[transaction - 1][k] - prices[k] == max_diff:
stack.append(k) # bought
transaction -= 1
break
for entry in range(len(stack) - 1, -1, -2):
print("Buy on day {day} at price {price}".format(day=stack[entry], price=prices[stack[transaction]]))
print("Sell on day {day} at price {price}".format(day=stack[entry], price=prices[stack[transaction - 1]]))
if __name__ == '__main__':
prices = [2, 5, 7, 1, 4, 3, 1, 3]
assert 10 == max_profit(prices, 3)
assert 10 == max_profit_slow_solution(prices, 3)
================================================
FILE: python/dynamic/string_interleaving.py
================================================
"""
Problem Statement
=================
Given three strings A, B and C. Write a function that checks whether C is an interleaving of A and B. C is said to be
interleaving A and B, if it contains all characters of A and B and order of all characters in individual strings is
preserved.
http://www.geeksforgeeks.org/check-whether-a-given-string-is-an-interleaving-of-two-other-given-strings-set-2/
Video: https://www.youtube.com/watch?v=ih2OZ9-M3OM
"""
def is_interleaved_recursive(str1, str2, str3, pos1, pos2, pos3):
if pos1 == len(str1) and pos2 == len(str2) and pos3 == len(str3):
return True
if pos3 == len(str3):
return False
return (((pos1 < len(str1) and str1[pos1] == str3[pos3]) and is_interleaved_recursive(str1, str2, str3, pos1 + 1, pos2, pos3 + 1)) or
(pos2 < len(str2) and str2[pos2] == str3[pos3]) and is_interleaved_recursive(str1, str2, str3, pos1, pos2 + 1, pos3 + 1))
def is_interleaved(str1, str2, str3):
if len(str3) != (len(str1) + len(str2)):
return False
cols = len(str1) + 1
rows = len(str2) + 1
T = [[False for _ in range(cols)] for _ in range(rows)]
for row in range(rows):
for col in range(cols):
index = row + col - 1
if row == 0 and col == 0:
T[row][col] = True
elif row == 0:
if str3[index] == str1[col - 1]:
T[row][col] = True and T[row][col - 1]
elif col == 0:
if str3[index] == str2[row - 1]:
T[row][col] = True and T[row - 1][col]
else:
T[row][col] = ((T[row][col - 1] if str3[index] == str1[col - 1] else False) or
(T[row - 1][col] if str3[index] == str2[row - 1] else False))
return T[rows - 1][cols - 1]
if __name__ == '__main__':
str1 = "XXYM"
str2 = "XXZT"
str3 = "XXXZXYTM"
assert True == is_interleaved(str1, str2, str3)
assert True == is_interleaved_recursive(str1, str2, str3, 0, 0, 0)
================================================
FILE: python/dynamic/sub_rectangular_maximum_sum.py
================================================
"""
Problem Statement
=================
Write a program to find maximum sum rectangle in give 2D matrix. Assume there is at least one positive number in the 2D
matrix.
Solution:
--------
* Keep temp array with size as number of rows. Start left and right from 0 and keep adding values for each row and
maintain them in this temp array.
* Run Kadane's algorithm to find max sum subarray in temp. Now increment right by 1.
* When right reaches last column reset right to 1 and left to 1.
Analysis
--------
* Space complexity of this algorithm is O(row)
* Time complexity of this algorithm is O(row*col*col)
Video
-----
* https://youtu.be/yCQN096CwWM
References
----------
* http://www.geeksforgeeks.org/dynamic-programming-set-27-max-sum-rectangle-in-a-2d-matrix/
"""
from collections import namedtuple
Result = namedtuple("Result","maxSum leftBound rightBound upBound lowBound")
KadanesResult = namedtuple("KadanesResult","maxSum start end")
def kadanes(temp):
max = 0
maxStart = -1
maxEnd = -1
currentStart = 0
maxSoFar = 0
for i in range(0, len(temp)):
maxSoFar += temp[i]
if maxSoFar < 0:
maxSoFar = 0
currentStart = i + 1
if maxSoFar > max:
maxStart = currentStart
maxEnd = i
max = maxSoFar
return KadanesResult(max, maxStart, maxEnd)
def max_sub_sub_rectangle(rectangle):
rows = len(rectangle)
cols = len(rectangle[0])
result = Result(float("-inf"), -1, -1, -1, -1)
for left in range(cols):
temp = [0 for _ in range(rows)]
for right in range(left, cols):
for i in range(rows):
temp[i] += rectangle[i][right]
kadanes_result = kadanes(temp)
if kadanes_result.maxSum > result.maxSum:
result = Result(kadanes_result.maxSum, left, right, kadanes_result.start, kadanes_result.end)
return result
if __name__ == '__main__':
rectangle = [[2, 1, -3, -4, 5],
[0, 6, 3, 4, 1],
[2, -2, -1, 4, -5],
[-3, 3, 1, 0, 3]]
result = max_sub_sub_rectangle(rectangle)
assert 18 == result.maxSum
print result
================================================
FILE: python/dynamic/subset_sum.py
================================================
"""
Problem Statement
=================
Given an array of non negative numbers and a total, is there subset of numbers in this array which adds up to given
total. Another variation is given an array is it possible to split it up into 2 equal sum partitions. Partition need not
be equal sized. Just equal sum.
Video
-----
* https://youtu.be/s6FhG--P7z0
Solution
--------
* Time complexity is O(input.size * total_sum)
* Space complexity is O(input.size*total_sum)
Reference
---------
* https://en.wikipedia.org/wiki/Subset_sum_problem
"""
def subset_sum(sequence, sum_value):
cols = sum_value + 1 # Plus 1 for 0 valued col.
rows = len(sequence) + 1 # Plus 1 for 0 valued row.
T = [[False for _ in range(cols)] for _ in range(rows)]
for row in range(rows):
T[row][0] = True
for index_i in range(1, rows):
for index_j in range(1, cols):
if index_j >= sequence[index_i - 1]:
T[index_i][index_j] = T[index_i - 1][index_j] or T[index_i - 1][index_j - sequence[index_i - 1]]
else:
T[index_i][index_j] = T[index_i - 1][index_j]
return T[rows - 1][cols - 1]
def partition(sequence):
sequence_sum = sum(sequence)
if sequence_sum % 2 != 0:
return False
expected = sequence_sum / 2
return subset_sum(sequence, expected)
if __name__ == '__main__':
sequence = [2, 3, 7, 8]
assert True == subset_sum(sequence, 11)
sequence = [1, 3, 5, 5, 2, 1, 1, 6]
assert True == partition(sequence)
================================================
FILE: python/dynamic/symbolexpressionevaluation.py
================================================
"""
Problem Statement
=================
Let there be a binary operation for 3 symbols a, b, c and result of these binary operation given in a table.
Given an expression of these 3 symbols and a final result, tell if this expression can be parenthesize in certain
way to produce the final result.
Complexity
----------
* Run time Complexity: O(n^3)
* SpaceL O(n^2)
Where n is the length of the expression.
"""
def evaluate_expression(expression_map, expression, result):
expression_length = len(expression)
T = [[set() for _ in range(expression_length)] for _ in range(len(expression))]
for idx, expr in enumerate(expression):
T[idx][idx].add(expr)
# We take a sub expression of length 2 until the total expression length
for sub_length in range(2, expression_length + 1):
for left_index in range(0, expression_length - sub_length + 1):
right_index = left_index + sub_length - 1
# we split the expression at different k indices for the total sub-expression length and store the result.
# at T[left_index][right_index]
# Like bbc, will be treated for (b(bc) and ((bb) c) and the final result is stored in a set at T[0][2]
for k in range(left_index, right_index):
for expr1 in T[left_index][k]:
for expr2 in T[k+1][right_index]:
T[left_index][right_index].add(expression_map[(expr1, expr2)])
for expr in T[0][-1]:
if result in expr:
return True
return False
if __name__ == '__main__':
expressions = ['a', 'b', 'c']
# expression table denotes the binary operation between two expression and its result.
expression_table = [
['b', 'b', 'a'],
['c', 'b', 'a'],
['a', 'a', 'c']
]
# For convenience, we can modify it to be more explicit and use the expression table
expression_map = {
('a', 'a'): 'b',
('a', 'b'): 'b',
('a', 'c'): 'a',
('b', 'a'): 'c',
('b', 'b'): 'b',
('b', 'c'): 'a',
('c', 'a'): 'a',
('c', 'b'): 'a',
('c', 'c'): 'c'
}
assert True == evaluate_expression(expression_map, 'bbbbac', 'a')
================================================
FILE: python/dynamic/weighted_job_scheduling_max_profit.py
================================================
"""
Problem Statement
=================
Given set of jobs with start and end interval and profit, how to maximize profit such that jobs in subset do not
overlap.
Video
-----
* https://youtu.be/cr6Ip0J9izc
Complexity
----------
* Runtime Complexity: O(n^2)
* Space Complexity: O(n)
Reference Link
--------------
* http://www.cs.princeton.edu/courses/archive/spr05/cos423/lectures/06dynamic-programming.pdf
"""
def can_sequence(job1, job2):
_, job1_finish_time = job1
job2_start_time, _ = job2
return job1_finish_time <= job2_start_time
def find_max_profit(jobs):
sequenced_jobs = sorted(jobs.keys(), key=lambda x: x[1])
T = [jobs[job_key] for job_key in sequenced_jobs]
num_jobs = len(sequenced_jobs)
for j in range(1, num_jobs):
for i in range(0, j):
if can_sequence(sequenced_jobs[i], sequenced_jobs[j]):
T[j] = max(T[j], T[i] + jobs[sequenced_jobs[j]])
return max(T)
if __name__ == '__main__':
jobs = {
(1, 3): 5, # (start_time, end_time, total_cost)
(2, 5): 6,
(4, 6): 5,
(6, 7): 4,
(5, 8): 11,
(7, 9): 2
}
assert 17 == find_max_profit(jobs)
================================================
FILE: python/geometry/skylinedrawing.py
================================================
# https://leetcode.com/problems/the-skyline-problem/
class BuildingPoint(object):
def __init__(self, point, is_start, height):
self.point = point;
self.is_start = is_start
self.height = height
def __lt__(self, other):
if self.point != other.point:
return self.point < other.point
else:
if self.is_start:
h1 = -self.height
else:
h1 = self.height
if other.is_start:
h2 = -other.height;
else:
h2 = other.height
return h1 < h2
def get_skyline(buildings):
building_points = []
for building in buildings:
building_points.append(BuildingPoint(building[0], True, building[2]))
building_points.append(BuildingPoint(building[1], False, building[2]))
building_points = sorted(building_points)
queue = {}
queue[0] = 1
prev_max_height = 0
result = []
for building_point in building_points:
if building_point.is_start:
if building_point.height in queue:
queue[building_point.height] = queue[building_point.height] + 1
else:
queue[building_point.height] = 1
else:
if queue[building_point.height] == 1:
del queue[building_point.height]
else:
queue[building_point.height] = queue[building_point.height] - 1
current_max_height = max(queue.keys())
if prev_max_height != current_max_height:
result.append([building_point.point, current_max_height])
prev_max_height = current_max_height
return result
if __name__ == '__main__':
buildings = [[1, 3, 4], [3, 4, 4], [2, 6, 2], [8, 11, 4], [7, 9, 3], [10, 11, 2]]
print(get_skyline(buildings))
================================================
FILE: python/graph/cycledirectedgraph.py
================================================
# detect cycle in directed graph
# https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/CycleInDirectedGraph.java
from graph import *
def has_cycle(graph):
white = set()
gray = set()
black = set()
for vertex in graph.all_vertex.values():
white.add(vertex)
while len(white) > 0:
current = next(iter(white))
if dfs(current, white, gray, black) == True:
return True
return False
def dfs(current, white, gray, black):
move_vertex(current, white, gray)
for neighbor in current.adjacent_vertices:
if neighbor in black:
continue
if neighbor in gray:
return True
if dfs(neighbor, white, gray, black) == True:
return True
move_vertex(current, gray, black)
return False
def move_vertex(vertex, source_set, destination_set):
source_set.remove(vertex)
destination_set.add(vertex)
if __name__ == '__main__':
graph = Graph(True)
graph.add_edge(1,2)
graph.add_edge(1,3)
graph.add_edge(2,3)
graph.add_edge(4,1)
graph.add_edge(4,5)
graph.add_edge(5,6)
graph.add_edge(6,4)
print(has_cycle(graph));
================================================
FILE: python/graph/cycleundirectedgraph.py
================================================
# detect cycle in undirected graph
# https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/CycleUndirectedGraph.java
from graph import *
from disjointset import *
def has_cycle_dfs(graph):
visited = set()
for vertex in graph.all_vertex.values():
if vertex in visited:
continue
flag = has_cycle_dfs_util(vertex, visited, None)
if flag:
return True
return False
def has_cycle_dfs_util(vertex, visited, parent):
visited.add(vertex)
for adjacent in vertex.adjacent_vertices:
if parent is not None and adjacent == parent:
continue
if adjacent in visited:
return True
has_cycle = has_cycle_dfs_util(adjacent, visited, vertex)
if has_cycle:
return True
return False
def has_cycle_using_disjoint_set(graph):
disjoint_set = DisjointSet()
for vertex in graph.all_vertex.values():
disjoint_set.make_set(vertex.id)
for edge in graph.all_edges:
parent1 = disjoint_set.find_set(edge.vertex1.id)
parent2 = disjoint_set.find_set(edge.vertex2.id)
if parent1 == parent2:
return True
disjoint_set.union(edge.vertex1.id, edge.vertex2.id)
return False
if __name__ == '__main__':
graph = Graph(False)
graph.add_edge(0,1)
graph.add_edge(1,2)
graph.add_edge(0,3)
graph.add_edge(3,4)
graph.add_edge(4,5)
graph.add_edge(5,1)
has_cycle1 = has_cycle_dfs(graph)
has_cycle2 = has_cycle_using_disjoint_set(graph)
print(str(has_cycle1) + " " + str(has_cycle2))
================================================
FILE: python/graph/dijkstrashortestpath.py
================================================
#dijkstra's algorithm
# java code https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/DijkstraShortestPath.java
from priorityqueue import PriorityQueue
from graph import Graph
import sys
def shortest_path(graph, sourceVertex):
min_heap = PriorityQueue(True)
distance = {}
parent = {}
for vertex in graph.all_vertex.values():
min_heap.add_task(sys.maxsize, vertex)
min_heap.change_task_priority(0, sourceVertex)
distance[sourceVertex] = 0
parent[sourceVertex] = None
while min_heap.is_empty() is False:
task = min_heap.peek_task()
weight = min_heap.get_task_priority(task)
current = min_heap.pop_task()
distance[current] = weight
for edge in current.edges:
adjacent = get_other_vertex_for_edge(current, edge)
if min_heap.contains_task(adjacent) is False:
continue
new_distance = distance[current] + edge.weight;
if min_heap.get_task_priority(adjacent) > new_distance:
min_heap.change_task_priority(new_distance, adjacent)
parent[adjacent] = current
return distance
def get_other_vertex_for_edge(vertex, edge):
if edge.vertex1.id == vertex.id:
return edge.vertex2
else:
return edge.vertex1
if __name__ == '__main__':
graph = Graph(False)
graph.add_edge(1,2,5)
graph.add_edge(2,3,2)
graph.add_edge(1,4,9)
graph.add_edge(1,5,3)
graph.add_edge(5,6,2)
graph.add_edge(6,4,2)
graph.add_edge(3,4,3)
distance = shortest_path(graph, graph.all_vertex[1])
print(distance)
================================================
FILE: python/graph/disjointset.py
================================================
# disjoint sets
# https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/DisjointSet.java
class Node(object):
def __init__(self, data, parent = None, rank = 0):
self.data = data
self.parent = parent
self.rank = rank
def __str__(self):
return str(self.data)
def __repr__(self):
return self.__str__()
class DisjointSet(object):
def __init__(self):
self.map = {}
def make_set(self, data):
node = Node(data)
node.parent = node
self.map[data] = node
def union(self, data1, data2):
node1 = self.map[data1]
node2 = self.map[data2]
parent1 = self.find_set_util(node1)
parent2 = self.find_set_util(node2)
if parent1.data == parent2.data:
return
if parent1.rank >= parent2.rank:
if parent1.rank == parent2.rank:
parent1.rank = parent1.rank + 1
parent2.parent = parent1
else:
parent1.parent = parent2
def find_set(self, data):
return self.find_set_util(self.map[data])
def find_set_util(self, node):
parent = node.parent
if parent == node:
return parent
node.parent = self.find_set_util(node.parent)
return node.parent
if __name__ == '__main__':
ds = DisjointSet()
ds.make_set(1)
ds.make_set(2)
ds.make_set(3)
ds.make_set(4)
ds.make_set(5)
ds.make_set(6)
ds.make_set(7)
ds.union(1,2)
ds.union(2,3)
ds.union(4,5)
ds.union(6,7)
ds.union(5,6)
ds.union(3,7)
for i in range(1,8):
print(ds.find_set(i))
================================================
FILE: python/graph/floydwarshall.py
================================================
# floyd warshall all pair shortest path
# java code https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/FloydWarshallAllPairShortestPath.java
import sys
INF = 1000000
class NegativeWeightCycleException(Exception):
def __init__(self):
pass
def all_pair_shortest_path(distance_matrix):
size = len(distance_matrix)
distance = [[0 for x in range(size)]
for x in range (size)]
path = [[0 for x in range(size)]
for x in range (size)]
for i in range(size):
for j in range(size):
distance[i][j] = distance_matrix[i][j]
if distance_matrix[i][j] != INF and i != j:
path[i][j] = i
else:
path[i][j] = -1
for k in range(size):
for i in range(size):
for j in range(size):
if distance[i][k] == INF or distance[k][j] == INF:
continue
if distance[i][j] > distance[i][k] + distance[k][j]:
distance[i][j] = distance[i][k] + distance[k][j]
path[i][j] = path[k][j]
for i in range(size):
if distance[i][i] < 0:
raise NegativeWeightCycleException()
print_path(path, 3, 2)
return (distance, path)
def print_path(path, start, end):
stack = []
stack.append(end)
while True:
end = path[start][end]
if end == -1:
return
stack.append(end)
if end == start:
break
print(stack[::-1])
if __name__ == '__main__':
distance_matrix = [[0, 3, 6, 15],
[INF, 0, -2, INF],
[INF, INF, 0, 2],
[1, INF, INF, 0]]
distance, path = all_pair_shortest_path(distance_matrix)
print(distance)
#print(path)
================================================
FILE: python/graph/fordfulkerson.py
================================================
#ford fulkerson method Edomonds Karp algorithm for finding max flow
# java code https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/FordFulkerson.java
from queue import Queue
import sys
def max_flow(capacity, source, sink):
residual_capacity = [x[:] for x in capacity]
augmented_paths = []
max_flow = 0
while True:
found_augmented_path, parent = bfs(residual_capacity, source, sink)
if not found_augmented_path:
break
augmented_path = []
v = sink
flow = sys.maxsize
while not v == source:
augmented_path.append(v)
u = parent[v]
if flow > residual_capacity[u][v]:
flow = residual_capacity[u][v]
v = u
augmented_path.append(source)
augmented_paths.append(augmented_path[::-1])
max_flow += flow
v = sink
while not v == source:
u = parent[v]
residual_capacity[u][v] -= flow
residual_capacity[v][u] += flow
v = u
print("Augmented path")
print(augmented_paths)
return max_flow
def bfs(residual_capacity, source, sink):
visited = set()
queue = Queue()
parent = {}
queue.put(source)
visited.add(source)
found_augmented_path = False
while not queue.empty():
u = queue.get()
for v in range(len(residual_capacity)):
if v not in visited and residual_capacity[u][v] > 0:
parent[v] = u
visited.add(v)
queue.put(v)
if v == sink:
found_augmented_path = True
break;
return found_augmented_path, parent
if __name__ == '__main__':
capacity = [[0, 3, 0, 3, 0, 0, 0],
[0, 0, 4, 0, 0, 0, 0],
[3, 0, 0, 1, 2, 0, 0],
[0, 0, 0, 0, 2, 6, 0],
[0, 1, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0, 9],
[0, 0, 0, 0, 0, 0, 0]]
max_val = max_flow(capacity, 0, 6)
print(max_val)
================================================
FILE: python/graph/graph.py
================================================
#Graph class
# Java code https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/Graph.java
class Graph(object):
def __init__(self, is_directed):
self.all_edges = []
self.all_vertex = {}
self.is_directed = is_directed
def add_edge(self, id1, id2, weight=0):
if id1 in self.all_vertex:
vertex1 = self.all_vertex[id1]
else:
vertex1 = Vertex(id1)
self.all_vertex[id1] = vertex1
if id2 in self.all_vertex:
vertex2 = self.all_vertex[id2]
else:
vertex2 = Vertex(id2)
self.all_vertex[id2] = vertex2
edge = Edge(vertex1, vertex2, self.is_directed, weight)
self.all_edges.append(edge)
vertex1.add_adjacent_vertex(edge, vertex2)
if self.is_directed is not True:
vertex2.add_adjacent_vertex(edge,vertex1)
class Edge(object):
def __init__(self, vertex1, vertex2, is_directed, weight):
self.vertex1 = vertex1
self.vertex2 = vertex2
self.is_directed = is_directed
self.weight = weight
def __eq__(self, other):
return self.vertex1.id == other.vertex1.id and self.vertex2.id == other.vertex2.id
def __hash(self):
return hash(vertex1) + hash(vertex2)
def __str__(self):
return "Edge " + str(self.vertex1) + " " + str(self.vertex2) + " Weight-" + str(self.weight)
def __repr__(self):
return self.__str__()
class Vertex(object):
def __init__(self, id):
self.id = id;
self.edges = []
self.adjacent_vertices = []
def add_adjacent_vertex(self, edge, vertex):
self.edges.append(edge)
self.adjacent_vertices.append(vertex)
def get_degree(self):
return len(self.edges)
def __eq__(self, other):
return self.id == other.id
def __hash__(self):
return hash(self.id)
def __str__(self):
return str("Vertex-" + str(self.id))
def __repr__(self):
return self.__str__();
def __lt__(self, other):
return self.id < other.id
def __gt__(self, other):
return self.id > other.id
if __name__ == '__main__':
g = Graph(False)
g.add_edge(1,2,10)
g.add_edge(2,3,5)
g.add_edge(1,4,6)
for edge in g.all_edges:
print(edge)
for vertex in g.all_vertex:
print("Vertex " + str(g.all_vertex[vertex]))
for edge in g.all_vertex[vertex].edges:
print("Edge " + str(edge))
================================================
FILE: python/graph/graphtraversal.py
================================================
#doing BFS and DFS traversal of the graph
# java code https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/GraphTraversal.java
from graph import *
import queue
def dfs_util(v, visited):
if v in visited:
return
visited.add(v)
print(v)
for vertex in v.adjacent_vertices:
dfs_util(vertex, visited)
def dfs(graph):
visited = set()
for id in graph.all_vertex:
dfs_util(graph.all_vertex[id], visited)
def bfs(graph):
q = queue.Queue()
visited = set()
for vertex in graph.all_vertex.values():
if vertex not in visited:
q.put(vertex)
visited.add(vertex)
while not q.empty():
v = q.get();
print(v)
for adj in v.adjacent_vertices:
if adj not in visited:
q.put(adj)
visited.add(adj)
if __name__ == '__main__':
g = Graph(False)
g.add_edge(1,2,10)
g.add_edge(2,3,5)
g.add_edge(1,4,6)
dfs(g)
bfs(g)
================================================
FILE: python/graph/kruskalmst.py
================================================
# kruskal minimum spanning tree
# java code https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/KruskalMST.java
from disjointset import *
from graph import *
def get_key(edge):
return edge.weight
def minimum_spanning_tree(graph):
disjoint_set = DisjointSet()
sorted_edges = sorted(graph.all_edges, key = get_key)
print(sorted_edges)
for vertex in graph.all_vertex.values():
disjoint_set.make_set(vertex.id)
result_edge = []
for edge in sorted_edges:
root1 = disjoint_set.find_set(edge.vertex1.id)
root2 = disjoint_set.find_set(edge.vertex2.id)
if root1 == root2:
continue
else:
result_edge.append(edge)
disjoint_set.union(edge.vertex1.id, edge.vertex2.id)
return result_edge
if __name__ == '__main__':
graph = Graph(False)
graph.add_edge(1,3,1)
graph.add_edge(1,2,4)
graph.add_edge(2,4,2)
graph.add_edge(2,5,1)
graph.add_edge(2,6,3)
graph.add_edge(3,4,5)
graph.add_edge(3,7,8)
graph.add_edge(4,7,2)
graph.add_edge(6,5,2)
graph.add_edge(6,4,3)
result = minimum_spanning_tree(graph)
for edge in result:
print(edge)
================================================
FILE: python/graph/primmst.py
================================================
#Prim's MST
# Java code https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/PrimMST.java
from graph import Graph
from priorityqueue import PriorityQueue
import sys
def minimum_spanning_tree(graph):
min_heap = PriorityQueue(True)
vertex_to_edge = {}
result = []
for vertex in graph.all_vertex.values():
min_heap.add_task(sys.maxsize, vertex)
start_vertex = next(iter((graph.all_vertex.values())))
min_heap.change_task_priority(0, start_vertex)
while min_heap.is_empty() is False:
current = min_heap.pop_task()
if(current in vertex_to_edge):
spanning_tree_edge = vertex_to_edge[current]
result.append(spanning_tree_edge)
for edge in current.edges:
adjacent = get_other_vertex_for_edge(current, edge)
if min_heap.contains_task(adjacent) is True and min_heap.get_task_priority(adjacent) > edge.weight:
min_heap.change_task_priority(edge.weight, adjacent)
vertex_to_edge[adjacent] = edge
return result
def get_other_vertex_for_edge(vertex, edge):
if edge.vertex1.id == vertex.id:
return edge.vertex2
else:
return edge.vertex1
if __name__ == '__main__':
graph = Graph(False)
graph.add_edge(1,2,3)
graph.add_edge(2,3,1)
graph.add_edge(3,1,1)
graph.add_edge(1,4,1)
graph.add_edge(2,4,3)
graph.add_edge(4,5,6)
graph.add_edge(5,6,2)
graph.add_edge(3,5,5)
graph.add_edge(3,6,4)
result = minimum_spanning_tree(graph)
print(result)
================================================
FILE: python/graph/priorityqueue.py
================================================
# add to heapq things like removing any item and changing key value
# implementation of priority queue to support contains, change_task_priority
# and remove_task in log time
from heapq import *
class PriorityQueue(object):
def __init__(self, is_min_heap):
self.pq = []
self.entry_finder = {}
if(is_min_heap is True):
self.mul = 1
else :
self.mul = -1
def contains_task(self, task):
if task in self.entry_finder:
return True
else:
return False
def get_task_priority(self, task):
if task in self.entry_finder:
return (self.entry_finder[task])[0]
raise ValueError("task does not exist")
def add_task(self, priority, task):
if task in self.entry_finder:
raise KeyError("Key already exists")
entry = [self.mul*priority, False, task]
self.entry_finder[task] = entry
heappush(self.pq, entry)
def change_task_priority(self, priority, task):
if task not in self.entry_finder:
raise KeyError("Task not found")
self.remove_task(task)
entry = [self.mul*priority, False, task]
self.entry_finder[task] = entry
heappush(self.pq, entry)
def remove_task(self, task):
entry = self.entry_finder.pop(task)
entry[1] = True
def pop_task(self):
while self.pq:
priority, removed, task = heappop(self.pq)
if removed is False:
del self.entry_finder[task]
return task
raise KeyError("pop from an empty priority queue")
def peek_task(self):
while self.pq:
priority, removed, task = tuple(heappop(self.pq))
if removed is False:
heappush(self.pq, [priority, False, task])
return task
raise KeyError("pop from an empty priority queue")
def is_empty(self):
try:
self.peek_task()
return False
except KeyError:
return True
def __str__(self):
return str(self.entry_finder) + " " + str(self.pq)
if __name__ == '__main__':
task1 = "Tushar"
task2 = "Roy"
task3 = "is"
task4 = "coder"
min_pq = PriorityQueue(True)
min_pq.add_task(1, task1)
min_pq.add_task(3, task2)
min_pq.add_task(6, task3)
min_pq.add_task(7, task4)
print(min_pq.contains_task(task3))
print(min_pq.get_task_priority(task3))
print(min_pq)
while min_pq.is_empty() is False:
print(min_pq.pop_task())
max_pq = PriorityQueue(False)
max_pq.add_task(1, task1)
max_pq.add_task(3, task2)
max_pq.add_task(6, task3)
max_pq.add_task(7, task4)
while max_pq.is_empty() is False:
print(max_pq.pop_task())
================================================
FILE: python/graph/topologicalsort.py
================================================
#topological sort
# java code https://github.com/mission-peace/interview/blob/master/src/com/interview/graph/TopologicalSort.java
from graph import Graph
def top_sort(graph):
stack = []
visited = set()
for vertex in graph.all_vertex.values():
if vertex in visited:
continue
top_sort_util(vertex, stack, visited)
return stack
def top_sort_util(vertex, stack, visited):
visited.add(vertex)
for adjacent in vertex.adjacent_vertices:
if adjacent in visited:
continue
top_sort_util(adjacent, stack, visited)
stack.append(vertex)
if __name__ == '__main__':
graph = Graph(True)
graph.add_edge(1,3)
graph.add_edge(1,2)
graph.add_edge(3,4)
graph.add_edge(5,6)
graph.add_edge(6,3)
graph.add_edge(3,8)
graph.add_edge(8,11)
stack = top_sort(graph)
print(stack[::-1])
================================================
FILE: python/recursion/setpairtogether.py
================================================
# http://www.geeksforgeeks.org/minimum-number-of-swaps-required-for-arranging-pairs-adjacent-to-each-other/
def find_minimum_swaps(input, pair):
index = {}
for i, val in enumerate(input):
index[val] = i
return find_minimum_swaps_util(input, pair, index, 0)
def find_minimum_swaps_util(input, pair, index, current):
if current == len(input):
return 0
v1 = input[current]
v2 = input[current + 1]
pv2 = pair[v1]
if pv2 == v2:
return find_minimum_swaps_util(input, pair, index, current + 2)
else:
idx1 = index.get(v1)
idx2 = index.get(v2)
idx3 = index.get(pair[v1])
idx4 = index.get(pair[v2])
swap(index, input, idx2, idx3)
val1 = find_minimum_swaps_util(input, pair, index, current+2)
swap(index, input, idx2, idx3)
swap(index, input, idx1, idx4)
val2 = find_minimum_swaps_util(input, pair, index, current+2)
swap(index, input, idx1, idx4)
return 1 + max(val1, val2)
def swap(index, input, i, j):
index[input[i]] = j
index[input[j]] = i
t = input[i]
input[i] = input[j]
input[j] = t
if __name__ == '__main__':
input = [3, 5, 6, 4, 1, 2]
pair = {}
pair[1] = 3
pair[3] = 1
pair[2] = 6
pair[6] = 2
pair[4] = 5
pair[5] = 4
print(find_minimum_swaps(input, pair))
================================================
FILE: python/recursion/stringpermutation.py
================================================
# string permutation in lexicographically order with repetition of characters in the string
def permute(input):
count_map = {}
for ch in input:
if ch in count_map.keys():
count_map[ch] = count_map[ch] + 1
else:
count_map[ch] = 1
keys = sorted(count_map)
str = []
count = []
for key in keys:
str.append(key)
count.append(count_map[key])
result = [0 for x in range(len(input))]
permute_util(str, count, result, 0)
def permute_util(str, count, result, level):
if level == len(result):
print(result)
return
for i in range(len(str)):
if count[i] == 0:
continue;
result[level] = str[i]
count[i] -= 1
permute_util(str, count, result, level + 1)
count[i] += 1
if __name__ == '__main__':
input = ['B', 'C', 'A', 'A']
permute(input)
================================================
FILE: python/string/Z_Algorithm.py
================================================
#author: Pankaj Kumar
#time complexity: O(length(string) + length(pattern))
#space complexity: O(length(string) + length(pattern))
#Link to theory: http://www.geeksforgeeks.org/z-algorithm-linear-time-pattern-searching-algorithm/
def z_algo(arr):
z = [0 for i in range(len(arr))]
left , right = 0 , 0
for k in range(1 , len(arr)):
if k > right:
left = k
right = k
while right < len(arr) and arr[right] == arr[right-left]:
right += 1
z[k] = right - left
right -= 1
else:
k1 = k - left
if z[k1] < right - k + 1:
z[k] = z[k1]
else:
left = k
while right < len(arr) and arr[right] == arr[right-left]:
right += 1
z[k] = right - left
right -= 1
return z
def makepattern(string , pattern):
n , m = len(string) , len(pattern)
str_arr = []
for i in range(m):
str_arr.append(pattern[i])
str_arr.append('$')
for i in range(n):
str_arr.append(string[i])
z_values = z_algo(str_arr)
result = []
for i in range(len(z_values)):
if z_values[i] == m:
result.append(i - m - 1)
print result
if __name__ == '__main__':
string = 'abcdeabcd'
pattern = 'abc'
makepattern(string , pattern)
================================================
FILE: python/string/knuthmorrispratt.py
================================================
# Knuth-Morris-Pratt algorithm
# Compute temporary array to maintain size of suffix which is same as prefix
# Time/space complexity is O(size of pattern)
def compute_temporary_array(pattern):
n = len(pattern)
lsp = [0 for j in range(n)]
index = 0
i = 1
while i < len(pattern):
if pattern[i] == pattern[index]:
lsp[i] = index + 1
index += 1
i += 1
else:
if index != 0:
index = lsp[index - 1]
else:
lsp[i] = 0
i += 1
return lsp
# KMP algorithm of pattern matching.
def kmp(text, pattern):
lsp = compute_temporary_array(pattern)
i = 0
j = 0
while i < len(text) and j < len(pattern):
if text[i] == pattern[j]:
i += 1
j += 1
else:
if j != 0:
j = lsp[j - 1]
else:
i += 1
if j == len(pattern):
return True
else:
return False
src = 'abcxabcdabcdabcy'
sub_string = 'abcdabcy'
result = kmp(src, sub_string)
print(result)
================================================
FILE: python/string/rabinkarp.py
================================================
#Rabin Karp algorithm
# Java code https://github.com/mission-peace/interview/blob/master/src/com/interview/string/RabinKarpSearch.java
prime = 101
def pattern_matching(text, pattern):
m = len(pattern)
n = len(text)
pattern_hash = create_hash(pattern, m - 1)
text_hash = create_hash(text, m - 1)
for i in range(1, n - m + 2):
if pattern_hash == text_hash:
if check_equal(text[i-1:i+m-1], pattern[0:]) is True:
return i - 1;
if i < n - m + 1:
text_hash = recalculate_hash(text, i-1, i+m-1, text_hash, m)
return -1;
def check_equal(str1, str2):
if len(str1) != len(str2):
return False;
i = 0
j = 0
for i, j in zip(str1, str2):
if i != j:
return False;
return True
def create_hash(input, end):
hash = 0
for i in range(end + 1):
hash = hash + ord(input[i])*pow(prime, i)
return hash
def recalculate_hash(input, old_index, new_index, old_hash, pattern_len):
new_hash = old_hash - ord(input[old_index])
new_hash = new_hash/prime
new_hash += ord(input[new_index])*pow(prime, pattern_len - 1)
return new_hash;
index = pattern_matching("TusharRoy", "sharRoy")
print("Index ", index)
index = pattern_matching("TusharRoy", "Roy")
print("Index ", index)
index = pattern_matching("TusharRoy", "shar")
print("Index ", index)
index = pattern_matching("TusharRoy", "usha")
print("Index ", index)
index = pattern_matching("TusharRoy", "Tus")
print("Index ", index)
index = pattern_matching("TusharRoy", "Roa")
print("Index ", index)
================================================
FILE: python/tree/binary_tree.py
================================================
from collections import namedtuple
Color = namedtuple("Color", "RED BLACK")
class Node:
def __init__(self):
self.color = None
self.height = None
self.lis = None
self.data = None
self.size = None
self.next = None
self.right = None
self.left = None
@staticmethod
def newNode(data):
n = Node()
n.data = data
n.lis = -1
n.height = 1
n.size = 1
n.color = Color.RED
return n
class BinaryTree:
def __init__(self):
pass
@staticmethod
def add_head(data, head):
temp_head = head
n = Node.newNode(data)
if head is None:
head = n
return head
prev = None
while head is not None:
prev = head
if head.data < data:
head = head.right
else:
head = head.left
if prev.data < data:
prev.right = n
else:
prev.left = n
return temp_head
================================================
FILE: python/tree/construct_tree_from_inorder_preorder.py
================================================
from binary_tree import Node
class ConstructTreeFromInorderPreOrder:
def __init__(self):
self.index = 0
def _createTree(self, inorder, preorder, start, end):
if start > end:
return None
i = 0
for i in range(start, end + 1):
if preorder[self.index] == inorder[i]:
break
node = Node.newNode(preorder[self.index])
self.index += 1
node.left = self._createTree(inorder, preorder, start, i - 1)
node.right = self._createTree(inorder, preorder, i + 1, end)
return node
def createTree(self, inorder, preorder):
return self._createTree(inorder, preorder, 0, len(inorder) - 1)
================================================
FILE: python/tree/fenwick_tree.py
================================================
#################################################################################################################################
#Implementation of Binary Indexed Tree OR Fenwick Tree
#Time Complexities:
# Construction of Tree: O (n.log (n))
# Updating an element: O (log (n))
# Prefix Query (sum of elements 0 to i) or Range Minimum Query (sum of elements x to y): O (log (n))
#Space Complexity: O (n)
#################################################################################################################################
class FenTree (object):
def __init__ (self, array):
self.array, self.tree = [0] * len (array), [0] * (len (array) + 1);
for i in range (len (array)):
self.update (i, array [i]);
def get_parent (self, child):
return (child - (child & -child));
def get_next (self, index):
return (index + (index & -index));
def update (self, index, item):
current, self.array [index] = self.array [index], item;
item -= current;
index += 1;
while (index <= len (self.array)):
self.tree [index] += item;
index = self.get_next (index);
def prefix_sum (self, index):
index += 1;
total = 0;
while (index > 0):
total += self.tree [index];
index = self.get_parent (index);
return (total);
def range_sum (self, x, y):
return (self.prefix_sum (max (x, y)) - self.prefix_sum (min (x, y) - 1));
def describe (self):
print ('ARRAY =>\t', self.array);
print ('Binary Indexed Tree =>\t', self.tree);
if (__name__ == '__main__'):
tree = FenTree ([3,2,-1,6,5,4]);
# tree = FenTree ([int (i) for i in input ('Enter the array (space-separated integers): ').split ()]);
tree.describe ();
tree.update (4, 8); #replaces 5 with 8 in the list given to the fenwick tree
tree.describe ();
print (tree.range_sum (1, 5)); #returns 2-1+6+5+4
print (tree.prefix_sum (5)); #returns 3+2-1+6+5+4
================================================
FILE: python/tree/largest_bst_in_binary_tree.py
================================================
""" Given a binary tree, find size of largest binary search subtree in this binary tree.
Approach
--------
Traverse tree in post order fashion. Left and right nodes return 4 piece of information to root which isBST, size of max
BST, min and max in those subtree.
If both left and right subtree are BST and this node data is greater than max of left and less than min of right then it
returns to above level left size + right size + 1 and new min will be min of left side and new max will be max of right
side.
Video link
----------
* https://youtu.be/4fiDs7CCxkc
References
----------
* http://www.geeksforgeeks.org/find-the-largest-subtree-in-a-tree-that-is-also-a-bst/
* https://leetcode.com/problems/largest-bst-subtree/
* http://www.geeksforgeeks.org/construct-tree-from-given-inorder-and-preorder-traversal/
"""
from construct_tree_from_inorder_preorder import ConstructTreeFromInorderPreOrder
class MinMax:
def __init__(self):
self.min = float("inf")
self.max = float("-inf")
self.isBST = True
self.size = 0
class LargestBSTBinaryTree:
def largestBST(self, root):
m = self.largest(root)
return m.size
def largest(self, root):
if root is None:
return MinMax()
leftMinMax = self.largest(root.left)
rightMinMax = self.largest(root.right)
m = MinMax()
if ((leftMinMax.isBST == False or rightMinMax.isBST == False)
or (leftMinMax.max > root.data or rightMinMax.min <= root.data)):
m.isBST = False
m.size = max(leftMinMax.size, rightMinMax.size)
return m
m.isBST = True
m.size = leftMinMax.size + rightMinMax.size + 1
m.min = leftMinMax.min if root.left is not None else root.data
m.max = rightMinMax.max if root.right is not None else root.data
return m
if __name__ == '__main__':
lbi = LargestBSTBinaryTree()
ctf = ConstructTreeFromInorderPreOrder()
inorder = [-7, -6, -5, -4, -3, -2, 1, 2, 3, 16, 6, 10, 11, 12, 14]
preorder = [3, -2, -3, -4, -5, -6, -7, 1, 2, 16, 10, 6, 12, 11, 14]
root = ctf.createTree(inorder, preorder)
largestBSTSize = lbi.largestBST(root)
print "Size of the largest BST in the Binary Tree is ", largestBSTSize
assert 8 == lbi.largestBST(root)
================================================
FILE: python/tree/max_depth_binary_tree.py
================================================
"""
Problem Statement
=================
Given a binary tree, write a program to find the maximum depth at any given node.
For e.g, for this binary tree.
1
/ \
2 3
/ \
4 5
The height at 1 is 3, and the height at 3 is 2.
"""
class Node:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
n1 = Node(1)
n2 = Node(2)
n3 = Node(3)
n4 = Node(4)
n5 = Node(5)
# construct the tree as given in the problem.
n1.left = n2
n1.right = n3
n3.left = n4
n3.right = n5
def find_max_depth(n):
if n is None:
return 0
left_height = find_max_depth(n.left)
right_height = find_max_depth(n.right)
if left_height > right_height:
result = left_height + 1
else:
result = right_height + 1
return result
if __name__ == '__main__':
assert 3 == find_max_depth(n1)
assert 2 == find_max_depth(n3)
================================================
FILE: python/tree/morris_traversal.py
================================================
"""Morris Traversal of a Binary Tree.
Video
-----
* https://youtu.be/wGXB9OWhPTg
Analysis
--------
* Time complexity O(n)
* Space complexity O(1)
"""
from binary_tree import BinaryTree
class MorrisTraversal:
def __init__(self):
pass
@staticmethod
def find_predecessor(current):
predecessor = current.left
while predecessor.right != current and predecessor.right is not None:
predecessor = predecessor.right
return predecessor
@staticmethod
def inorder(root_node):
current = root_node
while current is not None:
if current.left is None:
print "{data} ".format(data=current.data),
current = current.right
else:
predecessor = MorrisTraversal.find_predecessor(current)
if predecessor.right is None:
predecessor.right = current
current = current.left
else:
predecessor.right = None
print "{data} ".format(data=current.data),
current = current.right
@staticmethod
def preorder(root_node):
current = root_node
while current is not None:
if current.left is None:
print "{data} ".format(data=current.data),
current = current.right
else:
predecessor = MorrisTraversal.find_predecessor(current)
if predecessor.right is None:
print "{data} ".format(data=current.data),
predecessor.right = current
current = current.left
else:
predecessor.right = None
current = current.right
if __name__ == '__main__':
bt = BinaryTree()
root = None
root = bt.add_head(10, root)
root = bt.add_head(50, root)
root = bt.add_head(-10, root)
root = bt.add_head(7, root)
root = bt.add_head(9, root)
root = bt.add_head(-20, root)
root = bt.add_head(30, root)
mt = MorrisTraversal()
mt.inorder(root)
print "\n",
mt.preorder(root)
================================================
FILE: python/tree/segmenttreesum.py
================================================
def create_segment_tree(input):
size = next_power_of_2(len(input));
segment_tree = [0 for x in range(2*size - 1)]
construct_tree(segment_tree, input, 0, len(input) - 1, 0)
return segment_tree
def construct_tree(segment_tree, input, low, high, pos):
if low == high:
segment_tree[pos] = input[low]
return
mid = (low + high)/2
construct_tree(segment_tree, input, low, mid, 2*pos + 1)
construct_tree(segment_tree, input, mid + 1, high, 2*pos + 2)
segment_tree[pos] = segment_tree[2*pos+1] + segment_tree[2*pos+2]
def sum_range_query(segment_tree, q_low, q_high, len):
return sum_range_query_util(segment_tree, 0, len - 1, q_low, q_high, 0)
def sum_range_query_util(segment_tree, low, high, q_low, q_high, pos):
if q_low <= low and q_high >= high:
return segment_tree[pos]
if q_high < low or q_low > high:
return 0
mid = (low + high)/2
return sum_range_query_util(segment_tree, low, mid, q_low, q_high, 2*pos + 1)\
+ sum_range_query_util(segment_tree, mid + 1, high, q_low, q_high, 2*pos + 2)
def update_value(input, segment_tree, new_value, index):
diff = new_value - input[index]
input[index] = new_value
update_value_util(segment_tree, 0, len(input)-1, diff, index, 0)
def update_value_util(segment_tree, low, high, diff, index, pos):
if low > index or high < index:
return
segment_tree[pos] += diff
if low >= high:
return
mid = (low + high)/2
update_value_util(segment_tree, low, mid, diff, index, 2*pos + 1)
update_value_util(segment_tree, mid + 1, high, diff, index, 2*pos + 2)
def next_power_of_2(n):
if n == 0:
return 1
if n & (n - 1) == 0:
return n
while n & (n - 1) > 0:
n &= (n - 1)
return n << 1
if __name__ == '__main__':
input = [1,3,5,7,9,11]
segment_tree = create_segment_tree(input)
print(segment_tree)
print(sum_range_query(segment_tree, 2, 5, len(input)))
print(sum_range_query(segment_tree, 1, 3, len(input)))
update_value(input, segment_tree, 4, 3)
print(sum_range_query(segment_tree, 2, 5, len(input)))
print(sum_range_query(segment_tree, 1, 3, len(input)))
================================================
FILE: src/com/interview/array/AdditiveNumber.java
================================================
package com.interview.array;
import java.math.BigInteger;
/**
* Date 04/24/2016
* @author Tushar Roy
*
* Additive number is a string whose digits can form additive sequence.
* A valid additive sequence should contain at least three numbers.
* Except for the first two numbers, each subsequent number in the sequence must be the sum of the preceding two.
*
* https://leetcode.com/problems/additive-number/
*/
public class AdditiveNumber {
public boolean isAdditiveNumber(String num) {
if (num.length() < 3) {
return false;
}
for (int i = 0; i <= num.length()/2; i++) {
if (num.charAt(0) == '0' && i > 0) {
break;
}
BigInteger x1 = new BigInteger(num.substring(0, i + 1));
//make sure remaining size is at least size of first and second integer.
for (int j = i + 1; Math.max(i, j - (i + 1)) + 1 <= num.length() - j - 1 ; j++) {
if (num.charAt(i + 1) == '0' && j > i + 1) {
break;
}
BigInteger x2 = new BigInteger(num.substring(i + 1, j + 1));
if (isValid(num, j + 1, x1, x2)) {
return true;
}
}
}
return false;
}
private boolean isValid(String num, int start, BigInteger x1, BigInteger x2) {
if (start == num.length()) {
return true;
}
BigInteger x3 = x1.add(x2);
//if num starts with x3 from offset start means x3 is found. So look for next number.
return num.startsWith(x3.toString(), start) && isValid(num, start + x3.toString().length(), x2, x3);
}
}
================================================
FILE: src/com/interview/array/ArrayAddition.java
================================================
package com.interview.array;
public class ArrayAddition {
public int[] add(int arr1[], int arr2[]){
int l = Math.max(arr1.length, arr2.length);
int[] result = new int[l];
int c=0;
int i = arr1.length-1;
int j= arr2.length-1;
int r=0;
l--;
while(i >=0 && j >=0){
r = arr1[i--] + arr2[j--] + c;
c = r/10;
result[l--] = r%10;
}
while(i>=0){
r = arr1[i--] + c;
c = r/10;
result[l--] = r%10;
}
while(j>=0){
r = arr2[j--] + c;
c = r/10;
result[l--] = r%10;
}
if(c != 0){
int[] newResult = new int[result.length+1];
for(int t= newResult.length-1; t> 0; t--){
newResult[t] = result[t-1];
}
newResult[0] = c;
return newResult;
}
return result;
}
public static void main(String args[]){
int arr1[] = {9,9,9,9,9,9,9};
int arr2[] = {1,6,8,2,6,7};
ArrayAddition aa = new ArrayAddition();
int result[] = aa.add(arr1, arr2);
for(int i=0; i < result.length; i++){
System.out.print(" " + result[i]);
}
}
}
================================================
FILE: src/com/interview/array/BestMeetingPoint.java
================================================
package com.interview.array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Date 03/24/2016
* @author Tushar Roy
*
* A group of two or more people wants to meet and minimize the total travel distance.
* You are given a 2D grid of values 0 or 1, where each 1 marks the home of someone in the group.
* The distance is calculated using Manhattan Distance, where distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|.
* Find the total distance that needs to be travelled to reach this meeting point.
*
* Time complexity O(m*n)
* Space complexity O(m + n)
*
* https://leetcode.com/problems/best-meeting-point/
*/
public class BestMeetingPoint {
public int minTotalDistance(int[][] grid) {
if (grid.length == 0 || grid[0].length == 0) {
return 0;
}
List vertical = new ArrayList<>();
List horizontal = new ArrayList<>();
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 1) {
vertical.add(i);
horizontal.add(j);
}
}
}
Collections.sort(vertical);
Collections.sort(horizontal);
int size = vertical.size()/2;
int x = vertical.get(size);
int y = horizontal.get(size);
int distance = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 1) {
distance += Math.abs(x - i) + Math.abs(y - j);
}
}
}
return distance;
}
public static void main(String args[]) {
BestMeetingPoint bmp = new BestMeetingPoint();
int[][] grid = {{1, 0, 0, 0, 1}, {0, 0, 0, 0, 0},{0, 0, 1, 0, 0}};
System.out.print(bmp.minTotalDistance(grid));
}
}
================================================
FILE: src/com/interview/array/BuySellStockProfit.java
================================================
package com.interview.array;
/**
* Date 03/04/2016
* @author Tushar Roy
*
* Best time to buy and sell stocks.
* 1) Only 1 transaction is allowed
* 2) Infinite number transactions are allowed
*
* Time complexity O(n)
* Space complexity O(1)
*
* https://leetcode.com/problems/best-time-to-buy-and-sell-stock/
* https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/
*/
public class BuySellStockProfit {
public int oneProfit(int arr[]){
int minPrice = arr[0];
int maxProfit = 0;
for(int i=1; i < arr.length; i++){
if(arr[i] - minPrice > maxProfit){
maxProfit = arr[i] - minPrice;
}
if(arr[i] < minPrice){
minPrice = arr[i];
}
}
return maxProfit;
}
public int allTimeProfit(int arr[]){
int profit = 0;
for(int i=1; i < arr.length;i++){
if(arr[i-1] < arr[i]){
profit += arr[i] - arr[i-1];
}
}
return profit;
}
public static void main(String args[]){
int arr[] = {7,10,15,5,11,2,7,9,3};
int arr1[] = {6,4,1,3,5,7,3,1,3,4,7,9,2,5,6,0,1,2};
BuySellStockProfit bss = new BuySellStockProfit();
System.out.println(bss.oneProfit(arr));
System.out.print(bss.allTimeProfit(arr1));
}
}
================================================
FILE: src/com/interview/array/CheckIfArrayElementsAreConsecutive.java
================================================
package com.interview.array;
/**
* http://www.geeksforgeeks.org/check-if-array-elements-are-consecutive/
*/
public class CheckIfArrayElementsAreConsecutive {
public boolean areConsecutive(int input[]){
int min = Integer.MAX_VALUE;
for(int i=0; i < input.length; i++){
if(input[i] < min){
min = input[i];
}
}
for(int i=0; i < input.length; i++){
if(Math.abs(input[i]) - min >= input.length){
return false;
}
if(input[Math.abs(input[i]) - min] < 0){
return false;
}
input[Math.abs(input[i]) - min] = -input[Math.abs(input[i]) - min];
}
for(int i=0; i < input.length ; i++){
input[i] = Math.abs(input[i]);
}
return true;
}
public static void main(String args[]){
int input[] = {76,78,76,77,73,74};
CheckIfArrayElementsAreConsecutive cia = new CheckIfArrayElementsAreConsecutive();
System.out.println(cia.areConsecutive(input));
}
}
================================================
FILE: src/com/interview/array/ChunkMerge.java
================================================
package com.interview.array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.PriorityQueue;
/**
* Given a list of lists. Each element in the list is sorted. Sort the
* entire list.
* Test cases
* One or more lists are empty
* All elements in one list are smaller than all elements in another list
*/
public class ChunkMerge {
class Triplet implements Comparable{
int pos;
int val;
int index;
@Override
public int compareTo(Triplet o) {
if(val <= o.val){
return -1;
}else{
return 1;
}
}
}
public List mergeUsingHeap(List> chunks){
List result = new ArrayList();
PriorityQueue queue = new PriorityQueue();
//add first element of every chunk into queue
for(int i=0; i < chunks.size(); i++){
Triplet p = new Triplet();
p.pos = i;
p.val = chunks.get(i).get(0);
p.index = 1;
queue.add(p);
}
while(!queue.isEmpty()){
Triplet p = queue.poll();
result.add(p.val);
if(p.index < chunks.get(p.pos).size()){
p.val = chunks.get(p.pos).get(p.index);
p.index += 1;
queue.add(p);
}
}
return result;
}
public List mergeChunksOfDifferentSize(List> chunks){
List result = new ArrayList();
int sum[] = new int[chunks.size()+1];
sum[0] = 0;
for(int i =1; i < sum.length;i++){
sum[i] = sum[i-1] + chunks.get(i-1).size();
}
for(List chunk : chunks){
for(Integer i : chunk){
result.add(i);
}
}
mergeSort(result,0,chunks.size()-1,sum);
return result;
}
private void mergeSort(List result,int start,int end,int sum[]){
if(start >= end){
return;
}
int mid = (start + end)/2;
mergeSort(result,start,mid,sum);
mergeSort(result,mid+1,end,sum);
sortedMerge(result,start,end,sum);
}
private void sortedMerge(List result,int start,int end,int sum[]){
/**
* If chunks are of equal size then
* i = size*start to (mid+1)*size -1
* j = (mid+1)*size to size*(end+1)
*/
int mid = (start + end)/2;
int i = sum[start];
int j = sum[mid+1];
List temp = new ArrayList();
while(i < sum[mid+1] && j < sum[end+1]){
if(result.get(i) < result.get(j)){
temp.add(result.get(i));
i++;
}else{
temp.add(result.get(j));
j++;
}
}
while(i < sum[mid+1]){
temp.add(result.get(i));
i++;
}
while(j < sum[end+1]){
temp.add(result.get(j));
j++;
}
int index = sum[start];
for(int k : temp){
result.set(index, k);
index++;
}
}
public static void main(String args[]){
Integer arr1[] = {1,5,6,9,21};
Integer arr2[] = {4,6,11,14};
Integer arr3[] = {-1,0,7};
Integer arr4[] = {-4,-2,11,14,18};
Integer arr5[] = {2,6};
Integer arr6[] = {-5,-2,1,5,7,11,14};
Integer arr7[] = {-6,-1,0,15,17,22,24};
List list1 = Arrays.asList(arr1);
List list2 = Arrays.asList(arr2);
List list3 = Arrays.asList(arr3);
List list4 = Arrays.asList(arr4);
List list5 = Arrays.asList(arr5);
List list6 = Arrays.asList(arr6);
List list7 = Arrays.asList(arr7);
List> chunks = new ArrayList>();
chunks.add(list1);
chunks.add(list2);
chunks.add(list3);
chunks.add(list4);
chunks.add(list5);
chunks.add(list6);
chunks.add(list7);
ChunkMerge cm = new ChunkMerge();
List result = cm.mergeChunksOfDifferentSize(chunks);
System.out.println(result.size());
for(Integer r : result){
System.out.print(r + " ");
}
result = cm.mergeUsingHeap(chunks);
System.out.println();
for(Integer r : result){
System.out.print(r + " ");
}
}
}
================================================
FILE: src/com/interview/array/CommonThreeSortedArray.java
================================================
package com.interview.array;
import java.util.ArrayList;
import java.util.List;
/**
* Date 01/01/2016
* @author Tushar Roy
*
* Given 3 sorted array find common elements in these 3 sorted array.
*
* Time complexity is O(m + n + k)
*
* http://www.geeksforgeeks.org/find-common-elements-three-sorted-arrays/
*/
public class CommonThreeSortedArray {
public List commonElements(int input1[], int input2[], int input3[]) {
int i = 0;
int j = 0;
int k = 0;
List result = new ArrayList<>();
while (i < input1.length && j < input2.length && k < input3.length) {
if (input1[i] == input2[j] && input2[j] == input3[k]) {
result.add(input1[i]);
i++;
j++;
k++;
} else if (input1[i] < input2[j]) {
i++;
} else if (input2[j] < input3[k]) {
j++;
} else {
k++;
}
}
return result;
}
public static void main(String args[]) {
int input1[] = {1, 5, 10, 20, 40, 80};
int input2[] = {6, 7, 20, 80, 100};
int input3[] = {3, 4, 15, 20, 30, 70, 80, 120};
CommonThreeSortedArray cts = new CommonThreeSortedArray();
List result = cts.commonElements(input1, input2, input3);
result.forEach(i -> System.out.print(i + " "));
}
}
================================================
FILE: src/com/interview/array/ConvertAnArrayIntoDecreaseIncreaseFashion.java
================================================
package com.interview.array;
import java.util.Arrays;
/**
* Convert an unsorted array into an array such that
* a < b > c < d > e < f and so on
*/
public class ConvertAnArrayIntoDecreaseIncreaseFashion {
public void convert(int arr[]){
int k = 0;
if(arr.length % 2 ==0){
k = arr.length/2 ;
}else{
k = arr.length/2+1;
}
KthElementInArray kthElement = new KthElementInArray();
kthElement.kthElement(arr, k);
int high = k;
int low = 1;
while(low < high && high < arr.length){
swap(arr,low,high);
high++;
low += 2;
}
}
/**
* Sort the array first.
* Then swap every adjacent element to get final result
* @param arr
*/
public void convert1(int arr[]){
Arrays.sort(arr);
for(int i=1; i < arr.length; i+=2){
if(i+1 < arr.length){
swap(arr, i, i+1);
}
}
}
private void swap(int arr[],int low,int high){
int temp = arr[low];
arr[low] = arr[high];
arr[high] = temp;
}
public static void main(String args[]){
ConvertAnArrayIntoDecreaseIncreaseFashion can = new ConvertAnArrayIntoDecreaseIncreaseFashion();
int arr[] = {0,6,9,13,10,-1,8,2,4,14,-5};
can.convert(arr);
for(int i=0; i < arr.length; i++){
System.out.print(arr[i] + " ");
}
System.out.println();
int arr1[] = {0,6,9,13,10,-1,8,2,4,14,-5};
can.convert1(arr1);
for(int i=0; i < arr1.length; i++){
System.out.print(arr1[i] + " ");
}
}
}
================================================
FILE: src/com/interview/array/CountInversionOfSize3.java
================================================
package com.interview.array;
/**
* Date 12/29/15
* @author Tushar Roy
*
* Given input array find number of inversions where i < j < k and input[i] > input[j] > input[k]
*
* http://www.geeksforgeeks.org/count-inversions-of-size-three-in-a-give-array/
*/
public class CountInversionOfSize3 {
/**
* Time complexity of this method is O(n^2)
* Space complexity is O(1)
*/
public int findInversions(int input[]) {
int inversion = 0;
for (int i = 1; i < input.length - 1 ; i++) {
int larger = 0;
for (int k = 0; k < i; k++) {
if (input[k] > input[i]) {
larger++;
}
}
int smaller = 0;
for (int k = i+1; k < input.length; k++) {
if (input[k] < input[i]) {
smaller++;
}
}
inversion += smaller*larger;
}
return inversion;
}
public static void main(String args[]) {
int input[] = {9, 6, 4, 5, 8};
CountInversionOfSize3 ci = new CountInversionOfSize3();
System.out.print(ci.findInversions(input));
}
}
================================================
FILE: src/com/interview/array/CountSmallerOnRight.java
================================================
package com.interview.array;
import java.util.ArrayList;
import java.util.List;
/**
* Date 03/01/2016
* @author Tushar Roy
*
* Count number of smaller elements on right side of an array for every element.
*
* Time complexity is O(nlogn)
* Space complexity is O(n)
*
* https://leetcode.com/problems/count-of-smaller-numbers-after-self/
*/
public class CountSmallerOnRight {
static class NumberIndex {
int val;
int index;
NumberIndex(int val, int index) {
this.val = val;
this.index = index;
}
}
public List countSmaller(int[] nums) {
if (nums.length == 0) {
return new ArrayList<>();
}
NumberIndex[] input = new NumberIndex[nums.length];
for (int i = 0; i < nums.length; i++) {
input[i] = new NumberIndex(nums[i], i);
}
int result[] = new int[nums.length];
mergeUtil(input, result, 0, input.length - 1);
List r = new ArrayList<>();
for (int s : result) {
r.add(s);
}
return r;
}
private void mergeUtil(NumberIndex[] nums, int[] result, int low, int high) {
if (low == high) {
return;
}
int mid = (low + high)/2;
mergeUtil(nums, result, low, mid);
mergeUtil(nums, result, mid + 1, high);
int i = low;
int j = mid + 1;
NumberIndex[] t = new NumberIndex[high - low + 1];
int k = 0;
int tempResult[] = new int[high - low + 1];
while (i <= mid && j <= high) {
if (nums[i].val <= nums[j].val) {
tempResult[nums[i].index - low] = j - mid - 1;
t[k++] = nums[i++];
} else {
tempResult[nums[i].index - low] = j - mid;
t[k++] = nums[j++];
}
}
int i1= i;
while (i1 <= mid) {
tempResult[nums[i1].index - low] = j - mid - 1;
t[k++] = nums[i1++];
}
while (j <= high) {
t[k++] = nums[j++];
}
k = 0;
for (i = low; i <= high; i++) {
nums[i] = t[k];
result[i] += tempResult[k++];
}
}
public static void main(String args[]) {
CountSmallerOnRight csr = new CountSmallerOnRight();
int nums[] = {5, 2, 6, 1, 0, 3};
List result = csr.countSmaller(nums);
result.forEach(r -> System.out.print(r + " "));
}
}
================================================
FILE: src/com/interview/array/DivideNumbersInEqualGroupWithClosestSum.java
================================================
package com.interview.array;
/**
* This solution is incorrect. It is greedy approach which will not work
* e.g 1,6,6,8,9,10 - Result should be 1,9,10 and 6,6,8 but it will not give this result
* since it will greedily break 9 and 10 into different sets
*
* INCORRECT SOLUTION.(Still keeping the code in case I can improve it)
*
*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class DivideNumbersInEqualGroupWithClosestSum {
public void divide(int arr[],List list1, List list2){
Arrays.sort(arr);
int len = arr.length;
int sum1 = 0;
int sum2 = 0;
for(int i = len-1 ; i >=0; i--){
if((sum1 < sum2 && list1.size() < len/2) || (list2.size() >= len/2)){
list1.add(arr[i]);
sum1 = sum1 + arr[i];
}else{
list2.add(arr[i]);
sum2 = sum2 + arr[i];
}
}
}
public static void main(String args[]){
List list1 = new ArrayList();
List list2 = new ArrayList();
int arr[] = {15,14,13,1,3,2,};
int arr1[] = {23, 45, 34, 12,11, 98, 99, 4, 189, 1,7,19,105, 201};
DivideNumbersInEqualGroupWithClosestSum dn = new DivideNumbersInEqualGroupWithClosestSum();
dn.divide(arr, list1, list2);
System.out.println(list1);
System.out.println(list2);
list1.clear();
list2.clear();
dn.divide(arr1, list1, list2);
System.out.println(list1);
System.out.println(list2);
}
}
================================================
FILE: src/com/interview/array/DuplicateNumberDetection.java
================================================
package com.interview.array;
/**
* Date 03/04/2016
* @author Tushar Roy
*
* Given an array of size n + 1 with elements from 1 to n. One element is duplicated mulitiple times.
* Find that element in O(1) space. Array cannot be changed.
*
* Reference
* https://leetcode.com/problems/find-the-duplicate-number/
*/
public class DuplicateNumberDetection {
public int findDuplicate(int[] nums) {
if (nums.length == 0 || nums.length == 1) {
return -1;
}
int slow = nums[0];
int fast = nums[nums[0]];
while (slow != fast) {
slow = nums[slow];
fast = nums[nums[fast]];
}
fast = 0;
while (slow != fast) {
slow = nums[slow];
fast = nums[fast];
}
return fast;
}
public static void main(String args[]) {
int[] input = {2,1,3,4,3};
DuplicateNumberDetection dd = new DuplicateNumberDetection();
System.out.println(dd.findDuplicate(input));
}
}
================================================
FILE: src/com/interview/array/DuplicateWithinkIndices.java
================================================
package com.interview.array;
import java.util.HashSet;
import java.util.Set;
/**
* Write a function that determines whether a array contains duplicate
* characters within k indices of each other
*/
public class DuplicateWithinkIndices {
public boolean duplicate(int arr[],int k){
Set visited = new HashSet();
for(int i=0; i < arr.length; i++){
if(visited.contains(arr[i])){
return true;
}
if(i >= k){
visited.remove(arr[i-k]);
}
visited.add(arr[i]);
}
return false;
}
public static void main(String args[]){
int arr[] = {1,2,3,11,2,5,6};
DuplicateWithinkIndices dk = new DuplicateWithinkIndices();
System.out.println(dk.duplicate(arr, 3));
}
}
================================================
FILE: src/com/interview/array/FindElementsOccurringNByKTimesTetris.java
================================================
package com.interview.array;
/**
* http://www.geeksforgeeks.org/given-an-array-of-of-size-n-finds-all-the-elements-that-appear-more-than-nk-times/
* The reason this algorithm works is there can never be more than k-1 elements of size
* more than n/k
*
* This question does not make much sense. Why not just use a map and keep count and
* check if occurrence is more than n/k. This is way too much effort to find elements more than
* n by k even though it saves some space.
*/
public class FindElementsOccurringNByKTimesTetris {
public static class Pair{
public int element;
public int count;
}
public void printElementsOccurringKTimes(int arr[],int k){
Pair[] p = new Pair[k];
for(int i=0; i < k; i++){
p[i] = new Pair();
}
for(int i=0; i < arr.length; i++){
int j=0;
for(j=0; j < k; j++){
if(p[j].element == arr[i]){
p[j].count++;
break;
}
}
if(j == k){
int l=0;
for(l =0; l < k ; l++){
if(p[l].count == 0){
p[l].element = arr[i];
p[l].count = 1;
break;
}
}
if(l == k){
for(int t =0; t < k ; t++){
p[t].count--;
}
}
}
}
for(int i=0; i < k ; i++){
if(p[i].count > 0){
int count =0;
for(int j=0; j < arr.length; j++){
if(arr[j] == p[i].element){
count++;
}
}
if(count >= arr.length/k){
System.out.println(p[i].element);
}
}
}
}
public static void main(String args[]){
int arr[] = {3,2,2,1,1,2,3,3,4,5,3,1};
FindElementsOccurringNByKTimesTetris fe = new FindElementsOccurringNByKTimesTetris();
fe.printElementsOccurringKTimes(arr, 3);
}
}
================================================
FILE: src/com/interview/array/FirstPositiveMissing.java
================================================
package com.interview.array;
/**
* https://leetcode.com/problems/first-missing-positive/
*/
public class FirstPositiveMissing {
public int firstMissingPositive(int[] nums) {
int startOfPositive = segregate(nums);
for (int i = startOfPositive; i < nums.length; i++) {
int index = Math.abs(nums[i]) + startOfPositive - 1;
if (index < nums.length) {
nums[index] = -Math.abs(nums[index]);
}
}
for (int i = startOfPositive; i < nums.length; i++) {
if (nums[i] > 0) {
return i - startOfPositive + 1;
}
}
return nums.length - startOfPositive + 1;
}
private int segregate(int[] nums) {
int start = 0;
int end = nums.length -1 ;
while (start <= end) {
if (nums[start] <= 0) {
start++;
} else if (nums[end] > 0) {
end--;
} else {
swap(nums, start, end);
}
}
return start;
}
private void swap(int[] nums, int start, int end) {
int t = nums[start];
nums[start] = nums[end];
nums[end] = t;
}
}
================================================
FILE: src/com/interview/array/Flip0sMaximum1s.java
================================================
package com.interview.array;
/**
* Date 12/29/2015
* @author Tushar Roy
*
* Given input array of 0s and 1s and number of flips allowed from 0 to 1, what is maximum consecutive 1s we can have
* in array
*
* Time complexity - O(n)
* Space complexity - O(1)
*
* http://www.geeksforgeeks.org/find-zeroes-to-be-flipped-so-that-number-of-consecutive-1s-is-maximized/
*/
public class Flip0sMaximum1s {
public int flip0sToMaximizeConsecutive1s(int input[], int flipsAllowed) {
int windowStart = 0;
int countZero = 0;
int result = 0;
for (int i = 0 ; i < input.length; i++) {
if (input[i] == 1) {
result = Math.max(result, i - windowStart + 1);
} else {
if (countZero < flipsAllowed) {
countZero++;
result = Math.max(result, i - windowStart + 1);
} else {
while(true) {
if (input[windowStart] == 0) {
windowStart++;
break;
}
windowStart++;
}
}
}
}
return result;
}
public static void main(String args[]) {
int input[] = {0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1};
Flip0sMaximum1s fm = new Flip0sMaximum1s();
System.out.print(fm.flip0sToMaximizeConsecutive1s(input, 1));
}
}
================================================
FILE: src/com/interview/array/FourSum.java
================================================
package com.interview.array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* Date 07/31/2016
* @author Tushar Roy
*
* Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target?
* Find all unique quadruplets in the array which gives the sum of target.
*
* Time complexity O(n^3)
* Space complexity O(1)
*
* Reference
* https://leetcode.com/problems/4sum/
*/
public class FourSum {
public List> fourSum(int[] nums, int target) {
if (nums.length < 4) {
return Collections.EMPTY_LIST;
}
Arrays.sort(nums);
List> result = new ArrayList<>();
for (int i = 0; i < nums.length - 3; i++) {
if (i != 0 && nums[i] == nums[i - 1]) {
continue;
}
if(nums[i] + nums[i+1] + nums[i+2] + nums[i+3] > target) {
break;
}
if(nums[i] + nums[nums.length - 3] + nums[nums.length - 2] + nums[nums.length - 1] < target) {
continue;
}
for (int j = i + 1; j < nums.length - 2; j++) {
if (j != i + 1 && nums[j] == nums[j - 1]) {
continue;
}
if (nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) {
break;
}
if (nums[i] + nums[j] + nums[nums.length - 1] + nums[nums.length - 1] < target) {
continue;
}
int low = j + 1;
int high = nums.length - 1;
while (low < high) {
if (low != j + 1 && nums[low] == nums[low - 1]) {
low++;
continue;
}
if (high != nums.length - 1 && nums[high] == nums[high + 1]) {
high--;
continue;
}
int sum = nums[i] + nums[j] + nums[low] + nums[high];
if (sum == target) {
List r = new ArrayList<>();
r.add(nums[i]);
r.add(nums[j]);
r.add(nums[low]);
r.add(nums[high]);
result.add(r);
low++;
high--;
} else if (sum < target) {
low++;
} else {
high--;
}
}
}
}
return result;
}
public static void main(String args[]) {
int[] nums = {1, 1, 4, 5, 9, 11};
int[] nums1 = {1, 0, -1, 0, -2, 2};
int target = 0;
FourSum fourSum = new FourSum();
List> result = fourSum.fourSum(nums1, target);
result.forEach(System.out::print);
}
}
================================================
FILE: src/com/interview/array/GasStationCircle.java
================================================
package com.interview.array;
/**
* http://www.geeksforgeeks.org/find-a-tour-that-visits-all-stations/
* You can solve this one using kadane wrap since it finds max contiguous sum
* for wrapped array. That start point is a best place to start a tour.
* Test cases
* Check if length of both input array is same
* Check that there exists a path after kadane wrap responds
* Check that there is at least one positive difference before you call kadane
*/
public class GasStationCircle {
public int startTour(int gasAvailable[],int gasRequired[]){
int start = -1;
int end = 0;
int currentGas = 0;
boolean visitedOnce = false;
while(start != end){
currentGas += gasAvailable[end] - gasRequired[end];
if(start == -1){
start = end;
}
if(end == gasAvailable.length-1 && visitedOnce == false){
visitedOnce = true;
}else if(end == gasAvailable.length-1 && visitedOnce == true){
return -1;
}
if(currentGas < 0){
start = -1;
currentGas = 0;
}
end = (end + 1)%gasAvailable.length;
}
return end;
}
/**
* If it is not guaranteed that tour exists then once you get
* result of kadanewrap make an actual trip to see if value is positive
* @return -1 if no solution exists otherwise returns gas station at which to start.
*/
public int startTour1(int gasAvailable[], int gasRequired[]){
int diff[] = new int[gasAvailable.length];
for(int i=0; i < diff.length; i++){
diff[i] = gasAvailable[i] - gasRequired[i];
}
boolean allNegative = true;
for (int i = 0; i < diff.length; i++) {
if (diff[i] >= 0) {
allNegative = false;
break;
}
}
if (allNegative) {
return -1;
}
KadaneWrapArray kwa = new KadaneWrapArray();
Triplet t = kwa.kadaneWrap(diff);
//make sure this solution leads to answer
int i = t.start;
int netGas = 0;
do {
netGas += diff[i];
i = (i + 1)%diff.length;
if (netGas < 0) {
return -1;
}
} while (i != t.start);
return t.start;
}
public static void main(String args[]){
GasStationCircle gsc = new GasStationCircle();
int[] gasAvailable = {4, 4, 6};
int[] gasRequired = {5, 6, 1};
System.out.println(gsc.startTour(gasAvailable, gasRequired));
System.out.println(gsc.startTour1(gasAvailable, gasRequired));
}
}
================================================
FILE: src/com/interview/array/GreedyTextJustification.java
================================================
package com.interview.array;
import java.util.ArrayList;
import java.util.List;
/**
* Date 03/12/2016
* @author Tushar Roy
*
* Given an array of words and a length L, format the text such that each line has exactly L characters and is fully
* (left and right) justified.
* You should pack your words in a greedy approach; that is, pack as many words as you can in each line.
*
* Time complexity - O(n) where n is the number of words
* Space complexity - O(1)
*
* https://leetcode.com/problems/text-justification/
*/
public class GreedyTextJustification {
public List fullJustify(String[] words, int maxWidth) {
List result = new ArrayList<>();
for (int i = 0; i < words.length; ) {
int total = words[i].length();
int j = i + 1;
StringBuffer buff = new StringBuffer();
buff.append(words[i]);
while(j < words.length && total + words[j].length() + 1 <= maxWidth) {
total += words[j].length() + 1;
j++;
}
int remaining = maxWidth - total;
//since j is not word length means its not a last line. So pad accordingly.
if (j != words.length) {
int count = j - i - 1;
if (count == 0) {
padSpace(buff, remaining);
} else {
int q = remaining/count;
int r = remaining % count;
for (int k = i + 1; k < j; k++) {
padSpace(buff, q);
if (r > 0) {
buff.append(" ");
r--;
}
buff.append(" ").append(words[k]);
}
}
} else { //if it is last line then left justify all the words.
for (int k = i + 1; k < j; k++) {
buff.append(" ").append(words[k]);
}
padSpace(buff, remaining);
}
result.add(buff.toString());
i = j;
}
return result;
}
private void padSpace(StringBuffer buff, int count) {
for (int i = 0; i < count; i++) {
buff.append(" ");
}
}
public List fullJustify1(String[] words, int maxWidth) {
int currentLength = 0;
int prevIndex = 0;
List result = new ArrayList<>();
for (int i = 0; i < words.length; i++) {
//keep track of length for currentLine. For first word only use length while for remaining words use
//lenght + 1 since there will be a space b/w them.
currentLength += (words[i].length() + (i == prevIndex ? 0 : 1));
//if currentLength exceeds maxWidth it means currentWord cannot in same line.
if (currentLength > maxWidth) {
//subtract current word's length from currentLength
currentLength -= words[i].length() + 1;
StringBuffer builder = new StringBuffer();
//find number of words which will find in the line.
int gaps = i - 1 - prevIndex;
if (gaps > 0) {//if more than one word fits in the gap.
//available number of spaces is below. Subtract gaps because that many spaces have been accounted
//for in currentLength.
int availableSpace = maxWidth - currentLength + gaps;
//first remaining gaps get one extra space.
int remaining = availableSpace % gaps;
//every gap gets this much extra space.
int atleast = availableSpace / gaps;
for (int j = prevIndex; j <= i - 2; j++) {
builder.append(words[j]);
padSpace(builder, atleast);
if (j - prevIndex < remaining) {
padSpace(builder, 1);
}
}
builder.append(words[i - 1]);
} else { //if only one word can fit in a one line then left specify it.
builder.append(words[i - 1]);
padSpace(builder, maxWidth - words[i - 1].length());
}
result.add(builder.toString());
prevIndex = i;
currentLength = words[i].length();
}
}
//handle the last line. Left justify the remaining words
if (prevIndex < words.length) {
StringBuffer builder = new StringBuffer();
int count = 0;
while (prevIndex < words.length) {
builder.append(words[prevIndex]).append(" ");
count += words[prevIndex].length() + 1;
prevIndex++;
}
count--;
//delete extra space added by above for looop.
builder.deleteCharAt(builder.length() - 1);
//whatever spae is left just put it at the end.
padSpace(builder, maxWidth - count);
result.add(builder.toString());
}
return result;
}
public static void main(String args[]) {
String[] input = {"What","must","be","shall","be."};
GreedyTextJustification gtj = new GreedyTextJustification();
List result = gtj.fullJustify(input, 12);
System.out.print(result);
}
}
================================================
FILE: src/com/interview/array/GroupElementsInSizeM.java
================================================
package com.interview.array;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
/**
* http://www.careercup.com/question?id=6026101998485504
* This answer two questions.
* Group elements in size m such that in every group only unique elements are possible.
* It also answers question where rearrange array such that same elements are exactly m
* distance from each other
*/
class Pair{
int num;
int count;
Pair(int num,int count){
this.count = count;
this.num = num;
}
}
class Comparators implements Comparator{
@Override
public int compare(Pair o1, Pair o2) {
if(o1.count <= o2.count){
return 1;
}else{
return -1;
}
}
}
public class GroupElementsInSizeM {
public boolean group(int input[],int m){
Map count = new HashMap();
for(Integer i : input){
int c = 1;
if(count.containsKey(i)){
c = count.get(i);
c++;
}
count.put(i, c);
}
PriorityQueue maxHeap = new PriorityQueue(count.size(),new Comparators());
for(Integer s : count.keySet()){
int c = count.get(s);
//if any count is greater than len/m then this arrangement is not possible
if(c > Math.ceil(input.length*1.0/m)){
return false;
}
maxHeap.offer(new Pair(s,c));
}
int current = 0;
int start = current;
while(maxHeap.size() > 0){
Pair p = maxHeap.poll();
int i =0;
while(i < p.count){
input[start] = p.num;
start = start + m;
if(start >= input.length){
current++;
start = current;
}
i++;
}
}
return true;
}
public static void main(String args[]){
int input[] = {2,1,5,1,3,5,3,3,4};
int input1[] = {1,2,3,8,8,8,7,8};
GroupElementsInSizeM gps = new GroupElementsInSizeM();
boolean r = gps.group(input1, 3);
System.out.println(r);
for(int i=0; i < input1.length; i++){
System.out.println(input1[i]);
}
}
}
================================================
FILE: src/com/interview/array/HIndex.java
================================================
package com.interview.array;
/**
* Given an array of citations (each citation is a non-negative integer) of a researcher,
* write a function to compute the researcher's h-index.
* https://leetcode.com/problems/h-index/
*/
public class HIndex {
public int hIndex(int[] citations) {
int[] count = new int[citations.length + 1];
for (int c : citations) {
if (c <= citations.length) {
count[c]++;
} else {
count[citations.length]++;
}
}
int sum = 0;
int max = 0;
for (int i = 0; i < count.length; i++) {
sum += count[i];
//we are trying to see if i is answer.
//already everything before i has less than i citations.
//so only thing to check is that p >= i where p is
//total number of papers with i or more citations.
int p = citations.length - sum + count[i];
if (i <= p) {
max = i;
}
}
return max;
}
public static void main(String args[]) {
HIndex hi = new HIndex();
int[] input = {0, 1, 1, 1, 1, 6, 7 ,8};
System.out.print(hi.hIndex(input));
}
}
//0 1 2 6 6 6 6 7
//0 1 2 3 4 5 6 7
//0 1 1 1 3 6 7 8
//0 1 2 3 4 5 6 7
//0 1 2 5 6
================================================
FILE: src/com/interview/array/IncreasingSubsequnceOfLength3WithMaxProduct.java
================================================
package com.interview.array;
/**
* http://www.geeksforgeeks.org/increasing-subsequence-of-length-three-with-maximum-product/
* Keep two arrays which keeps max from current position to right side
* Other array keeps max on left size which is smaller than current element
* Once you have these two arrays from 2nd to 2nd last position keep multiplying
* elements at 3 arrays index position to get max product
* Test cases
* Negative numbers
* 0 in the input
*/
public class IncreasingSubsequnceOfLength3WithMaxProduct {
public int maxProduct(int arr[]){
int RGN[] = new int[arr.length];
int LGN[] = new int[arr.length];
RGN[arr.length-1] = arr[arr.length-1];
int max = arr[arr.length-1];
for(int i=arr.length-2; i>=0; i--){
if(max < arr[i]){
max = arr[i];
}
if(max > arr[i]){
RGN[i] = max;
}
else{
RGN[i] = 0;
}
}
LGN[0] = 0;
//This can be implemented using an AVL tree instead of this way which will
//make it O(nLogn) operation insteado ofO(n2).
for(int i=1; i < arr.length; i++){
getLGN(arr,i,LGN);
}
int maxProduct = 0;
for(int i=1; i < arr.length-1; i++){
int product = arr[i]*LGN[i]*RGN[i];
if(maxProduct < product){
maxProduct = product;
}
}
return maxProduct;
}
private void getLGN(int arr[],int pos,int LGN[]){
int max = 0;
int i =0;
while(i < pos){
if(arr[i] < arr[pos]){
if(arr[i] > max){
max = arr[i];
}
}
i++;
}
LGN[pos] = max;
}
public static void main(String args[]){
int arr[] = {6, 7, 8, 1, 2, 3, 9, 10};
IncreasingSubsequnceOfLength3WithMaxProduct iss = new IncreasingSubsequnceOfLength3WithMaxProduct();
System.out.println(iss.maxProduct(arr));
int arr1[] = {1, 5, 10, 8, 9};
System.out.println(iss.maxProduct(arr1));
}
}
================================================
FILE: src/com/interview/array/IncreasingTripletSubsequence.java
================================================
package com.interview.array;
/**
* Date 03/06/2016
* @author Tushar Roy
*
* Find if there exists an increasing triplet subsequence.
* Similar method to longest increasing subsequence in nlogn time.
*
* Time complexity is O(n)
* Space complexity is O(1)
*
* https://leetcode.com/problems/increasing-triplet-subsequence/
*/
public class IncreasingTripletSubsequence {
public boolean increasingTriplet(int[] nums) {
int T[] = new int[3];
int len = 0;
for (int i = 0; i < nums.length; i++) {
boolean found = false;
for (int j = 0; j < len; j++) {
if (T[j] >= nums[i]) {
T[j] = nums[i];
found = true;
break;
}
}
if (!found) {
T[len++] = nums[i];
}
if (len == 3) {
return true;
}
}
return false;
}
public static void main(String args[]) {
IncreasingTripletSubsequence tripletSubsequence = new IncreasingTripletSubsequence();
int input[] = {9, 10, -2, 12, 6, 7, -1};
System.out.print(tripletSubsequence.increasingTriplet(input));
}
}
================================================
FILE: src/com/interview/array/JumpGame.java
================================================
package com.interview.array;
/**
* Date 07/31/2016
* @author Tushar Roy
*
* Given an array of non-negative integers, you are initially positioned at the first index of the array.
* Each element in the array represents your maximum jump length at that position.
* Determine if you are able to reach the last index.
*
* Time complexity O(n)
* Space complexity O(1)
*
* https://leetcode.com/problems/jump-game/
*
* Given an array of non-negative integers, you are initially positioned at the first index of the array.
* Each element in the array represents your maximum jump length at that position.
* Your goal is to reach the last index in the minimum number of jumps.
*
* Time complexity O(n)
* Space complexity O(1)
*
* https://leetcode.com/problems/jump-game-ii/
*/
public class JumpGame {
public boolean canJump(int[] nums) {
int jump = 0;
int i;
for (i = 0; i < nums.length && i <= jump; i++) {
jump = Math.max(jump, i + nums[i]);
}
return i == nums.length;
}
public int jump(int[] nums) {
int current = 0;
int max = 0;
int count = 0;
for (int i = 0; i < nums.length - 1; i++) {
max = Math.max(max, i + nums[i]);
if (current == i) {
count++;
current = max;
}
}
return count;
}
public static void main(String args[]) {
JumpGame jumpGame = new JumpGame();
int[] nums = {3, 2, 3, 0, 2, 1};
System.out.println(jumpGame.jump(nums));
int[] nums1 = {3, 0, 2, 0, 0, 1};
System.out.println(jumpGame.canJump(nums1));
}
}
================================================
FILE: src/com/interview/array/KadaneWrapArray.java
================================================
package com.interview.array;
/**
* http://www.geeksforgeeks.org/maximum-contiguous-circular-sum/
* Test cases
* All negative
* All positives
* all 0s
*/
class Triplet{
int start;
int end;
int sum;
@Override
public String toString() {
return "Triplet [start=" + start + ", end=" + end + ", sum=" + sum
+ "]";
}
}
public class KadaneWrapArray {
public Triplet kadaneWrap(int arr[]){
Triplet straightKadane = kadane(arr);
int sum =0;
for(int i=0; i < arr.length; i++){
sum += arr[i];
arr[i] = -arr[i];
}
Triplet wrappedNegKadane = kadane(arr);
for(int i=0; i < arr.length; i++){
arr[i] = -arr[i];
}
if(straightKadane.sum < sum + wrappedNegKadane.sum){
straightKadane.sum = wrappedNegKadane.sum + sum;
straightKadane.start = wrappedNegKadane.end+1;
straightKadane.end = wrappedNegKadane.start-1;
}
return straightKadane;
}
/**
* This method assumes there is at least one positive number in the array.
* Otherwise it will break
* @param arr
* @return
*/
public Triplet kadane(int arr[]){
int sum =0;
int cStart = 0;
int mStart = 0;
int end = 0;
int maxSum = Integer.MIN_VALUE;
for(int i=0; i < arr.length; i++){
sum += arr[i];
if(sum <= 0){
sum = 0;
cStart = i+1;
}else{
if(sum > maxSum){
maxSum = sum;
mStart = cStart;
end = i;
}
}
}
Triplet p = new Triplet();
p.sum = maxSum;
p.start = mStart;
p.end = end;
return p;
}
public static void main(String args[]){
KadaneWrapArray kwa = new KadaneWrapArray();
int input[] = {12, -2, -6, 5, 9, -7, 3};
int input1[] = {8, -8, 9, -9, 10, -11, 12};
System.out.println(kwa.kadaneWrap(input));
System.out.println(kwa.kadaneWrap(input1));
}
}
================================================
FILE: src/com/interview/array/KthElementInArray.java
================================================
package com.interview.array;
import java.util.Arrays;
/**
* Kth largest element in an array.
* Use quickselect of quicksort to find the solution in hopefully O(nlogn) time.
* Test cases
* Sorted array
* Reverse sorted array
*/
public class KthElementInArray {
public int kthElement(int arr[],int k){
int low = 0;
int high = arr.length-1;
int pos =0;
while(true){
pos = quickSelect(arr,low,high);
if(pos == (k+low)){
return arr[pos];
}
if(pos > k + low){
high = pos-1;
}else{
k = k - (pos - low + 1);
low = pos+1;
}
}
}
private int quickSelect(int arr[],int low,int high){
int pivot = low;
low++;
while(low <= high){
if(arr[pivot] > arr[low]){
low++;
continue;
}
if(arr[pivot] <= arr[high]){
high--;
continue;
}
swap(arr,low,high);
}
if(arr[high] < arr[pivot]){
swap(arr,pivot,high);
}
return high;
}
private void swap(int arr[],int low,int high){
int temp = arr[low];
arr[low] = arr[high];
arr[high] = temp;
}
public static void main(String args[]){
int arr[] = {6, 2, 1, 6, 8, 9, 6};
KthElementInArray kthElement = new KthElementInArray();
System.out.print(kthElement.kthElement(arr, arr.length/2));
System.out.print(Arrays.toString(arr));
}
}
================================================
FILE: src/com/interview/array/KthLargestInTwoSortedArray.java
================================================
package com.interview.array;
/**
* http://stackoverflow.com/questions/4686823/given-2-sorted-arrays-of-integers-find-the-nth-largest-number-in-sublinear-time
* http://articles.leetcode.com/2011/01/find-k-th-smallest-element-in-union-of.html
*/
public class KthLargestInTwoSortedArray {
public int kthLargest1(int arr1[],int arr2[],int low1,int high1,int low2,int high2,int k){
int len1 = high1-low1 +1;
int len2 = high2 - low2+1;
if(len1 == 0){
return arr2[low2+k];
}
if(len2 ==0){
return arr1[low1+k];
}
if(k == 0){
return Math.min(arr1[low1], arr2[low2]);
}
int mid1 = len1*k/(len1 + len2);
int mid2 = k - mid1 - 1;
mid1 = low1+mid1;
mid2 = low2 + mid2;
if(arr1[mid1] > arr2[mid2]){
k = k - mid2 + low2 -1;
high1 = mid1;
low2 = mid2 + 1;
}else{
k = k - mid1 + low1 -1;
high2 = mid2;
low1 = mid1+1;
}
return kthLargest(arr1, arr2, low1, high1, low2, high2, k);
}
public int kthLargest(int input1[],int input2[],int k){
return kthLargest(input1, input2, 0, input1.length-1, 0, input2.length-1, k);
}
private int kthLargest(int input1[],int input2[],int l1, int h1, int l2,int h2,int k){
if(l1 > h1){
return input2[k-1];
}
if(l2 > h2){
return input1[k-1];
}
if((h1 - l1 + 1) + (h2 - l2 + 1) == k){
return Math.max(input1[h1], input2[h2]);
}
if(k == 1){
return Math.min(input1[l1],input2[l2]);
}
//handle the situation where only one element is left
//in either of array.
//e.g k =2 and arr1 = 8 arr2 = 1,9,11
//we try to find if 8 is before 9 betweenn 1 and 9
//or before 1. In all these cases k will be either
//1 8 or 9
if(l2 == h2 || l1 == h1){
if(l2 == h2){
if(input1[l1+k-1] < input2[l2]){
return input1[l1+k-1];
}else if(input1[l1+k-2] > input2[l2]){
return input1[l1+k-2];
}else{
return input2[l2];
}
}
if(l1 == h1){
if(input2[l2+k-1] < input1[l1]){
return input2[l2+k-1];
}else if(input2[l2+k-2] > input1[l1]){
return input2[l2+k-2];
}else{
return input1[l1];
}
}
}
int m1 = (h1 + l1)/2;
int m2 = (h2 + l2)/2;
int diff1 = m1 - l1+1;
int diff2 = m2 - l2+1;
if(diff1 + diff2 >= k){
if(input1[m1] < input2[m2]){
return kthLargest(input1, input2, l1, h1, l2, m2, k);
}else{
return kthLargest(input1, input2, l1, m1, l2, h2, k);
}
}else{
if(input1[m1] < input2[m2]){
return kthLargest(input1, input2,m1+1, h1, l2, h2, k - diff1);
}else{
return kthLargest(input1, input2, l1, h1, m2+1, h2, k -diff2);
}
}
}
public static void main(String args[]){
KthLargestInTwoSortedArray kis = new KthLargestInTwoSortedArray();
int input1[] = {1,4,7,11,17,21};
int input2[] = {-4,-1,3,4,6,28,35,41,56,70};
for(int i = 0; i < input1.length + input2.length; i++){
System.out.println(kis.kthLargest(input1, input2, i+1));
}
// System.out.println(kis.kthLargest(input1, input2, 6));
}
}
================================================
FILE: src/com/interview/array/LargerElementOnRight.java
================================================
package com.interview.array;
import java.util.Deque;
import java.util.LinkedList;
/**
* http://www.geeksforgeeks.org/next-greater-element/
* Find next larger element on right side of a number in array for
* all positions in array
* This is different than finding largest element on right side which can
* be done by keeping max while iterating from right
* It is also different from find next higher number on right side which can
* be found by keeping AVL tree and finding ceiling.
*/
public class LargerElementOnRight {
public int[] larger(int input[]){
Deque stack = new LinkedList();
int result[] = new int[input.length];
for(int i=0; i < result.length; i++){
result[i] = -1;
}
stack.offerFirst(0);
for(int i=1; i < input.length; i++){
while(stack.size() > 0){
int t = stack.peekFirst();
if(input[t] < input[i]){
result[t] = i;
stack.pollFirst();
}else{
break;
}
}
stack.offerFirst(i);
}
return result;
}
public static void main(String args[]){
LargerElementOnRight leo = new LargerElementOnRight();
int input[] = {4,2,-8,6,0,-3,-1,1,9};
int result[] = leo.larger(input);
for(int i=0; i < result.length; i++){
if(result[i] != -1){
System.out.print(input[result[i]] + " ");
}else{
System.out.print("NIL ");
}
}
}
}
================================================
FILE: src/com/interview/array/LargestMountain.java
================================================
package com.interview.array;
/**
* https://leetcode.com/problems/longest-mountain-in-array/description/
*/
public class LargestMountain {
public int longestMountain(int[] nums) {
int start = 0;
int max = 0;
State state = State.STARTED;
for (int i = 1; i < nums.length; i++) {
if (nums[i] == nums[i - 1]) {
start = i;
state = State.STARTED;
}
else if (nums[i] > nums[i - 1]) {
if (state == State.DECREASING || state == State.STARTED) {
start = i - 1;
state = State.INCREASING;
}
} else {
if (state == State.INCREASING || state == State.DECREASING) {
state = State.DECREASING;
max = Math.max(max, i - start + 1);
} else {
start = i;
}
}
}
return max;
}
enum State {
STARTED,
INCREASING,
DECREASING;
}
public static void main(String[] args) {
LargestMountain lm = new LargestMountain();
int[] nums = {2, 1, 4, 7, 3, 2, 5};
System.out.println(lm.longestMountain(nums));
}
}
================================================
FILE: src/com/interview/array/LargestSubArrayWithEqual0sAnd1s.java
================================================
package com.interview.array;
import java.util.HashMap;
import java.util.Map;
/**
* http://www.geeksforgeeks.org/largest-subarray-with-equal-number-of-0s-and-1s/
* Test cases
* Starting with either 0 or 1
* Maximum length of 0 1 2 or more
*
*/
public class LargestSubArrayWithEqual0sAnd1s {
public int equalNumber(int arr[]){
int sum[] = new int[arr.length];
sum[0] = arr[0] == 0? -1 : 1;
for(int i=1; i < sum.length; i++){
sum[i] = sum[i-1] + (arr[i] == 0? -1 : 1);
}
Map pos = new HashMap();
int maxLen = 0;
int i = 0;
for(int s : sum){
if(s == 0){
maxLen = Math.max(maxLen, i+1);
}
if(pos.containsKey(s)){
maxLen = Math.max(maxLen, i-pos.get(s));
}else{
pos.put(s, i);
}
i++;
}
return maxLen;
}
public static void main(String args[]){
int arr[] = {0,0,0,1,0,1,0,0,1,0,0,0};
LargestSubArrayWithEqual0sAnd1s mse = new LargestSubArrayWithEqual0sAnd1s();
System.out.println(mse.equalNumber(arr));
}
}
================================================
FILE: src/com/interview/array/LeetCodeCandy.java
================================================
package com.interview.array;
/**
* References
* https://leetcode.com/problems/candy/
*/
public class LeetCodeCandy {
public int candy(int[] ratings) {
int pointOfChange = 0;
int totalCandies = 1;
int currentCandy = 1;
boolean isIndependent = true;
int maxHeight = 0;
int diff = 0;
for (int i = 1; i < ratings.length; i++) {
diff = 0;
if (ratings[i] > ratings[i-1]) {
currentCandy += 1;
} else if (ratings[i] == ratings[i-1]) {
isIndependent = true;
pointOfChange = i;
currentCandy = 1;
} else {
if (currentCandy == 1) {
if (!isIndependent) {
if (i - pointOfChange == maxHeight - 1) {
pointOfChange--;
}
}
}
else {
maxHeight = currentCandy;
currentCandy = 1;
isIndependent = false;
pointOfChange = i;
}
diff = i - pointOfChange;
}
totalCandies += (diff + currentCandy);
}
return totalCandies;
}
}
================================================
FILE: src/com/interview/array/LongestConsecutiveSubsequence.java
================================================
package com.interview.array;
import java.util.HashMap;
import java.util.Map;
/**
* Date 12/03/2016
* @author Tushar Roy
*
* Find longest consecutive subsequence in unsorted array.
*
* Time complexity O(n)
* Space complexity O(n)
*
* Reference
* https://leetcode.com/problems/longest-consecutive-sequence/
*/
public class LongestConsecutiveSubsequence {
public int longestConsecutive(int[] nums) {
Map map = new HashMap();
int result = 1;
for (int i : nums) {
if (map.containsKey(i)) {
continue;
}
int left = map.containsKey(i - 1) ? map.get(i - 1) : 0;
int right = map.containsKey(i + 1) ? map.get(i + 1) : 0;
int sum = left + right + 1;
map.put(i, sum);
result = Math.max(sum, result);
map.put(i - left, sum);
map.put(i + right, sum);
}
return result;
}
public static void main(String args[]) {
LongestConsecutiveSubsequence lcs = new LongestConsecutiveSubsequence();
int[] input = {100, 4, 200, 1, 3, 2};
System.out.println(lcs.longestConsecutive(input));
}
}
================================================
FILE: src/com/interview/array/LongestIncreasingSubSequenceOlogNMethod.java
================================================
package com.interview.array;
import java.util.Arrays;
/**
* Date 08/01/2015
* @author Tushar Roy
*
* Given an array, find longest increasing subsequence in nlogn time complexity
*
* References
* http://www.geeksforgeeks.org/longest-monotonically-increasing-subsequence-size-n-log-n/
* http://www.geeksforgeeks.org/construction-of-longest-monotonically-increasing-subsequence-n-log-n/
*/
public class LongestIncreasingSubSequenceOlogNMethod {
/**
* Returns index in T for ceiling of s
*/
private int ceilIndex(int input[], int T[], int end, int s){
int start = 0;
int middle;
int len = end;
while(start <= end){
middle = (start + end)/2;
if(middle < len && input[T[middle]] < s && s <= input[T[middle+1]]){
return middle+1;
}else if(input[T[middle]] < s){
start = middle+1;
}else{
end = middle-1;
}
}
return -1;
}
public int longestIncreasingSubSequence(int input[]){
int T[] = new int[input.length];
int R[] = new int[input.length];
for(int i=0; i < R.length ; i++) {
R[i] = -1;
}
T[0] = 0;
int len = 0;
for(int i=1; i < input.length; i++){
if(input[T[0]] > input[i]){ //if input[i] is less than 0th value of T then replace it there.
T[0] = i;
}else if(input[T[len]] < input[i]){ //if input[i] is greater than last value of T then append it in T
len++;
T[len] = i;
R[T[len]] = T[len-1];
}else{ //do a binary search to find ceiling of input[i] and put it there.
int index = ceilIndex(input, T, len,input[i]);
T[index] = i;
R[T[index]] = T[index-1];
}
}
//this prints increasing subsequence in reverse order.
System.out.print("Longest increasing subsequence ");
int index = T[len];
while(index != -1) {
System.out.print(input[index] + " ");
index = R[index];
}
System.out.println();
return len+1;
}
public static void main(String args[]){
//int input[] = {2,5,3,1,2,10,6,7,8};
int input[] = {3, 4, -1, 5, 8, 2, 3, 12, 7, 9, 10};
LongestIncreasingSubSequenceOlogNMethod lis = new LongestIncreasingSubSequenceOlogNMethod();
System.out.println("Maximum length " + lis.longestIncreasingSubSequence(input));
}
}
================================================
FILE: src/com/interview/array/LongestSameSumSpan.java
================================================
package com.interview.array;
import java.util.HashMap;
import java.util.Map;
/**
* Date 12/29/2015
* @author Tushar Roy
*
* Give two arrays of same size consisting of 0s and 1s find span (i, j) such that
* sum of input1[i..j] = sum of input2[i..j]
*
* Time complexity O(n)
* Space complexity O(n)
*
* http://www.geeksforgeeks.org/longest-span-sum-two-binary-arrays/
*/
public class LongestSameSumSpan {
public int longestSpan(int input1[], int input2[]) {
if (input1.length != input2.length) {
throw new IllegalArgumentException("Not same length input");
}
Map diff = new HashMap<>();
int prefix1 = 0, prefix2 = 0;
int maxSpan = 0;
diff.put(0, -1);
for (int i = 0; i < input1.length ; i++) {
prefix1 += input1[i];
prefix2 += input2[i];
int currDiff = prefix1 - prefix2;
if (diff.containsKey(currDiff)) {
maxSpan = Math.max(maxSpan, i - diff.get(currDiff));
} else {
diff.put(currDiff, i);
}
}
return maxSpan;
}
public static void main(String args[]) {
int input1[] = {1, 0, 0, 1, 1, 0};
int input2[] = {0, 1, 1, 0, 1, 1};
LongestSameSumSpan lsss = new LongestSameSumSpan();
System.out.print(lsss.longestSpan(input1, input2));
}
}
================================================
FILE: src/com/interview/array/LongestSubstringWithAtMost2Char.java
================================================
package com.interview.array;
/**
* Longest Substring with At Most Two Distinct Characters
* https://leetcode.com/problems/longest-substring-with-at-most-two-distinct-characters/
*/
public class LongestSubstringWithAtMost2Char {
public int lengthOfLongestSubstringTwoDistinct(String s) {
int count1 = 0;
int count2 = 0;
char c1 = 0;
char c2 = 0;
int start = 0;
int current = 0;
int max = 0;
for (char ch: s.toCharArray()) {
if (ch == c1 || ch == c2) {
if (ch == c1) {
count1++;
} else {
count2++;
}
} else {
if (count1 != 0 && count2 != 0) {
while (start < current) {
if (s.charAt(start) == c1) {
count1--;
} else if (s.charAt(start) == c2) {
count2--;
}
start++;
if (count1 == 0 || count2 == 0) {
break;
}
}
}
if (count1 == 0) {
c1 = ch;
count1 = 1;
} else {
c2 = ch;
count2 = 1;
}
}
max = Math.max(max, current - start + 1);
current++;
}
return max;
}
public static void main(String args[]) {
LongestSubstringWithAtMost2Char lc = new LongestSubstringWithAtMost2Char();
System.out.print(lc.lengthOfLongestSubstringTwoDistinct("eceba"));
}
}
================================================
FILE: src/com/interview/array/MaxNumberFromTwoArray.java
================================================
package com.interview.array;
import java.util.Arrays;
import java.util.Deque;
import java.util.LinkedList;
/**
* Date 03/01/2016
* @author Tushar Roy
*
* Given two arrays of length m and n with digits 0-9 representing two numbers.
* Create the maximum number of length k <= m + n from digits of the two
*
* e.g
* nums1 = [3, 4, 6, 5]
* nums2 = [9, 1, 2, 5, 8, 3]
* k = 5
* return [9, 8, 6, 5, 3]
*
* https://leetcode.com/problems/create-maximum-number/
*/
public class MaxNumberFromTwoArray {
public int[] maxNumber(int[] nums1, int[] nums2, int k) {
int[] max = new int[k];
for (int i = 0; i <= k; i++) {
if (nums1.length < i || nums2.length < k - i) {
continue;
}
int[] a = merge(findLargest1(nums1, i), findLargest1(nums2, k - i));
if (isGreater(a, max, 0, 0)) {
max = a;
}
}
return max;
}
private int[] merge(int[] a1, int[] a2) {
int[] result = new int[a1.length + a2.length];
int i = 0;
int j = 0;
int k = 0;
while (i < a1.length || j < a2.length) {
if (i == a1.length) {
result[k++] = a2[j++];
} else if (j == a2.length) {
result[k++] = a1[i++];
} else if (a1[i] > a2[j]) {
result[k++] = a1[i++];
} else if (a1[i] < a2[j]) {
result[k++] = a2[j++];
} else {
if (isGreater(a1, a2, i, j)) {
result[k++] = a1[i++];
} else {
result[k++] = a2[j++];
}
}
}
return result;
}
private boolean isGreater(int[] a, int[] b, int i, int j) {
while (i < a.length && j < b.length) {
if (a[i] > b[j]) {
return true;
} else if (a[i] < b[j]) {
return false;
}
i++;
j++;
}
return j == b.length;
}
private int[] findLargest1(int[] nums, int k) {
if (k == 0) {
return new int[0];
}
int[] result = new int[k];
int index = 0;
for (int i = 0; i < nums.length; i++) {
while (index > 0 && index + (nums.length - i - 1) >= k && result[index - 1] < nums[i]) {
index--;
}
if (index < k) {
result[index++] = nums[i];
}
}
return result;
}
public static void main(String args[]) {
MaxNumberFromTwoArray max = new MaxNumberFromTwoArray();
int[] input1 = {9,1,2,5,8,3};
int[] input2 = {3,4,6,5};
int[] input3 = {2,5,6,4,4,0};
int[] input4 = {7,3,8,0,6,5,7,6,2};
int[] result = max.maxNumber(input3, input4, 15);
System.out.print(Arrays.toString(result));
}
}
================================================
FILE: src/com/interview/array/MaxProductSubarray.java
================================================
package com.interview.array;
/**
* Date 04/`7/2016
* @author Tushar Roy
*
* Find the contiguous subarray within an array (containing at least one number) which has the largest product.
*
* Time complexity is O(n)
* Space complexity is O(1)
*
* http://www.geeksforgeeks.org/maximum-product-subarray/
* https://leetcode.com/problems/maximum-product-subarray/
*/
public class MaxProductSubarray {
public int maxProduct(int[] nums) {
//neg maintains the multiplication which is negative since last 0
//pos maintains the multiplication which is positive since last 0
int neg = 1;
int pos = 1;
int maxProduct = nums[0];
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 0) {
neg = 1;
pos = 1;
maxProduct = Math.max(maxProduct, 0);
} else if (nums[i] < 0) {
int temp = pos;
if (neg < 0) {
pos = neg * nums[i];
maxProduct = Math.max(pos, maxProduct);
} else {
pos = 1;
}
neg = temp * nums[i];
} else {
if (neg < 0) {
neg *= nums[i];
}
pos *= nums[i];
maxProduct = Math.max(pos, maxProduct);
}
}
return maxProduct;
}
public static void main(String args[]){
MaxProductSubarray mps = new MaxProductSubarray();
int input[] = {-6, -3, 8, -9, -1, -1, 3, 6, 9, 0, 3, -1};
System.out.println(mps.maxProduct(input));
}
}
================================================
FILE: src/com/interview/array/MaxRepeatingNumber.java
================================================
package com.interview.array;
/**
* http://www.geeksforgeeks.org/find-the-maximum-repeating-number-in-ok-time/
* Given an array of size n, the array contains numbers in range from 0 to k-1
* where k is a positive integer and k <= n.
* Find the maximum repeating number in this array
*/
public class MaxRepeatingNumber {
public int maxRepeatingNumber(int arr[], int k){
int len = k;
for(int i=0; i < arr.length; i++){
arr[arr[i]%len] += len;
}
int maxRepeating = 0;
int maxRepeatingIndex =0;
for(int i=0; i < len; i++){
if(maxRepeating < arr[i]){
maxRepeating = arr[i];
maxRepeatingIndex = i;
}
}
for(int i=0; i < len; i++){
arr[i] = arr[i] % len;
}
return maxRepeatingIndex;
}
public static void main(String args[]){
MaxRepeatingNumber mrn = new MaxRepeatingNumber();
int arr[] = {2,2,1,3,1,2,0,3,0,0,0,4,5,4,4,4,4};
System.out.println(mrn.maxRepeatingNumber(arr, 6));
}
}
================================================
FILE: src/com/interview/array/MaximumGap.java
================================================
package com.interview.array;
/**
* Date 03/12/2016
* @author Tushar Roy
*
* Given an unsorted array find maximum gap between consecutive element in sorted array.
*
* Time complexity O(n)
* Space complexity O(n)
*
* Reference
* https://leetcode.com/problems/maximum-gap/
*/
public class MaximumGap {
class Bucket {
int low ;
int high;
boolean isSet = false;
void update(int val) {
if (!isSet) {
low = val;
high = val;
isSet = true;
} else {
low = Math.min(low, val);
high = Math.max(high, val);
}
}
}
public int maximumGap(int[] input) {
if (input == null || input.length < 2) {
return 0;
}
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < input.length; i++) {
min = Math.min(min, input[i]);
max = Math.max(max, input[i]);
}
int gap = (int) Math.ceil((double) (max - min) / (input.length - 1));
Bucket[] buckets = new Bucket[input.length - 1];
for (int i = 0; i < buckets.length; i++) {
buckets[i] = new Bucket();
}
for (int i = 0; i < input.length; i++) {
if (input[i] == max || input[i] == min) {
continue;
}
buckets[(input[i] - min) / gap].update(input[i]);
}
int prev = min;
int maxGap = 0;
for (int i = 0; i < buckets.length; i++) {
if (!buckets[i].isSet) {
continue;
}
maxGap = Math.max(maxGap, buckets[i].low - prev);
prev = buckets[i].high;
}
return Math.max(maxGap, max - prev);
}
public static void main(String args[]) {
int[] input = {4, 3, 13, 2, 9, 7};
MaximumGap mg = new MaximumGap();
System.out.println(mg.maximumGap(input));
}
}
================================================
FILE: src/com/interview/array/MaximumIminusJSuchThatAiGTAj.java
================================================
package com.interview.array;
import java.util.Iterator;
import java.util.LinkedList;
/**
* http://www.geeksforgeeks.org/given-an-array-arr-find-the-maximum-j-i-such-that-arrj-arri/
*/
public class MaximumIminusJSuchThatAiGTAj {
class Node{
int index;
int size;
}
public int maximumGeeks(int input[]){
int lhs[] = new int[input.length];
int rhs[] = new int[input.length];
lhs[0] = 0;
for(int i=1; i < lhs.length; i++){
if(input[lhs[i-1]] < input[i]){
lhs[i] = lhs[i-1];
}else{
lhs[i] = i;
}
}
rhs[input.length-1] = input.length-1;
for(int i=input.length-2; i >= 0; i--){
if(input[rhs[i+1]] > input[i]){
rhs[i] = rhs[i+1];
}else{
rhs[i] = i;
}
}
int i=0;
int j=0;
int max = 0;
for(;j < input.length;){
if(input[lhs[i]] < input[rhs[j]]){
max = Math.max(max, j-i);
j++;
}else{
i++;
}
}
return max;
}
public static void main(String args[]){
MaximumIminusJSuchThatAiGTAj mj = new MaximumIminusJSuchThatAiGTAj();
int input[] = {11,14,13,1,4,13,1,10};
System.out.println(mj.maximumGeeks(input));
}
}
================================================
FILE: src/com/interview/array/MaximumMinimumArrangement.java
================================================
package com.interview.array;
/**
* Date 04/16/2016
* @author Tushar Roy
*
* Given a sorted array of positive integers, rearrange the array alternately i.e first element should be maximum value,
* second minimum value, third second max, fourth second min and so on.
*
* Time complexity O(n)
* Space complexity O(1)
*
* http://www.geeksforgeeks.org/rearrange-array-maximum-minimum-form/
*/
public class MaximumMinimumArrangement {
public void rearrange(int[] input) {
for (int i = 0; i < input.length; i++) {
int t = input[i];
if (t < 0) {
continue;
}
int i1 = i;
while (true) {
int j = i1 < input.length/2 ? 2 * i1 + 1 : (input.length - 1 - i1) * 2;
if (j == i1) {
break;
}
if (input[j] < 0) {
break;
}
int t1 = input[j];
input[j] = -t;
t = t1;
i1 = j;
}
}
for (int i = 0; i < input.length; i++) {
input[i] = Math.abs(input[i]);
}
}
}
================================================
FILE: src/com/interview/array/MaximumOfSubarrayOfSizeK.java
================================================
package com.interview.array;
/**
* http://www.geeksforgeeks.org/maximum-of-all-subarrays-of-size-k/
* Test cases
* input containg neg and pos values
* val of k is neg 0 or pos
* val of k is larger than size of input
* val of k is same as size of input
*/
import java.util.Deque;
import java.util.LinkedList;
public class MaximumOfSubarrayOfSizeK {
public int[] maxSubArray(int input[], int k) {
Deque queue = new LinkedList();
int max[] = new int[input.length - k + 1];
int maxVal = Integer.MIN_VALUE;
//first find max of first k values and make it 0th element of max array
for (int i = 0; i < k; i++) {
if(maxVal < input[i]){
maxVal = input[i];
}
if (queue.isEmpty()) {
queue.offerLast(i);
} else {
while (!queue.isEmpty() && input[queue.peekLast()] <= input[i]) {
queue.pollLast();
}
queue.offerLast(i);
}
}
max[0] = maxVal;
int index=1;
//continue from k till end of the input array
for (int i = k; i < input.length; i++) {
//if index of peek is k distance from i then its no value to us.
//throw it away
if (i - k + 1 > queue.peekFirst()) {
queue.pollFirst();
}
while (!queue.isEmpty() && input[queue.peekLast()] <= input[i]) {
queue.pollLast();
}
queue.offerLast(i);
//Only reason first element survived was because it was biggest element.
//make it the max value for this k
max[index] = input[queue.peekFirst()];
index++;
}
return max;
}
public static void main(String args[]){
int input[] = {8, 5, 10, 7, 9, 4, 15, 12, 90, 13};
MaximumOfSubarrayOfSizeK msa = new MaximumOfSubarrayOfSizeK();
int max[] = msa.maxSubArray(input, 4);
for(int i : max){
System.out.print(i + " ");
}
}
}
================================================
FILE: src/com/interview/array/MaximumSumPathTwoArrays.java
================================================
package com.interview.array;
/**
* Date 12/31/2015
* @author Tushar Roy
*
* Given two sorted arrays such the arrays may have some common elements. Find the sum of the maximum sum
* path to reach from beginning of any array to end of any of the two arrays. We can switch from one array
* to another array only at common elements.
*
* Time complexity is O(n + m)
* Space complexity is O(1)
*
* http://www.geeksforgeeks.org/maximum-sum-path-across-two-arrays/
*/
public class MaximumSumPathTwoArrays {
public int maxSum(int input1[], int input2[]) {
int maxSum = 0;
int i = 0, j = 0;
int sum1 = 0;
int sum2 = 0;
while (i < input1.length && j < input2.length) {
if (input1[i] == input2[j]) {
if (sum1 > sum2) {
maxSum += sum1 + input1[i];
} else {
maxSum += sum2 + input2[j];
}
i++;
j++;
sum1 = 0;
sum2 = 0;
} else if (input1[i] < input2[j]) {
sum1 += input1[i++];
} else {
sum2 += input2[j++];
}
}
while(i < input1.length) {
sum1 += input1[i++];
}
while(j < input2.length) {
sum2 += input2[j++];
}
if (sum1 > sum2) {
maxSum += sum1;
} else {
maxSum += sum2;
}
return maxSum;
}
public static void main(String args[]) {
int input1[] = {2, 3, 7, 10, 12, 15, 30, 34};
int input2[] = {1, 5, 7, 8, 10, 15, 16, 19};
MaximumSumPathTwoArrays msp = new MaximumSumPathTwoArrays();
System.out.println(msp.maxSum(input1, input2));
}
}
================================================
FILE: src/com/interview/array/MaximumSumThreeNonOverlappingSubarray.java
================================================
package com.interview.array;
import java.util.Arrays;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
/**
*https://leetcode.com/problems/maximum-sum-of-3-non-overlapping-subarrays/description/
*/
public class MaximumSumThreeNonOverlappingSubarray {
public int[] maxSumOfThreeSubarrays(int[] nums, int k) {
int sum = 0;
int[] sumArray = new int[nums.length - k + 1];
for (int i = 0; i < nums.length; i++) {
if (i < k) {
sum += nums[i];
} else {
sumArray[i - k] = sum;
sum += nums[i];
sum -= nums[i - k];
}
}
sumArray[sumArray.length - 1] = sum;
int[][] dp = new int[4][sumArray.length + 1];
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= sumArray.length; j++) {
if (j >= k) {
if (dp[i][j - 1] >= sumArray[j - 1] + dp[i - 1][j - k]) {
dp[i][j] = dp[i][j - 1];
} else {
dp[i][j] = sumArray[j - 1] + dp[i - 1][j - k];
}
} else {
if (dp[i][j - 1] >= sumArray[j - 1]) {
dp[i][j] = dp[i][j - 1];
} else {
dp[i][j] = sumArray[j - 1];
}
}
}
}
int[] output = new int[3];
int j = dp[0].length - 1;
for (int i = 3; i > 0;) {
if (dp[i][j] == dp[i][j - 1]) {
j--;
} else {
output[i - 1] = j - 1;
i--;
j = j - k;
}
}
return output;
}
public static void main(String[] args) {
MaximumSumThreeNonOverlappingSubarray mss = new MaximumSumThreeNonOverlappingSubarray();
int[] input = {3, 2, 2, 1, 1, 0, 5};
int[] input1 = {1, 2, 1, 2, 6, 7, 5, 1};
int[] output = mss.maxSumOfThreeSubarrays(input1, 2);
for (int i : output) {
System.out.println(i);
}
}
}
================================================
FILE: src/com/interview/array/MeetingRooms.java
================================================
package com.interview.array;
import java.util.Arrays;
import java.util.PriorityQueue;
/**
* Date 05/01/2016
* @author Tushar Roy
*
* Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei),
* find the minimum number of conference rooms required.
*
* Both methods have time comlexity of nlogn
* Method 1 has space complexity of O(1)
*
* https://leetcode.com/problems/meeting-rooms-ii/
*/
public class MeetingRooms {
public static class Interval {
int start;
int end;
Interval() { start = 0; end = 0; }
Interval(int s, int e) { start = s; end = e; }
}
public int minMeetingRooms1(Interval[] intervals) {
int[] start = new int[intervals.length];
int[] end = new int[intervals.length];
for (int i = 0; i < intervals.length; i++) {
start[i] = intervals[i].start;
end[i] = intervals[i].end;
}
Arrays.sort(start);
Arrays.sort(end);
int j = 0;
int rooms = 0;
for (int i = 0; i < start.length; i++) {
if (start[i] < end[j]) {
rooms++;
} else {
j++;
}
}
return rooms;
}
public int minMeetingRooms(Interval[] intervals) {
if (intervals.length == 0) {
return 0;
}
Arrays.sort(intervals, (a, b) -> a.start - b.start);
PriorityQueue pq = new PriorityQueue<>((a, b) -> a.end - b.end);
pq.offer(intervals[0]);
int rooms = 1;
for (int i = 1; i < intervals.length; i++) {
Interval it = pq.poll();
if (it.end <= intervals[i].start) {
it = new Interval(it.start, intervals[i].end);
} else {
rooms++;
pq.offer(intervals[i]);
}
pq.offer(it);
}
return rooms;
}
}
================================================
FILE: src/com/interview/array/MinimumDistanceBetweenTwoNumbers.java
================================================
package com.interview.array;
/**
* http://www.geeksforgeeks.org/find-the-minimum-distance-between-two-numbers/
*/
public class MinimumDistanceBetweenTwoNumbers {
public int minDistance(int input[],int x, int y){
int prev = -1;
int prevFound = -1;
int min = 10000;
for(int i=0; i < input.length; i++){
if(input[i] == x){
if(prevFound == -1){
prevFound = x;
prev = i;
}else if(prevFound == x){
prev = i;
}else{
min = min > i - prev ? i -prev : min;
prev = i;
prevFound = x;
}
}else if(input[i] == y){
if(prevFound == -1){
prevFound = y;
prev = i;
}else if(prevFound == y){
prev =i;
}else{
min = min > i - prev ? i -prev : min;
prevFound = y;
prev = i;
}
}
}
return min;
}
public static void main(String args[]){
MinimumDistanceBetweenTwoNumbers mdb = new MinimumDistanceBetweenTwoNumbers();
int input[] = {6,4,1,5,6,9,10,4,6,6};
System.out.println(mdb.minDistance(input, 5, 6));
}
}
================================================
FILE: src/com/interview/array/MinimumNumberFromSequence.java
================================================
package com.interview.array;
import java.util.Arrays;
/**
* Date 02/26/2016
* @author Tushar Roy
*
* Time complexity : O(n^2)
* Space complexity : O(n)
*
* Reference
* http://www.geeksforgeeks.org/form-minimum-number-from-given-sequence/
*/
public class MinimumNumberFromSequence {
public int[] find(char[] input) {
int[] output = new int[input.length + 1];
output[0] = 1;
int low = 0;
int start = 0;
for (int i = 0; i < input.length; i++) {
if (input[i] == 'D') {
output[i + 1] = output[i] - 1;
if (output[i+1] == low) {
for (int j = start; j <= i + 1; j++) {
output[j] = output[j] + 1;
}
}
} else {
low = output[start];
output[i + 1] = low + 1;
start = i + 1;
}
}
return output;
}
public static void main(String args[]) {
MinimumNumberFromSequence ms = new MinimumNumberFromSequence();
int output[] = ms.find("DDIDDIID".toCharArray());
System.out.println(Arrays.toString(output));
output = ms.find("IIDDD".toCharArray());
System.out.println(Arrays.toString(output));
output = ms.find("DIDI".toCharArray());
System.out.println(Arrays.toString(output));
}
}
================================================
FILE: src/com/interview/array/MinimumSortedWhichSortsEntireArray.java
================================================
package com.interview.array;
/**
*http://www.geeksforgeeks.org/minimum-length-unsorted-subarray-sorting-which-makes-the-complete-array-sorted/
*/
public class MinimumSortedWhichSortsEntireArray {
public int minLength(int arr[]){
int i=0;
while(i < arr.length -1 && arr[i] < arr[i+1]){
i++;
}
if(i == arr.length-1){
return 0;
}
int j = arr.length-1;
while(j > 0 && arr[j] > arr[j-1]){
j--;
}
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for(int k = i; k <= j; k++){
if(max < arr[k]){
max = arr[k];
}
if(min > arr[k]){
min = arr[k];
}
}
int x = i-1;
while(x >=0){
if(min > arr[x]){
break;
}
x--;
}
int y = j +1;
while(y < arr.length){
if(max < arr[y]){
break;
}
y++;
}
return y -x -2 + 1;
}
public static void main(String args[]){
int arr[] = {4,5,10,21,18,23,7,8,19,34,38};
int arr1[] = {4,5,6,12,11,15};
int arr2[] = {4,5,6,10,11,15};
MinimumSortedWhichSortsEntireArray msw = new MinimumSortedWhichSortsEntireArray();
System.out.println(msw.minLength(arr1));
}
}
================================================
FILE: src/com/interview/array/MissingRanges.java
================================================
package com.interview.array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Given a sorted integer array where the range of elements are in the inclusive range [lower, upper], return its missing ranges.
* For example, given [0, 1, 3, 50, 75], lower = 0 and upper = 99, return ["2", "4->49", "51->74", "76->99"].
*
* Time complexity O(n)
*
* https://leetcode.com/problems/missing-ranges/
*/
public class MissingRanges {
public List findMissingRanges(int[] nums, int lower, int upper) {
if (nums.length == 0) {
return Collections.singletonList(makeRange(lower, upper));
}
List result = new ArrayList<>();
if (lower < nums[0]) {
result.add(makeRange(lower, nums[0] - 1));
}
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i] == nums[i + 1]) {
continue;
}
if ((nums[i] + 1) != nums[i + 1]) {
result.add(makeRange(nums[i] + 1, nums[i + 1] - 1));
}
}
if (nums[nums.length - 1] < upper) {
result.add(makeRange(nums[nums.length - 1] + 1, upper));
}
return result;
}
private String makeRange(int a, int b) {
if (a == b) {
return String.valueOf(a);
} else {
return a + "->" + b;
}
}
}
================================================
FILE: src/com/interview/array/MoveAllZerosToEnd.java
================================================
package com.interview.array;
public class MoveAllZerosToEnd {
public void moveZeros(int arr[]){
int slow =0;
int fast =0;
while(fast < arr.length){
if(arr[fast] == 0){
fast++;
continue;
}
arr[slow] = arr[fast];
slow++;
fast++;
}
while(slow < arr.length){
arr[slow++] = 0;
}
}
public static void main(String args[]){
MoveAllZerosToEnd maz = new MoveAllZerosToEnd();
int arr[] = {0,0,1,2,0,5,6,7,0};
maz.moveZeros(arr);
for(int i=0; i < arr.length; i++){
System.out.print(arr[i]);
}
}
}
================================================
FILE: src/com/interview/array/MultiplyAllFieldsExceptOwnPosition.java
================================================
package com.interview.array;
/**
* https://leetcode.com/problems/product-of-array-except-self/
*/
public class MultiplyAllFieldsExceptOwnPosition {
public int[] multiply(int nums[]) {
if (nums.length == 0) {
return new int[0];
}
int[] output = new int[nums.length];
output[0] = 1;
for (int i = 1; i < nums.length; i++) {
output[i] = output[i - 1] * nums[i - 1];
}
int mult = 1;
for (int i = nums.length - 1; i >= 0; i--) {
output[i] *= mult;
mult *= nums[i];
}
return output;
}
}
================================================
FILE: src/com/interview/array/NthElementOfCountNumberSequence.java
================================================
package com.interview.array;
import java.util.ArrayList;
import java.util.List;
/**
* Date 07/20/2015
* @author Tushar Roy
*
* Given a sequence like
* 1 11 21 1211 111221 312211
* Print nth element of this sequence.
*/
public class NthElementOfCountNumberSequence {
public List nthElement(int n) {
int i = 1;
List current = new ArrayList<>();
current.add(1);
List result = new ArrayList<>();
while(i < n) {
int count = 1;
int index = 0;
for(int j = 1; j < current.size(); j++) {
if(current.get(index) == current.get(j)) {
count++;
} else {
result.add(count);
result.add(current.get(index));
count = 1;
index = j;
}
}
result.add(count);
result.add(current.get(index));
current = result;
result = new ArrayList<>();
i++;
}
return current;
}
public static void main(String args[]) {
NthElementOfCountNumberSequence nes = new NthElementOfCountNumberSequence();
for(int i = 1 ; i <= 10; i++) {
List result = nes.nthElement(i);
result.forEach(System.out::print);
System.out.println();
}
}
}
================================================
FILE: src/com/interview/array/NumberOfTrianglesInUnsortedArray.java
================================================
package com.interview.array;
import java.util.Arrays;
/**
* http://www.geeksforgeeks.org/find-number-of-triangles-possible/
*/
public class NumberOfTrianglesInUnsortedArray {
public int numberOfTriangles(int input[]){
Arrays.sort(input);
int count = 0;
for(int i=0; i < input.length-2; i++){
int k = i+2;
for(int j=i+1; j < input.length; j++){
while(k < input.length && input[i] + input[j] > input[k]){
k++;
}
count += k - j -1;
}
}
return count;
}
public static void main(String args[]){
int input[] = {3, 4, 5, 6, 8, 9, 15};
NumberOfTrianglesInUnsortedArray not = new NumberOfTrianglesInUnsortedArray();
System.out.println(not.numberOfTriangles(input));
}
}
================================================
FILE: src/com/interview/array/PositiveAndNegativeNumberAlternatively.java
================================================
package com.interview.array;
/**
* http://www.geeksforgeeks.org/rearrange-positive-and-negative-numbers-publish/
*/
public class PositiveAndNegativeNumberAlternatively {
public void arrange(int arr[]){
int startOfPos = segregate(arr);
int startOfNeg = 1;
while(startOfNeg < startOfPos && startOfPos < arr.length){
swap(arr,startOfNeg,startOfPos);
startOfNeg+=2;
startOfPos++;
}
}
private int segregate(int arr[]){
int low =0;
int high = arr.length-1;
while(low < high){
if(arr[low] < 0){
low++;
}else if(arr[high] >= 0){
high--;
}else{
swap(arr,low,high);
}
}
return low;
}
private void swap(int arr[],int i,int j){
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
public static void main(String args[]){
int arr[] = {-1,-2,-3,-4,-5,1,2,3,4,5};
PositiveAndNegativeNumberAlternatively pan = new PositiveAndNegativeNumberAlternatively();
pan.arrange(arr);
for(int i=0; i < arr.length; i++){
System.out.print(arr[i]+ " ");
}
}
}
================================================
FILE: src/com/interview/array/PositiveAndNegativeNumberAlternativelyMaintainingOrder.java
================================================
package com.interview.array;
import java.util.Arrays;
/**
* Date 12/31/2015
* @author Tushar Roy
*
* Given an array of positive and negative integers arrange them alternatively maintaining initial order.
* If there are more +ve or -ve integer then push them to the end together.
*
* Time complexity is O(n)
* Space complexity is O(1)
*
* http://www.geeksforgeeks.org/rearrange-array-alternating-positive-negative-items-o1-extra-space/
*/
public class PositiveAndNegativeNumberAlternativelyMaintainingOrder {
public void rearrange(int input[]) {
for (int i = 0; i < input.length; i++) {
if (i % 2 == 0 && input[i] >= 0) {
int indexOfNextNegative = findNext(input, i + 1, false);
if (indexOfNextNegative == -1) {
return;
} else {
rightRotate(input, i, indexOfNextNegative);
}
} else if (i % 2 != 0 && input[i] < 0) {
int indexOfNextPositive = findNext(input, i + 1, true);
if (indexOfNextPositive == -1) {
return;
} else {
rightRotate(input, i, indexOfNextPositive);
}
}
}
}
private int findNext(int input[], int start, boolean isPositive) {
for (int i = start; i < input.length; i++) {
if ((isPositive && input[i] >= 0) || (!isPositive && input[i] < 0)) {
return i;
}
}
return -1;
}
private void rightRotate(int input[], int start, int end) {
int t = input[end];
for (int i = end; i > start; i--) {
input[i] = input[i - 1];
}
input[start] = t;
}
public static void main(String args[]) {
int input[] = {-5, -2, 5, 2, 4, 7, 1, 8, 0, -8};
PositiveAndNegativeNumberAlternativelyMaintainingOrder pss = new PositiveAndNegativeNumberAlternativelyMaintainingOrder();
pss.rearrange(input);
Arrays.stream(input).forEach(i -> System.out.print(i + " "));
}
}
================================================
FILE: src/com/interview/array/RearrangeArrayPerIndex.java
================================================
package com.interview.array;
import java.util.Arrays;
/**
* Date 12/30/2015
*
* Given an array of size n where elements are in range 0 to n-1. Rearrange elements of array
* such that if arr[i] = j then arr[j] becomes i.
*
* Time complexity O(n)
* Space complexity O(1)
*
* http://www.geeksforgeeks.org/rearrange-array-arrj-becomes-arri-j/
*/
public class RearrangeArrayPerIndex {
public void rearrange(int input[]) {
for (int i = 0; i < input.length; i++) {
input[i]++;
}
for (int i = 0; i < input.length; i++) {
if (input[i] > 0) {
rearrangeUtil(input, i);
}
}
for (int i = 0; i < input.length; i++) {
input[i] = -input[i] - 1;
}
}
private void rearrangeUtil(int input[], int start) {
int i = start + 1;
int v = input[start];
while (v > 0) {
int t = input[v - 1];
input[v - 1] = -i;
i = v;
v = t;
}
}
public static void main(String args[]) {
RearrangeArrayPerIndex rai = new RearrangeArrayPerIndex();
int input[] = {1, 2, 0, 5, 3, 4};
rai.rearrange(input);
Arrays.stream(input).forEach(i -> System.out.print(i + " "));
}
}
================================================
FILE: src/com/interview/array/RearrangeSuchThatArriBecomesArrArri.java
================================================
package com.interview.array;
/**
* http://www.geeksforgeeks.org/rearrange-given-array-place/
*/
public class RearrangeSuchThatArriBecomesArrArri {
public void rearrange(int arr[]){
for(int i=0; i < arr.length; i++){
int temp;
if(arr[arr[i]] > arr.length-1){
temp = arr[arr[i]]/arr.length-1;
}else{
temp = arr[arr[i]];
}
arr[i] = temp + arr.length*(arr[i]+1);
}
for(int i=0; i < arr.length;i++){
arr[i] = arr[i] % arr.length;
}
}
public static void main(String args[]){
int arr[] = {4,2,0,1,3};
RearrangeSuchThatArriBecomesArrArri rss = new RearrangeSuchThatArriBecomesArrArri();
rss.rearrange(arr);
for(int i=0; i < arr.length; i++){
System.out.print(arr[i]);
}
}
}
================================================
FILE: src/com/interview/array/ReorderArrayByIndex.java
================================================
package com.interview.array;
import java.util.Arrays;
/**
* Date 12/29/2015
* @author Tushar Roy
*
* Given two arrays one with values and other with index where values should be positioned. Move values to correct
* position
*
* Time complexity - O(n)
* Space complexity - O(1)
*
* http://www.geeksforgeeks.org/reorder-a-array-according-to-given-indexes/
*/
public class ReorderArrayByIndex {
public void reorder(int input[], int index[]) {
if(index.length != input.length) {
throw new IllegalArgumentException();
}
for (int i = 0 ; i < index.length; i++) {
while (index[i] != i) {
int sIndex = index[index[i]];
int sVal = input[index[i]];
index[index[i]] = index[i];
input[index[i]] = input[i];
index[i] = sIndex;
input[i] = sVal;
}
}
}
public static void main(String args[]) {
int input[] = {50, 40, 70, 60, 90};
int index[] = {3, 0, 4, 1, 2};
ReorderArrayByIndex reorderArrayByIndex = new ReorderArrayByIndex();
reorderArrayByIndex.reorder(input, index);
Arrays.stream(input).forEach(i -> System.out.print(i + " "));
System.out.println();
Arrays.stream(index).forEach(i -> System.out.print(i + " "));
}
}
================================================
FILE: src/com/interview/array/RepeatingAndMissingNumber.java
================================================
package com.interview.array;
/**
* http://www.geeksforgeeks.org/find-a-repeating-and-a-missing-number/
*/
public class RepeatingAndMissingNumber {
class Pair{
int repeating;
int missing;
public String toString(){
return repeating + " " + missing;
}
}
public Pair findNumbers(int input[]){
Pair p = new Pair();
for(int i=0; i < input.length; i++){
if(input[Math.abs(input[i])-1] < 0){
p.repeating = Math.abs(input[i]);
}else{
input[Math.abs(input[i])-1] = -input[Math.abs(input[i])-1];
}
}
for(int i=0; i < input.length; i++){
if(input[i] < 0){
input[i] = -input[i];
}else{
p.missing = i + 1;
}
}
return p;
}
public static void main(String args[]){
RepeatingAndMissingNumber rmn = new RepeatingAndMissingNumber();
int input[] = {3,1,2,4,6,8,2,7};
System.out.println(rmn.findNumbers(input));
}
}
================================================
FILE: src/com/interview/array/RotationWithMaxSum.java
================================================
package com.interview.array;
/**
* Date 12/30/2015
* @author Tushar Roy
*
* Given an input array find which rotation will give max sum of i * arr[i]
*
* Time complexity - O(n)
* Space complexity - O(1)
*
* http://www.geeksforgeeks.org/find-maximum-value-of-sum-iarri-with-only-rotations-on-given-array-allowed/
*/
public class RotationWithMaxSum {
int maxSum(int input[]) {
int arrSum = 0;
int rotationSum = 0;
for (int i =0; i < input.length; i++) {
arrSum += input[i];
rotationSum += i*input[i];
}
int maxRotationSum = rotationSum;
for (int i = 1; i < input.length; i++) {
rotationSum += input.length*input[i - 1] - arrSum;
maxRotationSum = Math.max(maxRotationSum, rotationSum);
}
return maxRotationSum;
}
public static void main(String args[]) {
int input[] = {10, 1, 2, 3, 4, 5, 6, 7, 8, 9};
RotationWithMaxSum rms = new RotationWithMaxSum();
System.out.print(rms.maxSum(input));
}
}
================================================
FILE: src/com/interview/array/SelfCrossing.java
================================================
package com.interview.array;
/**
* Created by tushar_v_roy on 3/10/16.
*/
public class SelfCrossing {
public boolean isSelfCrossing(int[] x) {
if (x.length < 4) {
return false;
}
int v1 = -x[0];
int v2 = -x[1];
int i = 2;
while (i < x.length) {
if (i % 2 == 0) {
if (i % 4 == 0) {
v1 -= x[i];
} else {
v1 += x[i];
}
} else {
if ((i + 1) % 4 == 0) {
v2 += x[i];
} else {
v2 -= x[i];
}
}
if (i % 2 != 0) {
if ((v1 >= 0 && v2 <= 0) || (v1 <= 0 && v2 >= 0)) {
return true;
}
}
i++;
}
return false;
}
public static void main(String args[]) {
SelfCrossing sc = new SelfCrossing();
int input[] = {3, 3, 4, 2, 2};
System.out.print(sc.isSelfCrossing(input));
}
}
================================================
FILE: src/com/interview/array/ShortestPalindrome.java
================================================
package com.interview.array;
/**
* Date 03/04/2016
* @author Tushar Roy
*
* How to append minimum numbers of characters in front of string to make it a palindrome.
*
* Idea is to create a new string which is original ttring + $ + reverse of original string
* Get value of suffix which is also prefix using KMP.
* This part of string is good. Rest needs to be copied in the front.
*
* Time complexity is O(n)
* Space complexity is O(n)
*
* https://leetcode.com/problems/shortest-palindrome/
*/
public class ShortestPalindrome {
public String shortestPalindrome(String s) {
char[] input = createInput(s);
int val = kmp(input);
StringBuffer sb = new StringBuffer();
int remaining = s.length() - val;
int i = s.length() - 1;
while (remaining > 0) {
sb.append(s.charAt(i));
i--;
remaining--;
}
sb.append(s);
return sb.toString();
}
private int kmp(char[] input) {
int T[] = new int[input.length];
int j = 1;
int i = 0;
T[0] = 0;
while (j < input.length) {
if (input[i] == input[j]) {
T[j] = i + 1;
i++;
} else {
while (i != 0) {
i = T[i-1];
if (input[j] == input[i]) {
T[j] = i + 1;
i++;
break;
}
}
}
j++;
}
return T[input.length - 1];
}
private char[] createInput(String s) {
char[] input = new char[2*s.length() + 1];
int index = 0;
for (char ch: s.toCharArray()) {
input[index++] = ch;
}
input[index++] = '$';
for (int i = s.length() - 1; i >= 0; i--) {
input[index++] = s.charAt(i);
}
return input;
}
public static void main(String args[]) {
ShortestPalindrome sp = new ShortestPalindrome();
System.out.print(sp.shortestPalindrome("aacecaaa"));
}
}
================================================
FILE: src/com/interview/array/SmallestIntegerNotRepresentedBySubsetSum.java
================================================
package com.interview.array;
/**
* Date 12/31/2015
* @author Tushar Roy
*
* Given array in non decreasing order find smallest integer which cannot be represented by
* subset sum of these integers.
*
* Time complexity is O(n)
*
* http://www.geeksforgeeks.org/find-smallest-value-represented-sum-subset-given-array/
*/
public class SmallestIntegerNotRepresentedBySubsetSum {
public int findSmallestInteger(int input[]) {
int result = 1;
for (int i = 0; i < input.length; i++) {
if (input[i] <= result) {
result += input[i];
} else {
break;
}
}
return result;
}
/**
* Leetcode variation https://leetcode.com/problems/patching-array/
*/
public int minPatches(int[] nums, int n) {
int patch = 0;
long t = 1;
int i = 0;
while(t <= n) {
if (i == nums.length || t < nums[i]) {
patch++;
t += t;
} else {
t = nums[i] + t;
i++;
}
}
return patch;
}
public static void main(String args[]) {
int input[] = {1, 2, 3, 8};
SmallestIntegerNotRepresentedBySubsetSum ss = new SmallestIntegerNotRepresentedBySubsetSum();
System.out.println(ss.findSmallestInteger(input));
int input1[] = {};
System.out.println(ss.minPatches(input1, 7));
}
}
================================================
FILE: src/com/interview/array/SmallestSubarrayWithAtleastKSum.java
================================================
package com.interview.array;
/**
* https://leetcode.com/problems/shortest-subarray-with-sum-at-least-k/description/
*/
public class SmallestSubarrayWithAtleastKSum {
public int shortestSubarray(int[] A, int K) {
int[] skip = new int[A.length];
int sum = 0;
int start = A.length - 1;
skip[A.length - 1] = 1;
for (int i = A.length - 1; i > 0; i--) {
skip[i - 1] = 1;
sum += A[i];
if (sum <= 0) {
skip[i - 1] = start - i + 1;
} else {
start = i;
sum = 0;
}
}
start = 0;
int end = 0;
sum = 0;
int min = Integer.MAX_VALUE;
while (end < A.length) {
sum += A[end++];
while (start <= end && sum >= K) {
min = Math.min(end - start, min);
for (int j = start; j < start + skip[start]; j++) {
sum -= A[j];
}
start = start + skip[start];
}
if (sum <= 0) {
start = end;
sum = 0;
}
}
return min == Integer.MAX_VALUE ? -1 : min;
}
public static void main(String[] args) {
int[] input = {1, 3, -1, -4, -2, 3, 4, -5, -1, 8};
SmallestSubarrayWithAtleastKSum ss = new SmallestSubarrayWithAtleastKSum();
ss.shortestSubarray(input, 8);
}
}
================================================
FILE: src/com/interview/array/SortedArrayTransformation.java
================================================
package com.interview.array;
/**
* Date 10/08/2016
* @author Tushar Roy
*
* Given a sorted array of integers nums and integer values a, b and c.
* Apply a function of the form f(x) = ax2 + bx + c to each element x in the array.
*
* Time complexity O(n)
*
* https://leetcode.com/problems/sort-transformed-array/
*/
public class SortedArrayTransformation {
public int[] sortTransformedArray(int[] nums, int a, int b, int c) {
int start = 0;
int end = nums.length - 1;
int[] result = new int[nums.length];
int index = (a >= 0 ? nums.length - 1 : 0);
while (start <= end) {
int x = apply(nums[start], a, b, c);
int y = apply(nums[end], a, b, c);
boolean condition = (a >= 0 ? x >= y : x <= y);
if (condition) {
result[index] = x;
start++;
} else {
result[index] = y;
end--;
}
index = index + (a >= 0 ? -1 : 1);
}
return result;
}
private int apply(int x, int a, int b, int c) {
return a*x*x + b * x + c;
}
}
================================================
FILE: src/com/interview/array/StableMarriageProblem.java
================================================
package com.interview.array;
public class StableMarriageProblem {
private boolean checkIfNewIsBetter(int priority[][], int bride,
int currentGroom, int suitor) {
for (int groom : priority[bride]) {
if (currentGroom == groom) {
return false;
}
if (suitor == groom) {
return true;
}
}
return false;
}
public int[] findPair(int[][] priority) {
int pair = priority[0].length;
int groomToBride[] = new int[pair];
int brideToGroom[] = new int[pair];
for(int i=0; i < groomToBride.length; i++){
groomToBride[i] = -1;
}
for(int i=0; i < brideToGroom.length; i++){
brideToGroom[i] = -1;
}
int groom ;
int remaingGrooms = pair;
while (remaingGrooms > 0) {
groom = -1;
for (int hasBride : groomToBride) {
if (hasBride != -1) {
continue;
}
groom++;
for (int bride : priority[groom]) {
if (brideToGroom[bride-pair] == -1) {
groomToBride[groom] = bride;
brideToGroom[bride-pair] = groom;
remaingGrooms--;
break;
} else {
boolean flag = checkIfNewIsBetter(priority, bride,
brideToGroom[bride-pair], groom);
if (flag) {
int currentGroom = brideToGroom[bride-pair];
brideToGroom[bride-pair] = groom;
groomToBride[groom] = bride;
groomToBride[currentGroom] = -1;
}
}
}
}
}
return groomToBride;
}
public static void main(String args[]){
int priority[][] = {{5,4,7,6},
{4,5,6,7},
{5,4,6,7},
{5,4,7,6},
{0,1,2,3},
{0,1,3,2},
{0,3,1,2},
{0,1,2,3}};
StableMarriageProblem smp = new StableMarriageProblem();
int[] result = smp.findPair(priority);
for(int i=0; i < result.length; i++){
System.out.println(i + " " + result[i]);
}
}
}
================================================
FILE: src/com/interview/array/SubarrayWithGivenSum.java
================================================
package com.interview.array;
/**
* http://www.geeksforgeeks.org/find-subarray-with-given-sum/
*/
public class SubarrayWithGivenSum {
class Pair{
int start;
int end;
public String toString(){
return start + " " + end;
}
}
public Pair findSubArray(int input[],int sum){
int currentSum = 0;
Pair p = new Pair();
p.start = 0;
for(int i=0; i < input.length; i++){
currentSum += input[i];
p.end = i;
if(currentSum == sum){
return p;
}else if(currentSum > sum){
int s = p.start;
while(currentSum > sum){
currentSum -= input[s];
s++;
}
p.start = s;
if(currentSum == sum){
return p;
}
}
}
return null;
}
public static void main(String args[]){
SubarrayWithGivenSum sgs = new SubarrayWithGivenSum();
int input[] = {6,3,9,11,1,3,5};
System.out.println(sgs.findSubArray(input,15));
}
}
================================================
FILE: src/com/interview/array/SummaryRanges.java
================================================
package com.interview.array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Date 10/19/2016
* @author Tushar Roy
*
* Given a sorted integer array without duplicates, return the summary of its ranges.
* For example, given [0,1,2,4,5,7], return ["0->2","4->5","7"].
*
* Solution -
* Just check if num[i] + 1 != num[i + 1]. If its not equal means you need to add previous range to result
* and start a new range.
*
* Time complexity O(n)
*
* https://leetcode.com/problems/summary-ranges/
*/
public class SummaryRanges {
public List summaryRanges(int[] nums) {
if (nums.length == 0) {
return Collections.EMPTY_LIST;
}
if (nums.length == 1) {
return Collections.singletonList(String.valueOf(nums[0]));
}
int start = 0;
List result = new ArrayList<>();
for (int i = 0; i < nums.length - 1; i++) {
if ((nums[i] + 1) != nums[i + 1]) {
result.add(makeRange(nums[start], nums[i]));
start = i + 1;
}
}
if ((nums[nums.length - 2] + 1) != nums[nums.length - 1]) {
start = nums.length - 1;
}
result.add(makeRange(nums[start], nums[nums.length - 1]));
return result;
}
private String makeRange(int a, int b) {
if (a == b) {
return String.valueOf(a);
}
return a + "->" + b;
}
}
================================================
FILE: src/com/interview/array/ThreeSumSmallerThanTarget.java
================================================
package com.interview.array;
import java.util.Arrays;
/**
* Given an array of n integers nums and a target, find the number of index triplets i, j, k
* with 0 <= i < j < k < n that satisfy the condition nums[i] + nums[j] + nums[k] < target.
*
* https://leetcode.com/problems/3sum-smaller/
*/
public class ThreeSumSmallerThanTarget {
public int threeSumSmaller(int[] nums, int target) {
if (nums.length < 3) {
return 0;
}
Arrays.sort(nums);
int count = 0;
for (int i = 0; i < nums.length; i++) {
int j = i + 1;
int k = nums.length - 1;
while (j < k) {
if (nums[i] + nums[j] + nums[k] >= target) {
k--;
} else {
count += k - j;
j++;
}
}
}
return count;
}
}
================================================
FILE: src/com/interview/array/TrappingWater.java
================================================
package com.interview.array;
/**
* References
* https://oj.leetcode.com/problems/trapping-rain-water/
* https://leetcode.com/problems/trapping-rain-water/
*/
public class TrappingWater {
public int trap(int[] height) {
if(height == null || height.length == 0) {
return 0;
}
int len = height.length;
int left[] = new int[len];
int right[] = new int[len];
left[0] = height[0];
right[len-1] = height[len -1];
for (int i = 1; i < len; i++) {
left[i] = Math.max(height[i], left[i-1]);
right[len - i - 1] = Math.max(height[len- i - 1], right[len-i]);
}
int maxWaterTrapped = 0;
for (int i = 1; i < len - 1; i++) {
int min = Math.min(left[i], right[i]);
if (height[i] < min) {
maxWaterTrapped += min - height[i];
}
}
return maxWaterTrapped;
}
public static void main(String args[]){
int input[] = {0,1,0,2,1,0,1,3,2,1,2,1};
TrappingWater tw = new TrappingWater();
System.out.println(tw.trap(input));
}
}
================================================
FILE: src/com/interview/array/TripletInArray.java
================================================
package com.interview.array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* http://www.geeksforgeeks.org/find-a-triplet-that-sum-to-a-given-value/
*/
public class TripletInArray {
class Triplet {
int a;
int b;
int c;
public String toString() {
return a + " " + b + " " + c;
}
}
public Triplet findTriplet(int input[], int sum) {
Arrays.sort(input);
for (int i = 0; i < input.length - 2; i++) {
int start = i + 1;
int end = input.length - 1;
int new_sum = sum - input[i];
while (start < end) {
if (new_sum == input[start] + input[end]) {
Triplet t = new Triplet();
t.a = input[i];
t.b = input[start];
t.c = input[end];
return t;
}
if (new_sum > input[start] + input[end]) {
start++;
} else {
end--;
}
}
}
return null;
}
/**
* https://leetcode.com/problems/3sum/
*/
public List> threeSum(int[] nums) {
Arrays.sort(nums);
List> result = new ArrayList<>();
for (int i = 0; i < nums.length - 2; i++) {
if (i != 0 && nums[i] == nums[i-1]) {
continue;
}
int start = i + 1;
int end = nums.length - 1;
while (start < end) {
if (nums[i] + nums[start] + nums[end] == 0) {
List r = new ArrayList<>();
r.add(nums[i]);
r.add(nums[start]);
r.add(nums[end]);
result.add(r);
start++;
end--;
while(start < nums.length && nums[start] == nums[start - 1]) {
start++;
}
while(end >= 0 && nums[end] == nums[end+1]) {
end--;
}
} else if (nums[i] + nums[start] + nums[end] < 0) {
start++;
} else {
end--;
}
}
}
return result;
}
public static void main(String args[]){
TripletInArray tip = new TripletInArray();
int input[] = {1,2,6,9,11,18,26,28};
int sum = 22;
System.out.println(tip.findTriplet(input, sum));
}
}
================================================
FILE: src/com/interview/array/TripletSumLessThanTotal.java
================================================
package com.interview.array;
import java.util.Arrays;
/**
* Date 12/29/2015
* @author Tushar Roy
*
* Given array with unique numbers and a total, find all triplets whose sum is less than total
*
* http://www.geeksforgeeks.org/count-triplets-with-sum-smaller-that-a-given-value/
*/
public class TripletSumLessThanTotal {
public int findAllTriplets(int input[], int total) {
Arrays.sort(input);
int result = 0;
for (int i = 0; i < input.length - 2; i++) {
int j = i + 1;
int k = input.length - 1;
while (j < k) {
if (input[i] + input[j] + input[k] >= total) {
k--;
} else {
result += k - j;
j++;
}
}
}
return result;
}
public static void main(String args[]) {
int input[] = {5, 1, 3, 4, 7};
TripletSumLessThanTotal tt = new TripletSumLessThanTotal();
System.out.print(tt.findAllTriplets(input, 12));
}
}
================================================
FILE: src/com/interview/array/TugOfWar.java
================================================
package com.interview.array;
import java.util.ArrayList;
import java.util.List;
/*
* http://www.geeksforgeeks.org/tug-of-war/
*/
public class TugOfWar {
private int minFoundSoFar = 1000000;
public int findMind(int arr[]){
int total = 0;
for(int i=0; i < arr.length; i++){
total += arr[i];
}
List result = new ArrayList<>();
combinationUtil(arr,arr.length/2,0,0,total,0,result);
return minFoundSoFar;
}
private void combinationUtil(int arr[],int k, int start,int sum, int total,int pos, List result){
if(pos == k){
if(Math.abs(sum - total/2) < minFoundSoFar) {
minFoundSoFar = Math.abs(sum - total/2);
System.out.println(result);
}
return;
}
for(int i=start; i < arr.length; i++){
sum += arr[i];
result.add(arr[i]);
combinationUtil(arr,k,i+1,sum,total,pos+1,result);
result.remove(result.size()-1);
sum -= arr[i];
}
}
public static void main(String args[]){
TugOfWar tow = new TugOfWar();
int arr[] = {23, 45, 34, 12,11, 98, 99, 4, 189, 1,7,19,105, 201};
int min = tow.findMind(arr);
System.out.print(min);
}
}
================================================
FILE: src/com/interview/array/WaterContainer.java
================================================
package com.interview.array;
/**
* Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai).
* n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines,
* which together with x-axis forms a container, such that the container contains the most water.
*
* https://leetcode.com/problems/container-with-most-water/
*/
public class WaterContainer {
public int maxArea(int[] height) {
int i = 0;
int j = height.length - 1;
int maxArea = 0;
while (i < j) {
if (height[i] < height[j]) {
maxArea = Math.max(maxArea, (height[i]) * (j - i));
i++;
} else {
maxArea = Math.max(maxArea, height[j] * (j - i));
j--;
}
}
return maxArea;
}
}
================================================
FILE: src/com/interview/array/WiggleSort.java
================================================
package com.interview.array;
import java.util.Arrays;
/**
* Date 03/23/2016
* @author Tushar Roy
*
* Convert an unsorted array into an array of form num[0] < num[1] > nums[2] < num[3]....
*
* Time complexity O(n) - This depends on KthElementInArray time
* Space complexity O(1)
*
* https://leetcode.com/problems/wiggle-sort/
* https://leetcode.com/problems/wiggle-sort-ii/
*/
public class WiggleSort {
//looking for nums[0] < nums[1] > nums[2] < nums[3] and so on.
public void wiggleSort2(int[] arr) {
if (arr.length == 0) {
return;
}
int k = arr.length/2;
KthElementInArray kthElementInArray = new KthElementInArray();
kthElementInArray.kthElement(arr, k);
int mid = arr[k];
int n = arr.length;
int i = 0, j = 0;
k = n - 1;
while (j <= k) {
if (arr[next(j, n)] > mid) {
swap(arr, next(i++, n), next(j++, n));
}
else if (arr[next(j, n)] < mid) {
swap(arr, next(j, n), next(k--, n));
}
else {
j++;
}
}
}
//in this version we are looking for nums[0] <= nums[1] >= nums[2] <= nums[3] and so on.
public void wiggleSort1(int[] nums) {
boolean flag = true;
for (int i = 0; i < nums.length - 1; i++) {
if (flag) {
if (nums[i] > nums[i + 1]) {
swap(nums, i, i + 1);
}
} else {
if (nums[i] < nums[i + 1]) {
swap(nums, i, i + 1);
}
}
flag = !flag;
}
}
private int next(int index, int n) {
return (2*index + 1) % (n | 1);
}
private void swap(int arr[],int low,int high){
int temp = arr[low];
arr[low] = arr[high];
arr[high] = temp;
}
public static void main(String args[]) {
WiggleSort ws = new WiggleSort();
int input[] = {6, 2, 1, 6, 8, 9, 6};
ws.wiggleSort2(input);
System.out.print(Arrays.toString(input));
}
}
================================================
FILE: src/com/interview/array/ZigZagArrangement.java
================================================
package com.interview.array;
import java.util.Arrays;
/**
* Date 12/30/2015
* @author Tushar Roy
*
* Given an array of unique elements rearrange the array to be a < b > c < d > e form
*
* Time complexity - O(n)
* Space complexity - O(1)
*
* http://www.geeksforgeeks.org/convert-array-into-zig-zag-fashion/
*/
public class ZigZagArrangement {
public void rearrange(int input[]) {
boolean isLess = true;
for (int i = 0; i < input.length - 1; i++) {
if(isLess) {
if (input[i] > input[i+1]) {
swap(input, i, i+1);
}
} else {
if (input[i] < input[i+1]) {
swap(input, i, i+1);
}
}
isLess = !isLess;
}
}
private void swap(int input[], int i, int j) {
int t = input[i];
input[i] = input[j];
input[j] = t;
}
public static void main(String args[]) {
int input[] = {4, 3, 2, 6, 7, 1, 9};
ZigZagArrangement zza = new ZigZagArrangement();
zza.rearrange(input);
Arrays.stream(input).forEach(i -> System.out.print(i + " "));
}
}
================================================
FILE: src/com/interview/binarysearch/ArithmeticProgressionSearch.java
================================================
package com.interview.binarysearch;
/**
* http://www.careercup.com/question?id=4798365246160896
*/
public class ArithmeticProgressionSearch {
public int search(int input[]){
int low =0;
int high = input.length-1;
int ap = (input[high] - input[low])/(input.length);
int middle = -1;
while(low <= high){
middle = (low + high)/2;
if(input[middle] == input[0] + (middle)*ap){
low = middle+1;
}else if((input[middle] > input[0] + (middle)*ap) &&
input[middle-1] == input[0] + (middle-1)*ap){
return input[0] + (middle)*ap;
}else{
high = middle-1;
}
}
return -1;
}
public static void main(String args[]){
int input[] = {1,7,10,13,16,19,22};
ArithmeticProgressionSearch aps = new ArithmeticProgressionSearch();
System.out.println(aps.search(input));
}
}
================================================
FILE: src/com/interview/binarysearch/BinarySearch.java
================================================
package com.interview.binarysearch;
/**
* Regular binary search
*/
public class BinarySearch {
public int search(final int input[], int search) {
int low = 0;
int high = input.length - 1;
int mid;
while (low <= high) {
mid = low + ((high - low) / 2);
if (input[mid] == search) {
return mid;
} else if (input[mid] < search) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return -1;
}
public static void main(String args[]) {
BinarySearch bSearch = new BinarySearch();
final int arr1[] = {1, 2, 4, 5, 7, 8};
System.out.println(bSearch.search(arr1, -1));
System.out.println(bSearch.search(arr1, 1));
System.out.println(bSearch.search(arr1, 8));
System.out.println(bSearch.search(arr1, 2));
}
}
================================================
FILE: src/com/interview/binarysearch/CircularBinarySearch.java
================================================
package com.interview.binarysearch;
/**
* http://www.careercup.com/question?id=4877486110277632
* Given a circle with N defined points and a point M outside the circle,
* find the point that is closest to M among the set of N. O(LogN)
* Test cases
* 1) smallest element at center
* 2) smallest element at left/right end
* 3) largest element at center
* 4) smallest element at left side
* 5) smallest element at right side
*/
public class CircularBinarySearch {
//if mid is greater than both ends than result is low of two ends else move in direction
//where either mid-1 or mid+1 is less
public int search(int arr[]) {
int low = 0;
int high = arr.length - 1;
int mid = 0;
while (low < high) {
mid = (low + high) / 2;
//if middle is less than both mid-1 and mid+1 then mid is the answer
if((low == mid || arr[mid] < arr[mid-1])&& arr[mid] < arr[mid+1]){
return arr[mid];
}
if ((arr[mid] >= arr[low] && arr[mid] >= arr[high])){
if(arr[low] < arr[high]){
high = mid-1;
}else{
low = mid+1;
}
}else{
if(arr[mid-1] < arr[mid+1]){
high = mid-1;
}else{
low = mid+1;
}
}
}
return arr[low];
}
public static void main(String args[]) {
CircularBinarySearch cbs = new CircularBinarySearch();
int arr[] = { 7, 10, 8, 5, 2, 3, 5 };
System.out.print(cbs.search(arr));
int arr1[] = { 5, 8, 10, 7, 5, 3, 2 };
System.out.print(cbs.search(arr1));
int arr2[] = { 3, 5, 7, 10, 8, 5, 2 };
System.out.print(cbs.search(arr2));
int arr3[] = { 8, 5, 2, 3, 5, 7, 10 };
System.out.print(cbs.search(arr3));
int arr4[] = { 5, 3, 2, 5, 8, 10, 7 };
System.out.print(cbs.search(arr4));
int arr5[] = {100,20,10,5,2,8,11,16,19};
System.out.print(cbs.search(arr5));
int arr6[] = {200,2,10,15,20,80,110,160,190};
System.out.print(cbs.search(arr6));
int arr7[] = {5,10,20,50,200,800,1100,1600,1900,2};
System.out.print(cbs.search(arr7));
int arr8[] = {2,5,10,20,50,200,800,1100,1600,1900};
System.out.print(cbs.search(arr8));
int arr9[] = {3,1,8,5,4};
System.out.print(cbs.search(arr9));
}
}
================================================
FILE: src/com/interview/binarysearch/CountNDistinctPairsWithDifferenceK.java
================================================
package com.interview.binarysearch;
import java.util.Arrays;
/**
* http://www.geeksforgeeks.org/count-pairs-difference-equal-k/
*/
public class CountNDistinctPairsWithDifferenceK {
public int count(int arr[],int k){
Arrays.sort(arr);
int count = 0;
for(int i=0; i < arr.length; i++){
boolean result = binarySearch(arr, i+1, arr.length-1, arr[i] + k);
if(result){
count++;
}
}
return count;
}
private boolean binarySearch(int arr[],int start,int end,int num){
if(start > end){
return false;
}
int mid = (start + end)/2;
if(arr[mid] == num){
return true;
}
else if(arr[mid] > num){
return binarySearch(arr,start,mid-1,num);
}else{
return binarySearch(arr,mid+1,end,num);
}
}
public static void main(String args[]){
CountNDistinctPairsWithDifferenceK cn = new CountNDistinctPairsWithDifferenceK();
int arr[] = {1,2,3,4,5,7,9};
System.out.print(cn.count(arr, 3));
}
}
================================================
FILE: src/com/interview/binarysearch/FirstOccurrenceOfNumberInSortedArray.java
================================================
package com.interview.binarysearch;
/**
* http://www.geeksforgeeks.org/check-for-majority-element-in-a-sorted-array/
*/
public class FirstOccurrenceOfNumberInSortedArray {
public int firstOccurrence(int input[], int x){
int low = 0;
int high = input.length-1;
while(low <= high){
int middle = (low + high)/2;
if(input[middle] == x && (middle == 0 || input[middle-1] < x)){
return middle;
}else if(input[middle] < x){
low = middle+1;
}else{
high = middle-1;
}
}
return -1;
}
public static void main(String args[]){
FirstOccurrenceOfNumberInSortedArray fos = new FirstOccurrenceOfNumberInSortedArray();
int input[] = {1,2,2,2,2,2,5,7,7};
System.out.println(fos.firstOccurrence(input, 6));
}
}
================================================
FILE: src/com/interview/binarysearch/FloorAndCeilingSortedArray.java
================================================
package com.interview.binarysearch;
/**
* http://www.geeksforgeeks.org/search-floor-and-ceil-in-a-sorted-array/
*/
public class FloorAndCeilingSortedArray {
public int floor(int input[], int x){
int low = 0;
int high = input.length-1;
while(low <= high){
int middle = (low + high)/2;
if(input[middle] == x || (input[middle] < x && (middle == input.length-1 || input[middle+1] > x))){
return middle;
}else if(input[middle] < x){
low = middle+1;
}else{
high = middle-1;
}
}
return -1;
}
public int ceiling(int input[], int x){
int low = 0;
int high = input.length-1;
while(low <= high){
int middle = (low + high)/2;
if(input[middle] == x || (input[middle] > x && (middle == 0 || input[middle-1] < x))){
return middle;
}else if(input[middle] < x){
low = middle+1;
}else{
high = middle-1;
}
}
return -1;
}
public static void main(String args[]){
int input[] = {1,2,5,6,11,15};
FloorAndCeilingSortedArray foc = new FloorAndCeilingSortedArray();
System.out.println(foc.floor(input, 15));
System.out.println(foc.ceiling(input, 2));
}
}
================================================
FILE: src/com/interview/binarysearch/MedianOfTwoSortedArray.java
================================================
package com.interview.binarysearch;
/**
* http://www.geeksforgeeks.org/median-of-two-sorted-arrays/
*/
public class MedianOfTwoSortedArray {
public double median(int arr1[],int arr2[]){
int low1 = 0;
int high1 = arr1.length-1;
int low2 = 0;
int high2 = arr2.length-1;
while(true){
if(high1 == low1){
return (arr1[low1] + arr2[low2])/2;
}
if(high1 - low1 == 1){
return (double)(Math.max(arr1[low1], arr2[low2]) + Math.min(arr1[high1], arr2[high2]))/2;
}
double med1 = getMedian(arr1,low1,high1);
double med2 = getMedian(arr2,low1,high2);
if(med1 <= med2){
if((high1-low1 + 1) % 2 == 0){
low1 = (high1+low1)/2;
high2 = (high2+low2)/2 + 1;
}else{
low1 = (low1+high1)/2;
high2 = (low2+high2)/2;
}
}
else{
if((high1-low1 + 1) % 2 == 0){
low2 = (high2+low2)/2;
high1 = (high1+low1)/2 + 1;
}else{
low2 = (low2+high2)/2;
high1 = (low1+high1)/2;
}
}
}
}
private double getMedian(int arr[],int low,int high){
int len = high - low+1;
if(len % 2 == 0){
return (arr[low + len/2] + arr[low+ len/2-1])/2;
}else{
return arr[low+len/2];
}
}
public static void main(String args[]){
int arr1[] = {1,2,3,4,6};
int arr2[] = {-1,5,6,7,8};
MedianOfTwoSortedArray mts = new MedianOfTwoSortedArray();
System.out.println(mts.median(arr1, arr2));
}
}
================================================
FILE: src/com/interview/binarysearch/MedianOfTwoSortedArrayOfDifferentLength.java
================================================
package com.interview.binarysearch;
/**
* There are two sorted arrays nums1 and nums2 of size m and n respectively.
* Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
*
* Solution
* Take minimum size of two array. Possible number of partitions are from 0 to m in m size array.
* Try every cut in binary search way. When you cut first array at i then you cut second array at (m + n + 1)/2 - i
* Now try to find the i where a[i-1] <= b[j] and b[j-1] <= a[i]. So this i is partition around which lies the median.
*
* Time complexity is O(log(min(x,y))
* Space complexity is O(1)
*
* https://leetcode.com/problems/median-of-two-sorted-arrays/
* https://discuss.leetcode.com/topic/4996/share-my-o-log-min-m-n-solution-with-explanation/4
*/
public class MedianOfTwoSortedArrayOfDifferentLength {
public double findMedianSortedArrays(int input1[], int input2[]) {
//if input1 length is greater than switch them so that input1 is smaller than input2.
if (input1.length > input2.length) {
return findMedianSortedArrays(input2, input1);
}
int x = input1.length;
int y = input2.length;
int low = 0;
int high = x;
while (low <= high) {
int partitionX = (low + high)/2;
int partitionY = (x + y + 1)/2 - partitionX;
//if partitionX is 0 it means nothing is there on left side. Use -INF for maxLeftX
//if partitionX is length of input then there is nothing on right side. Use +INF for minRightX
int maxLeftX = (partitionX == 0) ? Integer.MIN_VALUE : input1[partitionX - 1];
int minRightX = (partitionX == x) ? Integer.MAX_VALUE : input1[partitionX];
int maxLeftY = (partitionY == 0) ? Integer.MIN_VALUE : input2[partitionY - 1];
int minRightY = (partitionY == y) ? Integer.MAX_VALUE : input2[partitionY];
if (maxLeftX <= minRightY && maxLeftY <= minRightX) {
//We have partitioned array at correct place
// Now get max of left elements and min of right elements to get the median in case of even length combined array size
// or get max of left for odd length combined array size.
if ((x + y) % 2 == 0) {
return ((double)Math.max(maxLeftX, maxLeftY) + Math.min(minRightX, minRightY))/2;
} else {
return (double)Math.max(maxLeftX, maxLeftY);
}
} else if (maxLeftX > minRightY) { //we are too far on right side for partitionX. Go on left side.
high = partitionX - 1;
} else { //we are too far on left side for partitionX. Go on right side.
low = partitionX + 1;
}
}
//Only we we can come here is if input arrays were not sorted. Throw in that scenario.
throw new IllegalArgumentException();
}
public static void main(String[] args) {
int[] x = {1, 3, 8, 9, 15};
int[] y = {7, 11, 19, 21, 18, 25};
MedianOfTwoSortedArrayOfDifferentLength mm = new MedianOfTwoSortedArrayOfDifferentLength();
mm.findMedianSortedArrays(x, y);
}
}
================================================
FILE: src/com/interview/binarysearch/MinimumInSortedRotatedArray.java
================================================
package com.interview.binarysearch;
/**
* https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/
*/
public class MinimumInSortedRotatedArray {
public int findMin(int[] nums) {
int low = 0;
int high = nums.length - 1;
while (low < high) {
int middle = (low + high)/2;
if ((middle == 0 && nums[middle] < nums[middle + 1]) || (middle > 0 && nums[middle] < nums[middle - 1])) {
return nums[middle];
}
else if (nums[middle] > nums[high]) {
low = middle + 1;
} else {
high = middle - 1;
}
}
return nums[low];
}
}
================================================
FILE: src/com/interview/binarysearch/MissingNumberInConsecutiveNumbers.java
================================================
package com.interview.binarysearch;
/**
* Find missing number in consecutive numbers.
*/
public class MissingNumberInConsecutiveNumbers {
public Integer findMissing(int arr[]){
int lowNum = arr[0];
int low = 0;
int high = arr.length -1;
int middle = (low + high)/2;
while(low <= high){
middle = (low + high)/2;
if(arr[middle] == (middle+1 + lowNum) && middle-1 >=0 && arr[middle-1] == (middle + lowNum-1)){
return middle + lowNum;
}
else if((middle + lowNum) == arr[middle]){
low = middle+1;
}else {
high = middle-1;
}
}
return null;
}
public static void main(String args[]){
int arr[] = {3,4,5,6,7,8,9,10,11,12};
int arr1[] = {-5,-4,-3,-1,0,1,2,3};
MissingNumberInConsecutiveNumbers mn = new MissingNumberInConsecutiveNumbers();
System.out.println(mn.findMissing(arr1));
}
}
================================================
FILE: src/com/interview/binarysearch/MonotonicallyIncreasingFunctionBecomesPositive.java
================================================
package com.interview.binarysearch;
/**
* http://www.geeksforgeeks.org/find-the-point-where-a-function-becomes-negative/
*/
public class MonotonicallyIncreasingFunctionBecomesPositive {
private int f(int x){
return x*x - 10*x - 20;
}
public int findPoint(){
int i=1;
while(f(i) <=0 ){
i = i*2;
}
return binarySearch(i/2,i);
}
private int binarySearch(int start,int end){
int mid = (start+end)/2;
while(start < end){
mid = (start+end)/2;
if(f(mid) >0 && f(mid-1) <=0){
return mid;
}
if(f(mid) <=0 && f(mid+1)>0){
return mid+1;
}
if(f(mid) <= 0){
start = mid+1;
}else{
end = mid-1;
}
}
return mid;
}
public static void main(String args[]){
MonotonicallyIncreasingFunctionBecomesPositive mif = new MonotonicallyIncreasingFunctionBecomesPositive();
System.out.print(mif.findPoint());
}
}
================================================
FILE: src/com/interview/binarysearch/NumberOfPairWithXPowerYGreaterThanYPowerX.java
================================================
package com.interview.binarysearch;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* http://www.geeksforgeeks.org/find-number-pairs-xy-yx/
*/
public class NumberOfPairWithXPowerYGreaterThanYPowerX {
public int countPairs(int X[],int Y[]){
Map hardCoded = new HashMap();
for(int i=0; i < Y.length; i++){
if(Y[i] < 4){
Integer count = hardCoded.get(Y[i]);
if(count != null){
hardCoded.put(Y[i], count++);
}else{
hardCoded.put(Y[i], 1);
}
}
}
Arrays.sort(Y);
int countPairs = 0;
for(int i=0 ; i < X.length; i++){
countPairs += count(X[i],Y,hardCoded);
}
return countPairs;
}
private int count(int x, int Y[],Map hardCount){
if(x == 0){
return 0;
}
if(x == 1){
return upperBound(0,Y);
}
int result = Y.length - upperBound(x,Y);
result += (hardCount.containsKey(1) ? hardCount.get(1) : 0 ) + (hardCount.containsKey(0) ? hardCount.get(0) : 0);
if(x == 2){
result -= (hardCount.containsKey(3) ? hardCount.get(3) : 0);
}
if(x == 3){
result += (hardCount.containsKey(2) ? hardCount.get(2) : 0);
}
return result;
}
private int upperBound(int x, int arr[]){
int low = 0;
int high = arr.length-1;
while(low <= high){
int mid = (low+high)/2;
if(arr[mid] > x && (mid-1 < 0 || arr[mid-1] <= x)){
return mid;
}else if(arr[mid] > x){
high = mid-1;
}else{
low = mid+1;
}
}
return -1;
}
public static void main(String args[]){
NumberOfPairWithXPowerYGreaterThanYPowerX nop = new NumberOfPairWithXPowerYGreaterThanYPowerX();
int X[] = {7,9,5,8,9,11,0,1,1,3};
int Y[] = {6,8,9,11,14,5,1,0,2,3,9};
System.out.println(nop.countPairs(X, Y));
}
}
================================================
FILE: src/com/interview/binarysearch/PeakElement.java
================================================
package com.interview.binarysearch;
/**
* @author Tushar Roy
* Date 01/17/2107
* A peak element is an element that is greater than its neighbors. Find index of peak element in the array.
*
* Space complexity is O(1)
* Time complexity is O(n)
*
* https://leetcode.com/problems/find-peak-element/
*/
public class PeakElement {
public int findPeakElement(int[] nums) {
int low = 0;
int high = nums.length - 1;
int middle = 0;
while (low <= high) {
middle = (low + high)/2;
int before = Integer.MIN_VALUE;
if (middle > 0) {
before = nums[middle - 1];
}
int after = Integer.MIN_VALUE;
if (middle < nums.length - 1) {
after = nums[middle + 1];
}
if (nums[middle] > before && nums[middle] > after) {
return middle;
} else if (before > after) {
high = middle - 1;
} else {
low = middle + 1;
}
}
return middle;
}
public static void main(String args[]){
int arr[] = {10,5,15,2,23,90,67};
PeakElement pe = new PeakElement();
System.out.println(pe.findPeakElement(arr));
int arr1[] = {10,20,30,40,50};
System.out.println(pe.findPeakElement(arr1));
int arr2[] = {100,90,80,70,60};
System.out.println(pe.findPeakElement(arr2));
}
}
================================================
FILE: src/com/interview/binarysearch/SearchForRange.java
================================================
package com.interview.binarysearch;
/**
* Date 07/31/2016
* @author Tushar Roy
*
* Given a sorted array of integers, find the starting and ending position of a given target value.
*
* Time complexity O(logn)
* Space complexity O(1)
*
* https://leetcode.com/problems/search-for-a-range/
*/
public class SearchForRange {
public int[] searchRange(int[] nums, int target) {
int first = firstOccurence(nums, target);
if (first == -1) {
return new int[]{-1, -1};
}
int last = lastOccurence(nums, target);
return new int[]{first, last};
}
private int firstOccurence(int[] nums, int target) {
int low = 0;
int high = nums.length - 1;
while (low <= high) {
int mid = low + (high - low)/2;
if (nums[mid] == target && (mid == 0 || nums[mid - 1] < target)) {
return mid;
} else if (nums[mid] >= target) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return -1;
}
private int lastOccurence(int[] nums, int target) {
int low = 0;
int high = nums.length - 1;
while (low <= high) {
int mid = low + (high - low)/2;
if (nums[mid] == target && (mid == nums.length - 1 || nums[mid + 1] > target)) {
return mid;
} else if (nums[mid] <= target) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return -1;
}
public static void main(String args[]) {
SearchForRange searchForRange = new SearchForRange();
int[] nums = {0, 1, 1, 3, 6, 9, 11};
int[] r = searchForRange.searchRange(nums, 11);
System.out.println(r[0] + " " + r[1]);
r = searchForRange.searchRange(nums, 0);
System.out.println(r[0] + " " + r[1]);
}
}
================================================
FILE: src/com/interview/binarysearch/SearchInsertPosition.java
================================================
package com.interview.binarysearch;
/**
* https://leetcode.com/problems/search-insert-position/
*/
public class SearchInsertPosition {
public int searchInsert(int[] nums, int target) {
int low = 0;
int high = nums.length - 1;
while (low <= high) {
int middle = (low + high)/2;
if (nums[middle] == target) {
return middle;
}
if (nums[middle] < target && (middle == nums.length - 1 || nums[middle + 1] > target)) {
return middle + 1;
}
if (nums[middle] < target) {
low = middle + 1;
} else {
high = middle - 1;
}
}
return 0;
}
}
================================================
FILE: src/com/interview/binarysearch/SortedAndRotatedArraySearch.java
================================================
package com.interview.binarysearch;
/**
* @author Tushar Roy
* Date 01/22/17
*
* Search in sorted and rotated array. In one version duplicate is not allowed and
* in another version duplicate is allowed.
*
* Time complexity with no duplicate - O(logn)
* Time complexity with duplicates - O(n)
*
* https://leetcode.com/problems/search-in-rotated-sorted-array/
* https://leetcode.com/problems/search-in-rotated-sorted-array-ii/
*/
public class SortedAndRotatedArraySearch {
/**
* Duplicates are not allowed in arr.
*/
public int search(int arr[],int search){
int low =0;
int high = arr.length-1;
while(low <= high){
int mid = (low + high)/2;
if(arr[mid] == search){
return mid;
}
if(arr[mid] < arr[high]){
if(arr[mid] < search && search <= arr[high]){
low = mid+1;
}else{
high = mid-1;
}
}else{
if(search >= arr[low] && search < arr[mid]){
high = mid-1;
}else{
low = mid+1;
}
}
}
return -1;
}
/**
* Duplicates are allowed in arr.
*/
public boolean searchWithDuplicates(int[] arr, int search) {
int low =0;
int high = arr.length-1;
while(low <= high){
int mid = (low + high)/2;
if(arr[mid] == search) {
return true;
}
//if low is same as mid then increment low.
if (arr[mid] == arr[low]) {
low++;
} else if (arr[mid] == arr[high]) { //if high is same as mid then decrement high.
high--;
} else if (arr[mid] < arr[high]) {
if(arr[mid] < search && search <= arr[high]) {
low = mid + 1;
} else {
high = mid - 1;
}
} else {
if(search >= arr[low] && search < arr[mid]) {
high = mid - 1;
} else {
low = mid + 1;
}
}
}
return false;
}
public static void main(String args[]){
SortedAndRotatedArraySearch ras = new SortedAndRotatedArraySearch();
int arr1[] = {1,2,5,6,7,8,11,21};
System.out.print(ras.search(arr1, 1));
System.out.print(ras.search(arr1, 5));
System.out.print(ras.search(arr1, 22));
System.out.println();
int arr2[] = {18,21,1,2,5,6,7,8,10,15};
System.out.print(ras.search(arr2, 1));
System.out.print(ras.search(arr2, 5));
System.out.print(ras.search(arr2, 10));
System.out.print(ras.search(arr2, 14));
System.out.println();
int arr3[] = {7,8,15,17,18,21,1,2,5,6};
System.out.print(ras.search(arr3, 1));
System.out.print(ras.search(arr3, 5));
System.out.print(ras.search(arr3, 10));
System.out.print(ras.search(arr3, 7));
System.out.print(ras.search(arr3, 6));
System.out.print(ras.search(arr3, 16));
}
}
================================================
FILE: src/com/interview/binarysearch/SquareRootOfNumber.java
================================================
package com.interview.binarysearch;
/**
*
* https://leetcode.com/problems/sqrtx/
*/
public class SquareRootOfNumber {
public int mySqrt(int x) {
if (x == 0)
return 0;
int left = 1, right = x;
while (true) {
int mid = left + (right - left)/2;
if (mid > x/mid) {
right = mid - 1;
} else {
if (mid + 1 > x/(mid + 1))
return mid;
left = mid + 1;
}
}
}
}
================================================
FILE: src/com/interview/bits/AddTwoNumberInBinaryRepresentation.java
================================================
package com.interview.bits;
/**
* http://www.geeksforgeeks.org/add-two-bit-strings/
* http://www.geeksforgeeks.org/binary-representation-of-a-given-number/
* http://www.geeksforgeeks.org/add-two-numbers-without-using-arithmetic-operators/
*/
public class AddTwoNumberInBinaryRepresentation {
public int add(char[] num1,char[] num2){
int index1 = num1.length -1;
int index2 = num2.length -1;
int carry = 0;
int result = 0;
int index = 0;
while(index1 >= 0 && index2 >= 0){
int r1 = num1[index1] - '0';
int r2 = num2[index2] - '0';
result = result | (r1^r2^carry)<= 0){
int r1 = num1[index1] - '0';
result = result | (r1^carry)<= 0){
int r2 = num1[index2] - '0';
result = result | (r2^carry)<>>1){
if((num & i) > 0){
System.out.print("1");
}else{
System.out.print("0");
}
}
}
public static void main(String args[]){
AddTwoNumberInBinaryRepresentation anp = new AddTwoNumberInBinaryRepresentation();
char num1[] = "1010001110".toCharArray();
char num2[] = "10011".toCharArray();
int result = anp.add(num1, num2);
System.out.println(anp.addTwoNumbersWithoutArithmeticOperator(296, 5662));
System.out.println(anp.addTwoNumbersWithoutArithmeticOperatorFaster(296, 5662));
anp.printResult(result);
}
}
================================================
FILE: src/com/interview/bits/BitRotation.java
================================================
package com.interview.bits;
/*
* http://www.geeksforgeeks.org/rotate-bits-of-an-integer/
*/
public class BitRotation {
public byte rotateLeft(byte num, int d){
return (byte)((num << d) | (num >>> (8-d)));
}
public static void main(String args[]){
BitRotation br = new BitRotation();
System.out.println(br.rotateLeft((byte)28, 2));
}
}
================================================
FILE: src/com/interview/bits/ByteAsStorage.java
================================================
package com.interview.bits;
public class ByteAsStorage {
void useByteAsBoolean(boolean[] visited){
byte[] bytes = new byte[(int)(Math.ceil(visited.length*1.0/8))];
for(int i=0; i < visited.length; i++){
int row = i/8;
int col = i%8;
if(visited[i]){
bytes[row] = (byte)(bytes[row] | (byte)(1<= 1){
System.out.print("True");
}else{
System.out.print("False");
}
}
}
public static void main(String args[]){
boolean visited[] = {true,false,true,true,false};
ByteAsStorage bas = new ByteAsStorage();
bas.useByteAsBoolean(visited);
}
}
================================================
FILE: src/com/interview/bits/CountBits.java
================================================
package com.interview.bits;
/**
* http://www.geeksforgeeks.org/count-set-bits-in-an-integer/
*/
public class CountBits {
public CountBits(){
preCalculate();
}
public int countBits(int num){
int count=0;
while(num > 0){
num &= num-1;
count++;
}
return count;
}
private int count[] = new int[256];
void preCalculate(){
for(int i=0; i < 256; i++){
count[i] = countBits(i);
}
}
public int countBitsFaster(int num){
//get 8 bits at a time and check count from count array
int total = 0;
int mask = (1<<8) - 1;
for(int i=0 ; i < 4; i++){
total += count[num & mask];
num = num>>>8;
}
return total;
}
//http://bits.stephan-brumme.com/countBits.html
public int countBitsEvenFaster(int x){
// count bits of each 2-bit chunk
x = x - ((x >> 1) & 0x55555555);
// count bits of each 4-bit chunk
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
// count bits of each 8-bit chunk
x = x + (x >> 4);
// mask out junk
x &= 0xF0F0F0F;
// add all four 8-bit chunks
return (x * 0x01010101) >> 24;
}
public static void main(String args[]){
CountBits cb = new CountBits();
System.out.println(cb.countBits(3636363));
System.out.println(cb.countBitsFaster(3636363));
System.out.println(cb.countBitsEvenFaster(3636363));
}
}
================================================
FILE: src/com/interview/bits/CountingBitsTillNum.java
================================================
package com.interview.bits;
/**
* Date 04/03/2016
* @author Tushar Roy
*
* Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate
* the number of 1's in their binary representation and return them as an array.
*
* Time complexity O(n)
* Space complexity O(n)
*
* https://leetcode.com/problems/counting-bits/
*/
public class CountingBitsTillNum {
public int[] countBits(int num) {
if (num == 0) {
return new int[1];
}
int[] count = new int[num + 1];
count[0] = 0;
int n = 1;
int start = n;
while (start <= num) {
start = n;
count[start++] = 1;
int end = n<<1;
while (start < end && start <= num) {
count[start] = 1 + count[start - n];
start++;
}
n = n<<1;
}
return count;
}
}
================================================
FILE: src/com/interview/bits/DrawHorizontalLine.java
================================================
package com.interview.bits;
/**
* Exercise 5.8 150qs
*/
public class DrawHorizontalLine {
public void draw(byte[] screen, int width, int x1, int x2,int y){
int pos1 = y*width + x1;
int pos2 = y*width + x2;
int start = pos1;
while(start <= pos2){
int row = start/8;
int col = start%8;
screen[row] = (byte)(screen[row] | 1<>i;
}
result = result | (sum%3)< grayCode(int n) {
List result = new LinkedList<>();
for (int i = 0; i < 1<>1);
}
return result;
}
public static void main(String args[]) {
GrayCode gc = new GrayCode();
System.out.println(gc.grayCode(4));
}
}
================================================
FILE: src/com/interview/bits/InsertMintoNiTojBits.java
================================================
package com.interview.bits;
/**
* Exercise 5.1 150 qs
*/
public class InsertMintoNiTojBits {
public int insert(int M,int N, int i, int j){
int mask = 1<<(j+1) -1;
mask = mask< b.length() - a.length());
int[] masks = new int[words.length]; // alphabet masks
for(int i = 0; i < masks.length; i++){
for(char c: words[i].toCharArray()){
masks[i] |= 1 << (c - 'a');
}
}
for(int i = 0; i < masks.length; i++){
if(words[i].length() * words[i].length() <= max) {
break; //prunning
}
for(int j = i + 1; j < masks.length; j++){
if((masks[i] & masks[j]) == 0){
max = Math.max(max, words[i].length() * words[j].length());
break; //prunning
}
}
}
return max;
}
}
================================================
FILE: src/com/interview/bits/MissingNumbers.java
================================================
package com.interview.bits;
class Pair{
int x;
int y;
}
/**
* http://www.geeksforgeeks.org/find-the-two-repeating-elements-in-a-given-array/
* http://www.geeksforgeeks.org/find-a-repeating-and-a-missing-number/
*/
public class MissingNumbers {
public Pair findMissingAndRepeated(int arr[], int n){
int xor = 0;
for(int i=0; i < arr.length; i++){
xor = xor ^ arr[i];
}
for(int i=1; i <= n; i++){
xor = xor ^ i;
}
xor = xor & ~(xor-1);
int set1 = 0;
int set2 = 0;
for(int i=0; i < arr.length; i++){
if((arr[i] & xor) > 0){
set1 ^= arr[i];
}else{
set2 ^= arr[i];
}
}
Pair p = new Pair();
for(int i=1; i <= n; i++){
if((i & xor) > 0){
set1 ^= i;
}else{
set2 ^= i;
}
}
p.x = set1;
p.y = set2;
return p;
}
public Pair findTwoMissingNumber(int arr[], int n){
int xor = 0;
for(int i=0; i < arr.length; i++){
xor = xor ^ arr[i];
}
for(int i=1; i <= n; i++){
xor = xor ^ i;
}
xor = xor & ~(xor-1);
int set1 = 0;
int set2 = 0;
for(int i=0; i < arr.length; i++){
if((arr[i] & xor) > 0){
set1 ^= arr[i];
}else{
set2 ^= arr[i];
}
}
Pair p = new Pair();
for(int i=1; i <= n; i++){
if((i & xor) > 0){
set1 ^= i;
}else{
set2 ^= i;
}
}
p.x = set1;
p.y = set2;
return p;
}
public static void main(String args[]){
MissingNumbers mn = new MissingNumbers();
int arr[] = {1,2,3,5,5};
Pair p = mn.findMissingAndRepeated(arr, 5);
System.out.println(p.x + " " + p.y);
int arr1[] = {1,5,3,6};
p = mn.findMissingAndRepeated(arr1, 6);
System.out.println(p.x + " " + p.y);
}
}
================================================
FILE: src/com/interview/bits/NextHigherAndNextLowerWithSameNumberBits.java
================================================
package com.interview.bits;
/**
* Exercise 5.3 150 qs
*/
public class NextHigherAndNextLowerWithSameNumberBits {
public int nextHigher(int n){
int i = 1;
int first1 = 0;
//go till you find first 1
while((n & i) == 0){
i = i << 1;
first1++;
}
//count number of 1s before first 0
int count1s = 0;
while((n & i) > 0){
i = i <<1;
count1s++;
}
count1s--;
//change this first 0 after 1 to 1
n = n^i;
n = n ^ (i>>1);
int mask = ~(1<<(first1 + count1s) -1);
n = mask & n;
n = n | ((1< 0){
i = i << 1;
first0++;
}
int count0s = 0;
while((n & i) == 0){
i = i <<1;
count0s++;
}
count0s--;
//change this first 0 after 1 to 1
n = n^i;
n = n ^ (i>>1);
int mask = (1< 0 && (num & (num-1)) == 0){
return num;
}
while((num & (num-1)) > 0){
num = num & (num-1);
}
return num<<1;
}
public static void main(String args[]){
NextPowerOf2 np = new NextPowerOf2();
System.out.println(np.nextPowerOf2(4));
}
}
================================================
FILE: src/com/interview/bits/NumberOccuringOddTimes.java
================================================
package com.interview.bits;
/**
* http://www.geeksforgeeks.org/find-the-number-occurring-odd-number-of-times/
* http://www.geeksforgeeks.org/find-two-non-repeating-elements-in-an-array-of-repeating-elements/
*/
public class NumberOccuringOddTimes {
public int oneNumberOccuringOddTimes(int arr[]){
int r = 0;
for(int i=0; i < arr.length; i++){
r = r^arr[i];
}
return r;
}
class Pair{
int a;
int b;
}
public Pair twoNumbersOccuringOddTimes(int arr[]){
int r = 0;
for(int i=0; i < arr.length; i++){
r = r^arr[i];
}
r = r & ~(r-1);
int r1 = 0;
int r2 = 0;
for(int i=0; i < arr.length; i++){
if((r&arr[i]) == 0){
r1 = r1^arr[i];
}else{
r2 = r2^arr[i];
}
}
Pair p = new Pair();
p.a = r1;
p.b = r2;
return p;
}
public static void main(String args[]){
NumberOccuringOddTimes noot = new NumberOccuringOddTimes();
int arr[] = {1,2,9,9,2,1,9,7,2,1,9,1};
Pair p = noot.twoNumbersOccuringOddTimes(arr);
System.out.print(p.a + " " + p.b);
}
}
================================================
FILE: src/com/interview/bits/NumberOfBitsFlipToConvertNToM.java
================================================
package com.interview.bits;
/**
* Exercise 5.5 150 qs
*/
public class NumberOfBitsFlipToConvertNToM {
public int number(int m, int n){
int r = n^m;
int count = 0;
while(r != 0){
r = r & (r-1);
count++;
}
return count;
}
public static void main(String args[]){
NumberOfBitsFlipToConvertNToM nb = new NumberOfBitsFlipToConvertNToM();
System.out.println(nb.number(31, 14));
}
}
================================================
FILE: src/com/interview/bits/RealNumberToBinary.java
================================================
package com.interview.bits;
/**
* Exercise 5.2 150 qs
*/
public class RealNumberToBinary {
public void print(double num){
if(num > 1 || num < 0){
System.out.println("ERROR");
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("0.");
while(num > 0){
num = num*2;
int r = (int)num ;
stringBuilder.append(r);
num = num -r;
if(stringBuilder.length() > 32){
System.out.println("ERROR");
return;
}
}
System.out.println(stringBuilder);
}
public static void main(String args[]){
RealNumberToBinary rnb = new RealNumberToBinary();
rnb.print(0.8125);
rnb.print(0.72);
}
}
================================================
FILE: src/com/interview/bits/RepeatedDnaSequence.java
================================================
package com.interview.bits;
import java.util.*;
/**
* Date 03/08/2016
* @author Tushar Roy
*
* Find repeated sequence of length 10 in string consisting of A,C,G,T
*
* Time complexity is O(n)
* Space complexity is O(n)
*
* https://leetcode.com/problems/repeated-dna-sequences/
*/
public class RepeatedDnaSequence {
private static final int mask = 0xFFFFF;
private static final int mask1 = 3;
public List findRepeatedDnaSequences(String s) {
if (s.length() < 10) {
return Collections.emptyList();
}
Set set = new HashSet<>();
int val = 0;
for (int i = 0; i < 10; i++) {
val = add(val, s.charAt(i));
}
set.add(val);
List result = new ArrayList<>();
createString(val);
Set repeatSet = new HashSet<>();
for (int i = 10; i < s.length(); i++) {
val = add(val, s.charAt(i));
if (set.contains(val) && !repeatSet.contains(val)) {
result.add(createString(val));
repeatSet.add(val);
} else {
set.add(val);
}
}
return result;
}
private String createString(int input) {
StringBuffer sb = new StringBuffer();
for (int i = 9; i >= 0; i--) {
sb.append(getChar(input>>(i*2) & mask1));
}
return sb.toString();
}
private int add(int input, char ch) {
int val = getVal(ch);
input = input<<2;
input = input & mask;
return input | val;
}
private int getVal(char ch) {
switch(ch) {
case 'A':
return 0;
case 'C':
return 1;
case 'G':
return 2;
case 'T':
return 3;
default:
throw new IllegalArgumentException();
}
}
private char getChar(int val) {
switch (val) {
case 0:
return 'A';
case 1:
return 'C';
case 2:
return 'G';
case 3:
return 'T';
default:
throw new IllegalArgumentException();
}
}
public static void main(String args[]) {
RepeatedDnaSequence rds = new RepeatedDnaSequence();
List result = rds.findRepeatedDnaSequences("AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT");
System.out.print(result);
}
}
================================================
FILE: src/com/interview/bits/ReverseBits.java
================================================
package com.interview.bits;
/**
* http://www.geeksforgeeks.org/write-an-efficient-c-program-to-reverse-bits-of-a-number/
*/
public class ReverseBits {
public int reverse(int num){
//assuming int is 32 bits.
int result = 0;
int r1 = 1;
for(int i=31; i >= 0; i--,r1<<=1){
if((num & 1<> and <<
while((k & (k-1))!= 0){
result += n;
k--;
}
while(k > 1){
n = n<<1;
k = k>>1;
}
return result + n;
}
public int fastSquare(int n){
return fastSquareRec(n, n);
}
/**
* Start with 9,9. Then take 1 and keep left shifting 1 till you find number
* less than 9 but power of 2. Then shift 9 by that many powers and repeat
* the process with whatever is left between that number and 9.
*/
private int fastSquareRec(int n, int leftToMultiply){
if(leftToMultiply <= 0){
return 0;
}
int k = 1;
int count=0;
while(k <= leftToMultiply){
k = k<<1;
count++;
}
k = k>>1;
count--;
return (n<> 1 & mask2);
}
public static void main(String args[]){
SwapOddEvenBits soe = new SwapOddEvenBits();
System.out.println(soe.swap(697));
}
}
================================================
FILE: src/com/interview/bits/SwapTwoBits.java
================================================
package com.interview.bits;
/**
* http://www.careercup.com/question?id=17542662
*/
public class SwapTwoBits {
public int swap(int num,int i, int j){
int t1 = (num & 1<>i ^ (num & 1<>j) != 0){
num ^= 1< 1001 -> 101 -> 11
* 1010 -> 110 -> 101 -> 11
*
* No matter which route you take it leads to same result so just looking at swaps you can say
* which player will win
*
*/
public class WinnerWithBeautifulNumber {
public int winner(int n){
int sum = 0;
int i =1;
int result = 0;
while( i <= n){
i = i*2;
}
i = i/2;
while(i > 0){
if((n & i) != 0){
sum++;
}else{
result += sum;
}
i = i/2;
}
if(result % 2 == 0){
return 2;
}else{
return 1;
}
}
public static void main(String args[]){
WinnerWithBeautifulNumber wwb = new WinnerWithBeautifulNumber();
System.out.println(wwb.winner(37));
System.out.println(wwb.winner(10));
}
}
================================================
FILE: src/com/interview/dynamic/BitonicSequence.java
================================================
package com.interview.dynamic;
/**
* http://www.geeksforgeeks.org/dynamic-programming-set-15-longest-bitonic-subsequence/
*/
public class BitonicSequence {
public int longestSequence(int arr[]){
int lis[] = new int[arr.length];
int lds[] = new int[arr.length];
for(int i=0; i < arr.length; i++){
lis[i] = 1;
lds[i] = 1;
}
for(int i=1 ; i < arr.length; i++){
for(int j=0; j < i ; j++){
if(arr[i] > arr[j]){
lis[i] = Math.max(lis[i], lis[j] + 1);
}
}
}
for(int i = arr.length-2; i >=0 ; i--){
for(int j = arr.length-1; j > i; j--){
if(arr[i] > arr[j]){
lds[i] = Math.max(lds[i], lds[j] + 1);
}
}
}
int max = 0;
for(int i=0; i < arr.length; i++){
if(max < lis[i] + lds[i]-1){
max = lis[i] + lds[i] -1;
}
}
return max;
}
public static void main(String args[]){
BitonicSequence bs = new BitonicSequence();
int[] arr = {1,4,3,7,2,1,8,11,13,0};
int r = bs.longestSequence(arr);
System.out.print(r);
}
}
================================================
FILE: src/com/interview/dynamic/BoxStacking.java
================================================
package com.interview.dynamic;
import java.util.Arrays;
/**
* Date 05/09/2015
* @author tusroy
*
* Given different dimensions and unlimited supply of boxes for each dimension, stack boxes
* on top of each other such that it has maximum height but with caveat that length and width
* of box on top should be strictly less than length and width of box under it. You can
* rotate boxes as you like.
*
* 1) Create all rotations of boxes such that length is always greater or equal to width
* 2) Sort boxes by base area in non increasing order (length * width). This is because box
* with more area will never ever go on top of box with less area.
* 3) Take T[] and result[] array of same size as total boxes after all rotations are done
* 4) Apply longest increasing subsequence type of algorithm to get max height.
*
* If n number of dimensions are given total boxes after rotation will be 3n.
* So space complexity is O(n)
* Time complexity - O(nlogn) to sort boxes. O(n^2) to apply DP on it So really O(n^2)
*
* References
* http://www.geeksforgeeks.org/dynamic-programming-set-21-box-stacking-problem/
* http://people.cs.clemson.edu/~bcdean/dp_practice/
*/
public class BoxStacking {
public int maxHeight(Dimension[] input) {
//get all rotations of box dimension.
//e.g if dimension is 1,2,3 rotations will be 2,1,3 3,2,1 3,1,2 . Here length is always greater
//or equal to width and we can do that without loss of generality.
Dimension[] allRotationInput = new Dimension[input.length * 3];
createAllRotation(input, allRotationInput);
//sort these boxes in non increasing order by their base area.(length X width)
Arrays.sort(allRotationInput);
//apply longest increasing subsequence kind of algorithm on these sorted boxes.
int T[] = new int[allRotationInput.length];
int result[] = new int[allRotationInput.length];
for (int i = 0; i < T.length; i++) {
T[i] = allRotationInput[i].height;
result[i] = i;
}
for (int i = 1; i < T.length; i++) {
for (int j = 0; j < i; j++) {
if (allRotationInput[i].length < allRotationInput[j].length
&& allRotationInput[i].width < allRotationInput[j].width) {
if( T[j] + allRotationInput[i].height > T[i]){
T[i] = T[j] + allRotationInput[i].height;
result[i] = j;
}
}
}
}
//find max in T[] and that will be our max height.
//Result can also be found using result[] array.
int max = Integer.MIN_VALUE;
for(int i=0; i < T.length; i++){
if(T[i] > max){
max = T[i];
}
}
return max;
}
//create all rotations of boxes, always keeping length greater or equal to width
private void createAllRotation(Dimension[] input,
Dimension[] allRotationInput) {
int index = 0;
for (int i = 0; i < input.length; i++) {
allRotationInput[index++] = Dimension.createDimension(
input[i].height, input[i].length, input[i].width);
allRotationInput[index++] = Dimension.createDimension(
input[i].length, input[i].height, input[i].width);
allRotationInput[index++] = Dimension.createDimension(
input[i].width, input[i].length, input[i].height);
}
}
public static void main(String args[]) {
BoxStacking bs = new BoxStacking();
Dimension input[] = { new Dimension(3, 2, 5), new Dimension(1, 2, 4) };
int maxHeight = bs.maxHeight(input);
System.out.println("Max height is " + maxHeight);
assert 11 == maxHeight;
}
}
/**
* Utility class to hold dimensions
* @author tusroy
*
*/
class Dimension implements Comparable {
int height;
int length;
int width;
Dimension(int height, int length, int width) {
this.height = height;
this.length = length;
this.width = width;
}
Dimension() {
}
static Dimension createDimension(int height, int side1, int side2) {
Dimension d = new Dimension();
d.height = height;
if (side1 >= side2) {
d.length = side1;
d.width = side2;
} else {
d.length = side2;
d.width = side1;
}
return d;
}
/**
* Sorts by base area(length X width)
*/
@Override
public int compareTo(Dimension d) {
if (this.length * this.width >= d.length * d.width) {
return -1;
} else {
return 1;
}
}
@Override
public String toString() {
return "Dimension [height=" + height + ", length=" + length
+ ", width=" + width + "]";
}
}
================================================
FILE: src/com/interview/dynamic/BreakMultipleWordsWithNoSpaceIntoSpace.java
================================================
package com.interview.dynamic;
import java.util.*;
/**
* Date 08/01/2014
* @author tusroy
*
* Given a string and a dictionary, split this string into multiple words such that
* each word belongs in dictionary.
*
* e.g peanutbutter -> pea nut butter
* e.g Iliketoplay -> I like to play
*
* Solution
* DP solution to this problem
* if( input[i...j] belongs in dictionary) T[i][j] = i
* else{
* T[i][j] = k if T[i][k-1] != -1 && T[k][j] != -1
*
* Test cases
* 1) Empty string
* 2) String where entire string is in dictionary
* 3) String which cannot be split into words which are in dictionary
* 3) String which can be split into words which are in dictionary
*
*/
public class BreakMultipleWordsWithNoSpaceIntoSpace {
/**
* Recursive and slow version of breaking word problem.
* If no words can be formed it returns null
*/
public String breakWord(char[] str,int low,Set dictionary){
StringBuffer buff = new StringBuffer();
for(int i= low; i < str.length; i++){
buff.append(str[i]);
if(dictionary.contains(buff.toString())){
String result = breakWord(str, i+1, dictionary);
if(result != null){
return buff.toString() + " " + result;
}
}
}
if(dictionary.contains(buff.toString())){
return buff.toString();
}
return null;
}
/**
* Dynamic programming version for breaking word problem.
* It returns null string if string cannot be broken into multipe words
* such that each word is in dictionary.
* Gives preference to longer words over splits
* e.g peanutbutter with dict{pea nut butter peanut} it would result in
* peanut butter instead of pea nut butter.
*/
public String breakWordDP(String word, Set dict){
int T[][] = new int[word.length()][word.length()];
for(int i=0; i < T.length; i++){
for(int j=0; j < T[i].length ; j++){
T[i][j] = -1; //-1 indicates string between i to j cannot be split
}
}
//fill up the matrix in bottom up manner
for(int l = 1; l <= word.length(); l++){
for(int i=0; i < word.length() -l + 1 ; i++){
int j = i + l-1;
String str = word.substring(i,j+1);
//if string between i to j is in dictionary T[i][j] is true
if(dict.contains(str)){
T[i][j] = i;
continue;
}
//find a k between i+1 to j such that T[i][k-1] && T[k][j] are both true
for(int k=i+1; k <= j; k++){
if(T[i][k-1] != -1 && T[k][j] != -1){
T[i][j] = k;
break;
}
}
}
}
if(T[0][word.length()-1] == -1){
return null;
}
//create space separate word from string is possible
StringBuffer buffer = new StringBuffer();
int i = 0; int j = word.length() -1;
while(i < j){
int k = T[i][j];
if(i == k){
buffer.append(word.substring(i, j+1));
break;
}
buffer.append(word.substring(i,k) + " ");
i = k;
}
return buffer.toString();
}
/**
* Prints all the words possible instead of just one combination.
* Reference
* https://leetcode.com/problems/word-break-ii/
*/
public List wordBreakTopDown(String s, Set wordDict) {
Map> dp = new HashMap<>();
int max = 0;
for (String s1 : wordDict) {
max = Math.max(max, s1.length());
}
return wordBreakUtil(s, wordDict, dp, 0, max);
}
private List wordBreakUtil(String s, Set dict, Map> dp, int start, int max) {
if (start == s.length()) {
return Collections.singletonList("");
}
if (dp.containsKey(start)) {
return dp.get(start);
}
List words = new ArrayList<>();
for (int i = start; i < start + max && i < s.length(); i++) {
String newWord = s.substring(start, i + 1);
if (!dict.contains(newWord)) {
continue;
}
List result = wordBreakUtil(s, dict, dp, i + 1, max);
for (String word : result) {
String extraSpace = word.length() == 0 ? "" : " ";
words.add(newWord + extraSpace + word);
}
}
dp.put(start, words);
return words;
}
/**
* Check if any one solution exists.
* https://leetcode.com/problems/word-break/
*/
public boolean wordBreakTopDownOneSolution(String s, Set wordDict) {
Map dp = new HashMap<>();
int max = 0;
for (String s1 : wordDict) {
max = Math.max(max, s1.length());
}
return wordBreakTopDownOneSolutionUtil(s, wordDict, 0, max, dp);
}
private boolean wordBreakTopDownOneSolutionUtil(String s, Set dict, int start, int max, Map dp) {
if (start == s.length()) {
return true;
}
if (dp.containsKey(start)) {
return dp.get(start);
}
for (int i = start; i < start + max && i < s.length(); i++) {
String newWord = s.substring(start, i + 1);
if (!dict.contains(newWord)) {
continue;
}
if (wordBreakTopDownOneSolutionUtil(s, dict, i + 1, max, dp)) {
dp.put(start, true);
return true;
}
}
dp.put(start, false);
return false;
}
public boolean wordBreakBottomUp(String s, List wordList) {
boolean[] T = new boolean[s.length() + 1];
Set set = new HashSet<>();
for (String word : wordList) {
set.add(word);
}
T[0] = true;
for (int i = 1; i <= s.length(); i++) {
for (int j = 0; j < i; j++) {
if(T[j] && set.contains(s.substring(j, i))) {
T[i] = true;
break;
}
}
}
return T[s.length()];
}
public static void main(String args[]){
Set dictionary = new HashSet