From 8e0684b9039110841cf0b495839c42f0e6e40b43 Mon Sep 17 00:00:00 2001 From: shi-edward Date: Fri, 26 Jan 2018 21:48:47 -0600 Subject: [PATCH] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AAA.java | 23 +++ AddBinary.java | 39 +++++ AddDigits.java | 58 +++++++ AddStrings.java | 40 +++++ AddTwoNumbers.java | 47 ++++++ AddTwoNumbersII.java | 56 +++++++ AddandSearchWord.java | 85 ++++++++++ AdditiveNumber.java | 71 ++++++++ AlienDictionary.java | 126 ++++++++++++++ AndroidUnlockPatterns.java | 50 ++++++ ArithmeticSlices.java | 45 +++++ AssignCookies.java | 52 ++++++ AverageofLevelsinBinaryTree.java | 56 +++++++ BalancedBinaryTree.java | 53 ++++++ Base7.java | 55 +++++++ BasicCalculator.java | 53 ++++++ BasicCalculatorII.java | 88 ++++++++++ BattleshipsinaBoard.java | 48 ++++++ BestMeetingPoint.java | 76 +++++++++ BestTimetoBuyandSellStock.java | 34 ++++ BestTimetoBuyandSellStockII.java | 33 ++++ BestTimetoBuyandSellStockIII.java | 31 ++++ BestTimetoBuyandSellStockIV.java | 55 +++++++ BestTimetoBuyandSellStockwithCooldown.java | 50 ++++++ BinarySearchTreeIterator.java | 46 ++++++ BinaryTreeInorderTraversal.java | 50 ++++++ BinaryTreeLevelOrderTraversal.java | 75 +++++++++ BinaryTreeLevelOrderTraversalII.java | 77 +++++++++ BinaryTreeLongestConsecutiveSequence.java | 62 +++++++ BinaryTreeMaximumPathSum.java | 54 ++++++ BinaryTreePaths.java | 55 +++++++ BinaryTreePostorderTraversal.java | 46 ++++++ BinaryTreePreorderTraversal.java | 59 +++++++ BinaryTreeRightSideView.java | 74 +++++++++ BinaryTreeTilt.java | 58 +++++++ BinaryTreeUpsideDown.java | 57 +++++++ BinaryTreeVerticalOrderTraversal.java | 107 ++++++++++++ BinaryTreeZigzagLevelOrderTraversal.java | 62 +++++++ BinaryWatch.java | 61 +++++++ BitwiseANDofNumbersRange.java | 36 ++++ BombEnemy.java | 70 ++++++++ BulbSwitcher.java | 39 +++++ BullsandCows.java | 48 ++++++ BurstBalloons.java | 76 +++++++++ CanPlaceFlowers.java | 46 ++++++ Candy.java | 60 +++++++ ClimbingStairs.java | 54 ++++++ CloneGraph.java | 70 ++++++++ ClosestBinarSearchTreeValue.java | 43 +++++ ClosestBinarySearchTreeValueII.java | 136 ++++++++++++++++ CoinChange.java | 53 ++++++ CombinationSum.java | 59 +++++++ CombinationSumII.java | 66 ++++++++ CombinationSumIII.java | 62 +++++++ CombinationSumIV.java | 75 +++++++++ Combinations.java | 58 +++++++ CompareVersionNumbers.java | 45 +++++ ...yTreefromInorderandPostorderTraversal.java | 52 ++++++ ...ryTreefromPreorderandInorderTraversal.java | 49 ++++++ ContainerWithMostWater.java | 31 ++++ ContainsDuplicate.java | 33 ++++ ContainsDuplicateII.java | 27 +++ ContainsDuplicateIII.java | 78 +++++++++ ConvertSortedArraytoBinarySearchTree.java | 35 ++++ ConvertSortedListtoBinarySearchTree.java | 40 +++++ ConvertaNumbertoHexadecimal.java | 32 ++++ CopyListwithRandomPointer.java | 90 ++++++++++ CountCompleteTreeNodes.java | 85 ++++++++++ CountNumberswithUniqueDigits.java | 26 +++ CountPrimes.java | 34 ++++ CountUnivalueSubtrees.java | 63 +++++++ CountandSay.java | 49 ++++++ CountingBits.java | 59 +++++++ CountofRangeSum.java | 134 +++++++++++++++ CountofSmallerNumbersAfterSelf.java | 66 ++++++++ CourseSchedule.java | 89 ++++++++++ CourseScheduleII.java | 89 ++++++++++ CreateMaximumNumber.java | 95 +++++++++++ DataStreamasDisjointIntervals.java | 55 +++++++ DecodeString.java | 60 +++++++ DecodeWays.java | 74 +++++++++ DeleteNodeInALinkedList.java | 23 +++ DesignHitCounter.java | 104 ++++++++++++ DesignPhoneDirectory.java | 83 ++++++++++ DesignSnakeGame.java | 70 ++++++++ DesignTicTacToe.java | 88 ++++++++++ DesignTwitter.java | 117 +++++++++++++ DiameterofBinaryTree.java | 48 ++++++ DifferentWaystoAddParentheses.java | 72 ++++++++ DistinctSubsequences.java | 69 ++++++++ DivideTwoIntegers.java | 52 ++++++ DungeonGame.java | 59 +++++++ EditDistance.java | 68 ++++++++ EliminationGame.java | 51 ++++++ EncodeandDecodeStrings.java | 45 +++++ EvaluateDivision.java | 98 +++++++++++ EvaluateReversePolishNotation.java | 48 ++++++ ExcelSheetColumnNumber.java | 39 +++++ ExcelSheetColumnTitle.java | 36 ++++ ExpressionAddOperators.java | 63 +++++++ FactorCombinations.java | 76 +++++++++ FactorialTrailingZeroes.java | 27 +++ FindAllAnagramsinaString.java | 69 ++++++++ FindAllDuplicatesinanArray.java | 46 ++++++ FindAllNumbersDisappearedinanArray.java | 52 ++++++ FindBottomLeftTreeValue.java | 84 ++++++++++ FindKPairswithSmallestSums.java | 84 ++++++++++ FindLeavesofBinaryTree.java | 70 ++++++++ FindMedianfromDataStream.java | 52 ++++++ FindMinimuminRotatedSortedArray.java | 42 +++++ FindMinimuminRotatedSortedArrayII.java | 41 +++++ FindPeakElement.java | 50 ++++++ FindtheCelebrity.java | 48 ++++++ FindtheDifference.java | 51 ++++++ FindtheDuplicateNumber.java | 63 +++++++ FirstBadVersion.java | 49 ++++++ FirstMissingPositive.java | 43 +++++ FirstUniqueCharacterinaString.java | 39 +++++ FizzBuzz.java | 60 +++++++ Flatten2DVector.java | 58 +++++++ FlattenBinaryTreetoLinkedList.java | 66 ++++++++ FlattenNestedListIterator.java | 64 ++++++++ FlipGame.java | 41 +++++ FlipGameII.java | 58 +++++++ FourSum.java | 50 ++++++ FourSumII.java | 64 ++++++++ FractiontoRecurringDecimal.java | 73 +++++++++ GameofLife.java | 62 +++++++ GasStation.java | 60 +++++++ GeneralizedAbbreviation.java | 45 +++++ GenerateParentheses.java | 55 +++++++ GraphValidTree.java | 99 +++++++++++ GrayCode.java | 43 +++++ GroupAnagrams.java | 79 +++++++++ GroupShiftedStrings.java | 69 ++++++++ GuessNumberHigherorLower.java | 55 +++++++ GuessNumberHigherorLowerII.java | 92 +++++++++++ HIndex.java | 47 ++++++ HIndexII.java | 35 ++++ HappyNumber.java | 46 ++++++ HouseRobber.java | 40 +++++ HouseRobberII.java | 33 ++++ HouseRobberIII.java | 45 +++++ ImplementQueueusingStacks.java | 97 +++++++++++ ImplementStackusingQueues.java | 47 ++++++ ImplementTrie.java | 60 +++++++ ImplementstrStr.java | 28 ++++ IncreasingSubsequences.java | 51 ++++++ IncreasingTripletSubsequence.java | 42 +++++ InorderSuccessorinBST.java | 47 ++++++ InsertDeleteGetRandom.java | 63 +++++++ InsertDeleteGetRandomDuplicatesallowed.java | 64 ++++++++ InsertInterval.java | 48 ++++++ InsertionSortList.java | 41 +++++ IntegerBreak.java | 43 +++++ IntegerReplacement.java | 87 ++++++++++ IntegertoEnglishWords.java | 52 ++++++ IntegertoRoman.java | 34 ++++ InterleavingString.java | 70 ++++++++ IntersectionofTwoArrays.java | 119 ++++++++++++++ IntersectionofTwoArraysII.java | 78 +++++++++ IntersectionofTwoLinkedLists.java | 90 ++++++++++ Interval.java | 22 +++ InvertBinaryTree.java | 61 +++++++ IsSubsequence.java | 40 +++++ IsomorphicStrings.java | 62 +++++++ JumpGame.java | 32 ++++ JumpGameII.java | 70 ++++++++ KthLargestElementinanArray.java | 91 +++++++++++ KthSmallestElementinaBST.java | 36 ++++ KthSmallestElementinaSortedMatrix.java | 87 ++++++++++ LRUCache.java | 130 +++++++++++++++ LargestBSTSubtree.java | 77 +++++++++ LargestDivisibleSubset.java | 88 ++++++++++ LargestNumber.java | 54 ++++++ LargestRectangleinHistogram.java | 59 +++++++ LengthofLastWord.java | 26 +++ LetterCombinationsofaPhoneNumber.java | 63 +++++++ LexicographicalNumbers.java | 46 ++++++ LineReflection.java | 62 +++++++ LinkedListCycle.java | 33 ++++ LinkedListCycleII.java | 41 +++++ LinkedListRandomNode.java | 42 +++++ ListNode.java | 15 ++ LoggerRateLimiter.java | 57 +++++++ LongestAbsoluteFilePath.java | 56 +++++++ LongestCommonPrefix.java | 29 ++++ LongestConsecutiveSequence.java | 53 ++++++ LongestIncreasingPathinaMatrix.java | 73 +++++++++ LongestIncreasingSubsequence.java | 61 +++++++ LongestPalindrome.java | 65 ++++++++ LongestPalindromicSubsequence.java | 51 ++++++ LongestPalindromicSubstring.java | 75 +++++++++ ...stSubstringWithoutRepeatingCharacters.java | 60 +++++++ ...stringwithAtLeastKRepeatingCharacters.java | 73 +++++++++ ...ubstringwithAtMostKDistinctCharacters.java | 43 +++++ ...stringwithAtMostTwoDistinctCharacters.java | 54 ++++++ LongestValidParentheses.java | 55 +++++++ LowestCommonAncestorofaBinarySearchTree.java | 30 ++++ LowestCommonAncestorofaBinaryTree.java | 33 ++++ MajorityElement.java | 68 ++++++++ MajorityElementII.java | 66 ++++++++ MaxConsecutiveOnes.java | 39 +++++ MaxPointsonaLine.java | 60 +++++++ MaxSumofRectangleNoLargerThanK.java | 98 +++++++++++ MaximalRectangle.java | 133 +++++++++++++++ MaximalSquare.java | 47 ++++++ MaximumDepthofBinaryTree.java | 31 ++++ MaximumGap.java | 63 +++++++ MaximumProductSubarray.java | 35 ++++ MaximumProductofThreeNumbers.java | 65 ++++++++ MaximumProductofWordLengths.java | 70 ++++++++ MaximumSizeSubarraySumEqualsk.java | 53 ++++++ MaximumSubarray.java | 46 ++++++ MedianofTwoSortedArrays.java | 107 ++++++++++++ MeetingRooms.java | 38 +++++ MeetingRoomsII.java | 68 ++++++++ MergeIntervals.java | 48 ++++++ MergeSortedArray.java | 33 ++++ MergeTwoBinaryTrees.java | 52 ++++++ MergeTwoSortedLists.java | 47 ++++++ MergekSortedLists.java | 69 ++++++++ MinStack.java | 125 ++++++++++++++ MiniParser.java | 85 ++++++++++ MinimumDepthofBinaryTree.java | 26 +++ MinimumHeightTrees.java | 78 +++++++++ MinimumMovestoEqualArrayElements.java | 63 +++++++ MinimumPathSum.java | 42 +++++ MinimumSizeSubarraySum.java | 38 +++++ MinimumWindowSubstring.java | 79 +++++++++ MissingNumber.java | 45 +++++ MissingRanges.java | 52 ++++++ MoveZeroes.java | 65 ++++++++ MovingAveragefromDataStream.java | 44 +++++ MultiplyStrings.java | 49 ++++++ NQueens.java | 79 +++++++++ NQueensII.java | 49 ++++++ NestedInteger.java | 56 +++++++ NestedListWeightSum.java | 95 +++++++++++ NestedListWeightSumII.java | 78 +++++++++ NextGreaterElementI.java | 69 ++++++++ NextPermutation.java | 73 +++++++++ NimGame.java | 38 +++++ NonoverlappingIntervals.java | 85 ++++++++++ NthDigit.java | 55 +++++++ Numberof1Bits.java | 48 ++++++ NumberofBoomerangs.java | 65 ++++++++ ...onnectedComponentsinanUndirectedGraph.java | 69 ++++++++ NumberofDigitOne.java | 48 ++++++ NumberofIslands.java | 122 ++++++++++++++ NumberofIslandsII.java | 97 +++++++++++ NumberofSegmentsinaString.java | 33 ++++ OddEvenLinkedList.java | 43 +++++ OneEditDistance.java | 39 +++++ PaintFence.java | 42 +++++ PaintHouse.java | 42 +++++ PaintHouseII.java | 59 +++++++ PalindromeLinkedList.java | 54 ++++++ PalindromeNumber.java | 30 ++++ PalindromePairs.java | 82 ++++++++++ PalindromePartitioning.java | 61 +++++++ PalindromePartitioningII.java | 51 ++++++ PalindromePermutation.java | 55 +++++++ PalindromePermutationII.java | 76 +++++++++ PalindromicSubstrings.java | 62 +++++++ PartitionEqualSubsetSum.java | 12 ++ PartitionList.java | 56 +++++++ PascalTriangle.java | 46 ++++++ PascalTriangleII.java | 44 +++++ PatchingArray.java | 74 +++++++++ PathSum.java | 60 +++++++ PathSumII.java | 51 ++++++ PathSumIII.java | 84 ++++++++++ PeekingIterator.java | 55 +++++++ PerfectRectangle.java | 55 +++++++ PerfectSquares.java | 39 +++++ PermutationSequence.java | 79 +++++++++ Permutations.java | 81 +++++++++ PermutationsII.java | 91 +++++++++++ PlusOne.java | 41 +++++ PlusOneLinkedList.java | 87 ++++++++++ Point.java | 22 +++ PopulatingNextRightPointersinEachNode.java | 61 +++++++ PopulatingNextRightPointersinEachNodeII.java | 57 +++++++ Pow.java | 59 +++++++ PowerofFour.java | 40 +++++ PowerofThree.java | 37 +++++ PowerofTwo.java | 31 ++++ ProductofArrayExceptSelf.java | 35 ++++ QueueReconstructionbyHeight.java | 28 ++++ RandomPickIndex.java | 56 +++++++ RangeAddition.java | 71 ++++++++ RangeSumQuery2DImmutable.java | 58 +++++++ RangeSumQuery2DMutable.java | 60 +++++++ RangeSumQueryImmutable.java | 47 ++++++ RangeSumQueryMutable.java | 94 +++++++++++ RansomNote.java | 38 +++++ ReadNCharactersGivenRead4.java | 64 ++++++++ ...ractersGivenRead4II_Callmultipletimes.java | 65 ++++++++ RearrangeStringkDistanceApart.java | 110 +++++++++++++ ReconstructItinerary.java | 91 +++++++++++ ReconstructOriginalDigitsfromEnglish.java | 68 ++++++++ RecoverBinarySearchTree.java | 80 +++++++++ RectangleArea.java | 44 +++++ RegularExpressionMatching.java | 90 ++++++++++ RemoveDuplicateLetters.java | 77 +++++++++ RemoveDuplicatesfromSortedArray.java | 40 +++++ RemoveDuplicatesfromSortedArrayII.java | 39 +++++ RemoveDuplicatesfromSortedList.java | 32 ++++ RemoveDuplicatesfromSortedListII.java | 37 +++++ RemoveElement.java | 49 ++++++ RemoveInvalidParentheses.java | 60 +++++++ RemoveLinkedListElements.java | 58 +++++++ RemoveNthNodeFromEndofList.java | 39 +++++ ReorderList.java | 65 ++++++++ RepeatedDNASequences.java | 46 ++++++ RestoreIPAddresses.java | 47 ++++++ ReverseBits.java | 34 ++++ ReverseInteger.java | 35 ++++ ReverseLinkedList.java | 28 ++++ ReverseLinkedListII.java | 47 ++++++ ReverseNodesinkGroup.java | 49 ++++++ ReverseString.java | 31 ++++ ReverseStringII.java | 43 +++++ ReverseVowelsofaString.java | 46 ++++++ ReverseWordsinaString.java | 69 ++++++++ ReverseWordsinaStringII.java | 40 +++++ ReverseWordsinaStringIII.java | 56 +++++++ RomantoInteger.java | 43 +++++ RotateArray.java | 59 +++++++ RotateFunction.java | 75 +++++++++ RotateImage.java | 55 +++++++ RotateList.java | 40 +++++ RussianDollEnvelopes.java | 72 ++++++++ SameTree.java | 29 ++++ ScrambleString.java | 44 +++++ SearchInsertPosition.java | 50 ++++++ Searcha2DMatrix.java | 56 +++++++ Searcha2DMatrixII.java | 56 +++++++ SearchforaRange.java | 70 ++++++++ SearchinRotatedSortedArray.java | 54 ++++++ SearchinRotatedSortedArrayII.java | 49 ++++++ SelfCrossing.java | 83 ++++++++++ SerializeandDeserializeBST.java | 68 ++++++++ SerializeandDeserializeBinaryTree.java | 70 ++++++++ SetMatrixZeroes.java | 67 ++++++++ ShortestDistancefromAllBuildings.java | 146 +++++++++++++++++ ShortestPalindrome.java | 52 ++++++ ShortestWordDistance.java | 67 ++++++++ ShortestWordDistanceII.java | 83 ++++++++++ ShortestWordDistanceIII.java | 54 ++++++ ShuffleanArray.java | 62 +++++++ SimplifyPath.java | 49 ++++++ SingleNumber.java | 33 ++++ SingleNumberII.java | 45 +++++ SingleNumberIII.java | 56 +++++++ SlidingWindowMaximum.java | 59 +++++++ SmallestRectangleEnclosingBlackPixels.java | 97 +++++++++++ SortColors.java | 45 +++++ SortList.java | 56 +++++++ SortTransformedArray.java | 70 ++++++++ SparseMatrixMultiplication.java | 53 ++++++ SpiralMatrix.java | 71 ++++++++ SpiralMatrixII.java | 65 ++++++++ Sqrt.java | 47 ++++++ StringCompression.java | 80 +++++++++ StringtoInteger.java | 42 +++++ StrobogrammaticNumber.java | 47 ++++++ StrobogrammaticNumberII.java | 55 +++++++ StrobogrammaticNumberIII.java | 61 +++++++ SubarraySumEqualsK.java | 58 +++++++ Subsets.java | 67 ++++++++ SubsetsII.java | 54 ++++++ SubstringwithConcatenationofAllWords.java | 64 ++++++++ SudokuSolver.java | 49 ++++++ SumRoottoLeafNumbers.java | 42 +++++ SummaryRanges.java | 47 ++++++ SumofLeftLeaves.java | 67 ++++++++ SumofTwoIntegers.java | 37 +++++ SuperPow.java | 64 ++++++++ SuperUglyNumber.java | 62 +++++++ SurroundedRegions.java | 154 ++++++++++++++++++ SwapNodesinPairs.java | 41 +++++ SymmetricTree.java | 37 +++++ TextJustification.java | 88 ++++++++++ TheSkylineProblem.java | 84 ++++++++++ ThirdMaximumNumber.java | 87 ++++++++++ ThreeSum.java | 56 +++++++ ThreeSumClosest.java | 43 +++++ ThreeSumSmaller.java | 50 ++++++ TopKFrequentElements.java | 105 ++++++++++++ TrappingRainWater.java | 51 ++++++ TreeLinkNode.java | 17 ++ TreeNode.java | 16 ++ Triangle.java | 52 ++++++ 1. Two Sum.java => TwoSum.java | 8 + TwoSumII.java | 48 ++++++ TwoSumIII_Datastructuredesign.java | 92 +++++++++++ TwoSumIVInputisaBST.java | 73 +++++++++ UTF8Validation.java | 96 +++++++++++ UglyNumber.java | 42 +++++ UglyNumberII.java | 32 ++++ UndirectedGraphNode.java | 23 +++ UniqueBinarySearchTrees.java | 48 ++++++ UniqueBinarySearchTreesII.java | 87 ++++++++++ UniquePaths.java | 61 +++++++ UniquePathsII.java | 51 ++++++ UniqueWordAbbreviation.java | 70 ++++++++ ValidAnagram.java | 52 ++++++ ValidNumber.java | 61 +++++++ ValidPalindrome.java | 47 ++++++ ValidParentheses.java | 48 ++++++ ValidPerfectSquare.java | 68 ++++++++ ValidSudoku.java | 63 +++++++ ValidateBinarySearchTree.java | 38 +++++ VerifyPreorderSequenceinBinarySearchTree.java | 51 ++++++ VerifyPreorderSerializationofaBinaryTree.java | 66 ++++++++ WallsandGates.java | 93 +++++++++++ WaterandJugProblem.java | 71 ++++++++ WiggleSort.java | 32 ++++ WiggleSortII.java | 126 ++++++++++++++ WiggleSubsequence.java | 75 +++++++++ WildcardMatching.java | 66 ++++++++ WordBreak.java | 51 ++++++ WordBreakII.java | 57 +++++++ WordLadder.java | 105 ++++++++++++ WordLadderII.java | 127 +++++++++++++++ WordPattern.java | 52 ++++++ WordPatternII.java | 71 ++++++++ WordSearch.java | 58 +++++++ WordSearchII.java | 87 ++++++++++ ZigZagConversion.java | 49 ++++++ ZigzagIterator.java | 86 ++++++++++ 433 files changed, 25600 insertions(+) create mode 100644 AAA.java create mode 100644 AddBinary.java create mode 100644 AddDigits.java create mode 100644 AddStrings.java create mode 100644 AddTwoNumbers.java create mode 100644 AddTwoNumbersII.java create mode 100644 AddandSearchWord.java create mode 100644 AdditiveNumber.java create mode 100644 AlienDictionary.java create mode 100644 AndroidUnlockPatterns.java create mode 100644 ArithmeticSlices.java create mode 100644 AssignCookies.java create mode 100644 AverageofLevelsinBinaryTree.java create mode 100644 BalancedBinaryTree.java create mode 100644 Base7.java create mode 100644 BasicCalculator.java create mode 100644 BasicCalculatorII.java create mode 100644 BattleshipsinaBoard.java create mode 100644 BestMeetingPoint.java create mode 100644 BestTimetoBuyandSellStock.java create mode 100644 BestTimetoBuyandSellStockII.java create mode 100644 BestTimetoBuyandSellStockIII.java create mode 100644 BestTimetoBuyandSellStockIV.java create mode 100644 BestTimetoBuyandSellStockwithCooldown.java create mode 100644 BinarySearchTreeIterator.java create mode 100644 BinaryTreeInorderTraversal.java create mode 100644 BinaryTreeLevelOrderTraversal.java create mode 100644 BinaryTreeLevelOrderTraversalII.java create mode 100644 BinaryTreeLongestConsecutiveSequence.java create mode 100644 BinaryTreeMaximumPathSum.java create mode 100644 BinaryTreePaths.java create mode 100644 BinaryTreePostorderTraversal.java create mode 100644 BinaryTreePreorderTraversal.java create mode 100644 BinaryTreeRightSideView.java create mode 100644 BinaryTreeTilt.java create mode 100644 BinaryTreeUpsideDown.java create mode 100644 BinaryTreeVerticalOrderTraversal.java create mode 100644 BinaryTreeZigzagLevelOrderTraversal.java create mode 100644 BinaryWatch.java create mode 100644 BitwiseANDofNumbersRange.java create mode 100644 BombEnemy.java create mode 100644 BulbSwitcher.java create mode 100644 BullsandCows.java create mode 100644 BurstBalloons.java create mode 100644 CanPlaceFlowers.java create mode 100644 Candy.java create mode 100644 ClimbingStairs.java create mode 100644 CloneGraph.java create mode 100644 ClosestBinarSearchTreeValue.java create mode 100644 ClosestBinarySearchTreeValueII.java create mode 100644 CoinChange.java create mode 100644 CombinationSum.java create mode 100644 CombinationSumII.java create mode 100644 CombinationSumIII.java create mode 100644 CombinationSumIV.java create mode 100644 Combinations.java create mode 100644 CompareVersionNumbers.java create mode 100644 ConstructBinaryTreefromInorderandPostorderTraversal.java create mode 100644 ConstructBinaryTreefromPreorderandInorderTraversal.java create mode 100644 ContainerWithMostWater.java create mode 100644 ContainsDuplicate.java create mode 100644 ContainsDuplicateII.java create mode 100644 ContainsDuplicateIII.java create mode 100644 ConvertSortedArraytoBinarySearchTree.java create mode 100644 ConvertSortedListtoBinarySearchTree.java create mode 100644 ConvertaNumbertoHexadecimal.java create mode 100644 CopyListwithRandomPointer.java create mode 100644 CountCompleteTreeNodes.java create mode 100644 CountNumberswithUniqueDigits.java create mode 100644 CountPrimes.java create mode 100644 CountUnivalueSubtrees.java create mode 100644 CountandSay.java create mode 100644 CountingBits.java create mode 100644 CountofRangeSum.java create mode 100644 CountofSmallerNumbersAfterSelf.java create mode 100644 CourseSchedule.java create mode 100644 CourseScheduleII.java create mode 100644 CreateMaximumNumber.java create mode 100644 DataStreamasDisjointIntervals.java create mode 100644 DecodeString.java create mode 100644 DecodeWays.java create mode 100644 DeleteNodeInALinkedList.java create mode 100644 DesignHitCounter.java create mode 100644 DesignPhoneDirectory.java create mode 100644 DesignSnakeGame.java create mode 100644 DesignTicTacToe.java create mode 100644 DesignTwitter.java create mode 100644 DiameterofBinaryTree.java create mode 100644 DifferentWaystoAddParentheses.java create mode 100644 DistinctSubsequences.java create mode 100644 DivideTwoIntegers.java create mode 100644 DungeonGame.java create mode 100644 EditDistance.java create mode 100644 EliminationGame.java create mode 100644 EncodeandDecodeStrings.java create mode 100644 EvaluateDivision.java create mode 100644 EvaluateReversePolishNotation.java create mode 100644 ExcelSheetColumnNumber.java create mode 100644 ExcelSheetColumnTitle.java create mode 100644 ExpressionAddOperators.java create mode 100644 FactorCombinations.java create mode 100644 FactorialTrailingZeroes.java create mode 100644 FindAllAnagramsinaString.java create mode 100644 FindAllDuplicatesinanArray.java create mode 100644 FindAllNumbersDisappearedinanArray.java create mode 100644 FindBottomLeftTreeValue.java create mode 100644 FindKPairswithSmallestSums.java create mode 100644 FindLeavesofBinaryTree.java create mode 100644 FindMedianfromDataStream.java create mode 100644 FindMinimuminRotatedSortedArray.java create mode 100644 FindMinimuminRotatedSortedArrayII.java create mode 100644 FindPeakElement.java create mode 100644 FindtheCelebrity.java create mode 100644 FindtheDifference.java create mode 100644 FindtheDuplicateNumber.java create mode 100644 FirstBadVersion.java create mode 100644 FirstMissingPositive.java create mode 100644 FirstUniqueCharacterinaString.java create mode 100644 FizzBuzz.java create mode 100644 Flatten2DVector.java create mode 100644 FlattenBinaryTreetoLinkedList.java create mode 100644 FlattenNestedListIterator.java create mode 100644 FlipGame.java create mode 100644 FlipGameII.java create mode 100644 FourSum.java create mode 100644 FourSumII.java create mode 100644 FractiontoRecurringDecimal.java create mode 100644 GameofLife.java create mode 100644 GasStation.java create mode 100644 GeneralizedAbbreviation.java create mode 100644 GenerateParentheses.java create mode 100644 GraphValidTree.java create mode 100644 GrayCode.java create mode 100644 GroupAnagrams.java create mode 100644 GroupShiftedStrings.java create mode 100644 GuessNumberHigherorLower.java create mode 100644 GuessNumberHigherorLowerII.java create mode 100644 HIndex.java create mode 100644 HIndexII.java create mode 100644 HappyNumber.java create mode 100644 HouseRobber.java create mode 100644 HouseRobberII.java create mode 100644 HouseRobberIII.java create mode 100644 ImplementQueueusingStacks.java create mode 100644 ImplementStackusingQueues.java create mode 100644 ImplementTrie.java create mode 100644 ImplementstrStr.java create mode 100644 IncreasingSubsequences.java create mode 100644 IncreasingTripletSubsequence.java create mode 100644 InorderSuccessorinBST.java create mode 100644 InsertDeleteGetRandom.java create mode 100644 InsertDeleteGetRandomDuplicatesallowed.java create mode 100644 InsertInterval.java create mode 100644 InsertionSortList.java create mode 100644 IntegerBreak.java create mode 100644 IntegerReplacement.java create mode 100644 IntegertoEnglishWords.java create mode 100644 IntegertoRoman.java create mode 100644 InterleavingString.java create mode 100644 IntersectionofTwoArrays.java create mode 100644 IntersectionofTwoArraysII.java create mode 100644 IntersectionofTwoLinkedLists.java create mode 100644 Interval.java create mode 100644 InvertBinaryTree.java create mode 100644 IsSubsequence.java create mode 100644 IsomorphicStrings.java create mode 100644 JumpGame.java create mode 100644 JumpGameII.java create mode 100644 KthLargestElementinanArray.java create mode 100644 KthSmallestElementinaBST.java create mode 100644 KthSmallestElementinaSortedMatrix.java create mode 100644 LRUCache.java create mode 100644 LargestBSTSubtree.java create mode 100644 LargestDivisibleSubset.java create mode 100644 LargestNumber.java create mode 100644 LargestRectangleinHistogram.java create mode 100644 LengthofLastWord.java create mode 100644 LetterCombinationsofaPhoneNumber.java create mode 100644 LexicographicalNumbers.java create mode 100644 LineReflection.java create mode 100644 LinkedListCycle.java create mode 100644 LinkedListCycleII.java create mode 100644 LinkedListRandomNode.java create mode 100644 ListNode.java create mode 100644 LoggerRateLimiter.java create mode 100644 LongestAbsoluteFilePath.java create mode 100644 LongestCommonPrefix.java create mode 100644 LongestConsecutiveSequence.java create mode 100644 LongestIncreasingPathinaMatrix.java create mode 100644 LongestIncreasingSubsequence.java create mode 100644 LongestPalindrome.java create mode 100644 LongestPalindromicSubsequence.java create mode 100644 LongestPalindromicSubstring.java create mode 100644 LongestSubstringWithoutRepeatingCharacters.java create mode 100644 LongestSubstringwithAtLeastKRepeatingCharacters.java create mode 100644 LongestSubstringwithAtMostKDistinctCharacters.java create mode 100644 LongestSubstringwithAtMostTwoDistinctCharacters.java create mode 100644 LongestValidParentheses.java create mode 100644 LowestCommonAncestorofaBinarySearchTree.java create mode 100644 LowestCommonAncestorofaBinaryTree.java create mode 100644 MajorityElement.java create mode 100644 MajorityElementII.java create mode 100644 MaxConsecutiveOnes.java create mode 100644 MaxPointsonaLine.java create mode 100644 MaxSumofRectangleNoLargerThanK.java create mode 100644 MaximalRectangle.java create mode 100644 MaximalSquare.java create mode 100644 MaximumDepthofBinaryTree.java create mode 100644 MaximumGap.java create mode 100644 MaximumProductSubarray.java create mode 100644 MaximumProductofThreeNumbers.java create mode 100644 MaximumProductofWordLengths.java create mode 100644 MaximumSizeSubarraySumEqualsk.java create mode 100644 MaximumSubarray.java create mode 100644 MedianofTwoSortedArrays.java create mode 100644 MeetingRooms.java create mode 100644 MeetingRoomsII.java create mode 100644 MergeIntervals.java create mode 100644 MergeSortedArray.java create mode 100644 MergeTwoBinaryTrees.java create mode 100644 MergeTwoSortedLists.java create mode 100644 MergekSortedLists.java create mode 100644 MinStack.java create mode 100644 MiniParser.java create mode 100644 MinimumDepthofBinaryTree.java create mode 100644 MinimumHeightTrees.java create mode 100644 MinimumMovestoEqualArrayElements.java create mode 100644 MinimumPathSum.java create mode 100644 MinimumSizeSubarraySum.java create mode 100644 MinimumWindowSubstring.java create mode 100644 MissingNumber.java create mode 100644 MissingRanges.java create mode 100644 MoveZeroes.java create mode 100644 MovingAveragefromDataStream.java create mode 100644 MultiplyStrings.java create mode 100644 NQueens.java create mode 100644 NQueensII.java create mode 100644 NestedInteger.java create mode 100644 NestedListWeightSum.java create mode 100644 NestedListWeightSumII.java create mode 100644 NextGreaterElementI.java create mode 100644 NextPermutation.java create mode 100644 NimGame.java create mode 100644 NonoverlappingIntervals.java create mode 100644 NthDigit.java create mode 100644 Numberof1Bits.java create mode 100644 NumberofBoomerangs.java create mode 100644 NumberofConnectedComponentsinanUndirectedGraph.java create mode 100644 NumberofDigitOne.java create mode 100644 NumberofIslands.java create mode 100644 NumberofIslandsII.java create mode 100644 NumberofSegmentsinaString.java create mode 100644 OddEvenLinkedList.java create mode 100644 OneEditDistance.java create mode 100644 PaintFence.java create mode 100644 PaintHouse.java create mode 100644 PaintHouseII.java create mode 100644 PalindromeLinkedList.java create mode 100644 PalindromeNumber.java create mode 100644 PalindromePairs.java create mode 100644 PalindromePartitioning.java create mode 100644 PalindromePartitioningII.java create mode 100644 PalindromePermutation.java create mode 100644 PalindromePermutationII.java create mode 100644 PalindromicSubstrings.java create mode 100644 PartitionEqualSubsetSum.java create mode 100644 PartitionList.java create mode 100644 PascalTriangle.java create mode 100644 PascalTriangleII.java create mode 100644 PatchingArray.java create mode 100644 PathSum.java create mode 100644 PathSumII.java create mode 100644 PathSumIII.java create mode 100644 PeekingIterator.java create mode 100644 PerfectRectangle.java create mode 100644 PerfectSquares.java create mode 100644 PermutationSequence.java create mode 100644 Permutations.java create mode 100644 PermutationsII.java create mode 100644 PlusOne.java create mode 100644 PlusOneLinkedList.java create mode 100644 Point.java create mode 100644 PopulatingNextRightPointersinEachNode.java create mode 100644 PopulatingNextRightPointersinEachNodeII.java create mode 100644 Pow.java create mode 100644 PowerofFour.java create mode 100644 PowerofThree.java create mode 100644 PowerofTwo.java create mode 100644 ProductofArrayExceptSelf.java create mode 100644 QueueReconstructionbyHeight.java create mode 100644 RandomPickIndex.java create mode 100644 RangeAddition.java create mode 100644 RangeSumQuery2DImmutable.java create mode 100644 RangeSumQuery2DMutable.java create mode 100644 RangeSumQueryImmutable.java create mode 100644 RangeSumQueryMutable.java create mode 100644 RansomNote.java create mode 100644 ReadNCharactersGivenRead4.java create mode 100644 ReadNCharactersGivenRead4II_Callmultipletimes.java create mode 100644 RearrangeStringkDistanceApart.java create mode 100644 ReconstructItinerary.java create mode 100644 ReconstructOriginalDigitsfromEnglish.java create mode 100644 RecoverBinarySearchTree.java create mode 100644 RectangleArea.java create mode 100644 RegularExpressionMatching.java create mode 100644 RemoveDuplicateLetters.java create mode 100644 RemoveDuplicatesfromSortedArray.java create mode 100644 RemoveDuplicatesfromSortedArrayII.java create mode 100644 RemoveDuplicatesfromSortedList.java create mode 100644 RemoveDuplicatesfromSortedListII.java create mode 100644 RemoveElement.java create mode 100644 RemoveInvalidParentheses.java create mode 100644 RemoveLinkedListElements.java create mode 100644 RemoveNthNodeFromEndofList.java create mode 100644 ReorderList.java create mode 100644 RepeatedDNASequences.java create mode 100644 RestoreIPAddresses.java create mode 100644 ReverseBits.java create mode 100644 ReverseInteger.java create mode 100644 ReverseLinkedList.java create mode 100644 ReverseLinkedListII.java create mode 100644 ReverseNodesinkGroup.java create mode 100644 ReverseString.java create mode 100644 ReverseStringII.java create mode 100644 ReverseVowelsofaString.java create mode 100644 ReverseWordsinaString.java create mode 100644 ReverseWordsinaStringII.java create mode 100644 ReverseWordsinaStringIII.java create mode 100644 RomantoInteger.java create mode 100644 RotateArray.java create mode 100644 RotateFunction.java create mode 100644 RotateImage.java create mode 100644 RotateList.java create mode 100644 RussianDollEnvelopes.java create mode 100644 SameTree.java create mode 100644 ScrambleString.java create mode 100644 SearchInsertPosition.java create mode 100644 Searcha2DMatrix.java create mode 100644 Searcha2DMatrixII.java create mode 100644 SearchforaRange.java create mode 100644 SearchinRotatedSortedArray.java create mode 100644 SearchinRotatedSortedArrayII.java create mode 100644 SelfCrossing.java create mode 100644 SerializeandDeserializeBST.java create mode 100644 SerializeandDeserializeBinaryTree.java create mode 100644 SetMatrixZeroes.java create mode 100644 ShortestDistancefromAllBuildings.java create mode 100644 ShortestPalindrome.java create mode 100644 ShortestWordDistance.java create mode 100644 ShortestWordDistanceII.java create mode 100644 ShortestWordDistanceIII.java create mode 100644 ShuffleanArray.java create mode 100644 SimplifyPath.java create mode 100644 SingleNumber.java create mode 100644 SingleNumberII.java create mode 100644 SingleNumberIII.java create mode 100644 SlidingWindowMaximum.java create mode 100644 SmallestRectangleEnclosingBlackPixels.java create mode 100644 SortColors.java create mode 100644 SortList.java create mode 100644 SortTransformedArray.java create mode 100644 SparseMatrixMultiplication.java create mode 100644 SpiralMatrix.java create mode 100644 SpiralMatrixII.java create mode 100644 Sqrt.java create mode 100644 StringCompression.java create mode 100644 StringtoInteger.java create mode 100644 StrobogrammaticNumber.java create mode 100644 StrobogrammaticNumberII.java create mode 100644 StrobogrammaticNumberIII.java create mode 100644 SubarraySumEqualsK.java create mode 100644 Subsets.java create mode 100644 SubsetsII.java create mode 100644 SubstringwithConcatenationofAllWords.java create mode 100644 SudokuSolver.java create mode 100644 SumRoottoLeafNumbers.java create mode 100644 SummaryRanges.java create mode 100644 SumofLeftLeaves.java create mode 100644 SumofTwoIntegers.java create mode 100644 SuperPow.java create mode 100644 SuperUglyNumber.java create mode 100644 SurroundedRegions.java create mode 100644 SwapNodesinPairs.java create mode 100644 SymmetricTree.java create mode 100644 TextJustification.java create mode 100644 TheSkylineProblem.java create mode 100644 ThirdMaximumNumber.java create mode 100644 ThreeSum.java create mode 100644 ThreeSumClosest.java create mode 100644 ThreeSumSmaller.java create mode 100644 TopKFrequentElements.java create mode 100644 TrappingRainWater.java create mode 100644 TreeLinkNode.java create mode 100644 TreeNode.java create mode 100644 Triangle.java rename 1. Two Sum.java => TwoSum.java (89%) create mode 100644 TwoSumII.java create mode 100644 TwoSumIII_Datastructuredesign.java create mode 100644 TwoSumIVInputisaBST.java create mode 100644 UTF8Validation.java create mode 100644 UglyNumber.java create mode 100644 UglyNumberII.java create mode 100644 UndirectedGraphNode.java create mode 100644 UniqueBinarySearchTrees.java create mode 100644 UniqueBinarySearchTreesII.java create mode 100644 UniquePaths.java create mode 100644 UniquePathsII.java create mode 100644 UniqueWordAbbreviation.java create mode 100644 ValidAnagram.java create mode 100644 ValidNumber.java create mode 100644 ValidPalindrome.java create mode 100644 ValidParentheses.java create mode 100644 ValidPerfectSquare.java create mode 100644 ValidSudoku.java create mode 100644 ValidateBinarySearchTree.java create mode 100644 VerifyPreorderSequenceinBinarySearchTree.java create mode 100644 VerifyPreorderSerializationofaBinaryTree.java create mode 100644 WallsandGates.java create mode 100644 WaterandJugProblem.java create mode 100644 WiggleSort.java create mode 100644 WiggleSortII.java create mode 100644 WiggleSubsequence.java create mode 100644 WildcardMatching.java create mode 100644 WordBreak.java create mode 100644 WordBreakII.java create mode 100644 WordLadder.java create mode 100644 WordLadderII.java create mode 100644 WordPattern.java create mode 100644 WordPatternII.java create mode 100644 WordSearch.java create mode 100644 WordSearchII.java create mode 100644 ZigZagConversion.java create mode 100644 ZigzagIterator.java diff --git a/AAA.java b/AAA.java new file mode 100644 index 0000000..6477327 --- /dev/null +++ b/AAA.java @@ -0,0 +1,23 @@ +package leetcode; + +import java.util.*; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : AAA + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class AAA { + + public static int helper(int a) { + a = 50; + return a; + } + + public static void main(String[] args) { + + } +} diff --git a/AddBinary.java b/AddBinary.java new file mode 100644 index 0000000..1d21748 --- /dev/null +++ b/AddBinary.java @@ -0,0 +1,39 @@ +package leetcode; + +/** + * Created by Edward on 28/07/2017. + */ +public class AddBinary { + /** + * 67. Add Binary + * Given two binary strings, return their sum (also a binary string). + + For example, + a = "11" + b = "1" + Return "100". + + time : O(n); + space : O(n); + * @param a + * @param b + * @return + */ + public static String addBinary(String a, String b) { + StringBuilder sb = new StringBuilder(); + int i = a.length() - 1; + int j = b.length() - 1; + int remainder = 0; + while (i >= 0 || j >= 0) { + int sum = remainder; + if (i >= 0) sum += a.charAt(i) - '0'; + if (j >= 0) sum += b.charAt(j) - '0'; + sb.append(sum % 2); + remainder = sum / 2; + } + if (remainder != 0) { + sb.append(remainder); + } + return sb.reverse().toString(); + } +} diff --git a/AddDigits.java b/AddDigits.java new file mode 100644 index 0000000..a72b44d --- /dev/null +++ b/AddDigits.java @@ -0,0 +1,58 @@ +package leetcode; + +/** + * Created by Edward on 25/07/2017. + */ +public class AddDigits { + /** + * 258. Add Digits + * Given a non-negative integer num, repeatedly add all its digits until the result has only one digit. + + For example: + + Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only one digit, return it. + + 1 1 + 2 2 + 3 3 + 4 4 + 5 5 + 6 6 + 7 7 + 8 8 + 9 9 + 10 1 + 11 2 + 12 3 + 13 4 + 14 5 + 15 6 + 16 7 + 17 8 + 18 9 + 19 1 + 20 2 + + time : O(1); + space : O(1): + * @param num + * @return + */ + + public static int addDigits1(int num) { + int sum = 0; + while (num != 0) { + sum += num % 10; + num /= 10; + } + if (sum > 10) { + return addDigits1(sum); + } else { + return sum; + } + } + + public static int addDigits2(int num) { + return (num - 1) % 9 + 1; + } +} diff --git a/AddStrings.java b/AddStrings.java new file mode 100644 index 0000000..35b65fa --- /dev/null +++ b/AddStrings.java @@ -0,0 +1,40 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : AddStrings + * Creator : Edward + * Date : Nov, 2017 + * Description : 415. Add Strings + */ +public class AddStrings { + /** + * Given two non-negative integers num1 and num2 represented as string, return the sum of num1 and num2. + + Note: + + The length of both num1 and num2 is < 5100. + Both num1 and num2 contains only digits 0-9. + Both num1 and num2 does not contain any leading zero. + You must not use any built-in BigInteger library or convert the inputs to integer directly. + + time : O(n + m) + space : O(n) + + */ + public String addStrings(String num1, String num2) { + int i = num1.length() - 1; + int j = num2.length() - 1; + int carry = 0; + StringBuilder sb = new StringBuilder(); + while (i >= 0 || j >= 0 || carry == 1) { + int a = i >= 0 ? num1.charAt(i--) - '0' : 0; + int b = j >= 0 ? num2.charAt(j--) - '0' : 0; + int sum = a + b + carry; + sb.append(sum % 10); + carry = sum / 10; + } + return sb.reverse().toString(); + } +} diff --git a/AddTwoNumbers.java b/AddTwoNumbers.java new file mode 100644 index 0000000..ef1bded --- /dev/null +++ b/AddTwoNumbers.java @@ -0,0 +1,47 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : AddTwoNumbers + * Creator : Edward + * Date : Sep, 2017 + * Description : 2. Add Two Numbers + */ +public class AddTwoNumbers { + /** + + Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) + Output: 7 -> 0 -> 8 + + time : O(n) + space : O(n) + + * @param l1 + * @param l2 + * @return + */ + public ListNode addTwoNumbers(ListNode l1, ListNode l2) { + ListNode dummy = new ListNode(0); + int sum = 0; + ListNode cur = dummy; + ListNode p1 = l1, p2 = l2; + while (p1 != null || p2 != null) { + if (p1 != null) { + sum += p1.val; + p1 = p1.next; + } + if (p2 != null) { + sum += p2.val; + p2 = p2.next; + } + cur.next = new ListNode(sum % 10); + sum /= 10; + cur = cur.next; + } + if (sum == 1) { + cur.next = new ListNode(1); + } + return dummy.next; + } +} diff --git a/AddTwoNumbersII.java b/AddTwoNumbersII.java new file mode 100644 index 0000000..6b9e5c6 --- /dev/null +++ b/AddTwoNumbersII.java @@ -0,0 +1,56 @@ +package leetcode; + +import java.util.List; +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : AddTwoNumbersII + * Creator : Edward + * Date : Sep, 2017 + * Description : 445. Add Two Numbers II + */ +public class AddTwoNumbersII { + /** + + Input: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4) + Output: 7 -> 8 -> 0 -> 7 + + time : O(n) + space : O(n) + + 解法1 : Stack + 解法2 : Reverse + + * @param l1 + * @param l2 + * @return + */ + public ListNode addTwoNumbers(ListNode l1, ListNode l2) { + Stack s1 = new Stack<>(); + Stack s2 = new Stack<>(); + + while (l1 != null) { + s1.push(l1.val); + l1 = l1.next; + } + while (l2 != null) { + s2.push(l2.val); + l2 = l2.next; + } + + ListNode cur = new ListNode(0); + int sum = 0; + while (!s1.isEmpty() || !s2.isEmpty()) { + if (!s1.isEmpty()) sum += s1.pop(); + if (!s2.isEmpty()) sum += s2.pop(); + cur.val = sum % 10; + ListNode head = new ListNode(sum / 10); + head.next = cur; + cur = head; + sum /= 10; + } + return cur.val == 0 ? cur.next : cur; + } +} diff --git a/AddandSearchWord.java b/AddandSearchWord.java new file mode 100644 index 0000000..f325f46 --- /dev/null +++ b/AddandSearchWord.java @@ -0,0 +1,85 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : AddandSearchWord + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +class TrieNode { + + TrieNode[] children; + boolean isWord; + String word; + + public TrieNode() { + children = new TrieNode[26]; + isWord = false; + word = ""; + } +} +public class AddandSearchWord { + /** + * 211. Add and Search Word - Data structure design + * Design a data structure that supports the following two operations: + + void addWord(word) + bool search(word) + search(word) can search a literal word or a regular expression string containing only letters a-z or .. A . means it can represent any one letter. + + For example: + + addWord("bad") + addWord("dad") + addWord("mad") + search("pad") -> false + search("bad") -> true + search(".ad") -> true + search("b..") -> true + + */ + private TrieNode root; + + + /** Initialize your data structure here. */ + public AddandSearchWord() { + root = new TrieNode(); + } + + /** Adds a word into the data structure. */ + // time : O(n) n: word.length(); + // O(num of TrieNode * 26) = O(num of Words * word.length() * 26) + public void addWord(String word) { + TrieNode node = root; + for (int i = 0; i < word.length(); i++) { + int j = word.charAt(i) - 'a'; + if (node.children[j] == null) { + node.children[j] = new TrieNode(); + } + node = node.children[j]; + } + node.isWord = true; + node.word = word; + } + + /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ + public boolean search(String word) { + return find(word, root, 0); + } + + public boolean find(String word, TrieNode node, int index) { + if (index == word.length()) return node.isWord;//!node.word.equals(""); + if (word.charAt(index) == '.') { + for (TrieNode temp : node.children) { + if (temp != null && find(word, temp, index + 1)) return true; + } + return false; + } else { + int j = word.charAt(index) - 'a'; + TrieNode temp = node.children[j]; + return temp != null && find(word, temp, index + 1); + } + } +} diff --git a/AdditiveNumber.java b/AdditiveNumber.java new file mode 100644 index 0000000..6d40183 --- /dev/null +++ b/AdditiveNumber.java @@ -0,0 +1,71 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : AdditiveNumber + * Creator : Edward + * Date : Jan, 2018 + * Description : 306. Additive Number + */ +public class AdditiveNumber { + /** + * 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. + + For example: + "112358" is an additive number because the digits can form an additive sequence: 1, 1, 2, 3, 5, 8. + + 1 + 1 = 2, 1 + 2 = 3, 2 + 3 = 5, 3 + 5 = 8 + "199100199" is also an additive number, the additive sequence is: 1, 99, 100, 199. + 1 + 99 = 100, 99 + 100 = 199 + Note: Numbers in the additive sequence cannot have leading zeros, + so sequence 1, 2, 03 or 1, 02, 3 is invalid. + + Given a string containing only digits '0'-'9', write a function to determine if it's an additive number. + + 第一个数的范围: (n-1)/2 + 第二个数的范围: n-j>=i && n-j>=j-i + + 1 1 2 3 5 8 + + 1 99 100 199 + + x1 = 100 + x2 = 199 + sum = 199 + + time : O(n^2)不确定 + space : O(1) + + * @param num + * @return + */ + public boolean isAdditiveNumber(String num) { + for (int i = 1; i <= num.length() / 2; i++) { + for (int j = 1; Math.max(i, j) <= num.length() - i - j; j++) { + if (isValid(i, j, num)) return true; + } + } + return false; + } + + private boolean isValid(int i, int j, String num) { + if (num.charAt(0) == '0' && i > 1) return false; + if (num.charAt(i) == '0' && j > 1) return false; + String sum = ""; + Long x1 = Long.parseLong(num.substring(0, i)); + Long x2 = Long.parseLong(num.substring(i, i + j)); + for (int start = i + j; start != num.length(); start += sum.length()) { + x2 = x2 + x1; + x1 = x2 - x1; + sum = x2.toString(); + if (!num.startsWith(sum, start)) { + return false; + } + } + return true; + } +} diff --git a/AlienDictionary.java b/AlienDictionary.java new file mode 100644 index 0000000..ded9c39 --- /dev/null +++ b/AlienDictionary.java @@ -0,0 +1,126 @@ +package leetcode; + +import java.util.*; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : AlienDictionary + * Creator : Edward + * Date : Dec, 2017 + * Description : 269. Alien Dictionary + */ +public class AlienDictionary { + /** + * There is a new alien language which uses the latin alphabet. + * However, the order among letters are unknown to you. You receive a list of non-empty words from the dictionary, + * where words are sorted lexicographically by the rules of this new language. Derive the order of letters + * in this language. + + Example 1: + Given the following words in dictionary, + + [ + "wrt", + "wrf", + "er", + "ett", + "rftt" + ] + The correct order is: "wertf". + + Example 2: + Given the following words in dictionary, + + [ + "z", + "x" + ] + The correct order is: "zx". + + Example 3: + Given the following words in dictionary, + + [ + "z", + "x", + "z" + ] + The order is invalid, so return "". + + 图 -> 入度为0 -> BFS + + count = 5 + + degree : + w : 1 + e : 1 + r : 1 + t : 1 + f : 2 + + time : (V + E) -> O(n * words(max)) + space : O(n) -> O(26) -> O(1) + + * @param words + * @return + */ + public static String alienOrder(String[] words) { + + if (words == null || words.length == 0) return ""; + + StringBuilder res = new StringBuilder(); + HashMap> map = new HashMap<>(); + int[] degree = new int[26]; + int count = 0; + + for (String word : words) { + for (char c : word.toCharArray()) { + if (degree[c - 'a'] == 0) { + count++; + degree[c - 'a'] = 1; + } + } + } + + for (int i = 0; i < words.length - 1; i++) { + char[] cur = words[i].toCharArray(); + char[] next = words[i + 1].toCharArray(); + int len = Math.min(cur.length, next.length); + for (int j = 0; j < len; j++) { + if (cur[j] != next[j]) { + if (!map.containsKey(cur[j])) { + map.put(cur[j], new HashSet<>()); + } + if (map.get(cur[j]).add(next[j])) { + degree[next[j] - 'a']++; + } + break; + } + } + } + + Queue queue = new LinkedList<>(); + for (int i = 0; i < 26; i++) { + if (degree[i] == 1) { + queue.offer((char)('a' + i)); + } + } + + while (!queue.isEmpty()) { + char c = queue.poll(); + res.append(c); + if (map.containsKey(c)) { + for (char ch : map.get(c)) { + if (--degree[ch - 'a'] == 1) { + queue.offer(ch); + } + } + } + } + + if (res.length() != count) return ""; + return res.toString(); + } + +} diff --git a/AndroidUnlockPatterns.java b/AndroidUnlockPatterns.java new file mode 100644 index 0000000..2cc2112 --- /dev/null +++ b/AndroidUnlockPatterns.java @@ -0,0 +1,50 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : AndroidUnlockPatterns + * Creator : Edward + * Date : Oct, 2017 + * Description : 351. Android Unlock Patterns + */ +public class AndroidUnlockPatterns { + /** + * time : 不知道 + * space : 不知道 + * @param m + * @param n + * @return + */ + + public int numberOfPatterns(int m, int n) { + int[][] skip = new int[10][10]; + skip[1][3] = skip[3][1] = 2; + skip[1][7] = skip[7][1] = 4; + skip[3][9] = skip[9][3] = 6; + skip[7][9] = skip[9][7] = 8; + skip[1][9] = skip[9][1] = skip[2][8] = skip[8][2] = skip[3][7] = skip[7][3] = skip[4][6] = skip[6][4] = 5; + boolean[] visited = new boolean[10]; + int res = 0; + for (int i = m; i <= n; i++) { + res += DFS(visited, skip, 1, i - 1) * 4; // 1, 3, 7, 9 + res += DFS(visited, skip, 2, i - 1) * 4; // 2, 4, 6, 8 + res += DFS(visited, skip, 5, i - 1); // 5 + } + return res; + } + + public int DFS(boolean[] visited, int[][] skip, int cur, int remain) { + if (remain < 0) return 0; + if (remain == 0) return 1; + visited[cur] = true; + int res = 0; + for (int i = 1; i <= 9; i++) { + if (!visited[i] && (skip[cur][i] == 0 || visited[skip[cur][i]])) { + res += DFS(visited, skip, i, remain - 1); + } + } + visited[cur] = false; + return res; + } +} diff --git a/ArithmeticSlices.java b/ArithmeticSlices.java new file mode 100644 index 0000000..871b0f1 --- /dev/null +++ b/ArithmeticSlices.java @@ -0,0 +1,45 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ArithmeticSlices + * Creator : Edward + * Date : Nov, 2017 + * Description : 413. Arithmetic Slices + */ +public class ArithmeticSlices { + /** + * Example: + + A = [1, 2, 3, 4] + + return: 3, for 3 arithmetic slices in A: [1, 2, 3], [2, 3, 4] and [1, 2, 3, 4] itself. + + 数组 等差数列的数目 与上一数组的等差数列数目比较 + 1 2 3 1 1 - 0 = 1 + 1 2 3 4 3 3 - 1 = 2 + 1 2 3 4 5 6 6 - 3 = 3 + 1 2 3 4 5 6 10 10 - 6 = 4 + 1 2 3 4 5 6 7 15 15 - 10 = 5 + + time : O(n) + space : O(1) + + * @param A + * @return + */ + + public int numberOfArithmeticSlices(int[] A) { + int cur = 0, res = 0; + for (int i = 2; i < A.length; i++) { + if (A[i] - A[i - 1] == A[i - 1] - A[i - 2]) { + cur++; + res += cur; + } else { + cur = 0; + } + } + return res; + } +} diff --git a/AssignCookies.java b/AssignCookies.java new file mode 100644 index 0000000..5bb5dcc --- /dev/null +++ b/AssignCookies.java @@ -0,0 +1,52 @@ +package leetcode; + +import java.util.Arrays; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : AssignCookies + * Creator : Edward + * Date : Nov, 2017 + * Description : 455. Assign Cookies + */ +public class AssignCookies { + /** + * Example 1: + Input: [1,2,3], [1,1] + + Output: 1 + + Explanation: You have 3 children and 2 cookies. The greed factors of 3 children are 1, 2, 3. + And even though you have 2 cookies, since their size is both 1, you could only make the child whose greed factor is 1 content. + You need to output 1. + Example 2: + Input: [1,2], [1,2,3] + + Output: 2 + + Explanation: You have 2 children and 3 cookies. The greed factors of 2 children are 1, 2. + You have 3 cookies and their sizes are big enough to gratify all of the children, + You need to output 2. + + time : O(nlogn) + space : O(1) + + */ + public int findContentChildren(int[] g, int[] s) { + int res = 0; + Arrays.sort(g); + Arrays.sort(s); + int i = 0, j = 0; + while (i < g.length && j < s.length) { + if (g[i] <= s[j]) { + res++; + i++; + j++; + } else if (g[i] > s[j]) { + j++; + } + } + return res; + } +} diff --git a/AverageofLevelsinBinaryTree.java b/AverageofLevelsinBinaryTree.java new file mode 100644 index 0000000..5614987 --- /dev/null +++ b/AverageofLevelsinBinaryTree.java @@ -0,0 +1,56 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : AverageofLevelsinBinaryTree + * Creator : Edward + * Date : Aug, 2017 + * Description : 637. Average of Levels in Binary Tree + */ +public class AverageofLevelsinBinaryTree { + + /** + + Example 1: + Input: + 3 + / \ + 9 20 + / \ + 15 7 + Output: [3, 14.5, 11] + Explanation: + The average value of nodes on level 0 is 3, on level 1 is 14.5, and on level 2 is 11. + Hence return [3, 14.5, 11]. + + time : O(n) + space : O(n) + + * @param root + * @return + */ + public List averageOfLevels(TreeNode root) { + List res = new ArrayList<>(); + if (root == null) return res; + Queue queue = new LinkedList<>(); + queue.offer(root); + while (!queue.isEmpty()) { + int size = queue.size(); + double sum = 0; + for (int i = 0; i < size; i++) { + TreeNode cur = queue.poll(); + sum += cur.val; + if (cur.left != null) queue.offer(cur.left); + if (cur.right != null) queue.offer(cur.right); + } + res.add(sum / size); + } + return res; + } +} diff --git a/BalancedBinaryTree.java b/BalancedBinaryTree.java new file mode 100644 index 0000000..016d261 --- /dev/null +++ b/BalancedBinaryTree.java @@ -0,0 +1,53 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BalancedBinaryTree + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class BalancedBinaryTree { + + /** + * 110. Balanced Binary Tree + * Given a binary tree, determine if it is height-balanced. + + For this problem, a height-balanced binary tree is defined as a binary tree + in which the depth of the two subtrees of every node never differ by more than 1. + 1 -- 3 + / \ + 2 3 -- 1 + / \ + 4 5 -- 1 + + 1 + / \ + 2 3 2 --> 3 3 --> 1 + / \ + 4 5 -- 2 + \ + 9 -- 1 + + time : O(n); + space : O(n); + * @param root + * @return + */ + + public boolean isBalanced(TreeNode root) { + if (root == null) return true; + return helper(root) != -1; + } + + public int helper(TreeNode root) { + if (root == null) return 0; + int l = helper(root.left); + int r = helper(root.right); + if (l == -1 || r == -1 || Math.abs(l - r) > 1) { + return -1; + } + return Math.max(l, r) + 1; + } +} diff --git a/Base7.java b/Base7.java new file mode 100644 index 0000000..a0c3046 --- /dev/null +++ b/Base7.java @@ -0,0 +1,55 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : Base7 + * Creator : Edward + * Date : Nov, 2017 + * Description : 504. Base 7 + */ +public class Base7 { + /** + * Given an integer, return its base 7 string representation. + + Example 1: + Input: 100 + Output: "202" + Example 2: + Input: -7 + Output: "-10" + + time : O(n) + space : O(n) + + */ + + public String convertToBase7(int num) { + if (num == 0) return "0"; + + StringBuilder sb = new StringBuilder(); + boolean negative = false; + + if (num < 0) { + negative = true; + } + while (num != 0) { + sb.append(Math.abs(num % 7)); + num = num / 7; + } + if (negative) { + sb.append("-"); + } + return sb.reverse().toString(); + } + + public String convertToBase72(int num) { + if (num < 0) { + return "-" + convertToBase72(-num); + } + if (num < 7) { + return num + ""; + } + return convertToBase72(num / 7) + num % 7; + } +} diff --git a/BasicCalculator.java b/BasicCalculator.java new file mode 100644 index 0000000..726f26c --- /dev/null +++ b/BasicCalculator.java @@ -0,0 +1,53 @@ +package leetcode; + +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BasicCalculator + * Creator : Edward + * Date : Sep, 2017 + * Description : 224. Basic Calculator + */ +public class BasicCalculator { + /** + + "1 + 1" = 2 + " 2-1 + 2 " = 3 + "(1+(4+5+2)-3)+(6+8)" = 23 + + time : O(n) + space : O(n) + + * @param s + * @return + */ + public int calculate(String s) { + Stack stack = new Stack<>(); + int sign = 1; + int res = 0; + for (int i = 0; i < s.length(); i++) { + if (Character.isDigit(s.charAt(i))) { + int num = s.charAt(i) - '0'; + while (i + 1 < s.length() && Character.isDigit(s.charAt(i + 1))) { + num = num * 10 + s.charAt(i + 1) - '0'; + i++; + } + res += num * sign; + } else if (s.charAt(i) == '+') { + sign = 1; + } else if (s.charAt(i) == '-') { + sign = -1; + } else if (s.charAt(i) == '(') { + stack.push(res); + stack.push(sign); + res = 0; + sign = 1; + } else if (s.charAt(i) == ')') { + res = res * stack.pop() + stack.pop(); + } + } + return res; + } +} diff --git a/BasicCalculatorII.java b/BasicCalculatorII.java new file mode 100644 index 0000000..1e82f19 --- /dev/null +++ b/BasicCalculatorII.java @@ -0,0 +1,88 @@ +package leetcode; + +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BasicCalculatorII + * Creator : Edward + * Date : Sep, 2017 + * Description : 227. Basic Calculator II + */ +public class BasicCalculatorII { + /** + * + "3+2*2" = 7 + " 3/2 " = 1 + " 3+5 / 2 " = 5 + + 3*2+4-5/2 + + * @param s + * @return + */ + //time : O(n) space : O(n) + public int calculate(String s) { + if (s == null || s.length() == 0) return 0; + Stack stack = new Stack<>(); + int res = 0; + char sign = '+'; + int num = 0; + for (int i = 0; i < s.length(); i++) { + if (Character.isDigit(s.charAt(i))) { + num = s.charAt(i) - '0'; + while (i + 1 < s.length() && Character.isDigit(s.charAt(i + 1))) { + num = num * 10 + s.charAt(i + 1) - '0'; + i++; + } + } + if (!Character.isDigit(s.charAt(i)) && s.charAt(i) != ' ' || i == s.length() - 1) { + if (sign == '+') stack.push(num); + if (sign == '-') stack.push(-num); + if (sign == '*') stack.push(stack.pop() * num); + if (sign == '/') stack.push(stack.pop() / num); + sign = s.charAt(i); + num = 0; + } + } + for (int i : stack) { + res += i; + } + return res; + } + + // time : O(n) space : O(1) + public int calculate2(String s) { + if (s == null || s.length() == 0) return 0; + s = s.trim().replaceAll(" +", ""); + int res = 0; + int preVal = 0; + int i = 0; + char sign = '+'; + while (i < s.length()) { + int curVal = 0; + while (i < s.length() && Character.isDigit(s.charAt(i))) { + curVal = curVal * 10 + s.charAt(i) - '0'; + i++; + } + if (sign == '+') { + res += preVal; + preVal = curVal; + } else if (sign == '-') { + res += preVal; + preVal = -curVal; + } else if (sign == '*') { + preVal = preVal * curVal; + } else if (sign == '/') { + preVal = preVal / curVal; + } + if (i < s.length()) { + sign = s.charAt(i); + i++; + } + } + res += preVal; + return res; + } +} diff --git a/BattleshipsinaBoard.java b/BattleshipsinaBoard.java new file mode 100644 index 0000000..b95014c --- /dev/null +++ b/BattleshipsinaBoard.java @@ -0,0 +1,48 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BattleshipsinaBoard + * Creator : Edward + * Date : Nov, 2017 + * Description : 419. Battleships in a Board + */ +public class BattleshipsinaBoard { + /** + * Given an 2D board, count how many battleships are in it. The battleships are represented with 'X's, empty slots are represented with '.'s. You may assume the following rules: + + You receive a valid board, made of only battleships or empty slots. + Battleships can only be placed horizontally or vertically. In other words, they can only be made of the shape 1xN (1 row, N columns) or Nx1 (N rows, 1 column), where N can be of any size. + At least one horizontal or vertical cell separates between two battleships - there are no adjacent battleships. + Example: + X..X + ...X + ...X + In the above board there are 2 battleships. + + Invalid Example: + ...X + XXXX + ...X + This is an invalid board that you will not receive - as battleships will always have a cell separating between them. + + time : O(m * n) + space : O(1) + + * @param board + * @return + */ + public int countBattleships(char[][] board) { + int res = 0; + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + if (board[i][j] == '.') continue; + if (i > 0 && board[i - 1][j] == 'X') continue; + if (j > 0 && board[i][j - 1] == 'X') continue; + res++; + } + } + return res; + } +} diff --git a/BestMeetingPoint.java b/BestMeetingPoint.java new file mode 100644 index 0000000..d051b62 --- /dev/null +++ b/BestMeetingPoint.java @@ -0,0 +1,76 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BestMeetingPoint + * Creator : Edward + * Date : Dec, 2017 + * Description : 296. Best Meeting Point + */ +public class BestMeetingPoint { + + /** + * 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|. + + For example, given three people living at (0,0), (0,4), and (2,2): + + 1 - 0 - 0 - 0 - 1 + | | | | | + 0 - 0 - 0 - 0 - 0 + | | | | | + 0 - 0 - 1 - 0 - 0 + The point (0,2) is an ideal meeting point, as the total travel distance of 2+2+2=6 is minimal. So return 6. + + A C E D B + ------------------------ + + time : O(m * n) + space : O(n) + + + * @param grid + * @return + */ + + public int minTotalDistance(int[][] grid) { + int m = grid.length; + int n = grid[0].length; + + List I = new ArrayList<>(); + List J = new ArrayList<>(); + + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (grid[i][j] == 1) { + I.add(i); + } + } + } + + for (int j = 0; j < n; j++) { + for (int i = 0; i < m; i++) { + if (grid[i][j] == 1) { + J.add(j); + } + } + } + + return min(I) + min(J); + } + + private int min(List list) { + int i = 0, j = list.size(); + int sum = 0; + while (i < j) { + sum += list.get(j--) - list.get(i++); + } + return sum; + } +} diff --git a/BestTimetoBuyandSellStock.java b/BestTimetoBuyandSellStock.java new file mode 100644 index 0000000..4935291 --- /dev/null +++ b/BestTimetoBuyandSellStock.java @@ -0,0 +1,34 @@ +package leetcode; + +/** + * Created by Edward on 28/07/2017. + */ +public class BestTimetoBuyandSellStock { + /** + * 121. Best Time to Buy and Sell Stock + * Say you have an array for which the ith element is the price of a given stock on day i. + + If you were only permitted to complete at most one transaction (ie, + buy one and sell one share of the stock), design an algorithm to find the maximum profit. + Input: [7, 1, 5, 3, 6, 4] + Output: 5 + + max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price) + + time : O(n); + space : O(1); + + * @param prices + * @return + */ + public static int maxProfit(int[] prices) { + if (prices == null || prices.length < 2) return 0; + int min = prices[0]; + int profit = 0; + for (int price : prices) { + min = Math.min(min, price); + profit = Math.max(profit, price - min); + } + return profit; + } +} diff --git a/BestTimetoBuyandSellStockII.java b/BestTimetoBuyandSellStockII.java new file mode 100644 index 0000000..8d85990 --- /dev/null +++ b/BestTimetoBuyandSellStockII.java @@ -0,0 +1,33 @@ +package leetcode; + +/** + * Created by Edward on 28/07/2017. + */ +public class BestTimetoBuyandSellStockII { + /** + * 122. Best Time to Buy and Sell Stock II + * Say you have an array for which the ith element is the price of a given stock on day i. + + Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, + you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again). + + case : [5, 1, 2, 3, 4] + + time : O(n); + space : O(1); + * @param prices + * @return + */ + public static int maxProfit(int[] prices) { + if (prices == null || prices.length < 2) { + return 0; + } + int profit = 0; + for (int i = 1; i < prices.length; i++) { + if (prices[i] > prices[i - 1]) { + profit += prices[i] - prices[i - 1]; + } + } + return profit; + } +} diff --git a/BestTimetoBuyandSellStockIII.java b/BestTimetoBuyandSellStockIII.java new file mode 100644 index 0000000..c25f002 --- /dev/null +++ b/BestTimetoBuyandSellStockIII.java @@ -0,0 +1,31 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BestTimetoBuyandSellStockIII + * Creator : Edward + * Date : Nov, 2017 + * Description : 123. Best Time to Buy and Sell Stock III + */ +public class BestTimetoBuyandSellStockIII { + + /** + * time : O(n) + * space : O(1) + * @param prices + * @return + */ + + public int maxProfit(int[] prices) { + int buy1 = Integer.MIN_VALUE, buy2 = Integer.MIN_VALUE; + int sell1 = 0, sell2 = 0; + for (int price : prices) { + sell2 = Math.max(sell2, buy2 + price); + buy2 = Math.max(buy2, sell1 - price); + sell1 = Math.max(sell1, buy1 + price); + buy1 = Math.max(buy1, -price); + } + return sell2; + } +} diff --git a/BestTimetoBuyandSellStockIV.java b/BestTimetoBuyandSellStockIV.java new file mode 100644 index 0000000..55a8106 --- /dev/null +++ b/BestTimetoBuyandSellStockIV.java @@ -0,0 +1,55 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BestTimetoBuyandSellStockIV + * Creator : Edward + * Date : Dec, 2017 + * Description : 188. Best Time to Buy and Sell Stock IV + */ +public class BestTimetoBuyandSellStockIV { + /** + * Say you have an array for which the ith element is the price of a given stock on day i. + + Design an algorithm to find the maximum profit. You may complete at most k transactions. + + + dp[i, j] 当前到达第j天可以最多进行i次交易,最大的利润是多少 + tmpMax means the maximum profit of just doing at most i-1 transactions, using at most first j-1 prices, + and buying the stock at price[j] - this is used for the next loop. + + + time : O(k * n) + space : O(k * n) + + * @param k + * @param prices + * @return + */ + public int maxProfit(int k, int[] prices) { + int len = prices.length; + if (k >= len / 2) return helper(prices); + + int[][] dp = new int[k + 1][len]; + for (int i = 1; i <= k; i++) { + int tmpMax = -prices[0]; + for (int j = 1; j < len; j++) { + dp[i][j] = Math.max(dp[i][j - 1], prices[j] + tmpMax); + tmpMax = Math.max(tmpMax, dp[i - 1][j - 1] - prices[j]); + } + } + return dp[k][len - 1]; + } + + public int helper(int[] prices) { + int len = prices.length; + int res = 0; + for (int i = 1; i < len; i++) { + if (prices[i] > prices[i - 1]) { + res += prices[i] - prices[i - 1]; + } + } + return res; + } +} diff --git a/BestTimetoBuyandSellStockwithCooldown.java b/BestTimetoBuyandSellStockwithCooldown.java new file mode 100644 index 0000000..01a4098 --- /dev/null +++ b/BestTimetoBuyandSellStockwithCooldown.java @@ -0,0 +1,50 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BestTimetoBuyandSellStockwithCooldown + * Creator : Edward + * Date : Oct, 2017 + * Description : 309. Best Time to Buy and Sell Stock with Cooldown + */ +public class BestTimetoBuyandSellStockwithCooldown { + /** + * buy[i]表示在第i天之前最后一个操作是买,此时的最大收益。 + + sell[i]表示在第i天之前最后一个操作是卖,此时的最大收益。 + + rest[i]表示在第i天之前最后一个操作是冷冻期,此时的最大收益。 + + 我们写出递推式为: + + buy[i] = max(rest[i-1] - price, buy[i-1]) + sell[i] = max(buy[i-1] + price, sell[i-1]) + rest[i] = max(sell[i-1], buy[i-1], rest[i-1]) + + 上述递推式很好的表示了在买之前有冷冻期,买之前要卖掉之前的股票。一个小技巧是如何保证[buy, rest, buy]的情况不会出现, + 这是由于buy[i] <= rest[i], 即rest[i] = max(sell[i-1], rest[i-1]),这保证了[buy, rest, buy]不会出现。 + + 另外,由于冷冻期的存在,我们可以得出rest[i] = sell[i-1],这样,我们可以将上面三个递推式精简到两个: + + buy[i] = max(sell[i-2] - price, buy[i-1]) + sell[i] = max(buy[i-1] + price, sell[i-1]) + + time : O(n) + space : O(1) + + * @param prices + * @return + */ + public int maxProfit(int[] prices) { + int sell = 0, prevSell = 0; + int buy = Integer.MIN_VALUE, prevBuy = 0; + for (int price : prices) { + prevBuy = buy; + buy = Math.max(prevSell - price, prevBuy); + prevSell = sell; + sell = Math.max(prevBuy + price, prevSell); + } + return sell; + } +} diff --git a/BinarySearchTreeIterator.java b/BinarySearchTreeIterator.java new file mode 100644 index 0000000..9d4d3b8 --- /dev/null +++ b/BinarySearchTreeIterator.java @@ -0,0 +1,46 @@ +package leetcode; + +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BinarySearchTreeIterator + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class BinarySearchTreeIterator { + /** + * 173. Binary Search Tree Iterator + * + * time : O(n) + * @param root + */ + + private TreeNode cur; + private Stack stack; + + public BinarySearchTreeIterator(TreeNode root) { + cur = root; + stack = new Stack<>(); + } + + /** @return whether we have a next smallest number */ + public boolean hasNext() { + if (!stack.isEmpty() || cur != null) return true; + return false; + } + + /** @return the next smallest number */ + public int next() { + while (cur != null) { + stack.push(cur); + cur = cur.left; + } + cur = stack.pop(); + int val = cur.val; + cur = cur.right; + return val; + } +} diff --git a/BinaryTreeInorderTraversal.java b/BinaryTreeInorderTraversal.java new file mode 100644 index 0000000..f8db0d2 --- /dev/null +++ b/BinaryTreeInorderTraversal.java @@ -0,0 +1,50 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** + * Created by Edward on 25/07/2017. + */ +public class BinaryTreeInorderTraversal { + /** + * 94. Binary Tree Inorder Traversal + * Given a binary tree, return the inorder traversal of its nodes' values. + * time : O(n) + * space : O(n) + * @param root + * @return + */ + + public static List inorderTraversal(TreeNode root) { + List res = new ArrayList<>(); + if (root == null) return res; + helper(res, root); + return res; + } + + public static void helper(List res, TreeNode root) { + if (root == null) return; + helper(res, root.left); + res.add(root.val); + helper(res, root.right); + } + + public static List inorderTraversal2(TreeNode root) { + List res = new ArrayList<>(); + if (root == null) return res; + Stack stack = new Stack<>(); + TreeNode cur = root; + while (cur != null || !stack.isEmpty()) { + while (cur != null) { + stack.push(cur); + cur = cur.left; + } + cur = stack.pop(); + res.add(cur.val); + cur = cur.right; + } + return res; + } +} diff --git a/BinaryTreeLevelOrderTraversal.java b/BinaryTreeLevelOrderTraversal.java new file mode 100644 index 0000000..ec1b031 --- /dev/null +++ b/BinaryTreeLevelOrderTraversal.java @@ -0,0 +1,75 @@ +package leetcode; + +import org.omg.PortableServer.LIFESPAN_POLICY_ID; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * Created by Edward on 24/07/2017. + */ +public class BinaryTreeLevelOrderTraversal { + + /** + * 102. Binary Tree Level Order Traversal + * Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). + + For example: + Given binary tree [3,9,20,null,null,15,7], + 3 + / \ + 9 20 + / \ + 15 7 + [ + [3], + [9,20], + [15,7] + ] + time : O(n); + space : O(n); + * @param root + * @return + */ + + public static List> levelOrder(TreeNode root) { + + List> res = new ArrayList<>(); + if (root == null) return res; + + Queue queue = new LinkedList<>(); + queue.offer(root); + while (!queue.isEmpty()) { + int size = queue.size(); + List list = new ArrayList<>(); + for (int i = 0; i < size; i++) { + TreeNode cur = queue.poll(); + if (cur.left != null) queue.offer(cur.left); + if (cur.right != null) queue.offer(cur.right); + list.add(cur.val); + } + res.add(list); + } + + return res; + } + + public static List> levelOrder2(TreeNode root) { + List> res = new ArrayList<>(); + if (root == null) return res; + helper(res, root, 0); + return res; + } + + public static void helper(List> res, TreeNode root, int level) { + if (root == null) return; + if (level >= res.size()) { + res.add(new ArrayList<>()); + } + res.get(level).add(root.val); + helper(res, root.left, level + 1); + helper(res, root.right, level + 1); + } +} diff --git a/BinaryTreeLevelOrderTraversalII.java b/BinaryTreeLevelOrderTraversalII.java new file mode 100644 index 0000000..30556c1 --- /dev/null +++ b/BinaryTreeLevelOrderTraversalII.java @@ -0,0 +1,77 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BinaryTreeLevelOrderTreaversalII + * Creator : Edward + * Date : Sep, 2017 + * Description : 107. Binary Tree Level Order Traversal II (102 follow up) + */ +public class BinaryTreeLevelOrderTraversalII { + + /** + * + For example: + Given binary tree [3,9,20,null,null,15,7], + 3 + / \ + 9 20 + / \ + 15 7 + [ + [15,7], + [9,20], + [3] + ] + + time : O(n) + space : O(n) + + * @param root + * @return + */ + + public static List> levelOrderBottom(TreeNode root) { + List> res = new ArrayList<>(); + if (root == null) return res; + Queue queue = new LinkedList<>(); + queue.offer(root); + while (!queue.isEmpty()) { + int size = queue.size(); + List list = new ArrayList<>(); + for (int i = 0; i < size; i++) { + TreeNode cur = queue.poll(); + if (cur.left != null) queue.offer(cur.left); + if (cur.right != null) queue.offer(cur.right); + list.add(cur.val); + } + res.add(0, list); + } + return res; + } + + public static List> levelOrderBottom2(TreeNode root) { + List> res = new ArrayList<>(); + if (root == null) return res; + helper(res, root, 0); + return res; + } + + public static void helper(List> res, TreeNode root, int level) { + if (root == null) return; + if (level >= res.size()) { + res.add(0, new ArrayList<>()); + } + res.get(res.size() - level - 1).add(root.val); + helper(res, root.left, level + 1); + helper(res, root.right, level + 1); + + } + +} diff --git a/BinaryTreeLongestConsecutiveSequence.java b/BinaryTreeLongestConsecutiveSequence.java new file mode 100644 index 0000000..00adeee --- /dev/null +++ b/BinaryTreeLongestConsecutiveSequence.java @@ -0,0 +1,62 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BinaryTreeLongestConsecutiveSequence + * Creator : Edward + * Date : Aug, 2017 + * Description : 298. Binary Tree Longest Consecutive Sequence + */ +public class BinaryTreeLongestConsecutiveSequence { + + /** + * Given a binary tree, find the length of the longest consecutive sequence path. + + The path refers to any sequence of nodes from some starting node to any node + in the tree along the parent-child connections. The longest consecutive path need to + be from parent to child (cannot be the reverse). + + For example, + 1 + \ + 3 + / \ + 2 4 + \ + 5 + Longest consecutive sequence path is 3-4-5, so return 3. + 2 + \ + 3 + / + 2 + / + 1 + Longest consecutive sequence path is 2-3,not3-2-1, so return 2. + + time : O(n); + space : O(n); + * @param root + * @return + */ + + private int res = 0; + + public int longestConsecutive(TreeNode root) { + if (root == null) return 0; + helper(root, 0, root.val); + return res; + } + + public void helper(TreeNode root, int max, int target) { + if (root == null) return; + if (root.val == target) { + max++; + } else max = 1; + res = Math.max(res, max); + helper(root.left, max, root.val + 1); + helper(root.right, max, root.val + 1); + } + +} diff --git a/BinaryTreeMaximumPathSum.java b/BinaryTreeMaximumPathSum.java new file mode 100644 index 0000000..529f10c --- /dev/null +++ b/BinaryTreeMaximumPathSum.java @@ -0,0 +1,54 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BinaryTreeMaximumPathSum + * Creator : Edward + * Date : Nov, 2017 + * Description : 124. Binary Tree Maximum Path Sum + */ +public class BinaryTreeMaximumPathSum { + /** + * Given a binary tree, find the maximum path sum. + + For this problem, a path is defined as any sequence of nodes from some starting node to any node + in the tree along the parent-child connections. The path must contain at least one node and does not + need to go through the root. + + For example: + Given the below binary tree, + + 1 + / \ + 2 3 + Return 6. + + 3 + / \ + 9 20 + / \ + 15 7 + + + time : O(n) + space : O(n) + + */ + + int res; + + public int maxPathSum(TreeNode root) { + if (root == null) return 0; + res = Integer.MIN_VALUE; + helper(root); + return res; + } + public int helper(TreeNode root) { + if (root == null) return 0; + int left = Math.max(0, helper(root.left)); + int right = Math.max(0, helper(root.right)); + res = Math.max(res, left + right + root.val); + return Math.max(left, right) + root.val; + } +} diff --git a/BinaryTreePaths.java b/BinaryTreePaths.java new file mode 100644 index 0000000..571d48f --- /dev/null +++ b/BinaryTreePaths.java @@ -0,0 +1,55 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Edward on 25/07/2017. + */ +public class BinaryTreePaths { + /** + * 257. Binary Tree Paths + * Given a binary tree, return all root-to-leaf paths. + + For example, given the following binary tree: + 3 + / \ + 9 20 + / \ + 15 7 + ["3->9->15", "3->9->7", "3->20] + + case : + 3 + / \ + 9 20 + / \ + 15 7 + 3->9->15 + 3->9->7 + 3->20 + ["3->9->15", "3->9->7", "3->20] + + time : O(n); + space : O(n); + * @param root + * @return + */ + public static List binaryTreePaths(TreeNode root) { + List res = new ArrayList<>(); + if (root == null) return res; + helper(res, root, ""); + return res; + } + public static void helper(List res, TreeNode root, String path) { + if (root.left == null && root.right == null) { + res.add(path + root.val); + } + if (root.left != null) { + helper(res, root.left, path + root.val + "->"); + } + if (root.right != null) { + helper(res, root.right, path + root.val + "->"); + } + } +} diff --git a/BinaryTreePostorderTraversal.java b/BinaryTreePostorderTraversal.java new file mode 100644 index 0000000..5dd806c --- /dev/null +++ b/BinaryTreePostorderTraversal.java @@ -0,0 +1,46 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Stack; + +/** + * Created by Edward on 28/07/2017. + */ +public class BinaryTreePostorderTraversal { + /** + * 145. Binary Tree Postorder Traversal + * + * time : O(n); + * space : O(n); + * @param root + * @return + */ + public static List postorderTraversal(TreeNode root) { + List res = new ArrayList<>(); + if (root == null) return res; + helper(res, root); + return res; + } + public static void helper(List res, TreeNode root) { + if (root == null) return; + helper(res, root.left); + helper(res, root.right); + res.add(root.val); + } + + public static List postorderTraversal2(TreeNode root) { + LinkedList res = new LinkedList<>(); + if (root == null) return res; + Stack stack = new Stack<>(); + stack.push(root); + while (!stack.isEmpty()) { + TreeNode cur = stack.pop(); + res.addFirst(cur.val); + if (cur.left != null) stack.push(cur.left); + if (cur.right != null) stack.push(cur.right); + } + return res; + } +} diff --git a/BinaryTreePreorderTraversal.java b/BinaryTreePreorderTraversal.java new file mode 100644 index 0000000..a3d750e --- /dev/null +++ b/BinaryTreePreorderTraversal.java @@ -0,0 +1,59 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** + * Created by Edward on 25/07/2017. + */ +public class BinaryTreePreorderTraversal { + + /** + * 144. Binary Tree Preorder Traversal + * Given a binary tree, return the preorder traversal of its nodes' values. + + For example: + Given binary tree {1,#,2,3}, + 1 + \ + 2 + / + 3 + return [1,2,3]. + queue : 3, 2, 1 + stack : 1, 2, 3 + time : O(n); + space : O(n); + * @param root + * @return + */ + + public static List preorderTraversal(TreeNode root) { + List res = new ArrayList<>(); + if (root == null) return res; + helper(res, root); + return res; + } + + public static void helper(List res, TreeNode root) { + if (root == null) return; + res.add(root.val); + helper(res, root.left); + helper(res, root.right); + } + + public static List preorderTraversal2(TreeNode root) { + List res = new ArrayList<>(); + if (root == null) return res; + Stack stack = new Stack<>(); + stack.push(root); + while (!stack.isEmpty()) { + TreeNode cur = stack.pop(); + if (cur.right != null) stack.push(cur.right); + if (cur.left != null) stack.push(cur.left); + res.add(cur.val); + } + return res; + } +} diff --git a/BinaryTreeRightSideView.java b/BinaryTreeRightSideView.java new file mode 100644 index 0000000..9e62ee0 --- /dev/null +++ b/BinaryTreeRightSideView.java @@ -0,0 +1,74 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BinaryTreeRightSideView + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class BinaryTreeRightSideView { + + /** + * 199. Binary Tree Right Side View + * given a binary tree, imagine yourself standing on the right side of it, + * return the values of the nodes you can see ordered from top to bottom. + + For example: + Given the following binary tree, + 1 <--- + / \ + 2 3 <--- + \ \ + 5 4 <--- + You should return [1, 3, 4]. + + root 1 res : 0 level : 1 + + res : 1, 3, 4 + + time : O(n); + time ; O(n); + * @param root + * @return + */ + + public List rightSideView(TreeNode root) { + List res = new ArrayList<>(); + if (root == null) return res; + helper(res, root, 0); + return res; + } + + private void helper(List res, TreeNode root, int level) { + if (root == null) return; + if (res.size() == level) { + res.add(root.val); + } + helper(res, root.right, level + 1); + helper(res, root.left, level + 1); + } + + public List rightSideView2(TreeNode root) { + List res = new ArrayList<>(); + if (root == null) return res; + Queue queue = new LinkedList<>(); + queue.offer(root); + while (!queue.isEmpty()) { + int size = queue.size(); + for (int i = 0; i < size; i++) { + TreeNode cur = queue.poll(); + if (i == 0) res.add(cur.val); + if (cur.right != null) queue.offer(cur.right); + if (cur.left != null) queue.offer(cur.left); + } + } + return res; + } +} diff --git a/BinaryTreeTilt.java b/BinaryTreeTilt.java new file mode 100644 index 0000000..2e63097 --- /dev/null +++ b/BinaryTreeTilt.java @@ -0,0 +1,58 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BinaryTreeTilt + * Creator : Edward + * Date : Oct, 2017 + * Description : 563. Binary Tree Tilt + */ +public class BinaryTreeTilt { + /** + * Given a binary tree, return the tilt of the whole tree. + + The tilt of a tree node is defined as the absolute difference between the sum of all + left subtree node values and the sum of all right subtree node values. Null node has tilt 0. + + The tilt of the whole tree is defined as the sum of all nodes' tilt. + + Example: + Input: + 1 + / \ + 2 3 + / \ / \ + 4 5 6 7 + Output: 1 + Explanation: + Tilt of node 4 : 0 + Tilt of node 5 : 0 + Tilt of node 6 : 0 + Tilt of node 7 : 0 + Tilt of node 2 : |5-4| = 1 + Tilt of node 3 : |7-6| = 1 + Tilt of node 1 : |2+4+5-3-6-7| = 5 + Tilt of binary tree : 1 + 1 + 5 = 7 + + time : O(n) + space : O(n) + + * @param root + * @return + */ + int res = 0; + + public int findTilt(TreeNode root) { + helper(root); + return res; + } + + public int helper(TreeNode root) { + if (root == null) return 0; + int left = helper(root.left); + int right = helper(root.right); + res += Math.abs(left - right); + return left + right + root.val; + } +} diff --git a/BinaryTreeUpsideDown.java b/BinaryTreeUpsideDown.java new file mode 100644 index 0000000..7dbb2f4 --- /dev/null +++ b/BinaryTreeUpsideDown.java @@ -0,0 +1,57 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BinaryTreeUpsideDown + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class BinaryTreeUpsideDown { + /** + * 156. Binary Tree Upside Down + * Given a binary tree where all the right nodes are either leaf nodes with a + * sibling (a left node that shares the same parent node) or empty, + * flip it upside down and turn it into a tree where the original right nodes + * turned into left leaf nodes. Return the new root. + + For example: + Given a binary tree {1,2,3,4,5}, + 1 + / \ + 2 3 + / \ + 4 5 + return the root of the binary tree [4,5,2,#,#,3,1]. + 4 + / \ + 5 2 + / \ + 3 1 + + 1 1 + / \ / + 2 3 2 - 3 + / \ / + 4 5 4 - 5 + + time : O(n); + space : O(n); + * @param root + * @return + */ + public TreeNode upsideDownBinaryTree(TreeNode root) { + if (root == null || root.left == null && root.right == null) { + return root; + } + TreeNode newRoot = upsideDownBinaryTree(root.left); + root.left.left = root.right; + root.left.right = root; + + root.left = null; + root.right = null; + return newRoot; + } + +} diff --git a/BinaryTreeVerticalOrderTraversal.java b/BinaryTreeVerticalOrderTraversal.java new file mode 100644 index 0000000..7caf66c --- /dev/null +++ b/BinaryTreeVerticalOrderTraversal.java @@ -0,0 +1,107 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BinaryTreeVerticalOrderTraversal + * Creator : Edward + * Date : Jan, 2018 + * Description : 314. Binary Tree Vertical Order Traversal + */ +public class BinaryTreeVerticalOrderTraversal { + /** + *Given a binary tree, return the vertical order traversal of its nodes' values. (ie, from top to bottom, column by column). + + If two nodes are in the same row and column, the order should be from left to right. + + Examples: + + Given binary tree [3,9,20,null,null,15,7], + 3 + / \ + 9 20 + / \ + 15 7 + + | + . _ * _ * _ 0 _ . _ * + -2 -1 0 1 2 3 + + return its vertical order traversal as: + [ + [9], + [3,15], + [20], + [7] + ] + Given binary tree [3,9,8,4,0,1,7], + 3 + / \ + 9 8 + / \ / \ + 4 0 1 7 + -2 0 2 + + return its vertical order traversal as: + [ + [4], + [9], + [3,0,1], + [8], + [7] + ] + + 1, dfs max min + 2, bfs + + time : O(n) + space : O(n) + + + */ + private int min = 0; + private int max = 0; + + public List> verticalOrder(TreeNode root) { + List> res = new ArrayList<>(); + if (root == null) { + return res; + } + helper(root, 0); + for (int i = min; i <= max; i++) { + res.add(new ArrayList<>()); + } + + Queue queue = new LinkedList<>(); + Queue index = new LinkedList<>(); + index.offer(-min); + queue.offer(root); + while (!queue.isEmpty()) { + TreeNode cur = queue.poll(); + int idx = index.poll(); + res.get(idx).add(cur.val); + if (cur.left != null) { + queue.offer(cur.left); + index.offer(idx - 1); + } + if (cur.right != null) { + queue.offer(cur.right); + index.offer(idx + 1); + } + } + return res; + } + + private void helper(TreeNode root, int idx) { + if (root == null) return; + min = Math.min(min, idx); + max = Math.max(max, idx); + helper(root.left, idx - 1); + helper(root.right, idx + 1); + } +} diff --git a/BinaryTreeZigzagLevelOrderTraversal.java b/BinaryTreeZigzagLevelOrderTraversal.java new file mode 100644 index 0000000..df48172 --- /dev/null +++ b/BinaryTreeZigzagLevelOrderTraversal.java @@ -0,0 +1,62 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * Created by Edward on 28/07/2017. + */ +public class BinaryTreeZigzagLevelOrderTraversal { + /** + * 103. Binary Tree Zigzag Level Order Traversal + * Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). + + For example: + Given binary tree [3,9,20,null,null,15,7], + 3 + / \ + 9 20 + / \ + 15 7 + [ + [3], + [20,9], + [15,7] + ] + time : O(n) + space : O(n); + * @param root + * @return + */ + + public static List> zigzagLevelOrder(TreeNode root) { + List> res = new ArrayList<>(); + if (root == null) return res; + Queue queue = new LinkedList<>(); + queue.offer(root); + boolean x = true; + while (!queue.isEmpty()) { + int size = queue.size(); + List list = new ArrayList<>(); + for (int i = 0; i < size; i++) { + TreeNode cur = queue.poll(); + if (x) { + list.add(cur.val); + } else { + list.add(0, cur.val); + } + if (cur.left != null) { + queue.offer(cur.left); + } + if (cur.right != null) { + queue.offer(cur.right); + } + } + res.add(list); + x = x ? false : true; + } + return res; + } +} diff --git a/BinaryWatch.java b/BinaryWatch.java new file mode 100644 index 0000000..f5b919d --- /dev/null +++ b/BinaryWatch.java @@ -0,0 +1,61 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BinaryWatch + * Creator : Edward + * Date : Nov, 2017 + * Description : 401. Binary Watch + */ +public class BinaryWatch { + + /** + * num = 5 + * [8, 4, 2, 1] count = 2 + * + * time : 不知道 + * space : O(n) + * + * @param num + * @return + */ + + public List readBinaryWatch(int num) { + List res = new ArrayList<>(); + int[] nums1 = new int[]{8, 4, 2, 1}; + int[] nums2 = new int[]{32, 16, 8, 4, 2, 1}; + for (int i = 0; i <= num; i++) { + List list1 = generateDigit(nums1, i); + List list2 = generateDigit(nums2, num - i); + for (int num1 : list1) { + if (num1 >= 12) continue; + for (int num2 : list2) { + if (num2 >= 60) continue; + res.add(num1 + ":" + (num2 < 10 ? "0" + num2 : num2)); + } + } + } + return res; + } + + private List generateDigit(int[] nums, int count) { + List res = new ArrayList<>(); + helper(res, nums, count, 0, 0); + return res; + } + + private void helper(List res, int[] nums, int count, int start, int sum) { + if (count == 0) { + res.add(sum); + return; + } + for (int i = start; i < nums.length; i++) { + helper(res, nums, count - 1, i + 1, sum + nums[i]); + } + } + +} diff --git a/BitwiseANDofNumbersRange.java b/BitwiseANDofNumbersRange.java new file mode 100644 index 0000000..7faf18a --- /dev/null +++ b/BitwiseANDofNumbersRange.java @@ -0,0 +1,36 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BitwiseANDofNumbersRange + * Creator : Edward + * Date : Dec, 2017 + * Description : 201. Bitwise AND of Numbers Range + */ +public class BitwiseANDofNumbersRange { + + /** + * Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers in this range, inclusive. + + For example, given the range [5, 7], you should return 4. + + time : < O(n) ~ O(1) + space : O(1) + + + * @param m + * @param n + * @return + */ + + public int rangeBitwiseAnd(int m, int n) { + int offset = 0; + while (m != n) { + m >>= 1; + n >>= 1; + offset++; + } + return m << offset; + } +} diff --git a/BombEnemy.java b/BombEnemy.java new file mode 100644 index 0000000..32c07c5 --- /dev/null +++ b/BombEnemy.java @@ -0,0 +1,70 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BombEnemy + * Creator : Edward + * Date : Jan, 2018 + * Description : 361. Bomb Enemy + */ +public class BombEnemy { + /** + * Given a 2D grid, each cell is either a wall 'W', an enemy 'E' or empty '0' (the number zero), + * return the maximum enemies you can kill using one bomb. + The bomb kills all the enemies in the same row and column from the planted point until it hits the wall + since the wall is too strong to be destroyed. + Note that you can only put the bomb at an empty cell. + + Example: + For the given grid + + 0 E 0 0 + E 0 W E + 0 E 0 0 + + return 3. (Placing a bomb at (1,1) kills 3 enemies) + + for(i) + for(j) { + j + } + + 1,遍历 + 2,扫描当前行 :i 不变 j rowCount + 3,扫描当前列 :j 不变 i (colCount[]) + + time : O(m * n) + space : O(n) + + * @param grid + * @return + */ + public int maxKilledEnemies(char[][] grid) { + if (grid == null || grid.length == 0 || grid[0].length == 0) return 0; + int m = grid.length, n = grid[0].length; + int rowCount = 0; + int[] colCount = new int[n]; + int res = 0; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (j == 0 || grid[i][j - 1] == 'W') { + rowCount = 0; + for (int k = j; k < n && grid[i][k] != 'W'; k++) { + rowCount += grid[i][k] == 'E' ? 1 : 0; + } + } + if (i == 0 || grid[i - 1][j] == 'W') { + colCount[j] = 0; + for (int k = i; k < m && grid[k][j] != 'W'; k++) { + colCount[j] += grid[k][j] == 'E' ? 1 : 0; + } + } + if (grid[i][j] == '0') { + res = Math.max(res, colCount[j] + rowCount); + } + } + } + return res; + } +} diff --git a/BulbSwitcher.java b/BulbSwitcher.java new file mode 100644 index 0000000..4626dcd --- /dev/null +++ b/BulbSwitcher.java @@ -0,0 +1,39 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BulbSwitcher + * Creator : Edward + * Date : Dec, 2017 + * Description : 319. Bulb Switcher + */ +public class BulbSwitcher { + /** + * There are n bulbs that are initially off. You first turn on all the bulbs. + * Then, you turn off every second bulb. On the third round, you toggle every third bulb + * (turning on if it's off or turning off if it's on). For the ith round, you toggle every i bulb. For the nth round, + * you only toggle the last bulb. Find how many bulbs are on after n rounds. + + Example: + + Given n = 3. + + At first, the three bulbs are [off, off, off]. + After first round, the three bulbs are [on, on, on]. + After second round, the three bulbs are [on, off, on]. + After third round, the three bulbs are [on, off, off]. + + So you should return 1, because there is only one bulb is on. + + time : O(1) + space : O(1) + + + * @param n + * @return + */ + public int bulbSwitch(int n) { + return (int)Math.sqrt(n); + } +} diff --git a/BullsandCows.java b/BullsandCows.java new file mode 100644 index 0000000..49bac4b --- /dev/null +++ b/BullsandCows.java @@ -0,0 +1,48 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BullsandCows + * Creator : Edward + * Date : Dec, 2017 + * Description : 299. Bulls and Cows + */ +public class BullsandCows { + /** + * For example: + + Secret number: "1807" + Friend's guess: "7810" + Hint: 1 bull and 3 cows. (The bull is 8, the cows are 0, 1 and 7.) + Write a function to return a hint according to the secret number and friend's guess, + use A to indicate the bulls and B to indicate the cows. In the above example, your function should return "1A3B". + + Secret number: "1123" + Friend's guess: "0111" + In this case, the 1st 1 in friend's guess is a bull, the 2nd or 3rd 1 is a cow, and your function should return "1A1B". + + time : O(n) + space : O(1) + + + * @param secret + * @param guess + * @return + */ + + public String getHint(String secret, String guess) { + int bulls = 0; + int cows = 0; + int[] count = new int[10]; + for (int i = 0; i < secret.length(); i++) { + if (secret.charAt(i) == guess.charAt(i)) { + bulls++; + } else { + if (count[secret.charAt(i) - '0']++ < 0) cows++; + if (count[guess.charAt(i) - '0']-- > 0) cows++; + } + } + return bulls + "A" + cows + "B"; + } +} diff --git a/BurstBalloons.java b/BurstBalloons.java new file mode 100644 index 0000000..719fb3a --- /dev/null +++ b/BurstBalloons.java @@ -0,0 +1,76 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : BurstBalloons + * Creator : Edward + * Date : Jan, 2018 + * Description : 312. Burst Balloons + */ +public class BurstBalloons { + /** + * Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on + * it represented by array nums. You are asked to burst all the balloons. + * If the you burst balloon i you will get nums[left] * nums[i] * nums[right] coins. + * Here left and right are adjacent indices of i. After the burst, + * the left and right then becomes adjacent. + + Find the maximum coins you can collect by bursting the balloons wisely. + + Note: + (1) You may imagine nums[-1] =å nums[n] = 1. They are not real therefore you can not burst them. + (2) 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100 + + Example: + + Given [3, 1, 5, 8] + + Return 167 + + nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> [] + coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167 + i j + 1 3 1 5 8 1 + 3 1 8 + 1 5 1 + + dp[i][j]为打破的气球为i~j之间 + dp[i][j] = max(dp[i][j], dp[i][x – 1] + nums[i – 1] * nums[x] * nums[j + 1] + dp[x + 1][j]); + + 1 for + 2 dfs + memo + + time : O(n^3) + space : O(n^2) + + [3, 1, 5, 8] + 1 3 1 5 8 + + * @param nums + * @return + */ + + public int maxCoins(int[] nums) { + int n = nums.length; + int[] arr = new int[n + 2]; + for (int i = 0; i < n; i++) { + arr[i + 1] = nums[i]; + } + arr[0] = arr[n + 1] = 1; + int[][] dp = new int[n + 2][n + 2]; + return helper(1, n, arr, dp); + } + + private int helper(int i, int j, int[] nums, int[][] dp) { + if (i > j) return 0; + if (dp[i][j] > 0) return dp[i][j]; + for (int x = i; x <= j; x++) { + dp[i][j] = Math.max(dp[i][j], helper(i, x - 1, nums, dp) + + nums[i - 1] * nums[x] * nums[j + 1] + + helper(x + 1, j, nums, dp)); + } + return dp[i][j]; + } + +} diff --git a/CanPlaceFlowers.java b/CanPlaceFlowers.java new file mode 100644 index 0000000..70aa3a1 --- /dev/null +++ b/CanPlaceFlowers.java @@ -0,0 +1,46 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CanPlaceFlowers + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class CanPlaceFlowers { + /** + * 605. Can Place Flowers + * Suppose you have a long flowerbed in which some of the plots are planted + * and some are not. However, flowers cannot be planted in adjacent plots - they would compete for water and both would die. + + Given a flowerbed (represented as an array containing 0 and 1, where + 0 means empty and 1 means not empty), and a number n, return if n new flowers can be + planted in it without violating the no-adjacent-flowers rule. + + Input: flowerbed = [1,0,0,0,1], n = 1 + Output: True + Input: flowerbed = [1,0,0,0,1], n = 2 + Output: False + + time : O(n); + space : O(1); + * @param flowerbed + * @param n + * @return + */ + public static boolean canPlaceFlowers(int[] flowerbed, int n) { + int count = 0; + for (int i = 0; i < flowerbed.length; i++) { + if (flowerbed[i] == 0) { + if (i == 0 || flowerbed[i - 1] == 0) { + if (i == flowerbed.length - 1 || flowerbed[i + 1] == 0) { + flowerbed[i] = 1; + count++; + } + } + } + } + return count >= n; + } +} diff --git a/Candy.java b/Candy.java new file mode 100644 index 0000000..86fa93d --- /dev/null +++ b/Candy.java @@ -0,0 +1,60 @@ +package leetcode; + +import java.util.Arrays; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : Candy + * Creator : Edward + * Date : Dec, 2017 + * Description : 135. Candy + */ +public class Candy { + /** + * There are N children standing in a line. Each child is assigned a rating value. + + You are giving candies to these children subjected to the following requirements: + + Each child must have at least one candy. + Children with a higher rating get more candies than their neighbors. + What is the minimum candies you must give? + + ratings: [4, 5, 1, 1, 3, 7] + candies: [1, 1, 1, 1, 1, 1] + + ratings: [4, 5, 1, 1, 3, 7] + candies: [1, 2, 1, 1, 2, 3] + + ratings: [4, 5, 1, 1, 3, 7] + candies: [1, 2, 1, 1, 2, 3] + + time : O(n) + space : O(n) + + + * @param ratings + * @return + */ + public int candy(int[] ratings) { + int[] candies = new int[ratings.length]; + Arrays.fill(candies, 1); + + for (int i = 1; i < candies.length; i++) { + if (ratings[i] > ratings[i - 1]) { + candies[i] = candies[i - 1] + 1; + } + } + for (int i = candies.length - 2; i >= 0; i --) { + if (ratings[i] > ratings[i - 1]) { + candies[i] = Math.max(candies[i], candies[i + 1] + 1); + } + } + + int res = 0; + for (int candy : candies) { + res += candy; + } + return res; + } +} diff --git a/ClimbingStairs.java b/ClimbingStairs.java new file mode 100644 index 0000000..bb8c45f --- /dev/null +++ b/ClimbingStairs.java @@ -0,0 +1,54 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ClimbingStairs + * Creator : Edward + * Date : Nov, 2017 + * Description : 70. Climbing Stairs + */ +public class ClimbingStairs { + /** + * You are climbing a stair case. It takes n steps to reach to the top. + + Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? + + Note: Given n will be a positive integer. + + + Example 1: + + Input: 2 + Output: 2 + Explanation: There are two ways to climb to the top. + + 1. 1 step + 1 step + 2. 2 steps + + time : O(n) + space : O(n)/O(1) + + * @param n + * @return + */ + + public int climbStairs(int n) { + if (n <= 2) { + return n; + } else { + return climbStairs(n - 1) + climbStairs(n - 2); + } + } + + public int climbStairs2(int n) { + if (n <= 1) return 1; + int oneStep = 1, twoStep = 1, res = 0; + for (int i = 2; i <= n; i++) { + res = oneStep + twoStep; + twoStep = oneStep; + oneStep = res; + } + return res; + } +} diff --git a/CloneGraph.java b/CloneGraph.java new file mode 100644 index 0000000..7ae7079 --- /dev/null +++ b/CloneGraph.java @@ -0,0 +1,70 @@ +package leetcode; + +import java.util.*; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CloneGraph + * Creator : Edward + * Date : Oct, 2017 + * Description : 133. Clone Graph + */ +public class CloneGraph { + /** + * time : O(m + n) m : nodes n : edges + * space : O(m) + */ + + HashMap map = new HashMap<>(); + + public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { + return helper(node); + } + public UndirectedGraphNode helper(UndirectedGraphNode node) { + if (node == null) return null; + if (map.containsKey(node)) return map.get(node); + UndirectedGraphNode dup = new UndirectedGraphNode(node.label); + map.put(node, dup); + for (UndirectedGraphNode neighboer : node.neighbors) { + UndirectedGraphNode clone = helper(neighboer); + dup.neighbors.add(clone); + } + return dup; + } + + public UndirectedGraphNode cloneGraph2(UndirectedGraphNode node) { + if (node == null) return node; + List nodes = getNodes(node); + HashMap map = new HashMap<>(); + + for (UndirectedGraphNode cur : nodes) { + map.put(cur, new UndirectedGraphNode(cur.label)); + } + for (UndirectedGraphNode cur : nodes) { + UndirectedGraphNode newNode = map.get(cur); + for (UndirectedGraphNode neighbor : cur.neighbors) { + newNode.neighbors.add(map.get(neighbor)); + } + } + return map.get(node); + } + + public List getNodes(UndirectedGraphNode node) { + Queue queue = new LinkedList<>(); + HashSet set = new HashSet<>(); + queue.offer(node); + set.add(node); + + while (!queue.isEmpty()) { + UndirectedGraphNode cur = queue.poll(); + for (UndirectedGraphNode neighbor : cur.neighbors) { + if (!set.contains(neighbor)) { + set.add(neighbor); + queue.offer(neighbor); + } + } + } + return new ArrayList<>(set); + } +} diff --git a/ClosestBinarSearchTreeValue.java b/ClosestBinarSearchTreeValue.java new file mode 100644 index 0000000..39f0797 --- /dev/null +++ b/ClosestBinarSearchTreeValue.java @@ -0,0 +1,43 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ClosestBinarSearchTreeValue + * Creator : Edward + * Date : Oct, 2017 + * Description : 270. Closest Binary Search Tree Value + */ +public class ClosestBinarSearchTreeValue { + + // time : O(n) space : O(1) + public int closestValue(TreeNode root, double target) { + int res = root.val; + while (root != null) { + if (Math.abs(target - root.val) < Math.abs(target - res)) { + res = root.val; + } + root = root.val > target ? root.left : root.right; + } + return res; + } + + + // time : O(n) space : O(n) + public int closestValue2(TreeNode root, double target) { + return helper(root, target, root.val); + } + + public int helper(TreeNode root, double target, int val) { + if (root == null) return val; + if (Math.abs(root.val - target) < Math.abs(val - target)) { + val = root.val; + } + if (root.val < target) { + val = helper(root.right, target, val); + } else if (root.val > target) { + val = helper(root.left, target, val); + } + return val; + } +} diff --git a/ClosestBinarySearchTreeValueII.java b/ClosestBinarySearchTreeValueII.java new file mode 100644 index 0000000..efa31d5 --- /dev/null +++ b/ClosestBinarySearchTreeValueII.java @@ -0,0 +1,136 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ClosestBinarySearchTreeValueII + * Creator : Edward + * Date : Dec, 2017 + * Description : 272. Closest Binary Search Tree Value II + */ +public class ClosestBinarySearchTreeValueII { + + /** + * Given a non-empty binary search tree and a target value, find k values in the BST that are closest to the target. + + Note: + Given target value is a floating point. + You may assume k is always valid, that is: k ≤ total nodes. + You are guaranteed to have only one unique set of k values in the BST that are closest to the target. + + 8 + / \ + 3 9 + / \ + 2 7 + + target : 6 k = 2 + + Stack : pred : 3 + Stack : succ : 9 + + 3 1 + + res : 7 8 + + * @param root + * @param target + * @param k + * @return + */ + + // time : O(n) space : O(n) + public List closestKValues(TreeNode root, double target, int k) { + LinkedList res = new LinkedList<>(); + helper(res, root, target, k); + return res; + } + + private void helper(LinkedList res, TreeNode root, double target, int k) { + if (root == null) return; + helper(res, root.left, target, k); + if (res.size() == k) { + if (Math.abs(target - root.val) < Math.abs(target - res.peekFirst())) { + res.removeFirst(); + } else return; + } + res.add(root.val); + helper(res, root.right, target, k); + } + + // time : O(klogn) + public List closestKValues2(TreeNode root, double target, int k) { + List res = new ArrayList<>(); + Stack pred = new Stack<>(); + Stack succ = new Stack<>(); + iniPred(root, target, pred); + iniSucc(root, target, succ); + if (!pred.isEmpty() && !succ.isEmpty() && succ.peek().val == pred.peek().val) { + helper(pred, false); + } + while (k-- > 0) { + if (succ.isEmpty()) { + res.add(helper(pred, false)); + } else if (pred.isEmpty()) { + res.add(helper(succ, true)); + } else { + double succDiff = Math.abs((double)succ.peek().val - target); + double predDiff = Math.abs((double)pred.peek().val - target); + if (succDiff < predDiff) { + res.add(helper(succ, true)); + } else { + res.add(helper(pred, false)); + } + } + } + return res; + } + + private void iniSucc(TreeNode root, double target, Stack succ) { + while (root != null) { + if (root.val == target) { + succ.push(root); + break; + } else if (root.val > target) { + succ.push(root); + root = root.left; + } else { + root = root.right; + } + } + } + + private void iniPred(TreeNode root, double target, Stack pred) { + while (root != null) { + if (root.val == target) { + pred.push(root); + break; + } else if (root.val < target) { + pred.push(root); + root = root.right; + } else { + root = root.left; + } + } + } + + private int helper(Stack stack, boolean isSucc) { + TreeNode cur = stack.pop(); + int res = cur.val; + + if (isSucc) cur = cur.right; + else cur = cur.left; + + while (cur != null) { + stack.push(cur); + if (isSucc) cur = cur.left; + else cur = cur.right; + } + return res; + } +} diff --git a/CoinChange.java b/CoinChange.java new file mode 100644 index 0000000..d511c83 --- /dev/null +++ b/CoinChange.java @@ -0,0 +1,53 @@ +package leetcode; + +import java.util.Arrays; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CoinChange + * Creator : Edward + * Date : Jan, 2018 + * Description : 322. Coin Change + */ +public class CoinChange { + /** + * ou are given coins of different denominations and a total amount of money amount. + * Write a function to compute the fewest number of coins that you need to make up that amount. + * If that amount of money cannot be made up by any combination of the coins, return -1. + + Example 1: + coins = [1, 2, 5], amount = 11 + return 3 (11 = 5 + 5 + 1) + + Example 2: + coins = [2], amount = 3 + return -1. + + dp[] amount 需要多少coins + + min = Math.min(min, dp[i - coins[j]] + 1); + + * time : O(n*amount) + * space : O(amount) + * @param coins + * @param amount + * @return + */ + public int coinChange(int[] coins, int amount) { + if (amount == 0) return 0; + if (coins == null || coins.length == 0) return -1; + + int[] dp = new int[amount + 1]; + for (int i = 1; i <= amount; i++) { + int min = Integer.MAX_VALUE; + for (int j = 0; j < coins.length; j++) { + if (i >= coins[j] && dp[i - coins[j]] != -1) { + min = Math.min(min, dp[i - coins[j]] + 1); + } + } + dp[i] = min == Integer.MAX_VALUE ? -1 : min; + } + return dp[amount]; + } +} \ No newline at end of file diff --git a/CombinationSum.java b/CombinationSum.java new file mode 100644 index 0000000..32f3fdf --- /dev/null +++ b/CombinationSum.java @@ -0,0 +1,59 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CombinationSum + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class CombinationSum { + + /** + * 39. Combination Sum + * Given a set of candidate numbers (C) (without duplicates) and a target number (T), + * find all unique combinations in C where the candidate numbers sums to T. + + The same repeated number may be chosen from C unlimited number of times. + + Note: + All numbers (including target) will be positive integers. + The solution set must not contain duplicate combinations. + For example, given candidate set [2, 3, 6, 7] and target 7, + A solution set is: + [ + [7], + [2, 2, 3] + ] + + time : O(2^n) + space : O(n) + * @param candidates + * @param target + * @return + */ + + public List> combinationSum(int[] candidates, int target) { + List> res = new ArrayList<>(); + if (candidates == null || candidates.length == 0) return res; + helper(res, new ArrayList<>(), candidates, target, 0); + return res; + } + + public void helper(List> res, List list, int[] candidates, int target, int start) { + if (target < 0) return; + if (target == 0) { + res.add(new ArrayList<>(list)); + return; + } + for (int i = start; i < candidates.length; i++) { + list.add(candidates[i]); + helper(res, list, candidates, target - candidates[i], i); + list.remove(list.size() - 1); + } + } +} diff --git a/CombinationSumII.java b/CombinationSumII.java new file mode 100644 index 0000000..d4f6695 --- /dev/null +++ b/CombinationSumII.java @@ -0,0 +1,66 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CombinationSumII + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class CombinationSumII { + + /** + * 40. Combination Sum II + * Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. + + Each number in C may only be used once in the combination. + + Note: + All numbers (including target) will be positive integers. + The solution set must not contain duplicate combinations. + For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8, + A solution set is: + [ + [1, 7], + [1, 2, 5], + [2, 6], + [1, 1, 6] + ] + + [1,1,2,5,6,7,10] + [[1,1,6],[1,2,5],[1,7],[2,6]] + + time : O(2^n); + space : O(n); + * @param candidates + * @param target + * @return + */ + + public List> combinationSum2(int[] candidates, int target) { + List> res = new ArrayList<>(); + if (candidates == null || candidates.length == 0) return res; + Arrays.sort(candidates); + helper(res, new ArrayList<>(), candidates, target, 0); + return res; + } + + public void helper(List> res, List list, int[] candidates, int target, int start) { + if (target < 0) return; + if (target == 0) { + res.add(new ArrayList<>(list)); + return; + } + for (int i = start; i < candidates.length; i++) { + if (i != start && candidates[i] == candidates[i - 1]) continue; + list.add(candidates[i]); + helper(res, list, candidates, target - candidates[i], i + 1); + list.remove(list.size() - 1); + } + } +} diff --git a/CombinationSumIII.java b/CombinationSumIII.java new file mode 100644 index 0000000..6180e51 --- /dev/null +++ b/CombinationSumIII.java @@ -0,0 +1,62 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CombinationSumIII + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class CombinationSumIII { + + /** + * 216. Combination Sum III + * Find all possible combinations of k numbers that add up to a number n, + * given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers. + + + Example 1: + + Input: k = 3, n = 7 + + Output: + + [[1,2,4]] + + Example 2: + + Input: k = 3, n = 9 + + Output: + + [[1,2,6], [1,3,5], [2,3,4]] + + time : O(2^n) + space : O(n); + * @param k + * @param n + * @return + */ + + public List> combinationSum3(int k, int n) { + List> res = new ArrayList<>(); + helper(res, new ArrayList<>(), k, n, 1); + return res; + } + + public void helper(List> res, List list, int k, int n, int start) { + if (k == 0 && n == 0) { + res.add(new ArrayList<>(list)); + return; + } + for (int i = start; i <=9; i++) { + list.add(i); + helper(res, list, k - 1, n - i, i + 1); + list.remove(list.size() - 1); + } + } +} diff --git a/CombinationSumIV.java b/CombinationSumIV.java new file mode 100644 index 0000000..dd6a1e0 --- /dev/null +++ b/CombinationSumIV.java @@ -0,0 +1,75 @@ +package leetcode; + +import java.util.Arrays; +import java.util.HashMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CombinationSumIV + * Creator : Edward + * Date : Jan, 2018 + * Description : 377. Combination Sum IV + */ +public class CombinationSumIV { + /** + * nums = [1, 2, 3] + target = 4 + + The possible combination ways are: + (1, 1, 1, 1) + (1, 1, 2) + (1, 2, 1) + (1, 3) + (2, 1, 1) + (2, 2) + (3, 1) + + Note that different sequences are counted as different combinations. + + Therefore the output is 7. + + 1, DP : res[i] += res[i - num]; + 2, DFS + Memoization : HashMap + + + * @param nums + * @param target + * @return + */ + + // time : (n * k) space : O(k) + public int combinationSum4(int[] nums, int target) { + int[] res = new int[target + 1]; + res[0] = 1; + for (int i = 1; i < res.length; i++) { + for (int num : nums) { + if (i - num >= 0) { + res[i] += res[i - num]; + } + } + } + return res[target]; + } + + //time : < O(2^n) space : O(n) + public int combinationSum42(int[] nums, int target) { + if (nums.length == 0) return 0; + HashMap map = new HashMap<>(); + return helper(nums, target, map); + } + + private int helper(int[] nums, int target, HashMap map) { + if (target == 0) return 1; + if (target < 0) return 0; + if (map.containsKey(target)) { + return map.get(target); + } + int res = 0; + for (int i = 0; i < nums.length; i++) { + res += helper(nums, target - nums[i], map); + } + map.put(target, res); + return res; + } +} diff --git a/Combinations.java b/Combinations.java new file mode 100644 index 0000000..bb68f75 --- /dev/null +++ b/Combinations.java @@ -0,0 +1,58 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : Combinations + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class Combinations { + + /** + * 77. Combinations + * Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. + + For example, + If n = 4 and k = 2, a solution is: + + [ + [2,4], + [3,4], + [2,3], + [1,2], + [1,3], + [1,4], + ] + [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]] + + time : O(n^min{k,n-k}) + space : O(n); + http://stackoverflow.com/questions/31120402/complexity-when-generating-all-combinations + * @param n + * @param k + * @return + */ + + public List> combine(int n, int k) { + List> res = new ArrayList<>(); + helper(res, new ArrayList<>(), n, k, 1); + return res; + } + + public void helper(List> res, List list, int n, int k, int start) { + if (k == 0) { + res.add(new ArrayList<>(list)); + return; + } + for (int i = start; i <= n; i++) { + list.add(i); + helper(res, list, n, k - 1, i + 1); + list.remove(list.size() - 1); + } + } +} diff --git a/CompareVersionNumbers.java b/CompareVersionNumbers.java new file mode 100644 index 0000000..678ba5d --- /dev/null +++ b/CompareVersionNumbers.java @@ -0,0 +1,45 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CompareVersionNumbers + * Creator : Edward + * Date : Nov, 2017 + * Description : 165. Compare Version Numbers + */ +public class CompareVersionNumbers { + /** + * Compare two version numbers version1 and version2. + If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0. + + You may assume that the version strings are non-empty and contain only digits and the . character. + The . character does not represent a decimal point and is used to separate number sequences. + For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision. + + Here is an example of version numbers ordering: + + 0.1 < 1.1 < 1.2 < 13.37 + + time : O(n) + space : O(n) + + * @param version1 + * @param version2 + * @return + */ + public int compareVersion(String version1, String version2) { + String[] v1 = version1.split("\\."); + String[] v2 = version2.split("\\."); + for (int i = 0; i < Math.max(v1.length, v2.length); i++) { + int num1 = i < v1.length ? Integer.parseInt(v1[i]) : 0; + int num2 = i < v2.length ? Integer.parseInt(v2[i]) : 0; + if (num1 < num2) { + return -1; + } else if (num1 > num2) { + return 1; + } + } + return 0; + } +} diff --git a/ConstructBinaryTreefromInorderandPostorderTraversal.java b/ConstructBinaryTreefromInorderandPostorderTraversal.java new file mode 100644 index 0000000..acb82eb --- /dev/null +++ b/ConstructBinaryTreefromInorderandPostorderTraversal.java @@ -0,0 +1,52 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ConstructBinaryTreefromInorderandPostorderTraversal + * Creator : Edward + * Date : Nov, 2017 + * Description : 106. Construct Binary Tree from Inorder and Postorder Traversal + */ +public class ConstructBinaryTreefromInorderandPostorderTraversal { + /** + * 3 + / \ + 9 20 + / \ / \ + 15 7 1 5 + + inorder : 15 9 7 3 1 20 5 + postorder : 15 7 9 1 5 20 3 + + time : O(n) + space : O(n) + * @param inorder + * @param postorder + * @return + */ + + int pInorder; + int pPostorder; + + public TreeNode buildTree(int[] inorder, int[] postorder) { + pInorder = inorder.length - 1; + pPostorder = postorder.length - 1; + return helper(inorder, postorder, null); + } + + public TreeNode helper(int[] inorder, int[] postorder, TreeNode end) { + if (pPostorder < 0) { + return null; + } + TreeNode root = new TreeNode(postorder[pPostorder--]); + if (inorder[pInorder] != root.val) { + root.right = helper(inorder, postorder, root); + } + pInorder--; + if ((end == null) || (inorder[pInorder] != end.val)) { + root.left = helper(inorder, postorder, end); + } + return root; + } +} diff --git a/ConstructBinaryTreefromPreorderandInorderTraversal.java b/ConstructBinaryTreefromPreorderandInorderTraversal.java new file mode 100644 index 0000000..2d1f0b6 --- /dev/null +++ b/ConstructBinaryTreefromPreorderandInorderTraversal.java @@ -0,0 +1,49 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ConstructBinaryTreefromPreorderandInorderTraversal + * Creator : Edward + * Date : Nov, 2017 + * Description : 105. Construct Binary Tree from Preorder and Inorder Traversal + */ +public class ConstructBinaryTreefromPreorderandInorderTraversal { + /** + * 3 + / \ + 9 20 + / \ + 15 7 + + inorder : 15 9 7 3 20 + preorder : 3 9 15 7 20 + + time : O(n) + space : O(n) + + * @param preorder + * @param inorder + * @return + */ + public TreeNode buildTree(int[] preorder, int[] inorder) { + return helper(0, 0, inorder.length - 1, preorder, inorder); + } + + public TreeNode helper(int preStart, int inStart, int inEnd, int[] preorder, int[] inorder) { + if (preStart > preorder.length - 1 || inStart > inEnd) { + return null; + } + TreeNode root = new TreeNode(preorder[preStart]); + int inIndex = 0; + for (int i = inStart; i <= inEnd; i++) { + if (inorder[i] == root.val) { + inIndex = i; + } + } + root.left = helper(preStart + 1, inStart, inIndex - 1, preorder, inorder); + root.right = helper(preStart + inIndex - inStart + 1, inIndex + 1, inEnd, preorder, inorder); + return root; + } + +} diff --git a/ContainerWithMostWater.java b/ContainerWithMostWater.java new file mode 100644 index 0000000..fed0a43 --- /dev/null +++ b/ContainerWithMostWater.java @@ -0,0 +1,31 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ContainerWithMostWater + * Creator : Edward + * Date : Nov, 2017 + * Description : 11. Container With Most Water + */ +public class ContainerWithMostWater { + + /** + * time : O(n) + * space : O(1) + * @param height + * @return + */ + + public int maxArea(int[] height) { + int res = 0; + int l = 0, r = height.length - 1; + while (l < r) { + res = Math.max(res, Math.min(height[l], height[r]) * (r - l)); + if (height[l] < height[r]) { + l++; + } else r--; + } + return res; + } +} diff --git a/ContainsDuplicate.java b/ContainsDuplicate.java new file mode 100644 index 0000000..5aba5bd --- /dev/null +++ b/ContainsDuplicate.java @@ -0,0 +1,33 @@ +package leetcode; + +import java.util.Arrays; +import java.util.HashSet; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ContainsDuplicate + * Creator : Edward + * Date : Oct, 2017 + * Description : 217. Contains Duplicate + */ +public class ContainsDuplicate { + + // time : O(n) space : O(n) + public boolean containsDuplicate(int[] nums) { + HashSet set = new HashSet<>(); + for (int i = 0; i < nums.length; i++) { + if (!set.add(nums[i])) return true; + } + return false; + } + + // time : O(nlogn) space : O(1) + public boolean containsDuplicate2(int[] nums) { + Arrays.sort(nums); + for (int i = 1; i < nums.length; i++) { + if (nums[i] == nums[i - 1]) return true; + } + return false; + } +} diff --git a/ContainsDuplicateII.java b/ContainsDuplicateII.java new file mode 100644 index 0000000..6f3be77 --- /dev/null +++ b/ContainsDuplicateII.java @@ -0,0 +1,27 @@ +package leetcode; + +import java.util.HashMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ContainsDuplicateII + * Creator : Edward + * Date : Oct, 2017 + * Description : 219. Contains Duplicate II + */ +public class ContainsDuplicateII { + //time : O(n) space : O(n) + public boolean containsNearbyDuplicate(int[] nums, int k) { + HashMap map = new HashMap<>(); + for (int i = 0; i < nums.length; i++) { + if (map.containsKey(nums[i])) { + if ((i - map.get(nums[i])) <= k) { + return true; + } + } + map.put(nums[i], i); + } + return false; + } +} diff --git a/ContainsDuplicateIII.java b/ContainsDuplicateIII.java new file mode 100644 index 0000000..810e1e2 --- /dev/null +++ b/ContainsDuplicateIII.java @@ -0,0 +1,78 @@ +package leetcode; + +import java.util.HashMap; +import java.util.TreeSet; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ContainsDuplicateIII + * Creator : Edward + * Date : Dec, 2017 + * Description : 220. Contains Duplicate III + */ + +public class ContainsDuplicateIII { + /** + * Given an array of integers, find out whether there are two distinct indices i and j in the array such + * that the absolute difference between nums[i] and nums[j] is at most t and the absolute difference + * between i and j is at most k. + + time : O(nlogk) + space : O(k) + + * @param nums + * @param k + * @param t + * @return + */ + + public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) { + if( k < 1 || t < 0) return false; + TreeSet set = new TreeSet<>(); + for(int i = 0; i < nums.length; i++){ + Long floor = set.floor((long)nums[i] + t); + Long ceil = set.ceiling((long)nums[i] - t); + + if((floor != null && floor >= nums[i]) + || (ceil != null && ceil <= nums[i]) ) + return true; + + set.add((long)nums[i]); + if(i >= k){ + set.remove((long)nums[i-k]); + } + } + return false; + } + + /** + + time : O(n) + space : O(k) + + * @param nums + * @param k + * @param t + * @return + */ + + public boolean containsNearbyAlmostDuplicate2(int[] nums, int k, int t) { + if (k < 1 || t < 0) return false; + HashMap map = new HashMap<>(); + for (int i = 0; i < nums.length; i++) { + long remappedNum = (long) nums[i] - Integer.MIN_VALUE; + long bucket = remappedNum / ((long) t + 1); + if (map.containsKey(bucket) + || (map.containsKey(bucket - 1) && remappedNum - map.get(bucket - 1) <= t) + || (map.containsKey(bucket + 1) && map.get(bucket + 1) - remappedNum <= t)) + return true; + if (map.entrySet().size() >= k) { + long lastBucket = ((long) nums[i - k] - Integer.MIN_VALUE) / ((long) t + 1); + map.remove(lastBucket); + } + map.put(bucket, remappedNum); + } + return false; + } +} diff --git a/ConvertSortedArraytoBinarySearchTree.java b/ConvertSortedArraytoBinarySearchTree.java new file mode 100644 index 0000000..26748c5 --- /dev/null +++ b/ConvertSortedArraytoBinarySearchTree.java @@ -0,0 +1,35 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ConvertSortedArraytoBinarySearchTree + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class ConvertSortedArraytoBinarySearchTree { + /** + * 108. Convert Sorted Array to Binary Search Tree + + [1,2,3,4,5] + + time : O(n); + space : O(n); + * @param nums + * @return + */ + public TreeNode sortedArrayToBST(int[] nums) { + if (nums == null || nums.length == 0) return null; + return helper(nums, 0, nums.length - 1); + } + + public TreeNode helper(int[] nums, int left, int right) { // space : O(logn); + if (left > right) return null; + int mid = (right - left) / 2 + left; + TreeNode node = new TreeNode(nums[mid]); + node.left = helper(nums, left, mid - 1); + node.right = helper(nums, mid + 1, right); + return node; + } +} diff --git a/ConvertSortedListtoBinarySearchTree.java b/ConvertSortedListtoBinarySearchTree.java new file mode 100644 index 0000000..c65d260 --- /dev/null +++ b/ConvertSortedListtoBinarySearchTree.java @@ -0,0 +1,40 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ConvertSortedListtoBinarySearchTree + * Creator : Edward + * Date : Oct, 2017 + * Description : 109. Convert Sorted List to Binary Search Tree + */ +public class ConvertSortedListtoBinarySearchTree { + + /** + + time : O(n); + space : O(n); + + * @param head + * @return + */ + + public TreeNode sortedListToBST(ListNode head) { + if (head == null) return null; + return toBST(head, null); + } + + public TreeNode toBST(ListNode head, ListNode tail) { + if (head == tail) return null; + ListNode slow = head; + ListNode fast = head; + while (fast != tail && fast.next != tail) { + fast = fast.next.next; + slow = slow.next; + } + TreeNode root = new TreeNode(slow.val); + root.left = toBST(head, slow); + root.right = toBST(slow.next, tail); + return root; + } +} diff --git a/ConvertaNumbertoHexadecimal.java b/ConvertaNumbertoHexadecimal.java new file mode 100644 index 0000000..f9a92f2 --- /dev/null +++ b/ConvertaNumbertoHexadecimal.java @@ -0,0 +1,32 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ConvertaNumbertoHexadecimal + * Creator : Edward + * Date : Jan, 2018 + * Description : 405. Convert a Number to Hexadecimal + */ +public class ConvertaNumbertoHexadecimal { + /** + * + * time : < O(n) + * space : O(n) + + * @param num + * @return + */ + + char[] map = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; + + public String toHex(int num) { + if (num == 0) return "0"; + StringBuilder res = new StringBuilder(); + while (num != 0) { + res.append(map[num & 15]); + num = num >>> 4; + } + return res.reverse().toString(); + } +} diff --git a/CopyListwithRandomPointer.java b/CopyListwithRandomPointer.java new file mode 100644 index 0000000..8897a5f --- /dev/null +++ b/CopyListwithRandomPointer.java @@ -0,0 +1,90 @@ +package leetcode; + +import java.util.HashMap; +import java.util.Random; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CopyListwithRandomPointer + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +class RandomListNode { + int label; + RandomListNode next, random; + RandomListNode(int x) { this.label = x; } +} +public class CopyListwithRandomPointer { + /** + * 138. Copy List with Random Pointer + * A linked list is given such that each node contains an additional random pointer which could + * point to any node in the list or null. + + Return a deep copy of the list + + time : O(n); + space : O(n); + * @param head + * @return + */ + public RandomListNode copyRandomList(RandomListNode head) { + HashMap map = new HashMap<>(); + RandomListNode cur = head; + while (cur != null) { + map.put(cur, new RandomListNode(cur.label)); + cur = cur.next; + } + cur = head; + while (cur != null) { + map.get(cur).next = map.get(cur.next); + map.get(cur).random = map.get(cur.random); + cur = cur.next; + } + return map.get(head); + } + + /** + + 1->1'->2->2'->3->3'->4->4' + + 1'->2'->3'->4' + * @param head + * @return + */ + public RandomListNode copyRandomList2(RandomListNode head) { + RandomListNode cur = head; + RandomListNode next; + //next copy + while (cur != null) { + next = cur.next; + RandomListNode copy = new RandomListNode(cur.label); + cur.next = copy; + copy.next = next; + cur = next; + } + cur = head; + //random copy + while (cur != null) { + if (cur.random != null) { + cur.next.random = cur.random.next; + } + cur = cur.next.next; + } + cur = head; + RandomListNode dummy = new RandomListNode(0); + RandomListNode copy; + RandomListNode copycur = dummy; + + while (cur != null) { + next = cur.next.next; + copy = cur.next; + copycur.next = copy; + copycur = copy; + cur.next = next; + cur = next; + } + return dummy.next; + } +} diff --git a/CountCompleteTreeNodes.java b/CountCompleteTreeNodes.java new file mode 100644 index 0000000..234dae1 --- /dev/null +++ b/CountCompleteTreeNodes.java @@ -0,0 +1,85 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CountCompleteTreeNodes + * Creator : Edward + * Date : Dec, 2017 + * Description : 222. Count Complete Tree Nodes + */ +public class CountCompleteTreeNodes { + + /** + * Given a complete binary tree, count the number of nodes. + + Definition of a complete binary tree from Wikipedia: + In a complete binary tree every level, except possibly the last, is completely filled, and all nodes + in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h. + + 3 + / \ + 9 20 + / \ / \ + 15 7 1 + + 2^h - 1 + + time : O(logn * logn) + space : O(n) / O(logn) 不确定 + + * @param root + * @return + */ + + public int countNodes(TreeNode root) { + // int left = helper(root, true); + // int right = helper(root, false); + int left = leftDepth(root); + int right = rightDepth(root); + + if (left == right) { + return (1 << left) - 1; + } else { + return 1 + countNodes(root.left) + countNodes(root.right); + } + } + + private int leftDepth(TreeNode root) { + int res = 0; + while (root != null) { + root = root.left; + res++; + } + return res; + } + + private int rightDepth(TreeNode root) { + int res = 0; + while (root != null) { + root = root.right; + res++; + } + return res; + } + + private int helper(TreeNode root, boolean isLeft) { + if (root == null) return 0; + return isLeft ? helper(root.left, isLeft) + 1: helper(root.right, isLeft) + 1; + } + + public int countNodes2(TreeNode root) { + if (root == null) + return 0; + TreeNode left = root, right = root; + int height = 0; + while (right != null) { + left = left.left; + right = right.right; + height++; + } + if (left == null) + return (1 << height) - 1; + return 1 + countNodes(root.left) + countNodes(root.right); + } +} diff --git a/CountNumberswithUniqueDigits.java b/CountNumberswithUniqueDigits.java new file mode 100644 index 0000000..3b6c700 --- /dev/null +++ b/CountNumberswithUniqueDigits.java @@ -0,0 +1,26 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CountNumberswithUniqueDigits + * Creator : Edward + * Date : Jan, 2018 + * Description : 357. Count Numbers with Unique Digits + */ +public class CountNumberswithUniqueDigits { + + public int countNumbersWithUniqueDigits(int n) { + if (n == 0) return 1; + + int res = 10; + int uniqueDigits = 9; + int availableNumber = 9; + while (n-- > 1 && availableNumber > 0) { + uniqueDigits = uniqueDigits * availableNumber; + res += uniqueDigits; + availableNumber--; + } + return res; + } +} diff --git a/CountPrimes.java b/CountPrimes.java new file mode 100644 index 0000000..335f4ea --- /dev/null +++ b/CountPrimes.java @@ -0,0 +1,34 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CountPrimes + * Creator : Edward + * Date : Nov, 2017 + * Description : 204. Count Primes + */ +public class CountPrimes { + /** + * 厄拉多塞筛法,求一组质数,时间复杂度仅有O(nloglogn) + * 如果从1到n-1分别判断质数,时间复杂度为O(nsqrt(n))) + * 1 2 3 4 5 6 7 8 9 10 + * 11 12 13 14 15 16 17 18 18 20 + * + * @param n + * @return + */ + public int countPrimes(int n) { + boolean[] notPrime = new boolean[n]; + int res = 0; + for (int i = 2; i < n; i++) { + if (notPrime[i] == false) { + res++; + for (int j = 2; i * j < n; j++) { + notPrime[i * j] = true; + } + } + } + return res; + } +} diff --git a/CountUnivalueSubtrees.java b/CountUnivalueSubtrees.java new file mode 100644 index 0000000..cc9f47d --- /dev/null +++ b/CountUnivalueSubtrees.java @@ -0,0 +1,63 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CountUnivalueSubtrees + * Creator : Edward + * Date : Nov, 2017 + * Description : 250. Count Univalue Subtrees + */ +public class CountUnivalueSubtrees { + /** + * Given a binary tree, count the number of uni-value subtrees. + + A Uni-value subtree means all nodes of the subtree have the same value. + + For example: + Given binary tree, + 5 + / \ + 1 5 + / \ \ + 5 5 5 + return 4. + + root = 5 res = 2 + root = 1 + root = 5 res = 3 + root = 5 res = 4 + + time : O(n) + space : O(n) + + + */ + + int res; + + public int countUnivalSubtrees(TreeNode root) { + res = 0; + helper(root); + return res; + } + public boolean helper(TreeNode root) { + if (root == null) return true; + + boolean left = helper(root.left); + boolean right = helper(root.right); + + if (left && right) { + if (root.left != null && root.val != root.left.val) { + return false; + } + if (root.right != null && root.val != root.right.val) { + return false; + } + res++; + return true; + } + return false; + } + +} diff --git a/CountandSay.java b/CountandSay.java new file mode 100644 index 0000000..21a1c07 --- /dev/null +++ b/CountandSay.java @@ -0,0 +1,49 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CountandSay + * Creator : Edward + * Date : Oct, 2017 + * Description : 38. Count and Say + */ +public class CountandSay { + /** + 1. 1 + 2. 11 + 3. 21 + 4. 1211 + 5. 111221 + + time : 不知道 + space : O(n) + + * @param n + * @return + */ + public String countAndSay(int n) { + int i = 1; + String res = "1"; + while (i < n) { + int count = 0; + StringBuilder sb = new StringBuilder(); + char c = res.charAt(0); + for (int j = 0; j <= res.length(); j++) { + if (j != res.length() && res.charAt(j) == c) { + count++; + } else { + sb.append(count); + sb.append(c); + if (j != res.length()) { + count = 1; + c = res.charAt(j); + } + } + } + res = sb.toString(); + i++; + } + return res; + } +} diff --git a/CountingBits.java b/CountingBits.java new file mode 100644 index 0000000..1748892 --- /dev/null +++ b/CountingBits.java @@ -0,0 +1,59 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CountingBits + * Creator : Edward + * Date : Nov, 2017 + * Description : 338. Counting Bits + */ +public class CountingBits { + /** + * 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. + * + * https://www.cnblogs.com/grandyang/p/5294255.html + + Example: + + For num = 5 you should return [0,1,1,2,1,2]. + + 8 = 1000 0111 = 0000 i&(i-1) + + i bit '1' i&(i-1) + 0 0000 0 0 + ----------------------- + 1 0001 1 0000 1 + ----------------------- + 2 0010 1 0000 1 + 3 0011 2 0010 2 + ----------------------- + 4 0100 1 0000 + 5 0101 2 0100 + 6 0110 2 0100 + 7 0111 3 0110 + ----------------------- + 8 1000 1 0000 + 9 1001 2 1000 + 10 1010 2 1000 + 11 1011 3 1010 + 12 1100 2 1000 + 13 1101 3 1100 + 14 1110 3 1100 + 15 1111 4 1110 + + time : O(n) + space : O(n) + + * @param num + * @return + */ + public int[] countBits(int num) { + int[] res = new int[num + 1]; + for (int i = 1; i <= num; i++) { + res[i] = res[i & (i - 1)] + 1; + } + return res; + } +} diff --git a/CountofRangeSum.java b/CountofRangeSum.java new file mode 100644 index 0000000..8028534 --- /dev/null +++ b/CountofRangeSum.java @@ -0,0 +1,134 @@ +package leetcode; + +import java.util.Map; +import java.util.TreeMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CountofRangeSum + * Creator : Edward + * Date : Jan, 2018 + * Description : 327. Count of Range Sum + */ +public class CountofRangeSum { + /** + * Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive. + Range sum S(i, j) is defined as the sum of the elements in nums + between indices i and j (i ≤ j), inclusive. + + Note: + A naive algorithm of O(n2) is trivial. You MUST do better than that. + + Example: + Given nums = [-2, 5, -1], lower = -2, upper = 2, + Return 3. + The three ranges are : [0, 0], [2, 2], [0, 2] and their respective sums are: -2, -1, 2. + + 1 2 3 + 1 3 6 .. lower = 1 upper = 3 + + sum = 6 3 - 5 + treeMap : 1 3 + Map : (3,1) + + TreeMap + subMap + + * @param nums + * @param lower + * @param upper + * @return + */ + + // time : O(n^2) 不确定 space : O(n) + public int countRangeSum(int[] nums, int lower, int upper) { + if (nums == null || nums.length == 0) return 0; + TreeMap treeMap = new TreeMap<>(); + treeMap.put((long)0, (long)1); + long sum = 0; + long count = 0; + for (int i = 0; i < nums.length; i++) { + sum += nums[i]; + long from = sum - upper; + long to = sum - lower; + Map sub = treeMap.subMap(from, true, to, true); + for (Long value : sub.values()) { + count += value; + } + treeMap.put(sum, treeMap.getOrDefault(sum, (long)0) + 1); + } + return (int)count; + } + + // time : O(nlogn) space : O(n) + public int countRangeSum2(int[] nums, int lower, int upper) { + long[] sum = new long[nums.length + 1]; + for(int i = 1; i <= nums.length; i++) { + sum[i] = sum[i-1] + nums[i-1]; + } + return helper(sum, new long[sum.length], 0, sum.length - 1, lower, upper); + } + + /** + rangeEnd是第一个满足 sums[rangeEnd] - sums[i] > upper 的下标 + + rangeStart是第一个满足 sums[rangeStart] - sums[i] >= lower 的下标 + + [lower, upper]之间的区间的个数是rangeEnd - rangeStart + + + 遍历前半段 匹配后半段 + [1,3] [2,4] + + + * @param sum + * @param helper + * @param low + * @param high + * @param lower + * @param upper + * @return + */ + + private int helper(long[] sum, long[] helper, int low, int high, long lower, long upper) { + if (low >= high) { + return 0; + } + + int mid = (high + 1 - low) / 2 + low; + int count = helper(sum, helper, low, mid - 1, lower, upper) + + helper(sum, helper, mid, high, lower, upper); + + int rangeStart = mid, rangeEnd = mid; + for(int i = low; i < mid; i++) { + while(rangeStart <= high && sum[rangeStart] - sum[i] < lower) + rangeStart++; + while(rangeEnd <= high && sum[rangeEnd] - sum[i] <= upper) + rangeEnd++; + + count += rangeEnd - rangeStart; + } + + merge(sum, helper, low, mid, high); + return count; + } + + private void merge(long[] sum, long[] helper, int low, int mid, int high) { + int left = low, right = mid, idx = low; + + while(left < mid && right <= high) { + if (sum[left] <= sum[right]) + helper[idx++] = sum[left++]; + else + helper[idx++] = sum[right++]; + } + + while(left < mid) + helper[idx++] = sum[left++]; + while(right <= high) + helper[idx++] = sum[right++]; + + System.arraycopy(helper, low, sum, low, high + 1 - low); + } +} diff --git a/CountofSmallerNumbersAfterSelf.java b/CountofSmallerNumbersAfterSelf.java new file mode 100644 index 0000000..fdeef82 --- /dev/null +++ b/CountofSmallerNumbersAfterSelf.java @@ -0,0 +1,66 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CountofSmallerNumbersAfterSelf + * Creator : Edward + * Date : Nov, 2017 + * Description : 315. Count of Smaller Numbers After Self + */ +public class CountofSmallerNumbersAfterSelf { + /** + * You are given an integer array nums and you have to return a new counts array. + * The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i]. + + Example: + + Given nums = [5, 2, 6, 1] + + To the right of 5 there are 2 smaller elements (2 and 1). + To the right of 2 there is only 1 smaller element (1). + To the right of 6 there is 1 smaller element (1). + To the right of 1 there is 0 smaller element. + Return the array [2, 1, 1, 0]. + + [5, 2, 6, 1] + + int[] Arrays.asList() + 0 1 1 2 + + time : O(n^2) + space : O(n) + */ + public List countSmaller(int[] nums) { + Integer[] res = new Integer[nums.length]; + List list = new ArrayList<>(); + for (int i = nums.length - 1; i >= 0; i--) { + int index = findIndex(list, nums[i]); + res[i] = index; + list.add(index, nums[i]); + } + return Arrays.asList(res); + } + + private int findIndex(List list, int target) { + if (list.size() == 0) return 0; + int start = 0; + int end = list.size() - 1; + if (list.get(end) < target) return end + 1; + if (list.get(start) >= target) return 0; + while (start + 1 < end) { + int mid = (end - start) / 2 + start; + if (list.get(mid) < target) { + start = mid + 1; + } else { + end = mid; + } + } + if (list.get(start) >= target) return start; + return end; + } +} diff --git a/CourseSchedule.java b/CourseSchedule.java new file mode 100644 index 0000000..2e34dc0 --- /dev/null +++ b/CourseSchedule.java @@ -0,0 +1,89 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CourseSchedule + * Creator : Edward + * Date : Nov, 2017 + * Description : 207. Course Schedule + */ +public class CourseSchedule { + + /** + * There are a total of n courses you have to take, labeled from 0 to n - 1. + + Some courses may have prerequisites, for example to take course 0 you have to first take course 1, + which is expressed as a pair: [0,1] + + Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses? + + For example: + + 2, [[1,0]] + There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible. + + 2, [[1,0],[0,1]] + There are a total of 2 courses to take. To take course 1 you should have finished course 0, + and to take course 0 you should also have finished course 1. So it is impossible. + + 3- 0 - 1 + \ / + 2 + + 入度 = 0 + + 0 : 1 + 1 : 1 + 2 : 1 + + queue : 2 + + pre : 2 + + res = 3 + + + time : O(V + E) + space : O(n) + + * @param numCourses + * @param prerequisites + * @return + */ + + // BFS + public boolean canFinish(int numCourses, int[][] prerequisites) { + int[] indegree = new int[numCourses]; + int res = numCourses; + for (int[] pair : prerequisites) { + indegree[pair[0]]++; + } + + Queue queue = new LinkedList<>(); + for (int i = 0; i < indegree.length; i++) { + if (indegree[i] == 0) { + queue.offer(i); + } + } + + while (!queue.isEmpty()) { + int pre = queue.poll(); + res--; + for (int[] pair : prerequisites) { + if (pair[1] == pre) { + indegree[pair[0]]--; + if (indegree[pair[0]] == 0) { + queue.offer(pair[0]); + } + } + } + } + return res == 0; + } +} diff --git a/CourseScheduleII.java b/CourseScheduleII.java new file mode 100644 index 0000000..5855bd3 --- /dev/null +++ b/CourseScheduleII.java @@ -0,0 +1,89 @@ +package leetcode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CourseScheduleII + * Creator : Edward + * Date : Dec, 2017 + * Description : 210. Course Schedule II + */ +public class CourseScheduleII { + /** + * There are a total of n courses you have to take, labeled from 0 to n - 1. + + Some courses may have prerequisites, for example to take course 0 you have to first take course 1, + which is expressed as a pair: [0,1] + + Given the total number of courses and a list of prerequisite pairs, return the resing of courses you should + take to finish all courses. + + There may be multiple correct ress, you just need to return one of them. If it is impossible to finish all courses, + return an empty array. + + For example: + + 2, [[1,0]] + There are a total of 2 courses to take. To take course 1 you should have finished course 0. So the correct course res + is [0,1] + + 4, [[1,0],[2,0],[3,1],[3,2]] + There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. + Both courses 1 and 2 should be taken after you finished course 0. So one correct course res is [0,1,2,3]. + Another correct resing is[0,2,1,3]. + + + -> 1 -> + 0 3 + -> 2 -> + + + 入度 = 0 => BFS + + 0 : 0 + 1 : 0 + 2 : 0 + 3 : 0 + + queue : 3 + res : 0,1,2,3 + + time : O(V + E) + space : O(n) + + * @param numCourses + * @param prerequisites + * @return + */ + public int[] findres(int numCourses, int[][] prerequisites) { + int[] indegree = new int[numCourses]; + int[] res = new int[numCourses]; + int k = 0; + for (int[] pair : prerequisites) { + indegree[pair[0]]++; + } + Queue queue = new LinkedList<>(); + for (int i = 0; i < indegree.length; i++) { + if (indegree[i] == 0) { + queue.offer(i); + res[k++] = i; + } + } + while (!queue.isEmpty()) { + int pre = queue.poll(); + for (int[] pair : prerequisites) { + if (pair[1] == pre) { + indegree[pair[0]]--; + if (indegree[pair[0]] == 0) { + queue.offer(pair[0]); + res[k++] = pair[0]; + } + } + } + } + return (k == numCourses) ? res : new int[0]; + } +} diff --git a/CreateMaximumNumber.java b/CreateMaximumNumber.java new file mode 100644 index 0000000..46cdc35 --- /dev/null +++ b/CreateMaximumNumber.java @@ -0,0 +1,95 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : CreateMaximumNumber + * Creator : Edward + * Date : Jan, 2018 + * Description : 321. Create Maximum Number + */ +public class CreateMaximumNumber { + /** + * 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. + * The relative order of the digits from the same array must be preserved. + * Return an array of the k digits. You should try to optimize your time and space complexity. + + Example 1: + nums1 = [3, 4, 6, 5] 1 2 + nums2 = [9, 1, 2, 5, 8, 3] 4 3 + k = 5 + return [9, 8, 6, 5, 3] + + Example 2: + nums1 = [6, 7] + nums2 = [6, 0, 4] + k = 5 + return [6, 7, 6, 0, 4] + + Example 3: + nums1 = [3, 9] + nums2 = [8, 9] + k = 3 + return [9, 8, 9] + + 1:从nums1里取i个元素组成最大数组,从nums2里取k-i个元素组成最大数组。 + 2:合并之前结果,得到一个长度为k的最大数组。 + 3:对于不同长度分配的情况,比较每次得到的长度为k的最大数组,返回最大的一个。 + + Reference : https://segmentfault.com/a/1190000007655603 + + time : O((m+n)^3) 不确定 + space : O(k) + + [2,3,1] + [2,3] + + * @param nums1 + * @param nums2 + * @param k + * @return + */ + public int[] maxNumber(int[] nums1, int[] nums2, int k) { + int m = nums1.length; + int n = nums2.length; + int[] res = new int[k]; + for (int i = Math.max(0, k - n); i <= k && i <= m; i++) { + int[] temp = merge(maxArray(nums1, i), maxArray(nums2, k - i), k); + if (greater(temp, 0, res, 0)) { + res = temp; + } + } + return res; + } + + private int[] merge(int[] nums1, int[] nums2, int k) { + int[] res = new int[k]; + for (int i = 0, j = 0, r = 0; r < k; r++) { + res[r] = greater(nums1, i, nums2, j) ? nums1[i++] : nums2[j++]; + } + return res; + } + + private boolean greater(int[] nums1, int i, int[] nums2, int j) { + while (i < nums1.length && j < nums2.length && nums1[i] == nums2[j]) { + i++; + j++; + } + return j == nums2.length || (i < nums1.length && nums1[i] > nums2[j]); + } + + private int[] maxArray(int[] nums, int k) { + int n = nums.length; + int[] res = new int[k]; + for (int i = 0, j = 0; i < n; i++) { + while (n - i > k - j && j > 0 && nums[i] > res[j - 1]) { + j--; + } + if (j < k) { + res[j++] = nums[i]; + } + } + return res; + } +} diff --git a/DataStreamasDisjointIntervals.java b/DataStreamasDisjointIntervals.java new file mode 100644 index 0000000..9fe4179 --- /dev/null +++ b/DataStreamasDisjointIntervals.java @@ -0,0 +1,55 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; +import java.util.TreeMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : DataStreamasDisjointIntervals + * Creator : Edward + * Date : Jan, 2018 + * Description : 352. Data Stream as Disjoint Intervals + */ +public class DataStreamasDisjointIntervals { + + /** + + treeMap : (0,3) (7,7) + + lowerKey = null + higherKey = 1 + val = 0 + + */ + + TreeMap treeMap; + + public DataStreamasDisjointIntervals() { + treeMap = new TreeMap<>(); + } + + // time : O(logn) + public void addNum(int val) { + if (treeMap.containsKey(val)) return; + Integer lowerKey = treeMap.lowerKey(val); + Integer higherKey = treeMap.higherKey(val); + if (lowerKey != null && higherKey != null && treeMap.get(lowerKey).end + 1 == val + && val + 1 == treeMap.get(higherKey).start) { + treeMap.get(lowerKey).end = treeMap.get(higherKey).end; + treeMap.remove(higherKey); + } else if (lowerKey != null && val <= treeMap.get(lowerKey).end + 1) { + treeMap.get(lowerKey).end = Math.max(treeMap.get(lowerKey).end, val); + } else if (higherKey != null && treeMap.get(higherKey).start - 1 == val) { + treeMap.put(val, new Interval(val, treeMap.get(higherKey).end)); + treeMap.remove(higherKey); + } else { + treeMap.put(val, new Interval(val, val)); + } + } + + public List getIntervals() { + return new ArrayList<>(treeMap.values()); + } +} diff --git a/DecodeString.java b/DecodeString.java new file mode 100644 index 0000000..3ca932a --- /dev/null +++ b/DecodeString.java @@ -0,0 +1,60 @@ +package leetcode; + +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : DecodeString + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class DecodeString { + + /** + * 394. Decode String + * s = "3[a]2[bc]", return "aaabcbc". + s = "3[a2[c]]", return "accaccacc". + s = "2[abc]3[cd]ef", return "abcabccdcdcdef". + + + time : O(n); + space : O(n); + * @param s + * @return + */ + + public String decodeString(String s) { + if (s == null || s.length() == 0) return s; + String res = ""; + Stack countStack = new Stack<>(); + Stack resStack = new Stack<>(); + int idx = 0; + while (idx < s.length()) { + if (Character.isDigit(s.charAt(idx))) { + int count = 0; + while (Character.isDigit(s.charAt(idx))) { + count = count * 10 + (s.charAt(idx) - '0'); + idx++; + } + countStack.push(count); + } else if (s.charAt(idx) == '[') { + resStack.push(res); + res = ""; + idx++; + } else if (s.charAt(idx) == ']') { + StringBuilder temp = new StringBuilder(resStack.pop()); + int time = countStack.pop(); + for (int i = 0; i < time; i++) { + temp.append(res); + } + res = temp.toString(); + idx++; + } else { + res += s.charAt(idx++); + } + } + return res; + } +} diff --git a/DecodeWays.java b/DecodeWays.java new file mode 100644 index 0000000..31468cb --- /dev/null +++ b/DecodeWays.java @@ -0,0 +1,74 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : DecodeWays + * Creator : Edward + * Date : Nov, 2017 + * Description : 91. Decode Ways + */ +public class DecodeWays { + /** + * A message containing letters from A-Z is being encoded to numbers using the following mapping: + + 'A' -> 1 + 'B' -> 2 + ... + 'Z' -> 26 + Given an encoded message containing digits, determine the total number of ways to decode it. + + For example, + Given encoded message "12", it could be decoded as "AB" (1 2) or "L" (12). + + The number of ways decoding "12" is 2. + + + time : O(n) + + + * @param s + * @return + */ + + // space : O(n) + public int numDecodings(String s) { + if (s == null || s.length() == 0) return 0; + int len = s.length(); + int[] dp = new int[len + 1]; + dp[0] = 1; + dp[1] = s.charAt(0) != '0' ? 1 : 0; + for (int i = 2; i <= len; i++) { + int first = Integer.valueOf(s.substring(i - 1, i)); + int second = Integer.valueOf(s.substring(i - 2, i)); + if (first >= 1 && first <= 9) { + dp[i] += dp[i - 1]; + } + if (second >= 10 && second <= 26) { + dp[i] += dp[i - 2]; + } + } + return dp[len]; + } + + //space : O(1) + public int numDecodings2(String s) { + if (s == null || s.length() == 0 || s.charAt(0) == '0') { + return 0; + } + int c1 = 1; + int c2 = 1; + for (int i = 1; i < s.length(); i++) { + if (s.charAt(i) == '0') { + c1 = 0; + } + if (s.charAt(i - 1) == '1' || s.charAt(i - 1) == '2' && s.charAt(i) <= '6') { + c1 = c1 + c2; + c2 = c1 - c2; + } else { + c2 = c1; + } + } + return c1; + } +} diff --git a/DeleteNodeInALinkedList.java b/DeleteNodeInALinkedList.java new file mode 100644 index 0000000..09a0d05 --- /dev/null +++ b/DeleteNodeInALinkedList.java @@ -0,0 +1,23 @@ +package leetcode; + +/** + * Created by Edward on 25/07/2017. + */ +public class DeleteNodeInALinkedList { + /** + * 237. Delete Node in a Linked List + * Write a function to delete a node (except the tail) in a singly linked list, given only access to that node. + + Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function. + + time : O(1); + space : O(1); + * @param node + */ + + public static void deleteNode(ListNode node) { + if (node == null) return; + node.val = node.next.val; + node.next = node.next.next; + } +} diff --git a/DesignHitCounter.java b/DesignHitCounter.java new file mode 100644 index 0000000..3056d88 --- /dev/null +++ b/DesignHitCounter.java @@ -0,0 +1,104 @@ +package leetcode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : DesignHitCounter + * Creator : Edward + * Date : Jan, 2018 + * Description : 362. Design Hit Counter + */ +public class DesignHitCounter { + /** + * Design a hit counter which counts the number of hits received in the past 5 minutes. + + Each function accepts a timestamp parameter (in seconds granularity) and you may assume that calls are being made to the system in chronological order (ie, the timestamp is monotonically increasing). You may assume that the earliest timestamp starts at 1. + + It is possible that several hits arrive roughly at the same time. + + Example: + HitCounter counter = new HitCounter(); + + // hit at timestamp 1. + counter.hit(1); + + // hit at timestamp 2. + counter.hit(2); + + // hit at timestamp 3. + counter.hit(3); + + // get hits at timestamp 4, should return 3. + counter.getHits(4); + + // hit at timestamp 300. + counter.hit(300); + + // get hits at timestamp 300, should return 4. + counter.getHits(300); + + // get hits at timestamp 301, should return 3. + counter.getHits(301); + + 1, Queue + 2, 数组 + + */ + + Queue queue; + + /** Initialize your data structure here. */ + public DesignHitCounter() { + queue = new LinkedList<>(); + } + + /** Record a hit. + @param timestamp - The current timestamp (in seconds granularity). */ + public void hit(int timestamp) { + queue.offer(timestamp); + } + + /** Return the number of hits in the past 5 minutes. + @param timestamp - The current timestamp (in seconds granularity). */ + public int getHits(int timestamp) { + while (!queue.isEmpty() && timestamp - queue.peek() >= 300) { + queue.poll(); + } + return queue.size(); + } + + private int[] times; + private int[] hits; + + public void DesignHitCounter2() { + times = new int[300]; + hits = new int[300]; + } + + /** Record a hit. + @param timestamp - The current timestamp (in seconds granularity). */ + public void hit2(int timestamp) { + int index = timestamp % 300; + if (times[index] != timestamp) { + times[index] = timestamp; + hits[index] = 1; + } else { + hits[index]++; + } + } + + /** Return the number of hits in the past 5 minutes. + @param timestamp - The current timestamp (in seconds granularity). */ + public int getHits2(int timestamp) { + int res = 0; + for (int i = 0; i < 300; i++) { + if (timestamp - times[i] < 300) { + res += hits[i]; + } + } + return res; + } +} diff --git a/DesignPhoneDirectory.java b/DesignPhoneDirectory.java new file mode 100644 index 0000000..b1a599b --- /dev/null +++ b/DesignPhoneDirectory.java @@ -0,0 +1,83 @@ +package leetcode; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Queue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : DesignPhoneDirectory + * Creator : Edward + * Date : Jan, 2018 + * Description : 379. Design Phone Directory + */ +public class DesignPhoneDirectory { + /** + * Design a Phone Directory which supports the following operations: + + get: Provide a number which is not assigned to anyone. + check: Check if a number is available or not. + release: Recycle or release a number. + Example: + + // Init a phone directory containing a total of 3 numbers: 0, 1, and 2. + PhoneDirectory directory = new PhoneDirectory(3); + + // It can return any available phone number. Here we assume it returns 0. + directory.get(); + + // Assume it returns 1. + directory.get(); + + // The number 2 is available, so return true. + directory.check(2); + + // It returns 2, the only number that is left. + directory.get(); + + // The number 2 is no longer available, so return false. + directory.check(2); + + // Release number 2 back to the pool. + directory.release(2); + + // Number 2 is available again, return true. + directory.check(2); + + * @param maxNumbers + */ + + HashSet used = new HashSet<>(); + Queue queue = new LinkedList<>(); + int maxNumbers; + + public DesignPhoneDirectory(int maxNumbers) { + this.maxNumbers = maxNumbers; + for (int i = 0; i < maxNumbers; i++) { + queue.offer(i); + } + } + + public int get() { + Integer res = queue.poll(); + if (res == null) { + return -1; + } + used.add(res); + return res; + } + + public boolean check(int number) { + if (number >= maxNumbers || number < 0) { + return false; + } + return !used.contains(number); + } + + public void release(int number) { + if (used.remove(number)) { + queue.offer(number); + } + } +} diff --git a/DesignSnakeGame.java b/DesignSnakeGame.java new file mode 100644 index 0000000..a5dedef --- /dev/null +++ b/DesignSnakeGame.java @@ -0,0 +1,70 @@ +package leetcode; + +import java.util.Deque; +import java.util.HashSet; +import java.util.LinkedList; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : DesignSnakeGame + * Creator : Edward + * Date : Jan, 2018 + * Description : 353. Design Snake Game + */ +public class DesignSnakeGame { + + HashSet set; // 位置 + Deque deque; + int score; + int foodIndex; + int width; + int height; + int[][] food; + + public DesignSnakeGame(int width, int height, int[][] food) { + this.width = width; + this.height = height; + this.food = food; + set = new HashSet<>(); + deque = new LinkedList<>(); + score = 0; + foodIndex = 0; + set.add(0); + deque.offerLast(0); + } + + public int move(String direction) { + if (score == -1) { + return -1; + } + + int rowHead = deque.peekFirst() / width; + int colHead = deque.peekFirst() % width; + + switch (direction) { + case "U" : rowHead--; + break; + case "D" : rowHead++; + break; + case "L" : colHead--; + break; + default : colHead++; + } + int head = rowHead * width + colHead; + set.remove(deque.peekLast()); + if (rowHead < 0 || rowHead == height || colHead < 0 || colHead == width || set.contains(head)) { + return score = -1; + } + set.add(head); + deque.offerFirst(head); + if (foodIndex < food.length && rowHead == food[foodIndex][0] && colHead == food[foodIndex][1]) { + foodIndex++; + ++score; + set.add(deque.peekLast()); + return score; + } + deque.pollLast(); + return score; + } +} diff --git a/DesignTicTacToe.java b/DesignTicTacToe.java new file mode 100644 index 0000000..06a47c5 --- /dev/null +++ b/DesignTicTacToe.java @@ -0,0 +1,88 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : DesignTicTacToe + * Creator : Edward + * Date : Jan, 2018 + * Description : 348. Design Tic-Tac-Toe + */ +public class DesignTicTacToe { + /** + * Given n = 3, assume that player 1 is "X" and player 2 is "O" in the board. + + TicTacToe toe = new TicTacToe(3); + + toe.move(0, 0, 1); -> Returns 0 (no one wins) + |X| | | + | | | | // Player 1 makes a move at (0, 0). + | | | | + + toe.move(0, 2, 2); -> Returns 0 (no one wins) + |X| |O| + | | | | // Player 2 makes a move at (0, 2). + | | | | + + toe.move(2, 2, 1); -> Returns 0 (no one wins) + |X| |O| + | | | | // Player 1 makes a move at (2, 2). + | | |X| + + toe.move(1, 1, 2); -> Returns 0 (no one wins) + |X| |O| + | |O| | // Player 2 makes a move at (1, 1). + | | |X| + + toe.move(2, 0, 1); -> Returns 0 (no one wins) + |X| |O| + | |O| | // Player 1 makes a move at (2, 0). + |X| |X| + + toe.move(1, 0, 2); -> Returns 0 (no one wins) + |X| |O| + |O|O| | // Player 2 makes a move at (1, 0). + |X| |X| + + toe.move(2, 1, 1); -> Returns 1 (player 1 wins) + |X| |O| + |O|O| | // Player 1 makes a move at (2, 1). + |X|X|X| + + + cols[1,-2,3] + + * @param n + */ + + private int[] rows; + private int[] cols; + private int diagonal; + private int antiDiagonal; + private int size; + + public DesignTicTacToe(int n) { + rows = new int[n]; + cols = new int[n]; + this.size = n; + } + + //time : O(1) + public int move(int row, int col, int player) { + int toAdd = player == 1 ? 1 : -1; + + rows[row] += toAdd; + cols[col] += toAdd; + if (row == col) { + diagonal += toAdd; + } + if (col == (cols.length - row - 1)) { + antiDiagonal += toAdd; + } + if (Math.abs(rows[row]) == size || Math.abs(cols[col]) == size + || Math.abs(diagonal) == size || Math.abs(antiDiagonal) == size) { + return player; + } + return 0; + } +} diff --git a/DesignTwitter.java b/DesignTwitter.java new file mode 100644 index 0000000..fead54f --- /dev/null +++ b/DesignTwitter.java @@ -0,0 +1,117 @@ +package leetcode; + +import java.util.*; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : DesignTwitter + * Creator : Edward + * Date : Jan, 2018 + * Description : 355. Design Twitter + */ +public class DesignTwitter { + + private int timeStamp = 0; + private HashMap userMap; + + class Tweet { + public int id; + public int time; + public Tweet next; + + public Tweet(int id) { + this.id = id; + time = timeStamp++; + next = null; + } + } + + class User { + public int id; + public HashSet followed; + public Tweet tweetHead; + + public User(int id) { + this.id = id; + followed = new HashSet<>(); + follow(id); + tweetHead = null; + } + + public void follow(int id) { + followed.add(id); + } + + public void unFollow(int id) { + followed.remove(id); + } + + public void post(int id) { + Tweet tweet = new Tweet(id); + tweet.next = tweetHead; + tweetHead = tweet; + } + } + + /** Initialize your data structure here. */ + public DesignTwitter() { + userMap = new HashMap<>(); + } + + public void postTweet(int userId, int tweetId) { + if (!userMap.containsKey(userId)) { + User user = new User(userId); + userMap.put(userId, user); + } + userMap.get(userId).post(tweetId); + } + + /** Retrieve the 10 most recent tweet ids in the user's news feed. + * Each item in the news feed must be posted by users who the user followed or by the user herself. + * Tweets must be ordered from most recent to least recent. + * */ + public List getNewsFeed(int userId) { + List res = new LinkedList<>(); + + if (!userMap.containsKey(userId)) return res; + + HashSet users = userMap.get(userId).followed; + PriorityQueue pq = new PriorityQueue<>(users.size(), (a, b) -> (b.time - a.time)); + for (int user : users) { + Tweet tweet = userMap.get(user).tweetHead; + if (tweet != null) { + pq.offer(tweet); + } + } + int count = 0; + while (!pq.isEmpty() && count < 10) { + Tweet tweet = pq.poll(); + res.add(tweet.id); + count++; + if (tweet.next != null) { + pq.offer(tweet.next); + } + } + return res; + } + + public void follow(int followerId, int followeeId) { + if (!userMap.containsKey(followerId)) { + User user = new User(followerId); + userMap.put(followerId, user); + } + if (!userMap.containsKey(followeeId)) { + User user = new User(followeeId); + userMap.put(followeeId, user); + } + userMap.get(followerId).follow(followeeId); + } + + public void unfollow(int followerId, int followeeId) { + if (!userMap.containsKey(followerId) || followerId == followeeId) { + return; + } + userMap.get(followerId).unFollow(followeeId); + } +} diff --git a/DiameterofBinaryTree.java b/DiameterofBinaryTree.java new file mode 100644 index 0000000..0beb2a5 --- /dev/null +++ b/DiameterofBinaryTree.java @@ -0,0 +1,48 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : DiameterofBinaryTree + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class DiameterofBinaryTree { + /** + * 543. Diameter of Binary Tree + * Given a binary tree, you need to compute the length of the diameter of the tree. + * The diameter of a binary tree is the length of the longest path between any two nodes in a tree. + * This path may or may not pass through the root. + * Example: + Given a binary tree + 1 + / \ + 2 3 + / \ + 4 5 + Return 3, which is the length of the path [4,2,1,3] or [5,2,1,3]. + + length of longest path which pass it = MaxDepth of its left subtree + MaxDepth of its right subtree + + time : O(n) + space : O(n) + * @param root + * @return + */ + + private int res = 0; + + public int diameterOfBinaryTree(TreeNode root) { + helper(root); + return res; + } + + public int helper(TreeNode root) { + if (root == null) return 0; + int left = helper(root.left); + int right = helper(root.right); + res = Math.max(res, left + right); + return Math.max(left, right) + 1; + } +} diff --git a/DifferentWaystoAddParentheses.java b/DifferentWaystoAddParentheses.java new file mode 100644 index 0000000..39b810d --- /dev/null +++ b/DifferentWaystoAddParentheses.java @@ -0,0 +1,72 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : DifferentWaystoAddParentheses + * Creator : Edward + * Date : Nov, 2017 + * Description : 241. Different Ways to Add Parentheses + */ +public class DifferentWaystoAddParentheses { + /** + * Given a string of numbers and operators, return all possible results from computing + * all the different possible ways to group numbers and operators. The valid operators are +, - and *. + + + Example 1 + Input: "2-1-1". + + ((2-1)-1) = 0 + (2-(1-1)) = 2 + Output: [0, 2] + + + Example 2 + Input: "2*3-4*5" + + (2*(3-(4*5))) = -34 + ((2*3)-(4*5)) = -14 + ((2*(3-4))*5) = -10 + (2*((3-4)*5)) = -10 + (((2*3)-4)*5) = 10 + Output: [-34, -14, -10, -10, 10] + + time : O(n^3) 不确定 + space : O(n) + + + * @param input + * @return + */ + public List diffWaysToCompute(String input) { + List res = new ArrayList<>(); + for (int i = 0; i < input.length(); i++) { + char c = input.charAt(i); + if (c == '-' || c == '+' || c == '*') { + String a = input.substring(0, i); + String b = input.substring(i + 1); + List al = diffWaysToCompute(a); + List bl = diffWaysToCompute(b); + for (int x : al) { + for (int y : bl) { + if (c == '-') { + res.add(x - y); + } else if (c == '+') { + res.add(x + y); + } else if (c == '*') { + res.add(x * y); + } + } + } + } + } + if (res.size() == 0) { + res.add(Integer.valueOf(input)); + } + return res; + } +} diff --git a/DistinctSubsequences.java b/DistinctSubsequences.java new file mode 100644 index 0000000..9e91817 --- /dev/null +++ b/DistinctSubsequences.java @@ -0,0 +1,69 @@ +package leetcode; + +import java.util.Arrays; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : DistinctSubsequences + * Creator : Edward + * Date : Nov, 2017 + * Description : 115. Distinct Subsequences + */ +public class DistinctSubsequences { + /** + * Given a string S and a string T, count the number of distinct subsequences of S which equals T. + + A subsequence of a string is a new string which is formed from the original string + by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. + (ie, "ACE" is a subsequence of "ABCDE" while "AEC" is not). + + Here is an example: + S = "rabbbit", T = "rabbit" + + Return 3. + + int[][] dp + + 1, S.charAt(i) != T.charAt(j) + dp[i][j] = dp[i-1][j] + + 2, S.charAt(i) == T.charAt(j) + dp[i][j] = dp[i-1][j] + dp[i-1][j-1] + + r a b b i t + 1, 0, 0, 0, 0, 0, 0 + r 1, 1, 0, 0, 0, 0, 0 + a 1, 1, 1, 0, 0, 0, 0 + b 1, 1, 1, 1, 0, 0, 0 + b 1, 1, 1, 2, 1, 0, 0 + b 1, 1, 1, 3, 3, 0, 0 + i 1, 1, 1, 3, 3, 3, 0 + t 1, 1, 1, 3, 3, 3, 3 + + time : O(m * n) + space : O(m * n) + + + * @param S + * @param T + * @return + */ + public static int numDistinct(String S, String T) { + int[][] dp = new int[S.length() + 1][T.length() + 1]; + for (int i = 0; i < S.length(); i++) { + dp[i][0] = 1; + } + + for (int i = 1; i <= S.length(); i++) { + for (int j = 1; j <= T.length(); j++) { + if (S.charAt(i - 1) == T.charAt(j - 1)) { + dp[i][j] = dp[i-1][j] + dp[i-1][j-1]; + } else { + dp[i][j] = dp[i-1][j]; + } + } + } + return dp[S.length()][T.length()]; + } +} diff --git a/DivideTwoIntegers.java b/DivideTwoIntegers.java new file mode 100644 index 0000000..0139628 --- /dev/null +++ b/DivideTwoIntegers.java @@ -0,0 +1,52 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : DivideTwoIntegers + * Creator : Edward + * Date : Nov, 2017 + * Description : 29. Divide Two Integers + */ +public class DivideTwoIntegers { + /** + * Divide two integers without using multiplication, division and mod operator. + * 1, + - + * 2, 越界 + * 3, = 0 3/5 + * 4, 正常 + + time : O(logn) + space : O(logn) + + + * @param dividend + * @param divisor + * @return + */ + public int divide(int dividend, int divisor) { + int sign = 1; + if ((dividend > 0 && divisor < 0) || (dividend < 0 && divisor > 0)) sign = -1; + long ldividend = Math.abs((long)dividend); + long ldivisor = Math.abs((long)divisor); + if (ldividend < ldivisor || ldividend == 0) return 0; + long lres = divide(ldividend, ldivisor); + int res = 0; + if (lres > Integer.MAX_VALUE) { + res = (sign == 1) ? Integer.MAX_VALUE : Integer.MIN_VALUE; + } else res = (int)(sign * lres); + return res; + } + + public long divide(long ldividend, long ldivisor) { + if (ldividend < ldivisor) return 0; + long sum = ldivisor; + long multiple = 1; + while ((sum + sum) <= ldividend) { + sum += sum; + multiple += multiple; + } + return multiple + divide(ldividend - sum, ldivisor); + } + +} diff --git a/DungeonGame.java b/DungeonGame.java new file mode 100644 index 0000000..68503a5 --- /dev/null +++ b/DungeonGame.java @@ -0,0 +1,59 @@ +package leetcode; + +import java.lang.reflect.Array; +import java.util.Arrays; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : DungeonGame + * Creator : Edward + * Date : Dec, 2017 + * Description : 174. Dungeon Game + */ +public class DungeonGame { + + /** + + -2 -3 3 + -5 -10 1 + 10 30 -5 + + [7, 5, 2] + [6, 11, 5] + [1, 1, 6] + + time : O(m * n) + space : O(m * n) + + * @param dungeon + * @return + */ + + public int calculateMinimumHP(int[][] dungeon) { + if (dungeon == null || dungeon.length == 0 || dungeon[0].length == 0) return 0; + + int m = dungeon.length; + int n = dungeon[0].length; + int[][] dp = new int[m][n]; + + dp[m - 1][n - 1] = Math.max(1 - dungeon[m - 1][n - 1], 1); + + for (int i = m - 2; i >= 0; i--) { + dp[i][n - 1] = Math.max(dp[i + 1][n - 1] - dungeon[i][n - 1], 1); + } + for (int i = n - 2; i >= 0; i--) { + dp[m - 1][i] = Math.max(dp[m - 1][i + 1] - dungeon[m - 1][i], 1); + } + + for (int i = m - 2; i >= 0; i--) { + for (int j = n - 2; j >= 0; j--) { + int down = Math.max(dp[i + 1][j] - dungeon[i][j], 1); + int right = Math.max(dp[i][j + 1] - dungeon[i][j], 1); + dp[i][j] = Math.min(down, right); + } + } + return dp[0][0]; + } + +} diff --git a/EditDistance.java b/EditDistance.java new file mode 100644 index 0000000..49ed713 --- /dev/null +++ b/EditDistance.java @@ -0,0 +1,68 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : EditDistance + * Creator : Edward + * Date : Dec, 2017 + * Description : 72. Edit Distance + */ +public class EditDistance { + /** + * Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. + * (each operation is counted as 1 step.) + + You have the following 3 operations permitted on a word: + + a) Insert a character + b) Delete a character + c) Replace a character + + abcd -> aef + + dp[i][j]表示的是,从字符串1的i的位置转换到字符串2的j的位置,所需要的最少步数。 + + + 1,字符串中的字符相等: dp[i][j] = dp[i - 1][j - 1] + 2,字符串中的字符不等: + insert: dp[i][j] = dp[i][j - 1] + 1; + replace: dp[i][j] = dp[i - 1][j - 1] + 1; + delete: dp[i][j] = dp[i - 1][j] + 1; + + a b c d + 0 1 2 3 4 + a 1 0 1 2 3 + e 2 1 1 2 3 + f 3 2 2 2 3 + + time : O(m * n) + space : O(m * n) + + * @param word1 + * @param word2 + * @return + */ + public int minDistance(String word1, String word2) { + int len1 = word1.length(); + int len2 = word2.length(); + + int[][] dp = new int[len1 + 1][len2 + 1]; + for (int i = 0; i <= len1; i++) { + dp[i][0] = i; + } + for (int i = 0; i <= len2; i++) { + dp[0][i] = i; + } + for (int i = 1; i <= len1; i++) { + for (int j = 1; j <= len2; j++) { + if (word1.charAt(i - 1) == word2.charAt(j - 1)) { + dp[i][j] = dp[i - 1][j - 1]; + } else { + dp[i][j] = Math.min(Math.min(dp[i][j - 1], dp[i - 1][j]), dp[i -1][j - 1]); + } + } + } + return dp[len1][len2]; + } +} diff --git a/EliminationGame.java b/EliminationGame.java new file mode 100644 index 0000000..fc04993 --- /dev/null +++ b/EliminationGame.java @@ -0,0 +1,51 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : EliminationGame + * Creator : Edward + * Date : Oct, 2017 + * Description : 390. Elimination Game + */ +public class EliminationGame { + /** + * Example: + + Input: + n = 8, + 1 2 3 4 5 6 7 8 + 2 4 6 8 res = 2 + 2 6 res = 2 + 6 res = 6 + + + 1 2 3 4 5 6 7 + 2 4 6 + 4 + + Output: + 6 + + time : O(logn) + space : O(1) + + * @param n + * @return + */ + public int lastRemaining(int n) { + boolean left = true; + int remaining = n; + int step = 1; + int res = 1; // head + while (remaining > 1) { + if (left || remaining % 2 == 1) { + res = res + step; + } + remaining = remaining / 2; + step = step * 2; + left = !left; + } + return res; + } +} diff --git a/EncodeandDecodeStrings.java b/EncodeandDecodeStrings.java new file mode 100644 index 0000000..751938d --- /dev/null +++ b/EncodeandDecodeStrings.java @@ -0,0 +1,45 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : EncodeandDecodeStrings + * Creator : Edward + * Date : Oct, 2017 + * Description : 271. Encode and Decode Strings + */ +public class EncodeandDecodeStrings { + + + /** + * time : O(n); + * space : O(n) + * @param strs + * @return + */ + + // Encodes a list of strings to a single string. + public String encode(List strs) { + StringBuilder sb = new StringBuilder(); + for (String str : strs) { + sb.append(str.length()).append('/').append(str); + } + return sb.toString(); + } + + // Decodes a single string to a list of strings. + public List decode(String s) { + List res = new ArrayList<>(); + int i = 0; + while (i < s.length()) { + int slash = s.indexOf('/', i); + int size = Integer.valueOf(s.substring(i, slash)); + res.add(s.substring(slash + 1, slash + size + 1)); + i = slash + size + 1; + } + return res; + } +} diff --git a/EvaluateDivision.java b/EvaluateDivision.java new file mode 100644 index 0000000..8fb77a5 --- /dev/null +++ b/EvaluateDivision.java @@ -0,0 +1,98 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : EvaluateDivision + * Creator : Edward + * Date : Dec, 2017 + * Description : 399. Evaluate Division + */ +public class EvaluateDivision { + + /** + * Equations are given in the format A / B = k, where A and B are variables represented as strings, + * and k is a real number (floating point number). Given some queries, return the answers. + * If the answer does not exist, return -1.0. + + a / b * b / c = a / c + + Example: + Given a / b = 2.0, b / c = 3.0. + queries are: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ? . + return [6.0, 0.5, -1.0, 1.0, -1.0 ]. + + The input is: vector> equations, vector& values, vector> queries , + where equations.size() == values.size(), and the values are positive. This represents the equations. Return vector. + + According to the example above: + + equations = [ ["a", "b"], ["b", "c"] ], + values = [2.0, 3.0], + queries = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ]. + + equation : "b", "c" + + map : "a" 'b', 2.0 + "b" 'a', 1/2.0 + 'c', 3.0 + "c" 'b', 1/3.0 + + time : O(V+E) + space : O(n) + + + */ + + HashMap> map; + + public double[] calcEquation(String[][] equations, double[] values, String[][] queries) { + map = new HashMap<>(); + for (int i = 0; i < equations.length; i++) { + String[] equation = equations[i]; + if (!map.containsKey(equation[0])) { + map.put(equation[0], new ArrayList<>()); + } + map.get(equation[0]).add(new GraphNode(equation[1], values[i])); + if (!map.containsKey(equation[1])) { + map.put(equation[1], new ArrayList<>()); + } + map.get(equation[1]).add(new GraphNode(equation[0], 1 / values[i])); + } + + double[] res = new double[queries.length]; + for (int i = 0; i < res.length; i++) { + res[i] = find(queries[i][0], queries[i][1], 1, new HashSet<>()); + } + return res; + } + + private double find(String start, String end, double value, HashSet visited) { + if (visited.contains(start)) return -1; + if (!map.containsKey(start)) return -1; + + if (start.equals(end)) return value; + visited.add(start); + for (GraphNode next : map.get(start)) { + double sub = find(next.den, end, value * next.val, visited); + if (sub != -1.0) return sub; + } + visited.remove(start); + return -1; + } + + class GraphNode { + String den; + double val; + GraphNode(String den, double val) { + this.den = den; + this.val = val; + } + } +} + diff --git a/EvaluateReversePolishNotation.java b/EvaluateReversePolishNotation.java new file mode 100644 index 0000000..63ca320 --- /dev/null +++ b/EvaluateReversePolishNotation.java @@ -0,0 +1,48 @@ +package leetcode; + +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : EvaluateReversePolishNotation + * Creator : Edward + * Date : Sep, 2017 + * Description : 150. Evaluate Reverse Polish Notation + */ +public class EvaluateReversePolishNotation { + /** + * Valid operators are +, -, *, /. Each operand may be an integer or another expression. + + Some examples: + ["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9 + ["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6 + + time : O(n) + space : O(n) + + * @param tokens + * @return + */ + public int evalRPN(String[] tokens) { + Stack stack = new Stack<>(); + for (String s : tokens) { + if (s.equals("+")) { + stack.push(stack.pop() + stack.pop()); + } else if (s.equals("-")) { + int b = stack.pop(); + int a = stack.pop(); + stack.push(a - b); + } else if (s.equals("*")) { + stack.push(stack.pop() * stack.pop()); + } else if (s.equals("/")) { + int b = stack.pop(); + int a = stack.pop(); + stack.push(a / b); + } else { + stack.push(Integer.parseInt(s)); + } + } + return stack.pop(); + } +} diff --git a/ExcelSheetColumnNumber.java b/ExcelSheetColumnNumber.java new file mode 100644 index 0000000..b94c250 --- /dev/null +++ b/ExcelSheetColumnNumber.java @@ -0,0 +1,39 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ExcelSheetColumnNumber + * Creator : Edward + * Date : Oct, 2017 + * Description : 171. Excel Sheet Column Number + */ +public class ExcelSheetColumnNumber { + /** + * For example: + + A -> 1 + B -> 2 + C -> 3 + ... + Z -> 26 + AA -> 27 + AB -> 28 + + AB -> 28 + res = 1 * 26 + 2 = 28 + + time : O(n) + space : O(1) + + * @param s + * @return + */ + public int titleToNumber(String s) { + int res = 0; + for (int i = 0; i < s.length(); i++) { + res = res * 26 + (s.charAt(i) - 'A' + 1); + } + return res; + } +} diff --git a/ExcelSheetColumnTitle.java b/ExcelSheetColumnTitle.java new file mode 100644 index 0000000..1dc9586 --- /dev/null +++ b/ExcelSheetColumnTitle.java @@ -0,0 +1,36 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ExcelSheetColumnTitle + * Creator : Edward + * Date : Oct, 2017 + * Description : 168. Excel Sheet Column Title + */ +public class ExcelSheetColumnTitle { + /** + * 1 -> A + 2 -> B + 3 -> C + ... + 26 -> Z + 27 -> AA + 28 -> AB + + time : O(n) + space : O(n) + + * @param n + * @return + */ + public String convertToTitle(int n) { + StringBuilder sb = new StringBuilder(); + while (n > 0) { + n--; + sb.append((char)('A' + n % 26)); + n /= 26; + } + return sb.reverse().toString(); + } +} diff --git a/ExpressionAddOperators.java b/ExpressionAddOperators.java new file mode 100644 index 0000000..c3f7da8 --- /dev/null +++ b/ExpressionAddOperators.java @@ -0,0 +1,63 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ExpressionAddOperators + * Creator : Edward + * Date : Dec, 2017 + * Description : 282. Expression Add Operators + */ +public class ExpressionAddOperators { + + /** + * Given a string that contains only digits 0-9 and a target value, + * return all possibilities to add binary operators (not unary) +, -, or * + * between the digits so they evaluate to the target value. + + Examples: + "123", 6 -> ["1+2+3", "1*2*3"] + "232", 8 -> ["2*3+2", "2+3*2"] + "105", 5 -> ["1*0+5","10-5"] + "00", 0 -> ["0+0", "0-0", "0*0"] + "3456237490", 9191 -> [] + + time : 不知道 + space : O(n) + + + * @param num + * @param target + * @return + */ + + public List addOperators(String num, int target) { + List res = new ArrayList<>(); + if (num == null || num.length() == 0) return res; + helper(res, "", num, target, 0, 0, 0); + return res; + } + + private void helper(List res, String path, String num, int target, int pos, long val, long pre) { + if (pos == num.length()) { + if (target == val) { + res.add(path); + return; + } + } + for (int i = pos; i < num.length(); i++) { + if (i != pos && num.charAt(pos) == '0') break; + long cur = Long.parseLong(num.substring(pos, i + 1)); + if (pos == 0) { + helper(res, path + cur, num, target, i + 1, cur, cur); + } else { + helper(res, path + "+" + cur, num, target, i + 1, val + cur, cur); + helper(res, path + "-" + cur, num, target, i + 1, val - cur, -cur); + helper(res, path + "*" + cur, num, target, i + 1, val - pre + pre * cur, pre * cur); + } + } + } +} diff --git a/FactorCombinations.java b/FactorCombinations.java new file mode 100644 index 0000000..e1aeb24 --- /dev/null +++ b/FactorCombinations.java @@ -0,0 +1,76 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FactorCombinations + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class FactorCombinations { + + /** + * 254. Factor Combinations + * Numbers can be regarded as product of its factors. For example, + + 8 = 2 x 2 x 2; + = 2 x 4. + Write a function that takes an integer n and return all possible combinations of its factors. + + Note: + You may assume that n is always positive. + Factors should be greater than 1 and less than n. + Examples: + input: 1 + output: + [] + input: 37 + output: + [] + input: 12 + output: + [ + [2, 6], + [2, 2, 3], + [3, 4] + ] + input: 32 + output: + [ + [2, 16], + [2, 2, 8], + [2, 2, 2, 4], + [2, 2, 2, 2, 2], + [2, 4, 4], + [4, 8] + ] + + * @param n + * @return + */ + + public List> getFactors(int n) { + List> res = new ArrayList<>(); + helper(res, new ArrayList<>(), n, 2); + return res; + } + public void helper(List> res, List list, int n, int start) { + if (n == 1) { + if (list.size() > 1) { + res.add(new ArrayList<>(list)); + return; + } + } + for (int i = start; i <= n; i++) { + if (n % i == 0) { + list.add(i); + helper(res, list, n / i, i); + list.remove(list.size() - 1); + } + } + } +} diff --git a/FactorialTrailingZeroes.java b/FactorialTrailingZeroes.java new file mode 100644 index 0000000..2ca62ce --- /dev/null +++ b/FactorialTrailingZeroes.java @@ -0,0 +1,27 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FactorialTrailingZeroes + * Creator : Edward + * Date : Dec, 2017 + * Description : 172. Factorial Trailing Zeroes + */ +public class FactorialTrailingZeroes { + /** + * Given an integer n, return the number of trailing zeroes in n!. + + Note: Your solution should be in logarithmic time complexity. + + + time : O(logn) + space : O(n) + + * @param n + * @return + */ + public int trailingZeroes(int n) { + return n == 0 ? 0 : n / 5 + trailingZeroes(n / 5); + } +} diff --git a/FindAllAnagramsinaString.java b/FindAllAnagramsinaString.java new file mode 100644 index 0000000..fda6194 --- /dev/null +++ b/FindAllAnagramsinaString.java @@ -0,0 +1,69 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FindAllAnagramsinaString + * Creator : Edward + * Date : Nov, 2017 + * Description : 438. Find All Anagrams in a String + */ +public class FindAllAnagramsinaString { + /** + * Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. + + Strings consists of lowercase English letters only and the length of + both strings s and p will not be larger than 20,100. + + The order of output does not matter. + + Example 1: + + Input: + s: "cbaebabacd" p: "abc" + + Output: + [0, 6] + + Explanation: + The substring with start index = 0 is "cba", which is an anagram of "abc". + The substring with start index = 6 is "bac", which is an anagram of "abc". + + 0 1 2 3 4 5 6 7 8 9 + c b a e b a b a c d + e + s + + time : O(n) + space : O(n) + + + * @param s + * @param p + * @return + */ + + public static List findAnagrams(String s, String p) { + List res = new ArrayList<>(); + if (s == null || p == null || s.length() < p.length()) return res; + int[] chars = new int[26]; + for (char c : p.toCharArray()) { + chars[c - 'a']++; + } + int start = 0, end = 0; + int count = p.length(); + while (end < s.length()) { + if (end - start == p.length() && chars[s.charAt(start++) - 'a'] >= 0) { + count++; + } + if (--chars[s.charAt(end++) - 'a'] >= 0) { + count--; + } + if (count == 0) res.add(start); + } + return res; + } +} diff --git a/FindAllDuplicatesinanArray.java b/FindAllDuplicatesinanArray.java new file mode 100644 index 0000000..3d270c8 --- /dev/null +++ b/FindAllDuplicatesinanArray.java @@ -0,0 +1,46 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FindAllDuplicatesinanArray + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class FindAllDuplicatesinanArray { + /** + * 442. Find All Duplicates in an Array + * Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. + + Find all the elements that appear twice in this array. + + Could you do it without extra space and in O(n) runtime? + + Example: + Input: + [4,3,2,7,8,2,3,1] + + Output: + [2,3] + + time : O(n) space : O(1) + * @param nums + * @return + */ + public List findDuplicates(int[] nums) { + List res = new ArrayList<>(); + if (nums == null || nums.length == 0) return res; + for (int i = 0; i < nums.length; i++) { + int index = Math.abs(nums[i]) - 1; + if (nums[index] < 0) { + res.add(Math.abs(index + 1)); + } + nums[index] = -nums[index]; + } + return res; + } +} diff --git a/FindAllNumbersDisappearedinanArray.java b/FindAllNumbersDisappearedinanArray.java new file mode 100644 index 0000000..54458ca --- /dev/null +++ b/FindAllNumbersDisappearedinanArray.java @@ -0,0 +1,52 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FindAllNumbersDisappearedinanArray + * Creator : Edward + * Date : Nov, 2017 + * Description : 448. Find All Numbers Disappeared in an Array + */ +public class FindAllNumbersDisappearedinanArray { + /** + * Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. + + Find all the elements of [1, n] inclusive that do not appear in this array. + + Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space. + + Example: + + Input: + [4,3,2,7,8,2,3,1] + + Output: + [5,6] + + time : O(n) + space : O(n) + + * @param nums + * @return + */ + + public List findDisappearedNumbers(int[] nums) { + List res = new ArrayList<>(); + for (int i = 0; i < nums.length; i++) { + int index = Math.abs(nums[i]) - 1; + if (nums[index] > 0) { + nums[index] = -nums[index]; + } + } + for (int i = 0; i < nums.length; i++) { + if (nums[i] > 0) { + res.add(i + 1); + } + } + return res; + } +} diff --git a/FindBottomLeftTreeValue.java b/FindBottomLeftTreeValue.java new file mode 100644 index 0000000..6d90767 --- /dev/null +++ b/FindBottomLeftTreeValue.java @@ -0,0 +1,84 @@ +package leetcode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FindBottomLeftTreeValue + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class FindBottomLeftTreeValue { + + /** + * 513. Find Bottom Left Tree Value + *Given a binary tree, find the leftmost value in the last row of the tree. + + Example 1: + Input: + + 2 + / \ + 1 3 + + Output: + 1 + Example 2: + Input: + + 1 + / \ + 2 3 + / / \ + 4 5 6 + / + 7 + + Output: + 7 + + time : O(n); + space : O(n); + * @param root + * @return + */ + + int res = 0; + int height = 0; + + public int findBottomLeftValue(TreeNode root) { + if (root == null) return -1; + helper(root, 1); + return res; + } + + public void helper(TreeNode root, int depth) { + if (root == null) return; + if (height < depth) { + res = root.val; + height = depth; + } + helper(root.left, depth + 1); + helper(root.right, depth + 1); + } + + + + public int findBottomLeftValue2(TreeNode root) { + if (root == null) return -1; + int res = 0; + Queue queue = new LinkedList<>(); + queue.offer(root); + while (!queue.isEmpty()) { + TreeNode cur = queue.poll(); + res = cur.val; + if (cur.right != null) queue.offer(cur.right); + if (cur.left != null) queue.offer(cur.left); + } + return res; + } + +} diff --git a/FindKPairswithSmallestSums.java b/FindKPairswithSmallestSums.java new file mode 100644 index 0000000..79eb4e4 --- /dev/null +++ b/FindKPairswithSmallestSums.java @@ -0,0 +1,84 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; +import java.util.PriorityQueue; +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FindKPairswithSmallestSums + * Creator : Edward + * Date : Jan, 2018 + * Description : 373. Find K Pairs with Smallest Sums + */ +public class FindKPairswithSmallestSums { + /** + * You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. + + Define a pair (u,v) which consists of one element from the first array and one element from the second array. + + Find the k pairs (u1,v1),(u2,v2) ...(uk,vk) with the smallest sums. + + Example 1: + Given nums1 = [1,7,11], nums2 = [2,4,6], k = 3 + + Return: [1,2],[1,4],[1,6] + + The first 3 pairs are returned from the sequence: + [1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6] + + Example 2: + Given nums1 = [1,1,2], nums2 = [1,2,3], k = 2 + + Return: [1,1],[1,1] + + The first 2 pairs are returned from the sequence: + [1,1],[1,1],[1,2],[2,1],[1,2],[2,2],[1,3],[1,3],[2,3] + Example 3: + Given nums1 = [1,2], nums2 = [3], k = 3 + + Return: [1,3],[2,3] + + All possible pairs are returned from the sequence: + [1,3],[2,3] + + 前 k 个最小:PriorityQueue size = k + + nums1 = [1,7,11], nums2 = [2,4,6], k = 3 + + 1,6,2 7,2,0 11,2,0 + + 1,2,0 -> 1,4,1 -> 1,6,2 + + + + time : O(kLogk) + space : O(k) + + * @param nums1 + * @param nums2 + * @param k + * @return + */ + public List kSmallestPairs(int[] nums1, int[] nums2, int k) { + List res = new ArrayList<>(); + if (nums1.length == 0 || nums2.length == 0 || k == 0) { + return res; + } + + PriorityQueue pq = new PriorityQueue<>((a, b) -> (a[0] + a[1] - b[0] - b[1])); + for (int i = 0; i < nums1.length && i < k; i++) { + pq.offer(new int[]{nums1[i], nums2[0], 0}); + } + + while (!pq.isEmpty() && k-- > 0) { + int[] cur = pq.poll(); + res.add(new int[]{cur[0], cur[1]}); + if (cur[2] == nums2.length - 1) continue; + pq.offer(new int[]{cur[0], nums2[cur[2] + 1], cur[2] + 1}); + } + return res; + } +} diff --git a/FindLeavesofBinaryTree.java b/FindLeavesofBinaryTree.java new file mode 100644 index 0000000..0c39676 --- /dev/null +++ b/FindLeavesofBinaryTree.java @@ -0,0 +1,70 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FindLeavesofBinaryTree + * Creator : Edward + * Date : Jan, 2018 + * Description : 366. Find Leaves of Binary Tree + */ +public class FindLeavesofBinaryTree { + /** + * Given a binary tree, collect a tree's nodes as if you were doing this: Collect and remove all leaves, + * repeat until the tree is empty. + + Example: + Given binary tree + 1 + / \ + 2 3 + / \ + 4 5 0 + / + null -1 + Returns [4, 5, 3], [2], [1]. + + + Explanation: + 1. Removing the leaves [4, 5, 3] would result in this tree: + + 1 + / + 2 + 2. Now removing the leaf [2] would result in this tree: + + 1 + 3. Now removing the leaf [1] would result in the empty tree: + + [] + Returns [4, 5, 3], [2], [1]. + + time : O(n) + space : O(n) + + * @param root + * @return + */ + public List> findLeaves(TreeNode root) { + List> res = new ArrayList<>(); + helper(res, root); + return res; + } + + private int helper(List> res, TreeNode root) { + if (root == null) return -1; + int left = helper(res, root.left); + int right = helper(res, root.right); + int level = Math.max(left, right) + 1; + if (res.size() == level) { + res.add(new ArrayList<>()); + } + res.get(level).add(root.val); + root.left = null; + root.right = null; + return level; + } +} diff --git a/FindMedianfromDataStream.java b/FindMedianfromDataStream.java new file mode 100644 index 0000000..a93638c --- /dev/null +++ b/FindMedianfromDataStream.java @@ -0,0 +1,52 @@ +package leetcode; + +import java.util.PriorityQueue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FindMedianfromDataStream + * Creator : Edward + * Date : Nov, 2017 + * Description : 295. Find Median from Data Stream + */ +public class FindMedianfromDataStream { + /** + * For example: + + addNum(1) + addNum(2) + findMedian() -> 1.5 + addNum(3) + findMedian() -> 2 + + 1 2 -3 4 + -3 1 2 4 + + small : 3 -1 + large : 2 4 + + time : O(logn) + space : O(n) + */ + + private PriorityQueue small; + private PriorityQueue large; + + public FindMedianfromDataStream() { // MedianFinder() + small = new PriorityQueue<>(); + large = new PriorityQueue<>(); + } + + public void addNum(int num) { + large.add((long)num); + small.add(-large.poll()); + if (large.size() < small.size()) { + large.add(-small.poll()); + } + } + + public double findMedian() { + return large.size() > small.size() ? large.peek() : (large.peek() - small.peek()) / 2; + } +} diff --git a/FindMinimuminRotatedSortedArray.java b/FindMinimuminRotatedSortedArray.java new file mode 100644 index 0000000..1926a0f --- /dev/null +++ b/FindMinimuminRotatedSortedArray.java @@ -0,0 +1,42 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FindMinimuminRotatedSortedArray + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class FindMinimuminRotatedSortedArray { + /** + * 153. Find Minimum in Rotated Sorted Array + * Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. + * + 4 5 6 7 0 1 2 + + 4 5 6 0 1 2 3 + + 2 1 + + * time : O(logn) + * space : O(1); + * @param nums + * @return + */ + public int findMin(int[] nums) { + if (nums == null || nums.length == 0) return -1; + int start = 0; + int end = nums.length - 1; + while (start + 1 < end) { + int mid = (end - start) / 2 + start; + if (nums[mid] < nums[end]) { + end = mid; + } else { + start = mid + 1; + } + } + if (nums[start] < nums[end]) return nums[start]; + else return nums[end]; + } +} diff --git a/FindMinimuminRotatedSortedArrayII.java b/FindMinimuminRotatedSortedArrayII.java new file mode 100644 index 0000000..329fc43 --- /dev/null +++ b/FindMinimuminRotatedSortedArrayII.java @@ -0,0 +1,41 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FindMinimuminRotatedSortedArrayII + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class FindMinimuminRotatedSortedArrayII { + /** + * 154. Find Minimum in Rotated Sorted Array II + * + * + * 6 7 8 9 1 3 5; + * 1 1 1 1 2 1 + * + * time : O(logn) worst: O(n); + * space : O(1); + * @param nums + * @return + */ + public int findMin(int[] nums) { + if (nums == null || nums.length == 0) return -1; + int start = 0; + int end = nums.length - 1; + while (start + 1 < end) { + int mid = (end - start) / 2 + start; + if (nums[mid] < nums[end]) { + end = mid; + } else if (nums[mid] > nums[end]) { + start = mid + 1; + } else { + end--; + } + } + if (nums[start] < nums[end]) return nums[start]; + else return nums[end]; + } +} diff --git a/FindPeakElement.java b/FindPeakElement.java new file mode 100644 index 0000000..6590361 --- /dev/null +++ b/FindPeakElement.java @@ -0,0 +1,50 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FindPeakElement + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class FindPeakElement { + + /** + * 162. Find Peak Element + * A peak element is an element that is greater than its neighbors. + + Given an input array where num[i] ≠ num[i+1], find a peak element and return its index. + + The array may contain multiple peaks, in that case return the index to any one of the peaks is fine. + + You may imagine that num[-1] = num[n] = -∞. + + For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index number 2. + + + 1 2 3 1 + + 1 2 3 2 1 + + time : O(logn); + space : O(1); + * @param nums + * @return + */ + + public int findPeakElement(int[] nums) { + int start = 0; + int end = nums.length - 1; + while (start + 1 < end) { + int mid = (end - start) / 2 + start; + if (nums[mid] > nums[mid + 1]) { + end = mid; + } else { + start = mid + 1; + } + } + if (nums[start] > nums[end]) return start; + return end; + } +} diff --git a/FindtheCelebrity.java b/FindtheCelebrity.java new file mode 100644 index 0000000..410c643 --- /dev/null +++ b/FindtheCelebrity.java @@ -0,0 +1,48 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FindtheCelebrity + * Creator : Edward + * Date : Nov, 2017 + * Description : 277. Find the Celebrity + */ +public class FindtheCelebrity { + /** + * Suppose you are at a party with n people (labeled from 0 to n - 1) and among them, there may exist one celebrity. + * The definition of a celebrity is that all the other n - 1 people know him/her but he/she does not know any of them. + * You are given a helper function bool knows(a, b) which tells you whether A knows B. + * Implement a function int findCelebrity(n), your function should minimize the number of calls to knows. + * + * 0 1 2 3 4 5 + * 3 : Celebrity + * 0 : 1 1: 2 2 : 4 4 : 5 5 : 1 + * possible = 3 + * + * time : O(n) + * space : O(1) + * + * @param n + * @return + */ + public int findCelebrity(int n) { + if (n < 2) return -1; + int possible = 0; + for (int i = 1; i < n; i++) { + if (knows(possible, i)) { + possible = i; + } + } + for (int i = 0; i < n; i++) { + if (possible != i && ((knows(possible, i) || !knows(i, possible)))) { + return -1; + } + } + return possible; + } + + public boolean knows(int a, int b) { + return true; + } +} diff --git a/FindtheDifference.java b/FindtheDifference.java new file mode 100644 index 0000000..e684d96 --- /dev/null +++ b/FindtheDifference.java @@ -0,0 +1,51 @@ +package leetcode; + +/** + * Created by Edward on 25/07/2017. + */ +public class FindtheDifference { + /** + * 389. Find the Difference + * Given two strings s and t which consist of only lowercase letters. + + String t is generated by random shuffling string s and then add one more letter at a random position. + + Find the letter that was added in t + Input: + s = "abcd" + t = "abcde" + + Output: + e + + Explanation: + 'e' is the letter that was added. + + 异或: ^ (相同为零,不同为一) + + 0 0 0 + 0 1 1 + 1 0 1 + 1 1 0 + + 4 : 0100 + 6 : 0110 + 0010 + 4 :0100 + 0110 ->6 + + time: O(n); + space: O(1); + * @param s + * @param t + * @return + */ + public char findTheDifference(String s, String t) { + char c = t.charAt(t.length() - 1); + for (int i = 0; i < s.length(); i++) { + c ^= s.charAt(i); + c ^= t.charAt(i); + } + return c; + } +} diff --git a/FindtheDuplicateNumber.java b/FindtheDuplicateNumber.java new file mode 100644 index 0000000..7d0327a --- /dev/null +++ b/FindtheDuplicateNumber.java @@ -0,0 +1,63 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FindtheDuplicateNumber + * Creator : Edward + * Date : Nov, 2017 + * Description : 287. Find the Duplicate Number + */ +public class FindtheDuplicateNumber { + /** + * Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), + * prove that at least one duplicate number must exist. Assume that there is only one duplicate number, + * find the duplicate one. + + 1 2 3 4 5 6 7 8 8 9 10 + 0 1 2 3 4 5 6 7 8 9 10 len = 11 + + https://segmentfault.com/a/1190000003817671 + + + * @param nums + * @return + */ + + // time : O(nlogn) space : O(1) + public int findDuplicate(int[] nums) { + int min = 0; + int max = nums.length - 1; + while (min <= max) { + int mid = (max - min) / 2 + min; + int count = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i] <= mid) { + count++; + } + } + if (count > mid) { + max = mid - 1; + } else { + min = mid + 1; + } + } + return min; + } + + // time : O(n) space : O(1) + public int findDuplicate2(int[] nums) { + 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 slow; + } +} diff --git a/FirstBadVersion.java b/FirstBadVersion.java new file mode 100644 index 0000000..e3108de --- /dev/null +++ b/FirstBadVersion.java @@ -0,0 +1,49 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FirstBadVersion + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class FirstBadVersion { + /** + * 278. First Bad Version + * You are a product manager and currently leading a team to develop a new product. Unfortunately, + * the latest version of your product fails the quality check. Since each version is developed based on the previous version, all the versions after a bad version are also bad. + + Suppose you have n versions [1, 2, ..., n] and you want to find out the first bad one, + which causes all the following ones to be bad. + + You are given an API bool isBadVersion(version) which will return whether version is bad. + Implement a function to find the first bad version. You should minimize the number of calls to the API. + + bad + 1, 2, 3, 4, 5, 6, 7 + + time : O(logn) + space : O(1) + * @param n + * @return + */ + public int firstBadVersion(int n) { + int start = 1; + int end = n; + while (start + 1 < end) { + int mid = (end - start) / 2 + start; + if (isBadVersion(mid)) { + end = mid; + } else start = mid; + } + if (isBadVersion(start)) { + return start; + } + return end; + } + + public boolean isBadVersion(int mid) { + return true; + } +} diff --git a/FirstMissingPositive.java b/FirstMissingPositive.java new file mode 100644 index 0000000..9e8eeb1 --- /dev/null +++ b/FirstMissingPositive.java @@ -0,0 +1,43 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FirstMissingPositive + * Creator : Edward + * Date : Nov, 2017 + * Description : 41. First Missing Positive + */ +public class FirstMissingPositive { + /** + * Given an unsorted integer array, find the first missing positive integer. + + For example, + Given [1,2,0] return 3, + and [3,4,-1,1] return 2. + + Your algorithm should run in O(n) time and uses constant space. + + time : O(n) + space : O(1) + + * @param nums + * @return + */ + public int firstMissingPositive(int[] nums) { + if (nums == null || nums.length == 0) return 1; + for (int i = 0; i < nums.length; i++) { + while (nums[i] > 0 && nums[i] <= nums.length && nums[nums[i] - 1] != nums[i]) { + int temp = nums[nums[i] - 1]; + nums[nums[i] - 1] = nums[i]; + nums[i] = temp; + } + } + for (int i = 0; i < nums.length; i++) { + if (nums[i] != i + 1) { + return i + 1; + } + } + return nums.length + 1; + } +} diff --git a/FirstUniqueCharacterinaString.java b/FirstUniqueCharacterinaString.java new file mode 100644 index 0000000..9560ef6 --- /dev/null +++ b/FirstUniqueCharacterinaString.java @@ -0,0 +1,39 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FirstUniqueCharacterinaString + * Creator : Edward + * Date : Oct, 2017 + * Description : 387. First Unique Character in a String + */ +public class FirstUniqueCharacterinaString { + /** + * Examples: + + s = "leetcode" + return 0. + + s = "loveleetcode", + return 2. + + time : O(n); + space : O(1); + + * @param s + * @return + */ + public int firstUniqChar(String s) { + int[] count = new int[26]; + for (int i = 0; i < s.length(); i++) { + count[s.charAt(i) - 'a']++; + } + for (int i = 0; i < s.length(); i++) { + if (count[s.charAt(i) - 'a'] == 1) { + return i; + } + } + return -1; + } +} diff --git a/FizzBuzz.java b/FizzBuzz.java new file mode 100644 index 0000000..96762f5 --- /dev/null +++ b/FizzBuzz.java @@ -0,0 +1,60 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Edward on 28/07/2017. + */ +public class FizzBuzz { + /** + * 412. Fizz Buzz + * Write a program that outputs the string representation of numbers from 1 to n. + + But for multiples of three it should output “Fizz” instead of the number and for the multiples of five + output “Buzz”. For numbers which are multiples of both three and five output “FizzBuzz”. + + n = 15, + + Return: + [ + "1", + "2", + "Fizz", + "4", + "Buzz", + "Fizz", + "7", + "8", + "Fizz", + "Buzz", + "11", + "Fizz", + "13", + "14", + "FizzBuzz" + ] + + time : O(n); + space : O(n); + + * @param n + * @return + */ + public static List fizzBuzz(int n) { + List res = new ArrayList<>(); + if (n == 0) return res; + for (int i = 1; i <= n; i++) { + if (i % 3 == 0 && i % 5 == 0) { + res.add("FizzBuzz"); + } else if (i % 3 == 0) { + res.add("Fizz"); + } else if (i % 5 == 0) { + res.add("Buzz"); + } else { + res.add(String.valueOf(i)); + } + } + return res; + } +} diff --git a/Flatten2DVector.java b/Flatten2DVector.java new file mode 100644 index 0000000..7bbec39 --- /dev/null +++ b/Flatten2DVector.java @@ -0,0 +1,58 @@ +package leetcode; + +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : Flatten2DVector + * Creator : Edward + * Date : Nov, 2017 + * Description : 251. Flatten 2D Vector + */ +public class Flatten2DVector { + /** + * Given 2d vector = + + [ + [1,2], + [3], + [4,5,6] + ] + By calling next repeatedly until hasNext returns false, + the order of elements returned by next should be: [1,2,3,4,5,6]. + + time : O(n) + space : O(1) + + */ + + int indexList, indexElement; + List> list; + + + public Flatten2DVector(List> vec2d) { + indexElement = 0; + indexList = 0; + list = vec2d; + } + + + //@Override + public Integer next() { + return list.get(indexList).get(indexElement++); + } + + //@Override + public boolean hasNext() { + while (indexList < list.size()) { + if (indexElement < list.get(indexList).size()) { + return true; + } else { + indexList++; + indexElement = 0; + } + } + return false; + } +} diff --git a/FlattenBinaryTreetoLinkedList.java b/FlattenBinaryTreetoLinkedList.java new file mode 100644 index 0000000..aadb29d --- /dev/null +++ b/FlattenBinaryTreetoLinkedList.java @@ -0,0 +1,66 @@ +package leetcode; + +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FlattenBinaryTreetoLinkedList + * Creator : Edward + * Date : Oct, 2017 + * Description : 114. Flatten Binary Tree to Linked List + */ +public class FlattenBinaryTreetoLinkedList { + /** + * For example, + Given + + 1 + / \ + 2 5 + / \ \ + 3 4 6 + The flattened tree should look like: + 1 + \ + 2 + \ + 3 + \ + 4 + \ + 5 + \ + 6 + + time : O(n) + space : O(n) + + + * @param root + */ + private TreeNode prev = null; + + public void flatten(TreeNode root) { + if (root == null) return; + flatten(root.right); + flatten(root.left); + root.right = prev; + root.left = null; + prev = root; + } + public void flatten2(TreeNode root) { + if (root == null) return; + Stack stack = new Stack<>(); + stack.push(root); + while (!stack.isEmpty()) { + TreeNode cur = stack.pop(); + if (cur.right != null) stack.push(cur.right); + if (cur.left != null) stack.push(cur.left); + if (!stack.isEmpty()) { + cur.right = stack.peek(); + } + cur.left = null; + } + } +} diff --git a/FlattenNestedListIterator.java b/FlattenNestedListIterator.java new file mode 100644 index 0000000..4e45cbe --- /dev/null +++ b/FlattenNestedListIterator.java @@ -0,0 +1,64 @@ +package leetcode; + +import java.util.List; +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FlattenNestedListIterator + * Creator : Edward + * Date : Sep, 2017 + * Description : 341. Flatten Nested List Iterator + */ +public class FlattenNestedListIterator { + /** + * Given a nested list of integers, implement an iterator to flatten it. + + Each element is either an integer, or a list -- whose elements may also be integers or other lists. + + Example 1: + Given the list [[1,1],2,[1,1]], + + By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,1,2,1,1]. + + Example 2: + Given the list [1,[4,[6]]], + + By calling next repeatedly until hasNext returns false, the order of elements returned by next should be: [1,4,6]. + + time : O(n) + space : O(n) + + */ + + Stack stack; + + public FlattenNestedListIterator(List nestedList) { + stack = new Stack<>(); + for (int i = nestedList.size() - 1; i >= 0; i--) { + stack.push(nestedList.get(i)); + } + } + + //@Override + public Integer next() { + return stack.pop().getInteger(); + } + + //@Override + public boolean hasNext() { + while (!stack.isEmpty()) { + NestedInteger cur = stack.peek(); + if (cur.isInteger()) { + return true; + } + stack.pop(); + for (int i = cur.getList().size() - 1; i >= 0; i--) { + stack.push(cur.getList().get(i)); + } + } + return false; + } + +} diff --git a/FlipGame.java b/FlipGame.java new file mode 100644 index 0000000..dd849b6 --- /dev/null +++ b/FlipGame.java @@ -0,0 +1,41 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FlipGame + * Creator : Edward + * Date : Oct, 2017 + * Description : 293. Flip Game + */ +public class FlipGame { + /** + * For example, given s = "++++", after one move, it may become one of the following states: + + [ + "--++", + "+--+", + "++--" + ] + If there is no valid move, return an empty list []. + + time : O(n) + space : O(n); + + + * @param s + * @return + */ + public List generatePossibleNextMoves(String s) { + List res = new ArrayList<>(); + for (int i = 1; i < s.length(); i++) { + if (s.charAt(i) == '+' && s.charAt(i - 1) == '+') { + res.add(s.substring(0, i - 1) + "--" + s.substring(i + 1, s.length())); + } + } + return res; + } +} diff --git a/FlipGameII.java b/FlipGameII.java new file mode 100644 index 0000000..479fc52 --- /dev/null +++ b/FlipGameII.java @@ -0,0 +1,58 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FlipGameII + * Creator : Edward + * Date : Dec, 2017 + * Description : 294. Flip Game II + */ +public class FlipGameII { + + /** + * You are playing the following Flip Game with your friend: Given a string that contains + * only these two characters: + and -, you and your friend take turns to flip two consecutive "++" into "--". + * The game ends when a person can no longer make a move and therefore the other person will be the winner. + + Write a function to determine if the starting player can guarantee a win. + + For example, given s = "++++", return true. The starting player can guarantee a win by + flipping the middle "++" to become "+--+". + + HashMap + + + * time : O(2^N) 不确定 + * space : O(2^N) + * @param s + * @return + */ + + public boolean canWin(String s) { + if (s == null || s.length() == 0) return false; + HashMap map = new HashMap<>(); + return helper(s, map); + } + + private boolean helper(String s, HashMap map) { + if (map.containsKey(s)) return map.get(s); + for (int i = 0; i < s.length() - 1; i++) { + if (s.charAt(i) == '+' && s.charAt(i + 1) == '+') { + String opponent = s.substring(0, i) + "--" + s.substring(i + 2); + if (!helper(opponent, map)) { + map.put(s, true); + return true; + } + } + } + map.put(s, false); + return false; + } +} + diff --git a/FourSum.java b/FourSum.java new file mode 100644 index 0000000..4a24d6e --- /dev/null +++ b/FourSum.java @@ -0,0 +1,50 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FourSum + * Creator : Edward + * Date : Oct, 2017 + * Description : 18. 4Sum + */ +public class FourSum { + + /** + time : O(n^3); + space : O(n); + * @param nums + * @param target + * @return + */ + + public List> fourSum(int[] nums, int target) { + List> res = new ArrayList<>(); + if (nums.length < 4) return res; + Arrays.sort(nums); + for (int i = 0; i < nums.length - 3; i++) { + if (i > 0 && nums[i] == nums[i - 1]) continue; + for (int j = i + 1; j < nums.length - 2; j++) { + if (j > i + 1 && nums[j] == nums[j - 1]) continue; + int low = j + 1, high = nums.length - 1; + while (low < high) { + int sum = nums[i] + nums[j] + nums[low] + nums[high]; + if (sum == target) { + res.add(Arrays.asList(nums[i], nums[j], nums[low], nums[high])); + while (low < high && nums[low] == nums[low + 1]) low++; + while (low < high && nums[high] == nums[high - 1]) high--; + low++; + high--; + } else if (sum < target) { + low++; + } else high--; + } + } + } + return res; + } +} diff --git a/FourSumII.java b/FourSumII.java new file mode 100644 index 0000000..21a0406 --- /dev/null +++ b/FourSumII.java @@ -0,0 +1,64 @@ +package leetcode; + +import java.util.HashMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FourSumII + * Creator : Edward + * Date : Nov, 2017 + * Description : 454. 4Sum II + */ +public class FourSumII { + /** + * Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) + * there are such that A[i] + B[j] + C[k] + D[l] is zero. + + To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. + All integers are in the range of -228 to 228 - 1 and the result is guaranteed to be at most 231 - 1. + + Example: + + Input: + A = [ 1, 2] + B = [-2,-1] + C = [-1, 2] + D = [ 0, 2] + + Output: + 2 + + Explanation: + The two tuples are: + 1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0 + 2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0 + + time : O(n^2) + space : O(n) + + space : ON^2??? + * @param A + * @param B + * @param C + * @param D + * @return + */ + public int fourSumCount(int[] A, int[] B, int[] C, int[] D) { + HashMap map = new HashMap<>(); + int res = 0; + for (int a : A) { + for (int b : B) { + int sum = a + b; + map.put(sum, map.getOrDefault(sum, 0) + 1); + } + } + for (int c : C) { + for (int d : D) { + int sum = -c - d; + res += map.getOrDefault(sum, 0); + } + } + return res; + } +} diff --git a/FractiontoRecurringDecimal.java b/FractiontoRecurringDecimal.java new file mode 100644 index 0000000..d6e2f53 --- /dev/null +++ b/FractiontoRecurringDecimal.java @@ -0,0 +1,73 @@ +package leetcode; + +import java.util.HashMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : FractiontoRecurringDecimal + * Creator : Edward + * Date : Dec, 2017 + * Description : 166. Fraction to Recurring Decimal + */ +public class FractiontoRecurringDecimal { + + /** + * Given two integers representing the numerator and denominator of a fraction, return the fraction in string format. + + If the fractional part is repeating, enclose the repeating part in parentheses. + + For example, + + Given numerator = 1, denominator = 2, return "0.5". + Given numerator = 2, denominator = 1, return "2". + Given numerator = 2, denominator = 3, return "0.(6)". + + 0.2(34) + + 1, 0 + - 越界 + 2, 整数 + 3, 小数 -> 循环 + + time : O(n) + space : O(n) + + * @param numerator + * @param denominator + * @return + */ + public String fractionToDecimal(int numerator, int denominator) { + if (numerator == 0) { + return "0"; + } + StringBuilder res = new StringBuilder(); + res.append(((numerator > 0) ^ (denominator > 0) ? "-" : "")); + long num = Math.abs((long)numerator); + long den = Math.abs((long)denominator); + + res.append(num / den); + num %= den; + if (num == 0) { + return res.toString(); + } + + res.append("."); + HashMap map = new HashMap<>(); + map.put(num, res.length()); + + while (num != 0) { + num *= 10; + res.append(num / den); + num %= den; + if (map.containsKey(num)) { + int index = map.get(num); + res.insert(index, "("); + res.append(")"); + break; + } else { + map.put(num, res.length()); + } + } + return res.toString(); + } +} diff --git a/GameofLife.java b/GameofLife.java new file mode 100644 index 0000000..06250cc --- /dev/null +++ b/GameofLife.java @@ -0,0 +1,62 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : GameofLife + * Creator : Edward + * Date : Dec, 2017 + * Description : 289. Game of Life + */ +public class GameofLife { + + /** + * Given a board with m by n cells, each cell has an initial state live (1) or dead (0). Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules (taken from the above Wikipedia article): + + Any live cell with fewer than two live neighbors dies, as if caused by under-population. + Any live cell with two or three live neighbors lives on to the next generation. + Any live cell with more than three live neighbors dies, as if by over-population.. + Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction. + Write a function to compute the next state (after one update) of the board given its current state. + + time : O(m * n) + space : O(1) + + * @param board + */ + + public void gameOfLife(int[][] board) { + if (board == null || board.length == 0) return; + int m = board.length; + int n = board[0].length; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + int count = countNeighbor(board, i, j); + if (board[i][j] == 1) { + if (count == 2 || count == 3) { + board[i][j] += 2; + } + } else if (count == 3) { + board[i][j] += 2; + } + } + } + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + board[i][j] = board[i][j] >> 1; + } + } + } + + private int countNeighbor(int[][] board, int i, int j) { + int count = 0; + for (int row = Math.max(0, i - 1); row <= Math.min(i + 1, board.length - 1); row++) { + for (int col = Math.max(0, j - 1); col <= Math.min(j + 1, board[0].length - 1); col++) { + if (row == i && col == j) continue; + if ((board[row][col] & 1) == 1) count++; + } + } + return count; + } + +} diff --git a/GasStation.java b/GasStation.java new file mode 100644 index 0000000..ce8cfe7 --- /dev/null +++ b/GasStation.java @@ -0,0 +1,60 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : GasStation + * Creator : Edward + * Date : Nov, 2017 + * Description : 134. Gas Station + */ +public class GasStation { + /** + * There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. + + You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). + You begin the journey with an empty tank at one of the gas stations. + + Return the starting gas station's index if you can travel around the circuit once, otherwise return -1. + + 非常经典的一道题。可以转换成求最大连续和做,但是有更简单的方法。基于一个数学定理: + + 如果一个数组的总和非负,那么一定可以找到一个起始位置,从他开始绕数组一圈,累加和一直都是非负的 + (证明貌似不难,以后有时间再补) + + + 有了这个定理,判断到底是否存在这样的解非常容易,只需要把全部的油耗情况计算出来看看是否大于等于0即可。 + + 那么如何求开始位置在哪? + + 注意到这样一个现象: + + 1. 假如从位置i开始,i+1,i+2...,一路开过来一路油箱都没有空。说明什么?说明从i到i+1,i+2,...肯定是正积累。 + 2. 现在突然发现开往位置j时油箱空了。这说明什么?说明从位置i开始没法走完全程(废话)。那么,我们要从位置i+1开始重新尝试吗?不需要!为什么? + 因为前面已经知道,位置i肯定是正积累,那么,如果从位置i+1开始走更加没法走完全程了,因为没有位置i的正积累了。 + 同理,也不用从i+2,i+3,...开始尝试。所以我们可以放心地从位置j+1开始尝试。 + + https://www.cnblogs.com/boring09/p/4248482.html + + time : O(n) + space : O(1) + + * @param gas + * @param cost + * @return + */ + public int canCompleteCircuit(int[] gas, int[] cost) { + if (gas.length == 0 || cost.length == 0 || gas.length != cost.length) return -1; + int total = 0, sum = 0, start = 0; + for (int i = 0; i < gas.length; i++) { + total += (gas[i] - cost[i]); + if (sum < 0) { + sum = (gas[i] - cost[i]); + start = i; + } else { + sum += (gas[i] - cost[i]); + } + } + return total < 0 ? -1 : start; + } +} diff --git a/GeneralizedAbbreviation.java b/GeneralizedAbbreviation.java new file mode 100644 index 0000000..0391665 --- /dev/null +++ b/GeneralizedAbbreviation.java @@ -0,0 +1,45 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : GeneralizedAbbreviation + * Creator : Edward + * Date : Oct, 2017 + * Description : 320. Generalized Abbreviation + */ +public class GeneralizedAbbreviation { + /** + * Example: + Given word = "word", return the following list (order does not matter): + ["word", "1ord", "w1rd", "wo1d", "wor1", "2rd", "w2d", "wo2", "1o1d", "1or1", "w1r1", "1o2", "2r1", "3d", "w3", "4"] + + ["4","3d","2r1","2rd","1o2","1o1d","1or1","1ord","w3","w2d","w1r1","w1rd","wo2","wo1d","wor1","word"] + + time : O(2^n) + space : O(n) (不确定) + + * @param word + * @return + */ + public List generateAbbreviations(String word) { + List res = new ArrayList<>(); + helper(res, word, 0, "", 0); + return res; + } + + public void helper(List res, String word, int pos, String cur, int count) { + if (pos == word.length()) { + if (count > 0) cur += count; + res.add(cur); + } else { + helper(res, word, pos + 1, cur, count + 1); + helper(res, word, pos + 1, cur + (count > 0 ? count : "") + word.charAt(pos), 0); + } + + } + +} diff --git a/GenerateParentheses.java b/GenerateParentheses.java new file mode 100644 index 0000000..3d0b86c --- /dev/null +++ b/GenerateParentheses.java @@ -0,0 +1,55 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Edward on 27/07/2017. + */ +public class GenerateParentheses { + /** + * 22. Generate Parentheses + * Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. + + For example, given n = 3, a solution set is: + [ + "((()))", + "(()())", + "(())()", + "()(())", + "()()()" + ] + + + time : O(n!) (2^n) + space : O(n) + + 卡特兰数: + (0,n-1) (1,n-2) (2,n-3) ... (n-1,0) + + * @param n + * @return + */ + + public static List generateParenthesis(int n) { + List res = new ArrayList<>(); + if (n == 0) return res; + helper(res, "", n, n); + return res; + } + public static void helper(List res, String s, int left, int right) { + if (left > right) { + return; + } + if (left == 0 && right == 0) { + res.add(s); + return; + } + if (left > 0) { + helper(res, s + "(", left - 1, right); + } + if (right > 0) { + helper(res, s + ")", left, right - 1); + } + } +} diff --git a/GraphValidTree.java b/GraphValidTree.java new file mode 100644 index 0000000..6ea7da1 --- /dev/null +++ b/GraphValidTree.java @@ -0,0 +1,99 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : GraphValidTree + * Creator : Edward + * Date : Dec, 2017 + * Description : 261. Graph Valid Tree + */ +public class GraphValidTree { + /** + * Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), + * write a function to check whether these edges make up a valid tree. + + For example: + + Given n = 5 and edges = [[0, 1], [0, 2], [0, 3], [1, 4]], return true. + + Given n = 5 and edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]], return false. + + 2 -- 0 -- 1 -- 4 + | + 3 + + 4 + | + 0 -- 1 -- 2 + \ / + 3 + + + time : O(edges * nodes) + space : O(n) + + * @param n + * @param edges + * @return + */ + + public boolean validTree(int n, int[][] edges) { + if (n == 1 && edges.length == 0) return true; + if (n < 1 || edges == null || edges.length != n - 1) return false; + + int[] roots = new int[n]; + for (int i = 0; i < n; i++) { + roots[i] = -1; + } + + for (int[] pair : edges) { + int x = find(roots, pair[0]); + int y = find(roots, pair[1]); + if (x == y) return false; + roots[x] = y; + } + return true; + } + + private int find(int[] roots, int i) { + while (roots[i] != -1) { + i = roots[i]; + } + return i; + } + + public boolean validTree2(int n, int[][] edges) { + List> graph = new ArrayList<>(); + for (int i = 0; i < n; i++) { + graph.add(new ArrayList<>()); + } + for (int i = 0; i < edges.length; i++) { + graph.get(edges[i][0]).add(edges[i][1]); + graph.get(edges[i][1]).add(edges[i][0]); + } + + HashSet visited = new HashSet<>(); + visited.add(0); + + boolean res = helper(graph, visited, 0, -1); + if (res == false) return false; + return visited.size() == n ? true : false; + } + + private boolean helper(List> graph, HashSet visited, int node, int parent) { + List sub = graph.get(node); + for (int v : sub) { + if (v == parent) continue; + if (visited.contains(v)) return false; + visited.add(v); + boolean res = helper(graph, visited, v, node); + if (res == false) return false; + } + return true; + } +} diff --git a/GrayCode.java b/GrayCode.java new file mode 100644 index 0000000..d335196 --- /dev/null +++ b/GrayCode.java @@ -0,0 +1,43 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : GrayCode + * Creator : Edward + * Date : Nov, 2017 + * Description : 89. Gray Code + */ +public class GrayCode { + /** + * The gray code is a binary numeral system where two successive values differ in only one bit. + + Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. + A gray code sequence must begin with 0. + + For example, given n = 2, return [0,1,3,2]. Its gray code sequence is: + + 00 - 0 + 01 - 1 + 11 - 3 + 10 - 2 + + G(i) = i ^ (i/2) + + time : O(1 << n) / O(n) + space : O(1 << n) / O(n) + + * @param n + * @return + */ + public List grayCode(int n) { + List res = new ArrayList<>(); + for (int i = 0; i < 1 << n; i++) { + res.add(i ^ i >> 1); + } + return res; + } +} diff --git a/GroupAnagrams.java b/GroupAnagrams.java new file mode 100644 index 0000000..4c4c6e0 --- /dev/null +++ b/GroupAnagrams.java @@ -0,0 +1,79 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +/** + * Created by Edward on 28/07/2017. + */ +public class GroupAnagrams { + /** + * 49. Group Anagrams + * Given an array of strings, group anagrams together. + + For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"], + Return: + [ + ["ate", "eat","tea"], + ["nat","tan"], + ["bat"] + ] + + + * @param strs + * @return + */ + + // time : O(m * n * logn) space : O(n) + + public List> groupAnagrams(String[] strs) { + List> res = new ArrayList<>(); + if (strs == null || strs.length == 0) return res; + HashMap map = new HashMap<>(); + for (String str : strs) { + char[] ch = str.toCharArray(); + Arrays.sort(ch); + String s = new String(ch); + if (map.containsKey(s)) { + List list = res.get(map.get(s)); + list.add(str); + } else { + List list = new ArrayList<>(); + list.add(str); + map.put(s, res.size()); + res.add(list); + } + } + return res; + } + + // time : O(m * n) space : O(n) counting sort + + + public List> groupAnagrams2(String[] strs) { + HashMap> map = new HashMap<>(); + for (String str : strs) { + int[] count = new int[26]; + for (Character ch : str.toCharArray()) { + count[ch - 'a']++; + } + String s = ""; + for (int i = 0; i < count.length; i++) { + if (count[i] != 0) { + s += String.valueOf(count[i]) + String.valueOf((char)(i + 'a')); + } + } + if (map.containsKey(s)) { + List list = map.get(s); + list.add(str); + } else { + List list = new ArrayList<>(); + list.add(str); + map.put(s, list); + } + } + return new ArrayList<>(map.values()); + } +} diff --git a/GroupShiftedStrings.java b/GroupShiftedStrings.java new file mode 100644 index 0000000..c798230 --- /dev/null +++ b/GroupShiftedStrings.java @@ -0,0 +1,69 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : GroupShiftedStrings + * Creator : Edward + * Date : Dec, 2017 + * Description : 249. Group Shifted Strings + */ +public class GroupShiftedStrings { + /** + * Given a string, we can "shift" each of its letter to its successive letter, for example: "abc" -> "bcd". + * We can keep "shifting" which forms the sequence: + + "abc" -> "bcd" -> ... -> "xyz" + Given a list of strings which contains only lowercase alphabets, group all strings + that belong to the same shifting sequence. + + For example, given: ["abc", "bcd", "acef", "xyz", "az", "ba", "a", "z"], + A solution is: + + [ + ["abc","bcd","xyz"], + ["az","ba"], + ["acef"], + ["a","z"] + ] + + time : (n * m) + space : O(n) + + + * @param strings + * @return + */ + + public List> groupStrings(String[] strings) { + List> res = new ArrayList<>(); + HashMap> map = new HashMap<>(); + for (String str : strings) { + int offset = str.charAt(0) - 'a'; + String key = ""; + for (int i = 0; i < str.length(); i++) { + char c = (char)(str.charAt(i) - offset); + if (c < 'a') { + c += 26; + } + key += c; + } + if (!map.containsKey(key)) { + List list = new ArrayList<>(); + map.put(key, list); + } + map.get(key).add(str); + } + for (String key : map.keySet()) { + List list = map.get(key); + Collections.sort(list); + res.add(list); + } + return res; + } +} diff --git a/GuessNumberHigherorLower.java b/GuessNumberHigherorLower.java new file mode 100644 index 0000000..d0381c9 --- /dev/null +++ b/GuessNumberHigherorLower.java @@ -0,0 +1,55 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : GuessNumberHigherorLower + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class GuessNumberHigherorLower { + /** + * 374. Guess Number Higher or Lower + * + * We are playing the Guess Game. The game is as follows: + + I pick a number from 1 to n. You have to guess which number I picked. + + Every time you guess wrong, I'll tell you whether the number is higher or lower. + + You call a pre-defined API guess(int num) which returns 3 possible results (-1, 1, or 0): + + -1 : My number is lower + 1 : My number is higher + 0 : Congrats! You got it! + + + * time : O(logn); + * space : O(1); + * @param n + * @return + */ + public int guessNumber(int n) { + int start = 1; + int end = n; + while (start + 1 < end) { + int mid = (end - start) / 2 + start; + if (guess((mid)) == 0) { + return mid; + } else if (guess(mid) == 1) { + start = mid; + } else { + end = mid; + } + } + if (guess(start) == 0) return start; + return end; + } + + + // 防止编译器报错函数 + public int guess(int num) { + return 0; + } +} diff --git a/GuessNumberHigherorLowerII.java b/GuessNumberHigherorLowerII.java new file mode 100644 index 0000000..0f4991b --- /dev/null +++ b/GuessNumberHigherorLowerII.java @@ -0,0 +1,92 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : GuessNumberHigherorLowerII + * Creator : Edward + * Date : Jan, 2018 + * Description : 375. Guess Number Higher or Lower II + */ +public class GuessNumberHigherorLowerII { + /** + * We are playing the Guess Game. The game is as follows: + + I pick a number from 1 to n. You have to guess which number I picked. + + Every time you guess wrong, I'll tell you whether the number I picked is higher or lower. + + However, when you guess a particular number x, and you guess wrong, you pay $x. You win the game when you guess the number I picked. + + Example: + + n = 10, I pick 8. + + First round: You guess 5, I tell you that it's higher. You pay $5. + Second round: You guess 7, I tell you that it's higher. You pay $7. + Third round: You guess 9, I tell you that it's lower. You pay $9. + + Game over. 8 is the number I picked. + + You end up paying $5 + $7 + $9 = $21. + Given a particular n ≥ 1, find out how much money you need to have to guarantee a win. + + 1 2 3 4 5 6 7 (8) 9 10 + + dp[i][j] : i - j 肯定赢所需多少钱 + + 最小的最大值问题: + i - j 中,任意猜一个数x,获胜所花的钱为 x + max(helper(i ,x-1), helper(x+1 ,j)) + + 5 : 10 11 + + + 1,for + 2,dfs + memo + + time : O(n^3) + space : O(n^2) + + + * @param n + * @return + */ + + int[][] dp; + + public int getMoneyAmount(int n) { + dp = new int[n + 1][n + 1]; + return helper(1, n); + } + + private int helper(int i, int j) { + if (i > j) return 0; + if (dp[i][j] != 0) return dp[i][j]; + int res = Integer.MAX_VALUE; + for (int x = i; x <= j; x++) { + res = Math.min(res, Math.max(helper(i, x - 1), helper(x + 1, j)) + x); + } + dp[i][j] = res; + return res; + } + + /** x + * 1 2 3 4 5 6 7 (8) 9 10 + * i j + * @param n + * @return + */ + + public int getMoneyAmount2(int n) { + int[][] dp = new int[n + 1][n + 1]; + for (int i = n - 1; i > 0; i--) { + for (int j = i + 1; j <= n; j++) { + dp[i][j] = Integer.MAX_VALUE; + for (int x = i; x < j; x++) { + dp[i][j] = Math.min(dp[i][j], x + Math.max(dp[i][x - 1], dp[x + 1][j])); + } + } + } + return dp[1][n]; + } +} diff --git a/HIndex.java b/HIndex.java new file mode 100644 index 0000000..1d26e9a --- /dev/null +++ b/HIndex.java @@ -0,0 +1,47 @@ +package leetcode; + +import java.util.Arrays; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : HIndex + * Creator : Edward + * Date : Nov, 2017 + * Description : 274. H-Index + */ +public class HIndex { + /** + * For example, given citations = [3, 0, 6, 1, 5], which means the researcher has 5 papers in total + * and each of them had received 3, 0, 6, 1, 5 citations respectively. Since the researcher has 3 papers with at + * least 3 citations each and the remaining two with no more than 3 citations each, his h-index is 3. + + * 0 1 2 3 4 + * 6 5 3 1 0 + */ + // time : O(nlogn) space : O(1) + public int hIndex(int[] citations) { + Arrays.sort(citations); + int res = 0; + while (res < citations.length && citations[citations.length - 1 - res] > res) { + res++; + } + return res; + } + + // time : O(n) space : O(n) + public int hIndex2(int[] citations) { + int[] helper = new int[citations.length + 1]; + for (int i = 0; i < citations.length; i++) { + helper[citations[i] <= citations.length ? citations[i] : citations.length] += 1; + } + int sum = 0; + for (int i = citations.length; i > 0; i--) { + sum += helper[i]; + if (sum >= i) { + return i; + } + } + return 0; + } +} diff --git a/HIndexII.java b/HIndexII.java new file mode 100644 index 0000000..5b44180 --- /dev/null +++ b/HIndexII.java @@ -0,0 +1,35 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : HIndexII + * Creator : Edward + * Date : Nov, 2017 + * Description : 275. H-Index II + */ +public class HIndexII { + /** + * [0, 1, 4, 5, 6] + * + * time : O(logn) space : O(1) + * + * @param citations + * @return + */ + public int hIndex(int[] citations) { + int len = citations.length; + int start = 0, end = len - 1; + while (start <= end) { + int mid = (end - start) / 2 + start; + if (citations[mid] == len - mid) { + return len - mid; + } else if (citations[mid] < len - mid) { + start = mid + 1; + } else { + end = mid - 1; + } + } + return len - start; + } +} diff --git a/HappyNumber.java b/HappyNumber.java new file mode 100644 index 0000000..5163aba --- /dev/null +++ b/HappyNumber.java @@ -0,0 +1,46 @@ +package leetcode; + +import java.util.HashSet; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : HappyNumber + * Creator : Edward + * Date : Nov, 2017 + * Description : 202. Happy Number + */ +public class HappyNumber { + /** + * Example: 19 is a happy number + + 1^2 + 9^2 = 82 + 8^2 + 2^2 = 68 + 6^2 + 8^2 = 100 + 1^2 + 0^2 + 0^2 = 1 + + time : 不知道 + space : O(n) + + * @param n + * @return + */ + public boolean isHappy(int n) { + HashSet set = new HashSet<>(); + int squareSum, remain; + while (set.add(n)) { + squareSum = 0; + while (n > 0) { + remain = n % 10; + squareSum += remain * remain; + n /= 10; + } + if (squareSum == 1) { + return true; + } else { + n = squareSum; + } + } + return false; + } +} diff --git a/HouseRobber.java b/HouseRobber.java new file mode 100644 index 0000000..4078e69 --- /dev/null +++ b/HouseRobber.java @@ -0,0 +1,40 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : HouseRobber + * Creator : Edward + * Date : Oct, 2017 + * Description : 198. House Robber + */ +public class HouseRobber { + /** + * You are a professional robber planning to rob houses along a street. + * Each house has a certain amount of money stashed, the only constraint stopping you from robbing + * each of them is that adjacent houses have security system connected and it will automatically contact + * the police if two adjacent houses were broken into on the same night. + * + [1, 3, 2, 4, 1] + No Yes + 1 : 0 1 + 3 : 1 3 + 2 : 3 3 + + time : O(n) + space : O(1) + + * @param nums + * @return + */ + public int rob(int[] nums) { + int prevNo = 0; + int prevYes = 0; + for (int num : nums) { + int temp = prevNo; + prevNo = Math.max(prevNo, prevYes); + prevYes = num + temp; + } + return Math.max(prevNo, prevYes); + } +} diff --git a/HouseRobberII.java b/HouseRobberII.java new file mode 100644 index 0000000..e8d821c --- /dev/null +++ b/HouseRobberII.java @@ -0,0 +1,33 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : HouseRobberII + * Creator : Edward + * Date : Dec, 2017 + * Description : 213. House Robber II + */ +public class HouseRobberII { + /** + * time : O(n) + * space : O(1) + * @param nums + * @return + */ + public int rob(int[] nums) { + if (nums.length == 1) return nums[0]; + return Math.max(rob(nums, 0, nums.length - 2), rob(nums, 1, nums.length - 1)); + } + + public int rob(int[] nums, int lo, int hi) { + int prevNo = 0; + int prevYes = 0; + for (int i = lo; i <= hi; i++) { + int temp = prevNo; + prevNo = Math.max(prevNo, prevYes); + prevYes = nums[i] + temp; + } + return Math.max(prevNo, prevYes); + } +} diff --git a/HouseRobberIII.java b/HouseRobberIII.java new file mode 100644 index 0000000..49dacf5 --- /dev/null +++ b/HouseRobberIII.java @@ -0,0 +1,45 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : HouseRobberIII + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class HouseRobberIII { + /** + * 337. House Robber III + * Example 1: + 3 red + / \ + 2 3 + \ \ + 3 1 red + Maximum amount of money the thief can rob = 3 + 3 + 1 = 7. + Example 2: + 3 + / \ + 4 5 red + / \ \ + 1 3 1 + Maximum amount of money the thief can rob = 4 + 5 = 9. + + time : O(n) + space : O(n) + * @param root + * @return + */ + public int rob(TreeNode root) { + if (root == null) return 0; + int val = 0; + if (root.left != null) { + val += rob(root.left.left) + rob(root.left.right); + } + if (root.right != null) { + val += rob(root.right.left) + rob(root.right.right); + } + return Math.max(val + root.val, rob(root.left) + rob(root.right)); + } +} diff --git a/ImplementQueueusingStacks.java b/ImplementQueueusingStacks.java new file mode 100644 index 0000000..5e50953 --- /dev/null +++ b/ImplementQueueusingStacks.java @@ -0,0 +1,97 @@ +package leetcode; + +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ImplementQueueusingStacks + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class ImplementQueueusingStacks { + /** + * 232. Implement Queue using Stacks + * + + */ + /** Initialize your data structure here. 构造函数因为类而不一样*/ + + Stack s1; + Stack s2; + + public ImplementQueueusingStacks() { + s1 = new Stack<>(); + s2 = new Stack<>(); + } + + /** Push element x to the back of queue. */ + public void push(int x) { + s1.push(x); + } + + // time : O(n); + /** Removes the element from in front of queue and returns that element. */ + public int pop() { + if (!s2.isEmpty()) return s2.pop(); + else { + while (!s1.isEmpty()) s2.push(s1.pop()); + return s2.pop(); + } + } + + // time : O(n); + /** Get the front element. */ + public int peek() { + if (!s2.isEmpty()) return s2.peek(); + else { + while (!s1.isEmpty()) s2.push(s1.pop()); + return s2.peek(); + } + } + + /** Returns whether the queue is empty. */ + public boolean empty() { + return s1.isEmpty() && s2.isEmpty(); + } +} + +class ImplementQueueusingStacks2 { + + Stack s1; + Stack s2; + private int front; + /** Initialize your data structure here. */ + public ImplementQueueusingStacks2() { + s1 = new Stack<>(); + s2 = new Stack<>(); + } + + // time : O(n); + /** Push element x to the back of queue. */ + public void push(int x) { + while (!s1.isEmpty()) { + s2.push(s1.pop()); + } + s2.push(x); + while (!s2.isEmpty()) { + s1.push(s2.pop()); + } + } + + /** Removes the element from in front of queue and returns that element. */ + public int pop() { + return s1.pop(); + } + + /** Get the front element. */ + public int peek() { + return s1.peek(); + } + + /** Returns whether the queue is empty. */ + public boolean empty() { + return s1.isEmpty(); + } +} diff --git a/ImplementStackusingQueues.java b/ImplementStackusingQueues.java new file mode 100644 index 0000000..d8aa23b --- /dev/null +++ b/ImplementStackusingQueues.java @@ -0,0 +1,47 @@ +package leetcode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ImplementStackusingQueues + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class ImplementStackusingQueues { + /** + * 225. Implement Stack using Queues + */ + Queue queue; + + /** Initialize your data structure here. 构造函数因为类而不一样*/ + public ImplementStackusingQueues() { + queue = new LinkedList<>(); + } + + /** Push element x onto stack. */ + public void push(int x) { + queue.add(x); + for (int i = 0; i < queue.size() - 1; i++) { + queue.add(queue.poll()); + } + } + + /** Removes the element on top of the stack and returns that element. */ + public int pop() { + return queue.poll(); + } + + /** Get the top element. */ + public int top() { + return queue.peek(); + } + + /** Returns whether the stack is empty. */ + public boolean empty() { + return queue.isEmpty(); + } +} diff --git a/ImplementTrie.java b/ImplementTrie.java new file mode 100644 index 0000000..547e4f6 --- /dev/null +++ b/ImplementTrie.java @@ -0,0 +1,60 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ImplementTrie + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class ImplementTrie { + + /** + * 208. Implement Trie (Prefix Tree) + */ + + TrieNode root; + + /** Initialize your data structure here. */ + public ImplementTrie() { + root = new TrieNode(); + } + + // time : O(n) n: word.length(); + // O(num of TrieNode * 26) = O(num of Words * word.length() * 26) + /** Inserts a word into the trie. */ + public void insert(String word) { + TrieNode node = root; + for (int i = 0; i < word.length(); i++) { + int j = word.charAt(i) - 'a'; + if (node.children[j] == null) { + node.children[j] = new TrieNode(); + } + node = node.children[j]; + } + node.isWord = true; + } + + /** Returns if the word is in the trie. */ + public boolean search(String word) { + TrieNode node = root; + for (int i = 0; i < word.length(); i++) { + int j = word.charAt(i) - 'a'; + if (node.children[j] == null) return false; + node = node.children[j]; + } + return node.isWord; + } + + /** Returns if there is any word in the trie that starts with the given prefix. */ + public boolean startsWith(String prefix) { + TrieNode node = root; + for (int i = 0; i < prefix.length(); i++) { + int j = prefix.charAt(i) - 'a'; + if (node.children[j] == null) return false; + node = node.children[j]; + } + return true; + } +} diff --git a/ImplementstrStr.java b/ImplementstrStr.java new file mode 100644 index 0000000..5f20d8d --- /dev/null +++ b/ImplementstrStr.java @@ -0,0 +1,28 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ImplementstrStr + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class ImplementstrStr { + /** + * 28. Implement strStr() + + time : O(n^2) + space : O(1) + * @param haystack + * @param needle + * @return + */ + public int strStr(String haystack, String needle) { + if (needle.length() == 0) return 0; + for (int i = 0; i <= haystack.length() - needle.length(); i++) { + if (haystack.substring(i, i + needle.length()).equals(needle)) return i; + } + return -1; + } +} diff --git a/IncreasingSubsequences.java b/IncreasingSubsequences.java new file mode 100644 index 0000000..ac8c8d2 --- /dev/null +++ b/IncreasingSubsequences.java @@ -0,0 +1,51 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : IncreasingSubsequences + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class IncreasingSubsequences { + /** + * 491. Increasing Subsequences + * Given an integer array, your task is to find all the different possible increasing + * subsequences of the given array, and the length of an increasing subsequence should be at least 2 . + + Example: + Input: [4, 6, 7, 7] + Output: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]] + + + time : O(2^n); + space : O(n); + * @param nums + * @return + */ + public List> findSubsequences(int[] nums) { + HashSet> res = new HashSet<>(); + if (nums == null || nums.length == 0) return new ArrayList<>(); + helper(res, new ArrayList<>(), nums, 0); + List ret = new ArrayList(res); + return ret; + } + + public void helper(HashSet> res, List list, int[] nums, int start) { + if (list.size() >= 2) { + res.add(new ArrayList<>(list)); + } + for (int i = start; i < nums.length; i++) { + if (list.size() == 0 || list.get(list.size() - 1) <= nums[i]) { + list.add(nums[i]); + helper(res, list, nums, i + 1); + list.remove(list.size() - 1); + } + } + } +} diff --git a/IncreasingTripletSubsequence.java b/IncreasingTripletSubsequence.java new file mode 100644 index 0000000..cb16a68 --- /dev/null +++ b/IncreasingTripletSubsequence.java @@ -0,0 +1,42 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : IncreasingTripletSubsequence + * Creator : Edward + * Date : Nov, 2017 + * Description : 334. Increasing Triplet Subsequence + */ +public class IncreasingTripletSubsequence { + /** + * Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the array. + + Formally the function should: + Return true if there exists i, j, k + such that arr[i] < arr[j] < arr[k] given 0 ≤ i < j < k ≤ n-1 else return false. + Your algorithm should run in O(n) time complexity and O(1) space complexity. + + Examples: + Given [1, 2, 3, 4, 5], + return true. + + Given [5, 4, 3, 2, 1], + return false. + + time : O(n) + space : O(1) + + * @param nums + * @return + */ + public boolean increasingTriplet(int[] nums) { + int min = Integer.MAX_VALUE, sedMin = Integer.MAX_VALUE; + for (int num : nums) { + if (num <= min) min = num; + else if (num < sedMin) sedMin = num; + else if (num > sedMin) return true; + } + return false; + } +} diff --git a/InorderSuccessorinBST.java b/InorderSuccessorinBST.java new file mode 100644 index 0000000..3218db5 --- /dev/null +++ b/InorderSuccessorinBST.java @@ -0,0 +1,47 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : InorderSuccessorinBST + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class InorderSuccessorinBST { + /** + * 285. Inorder Successor in BST + * Given a binary search tree and a node in it, find the in-order successor of that node in the BST. + + Note: If the given node has no in-order successor in the tree, return null. + + time : O(n); + space : O(n); + * @param root + * @param p + * @return + */ + + public TreeNode inorderSuccessor(TreeNode root, TreeNode p) { + TreeNode res = null; + while (root != null) { + if (root.val <= p.val) { + root = root.right; + } else { + res = root; + root = root.left; + } + } + return res; + } + + public TreeNode successor(TreeNode root, TreeNode p) { + if (root == null) return null; + if (root.val <= p.val) { + return successor(root.right, p); + } else { + TreeNode temp = successor(root.left, p); + return (temp != null) ? temp : root; + } + } +} diff --git a/InsertDeleteGetRandom.java b/InsertDeleteGetRandom.java new file mode 100644 index 0000000..c05f419 --- /dev/null +++ b/InsertDeleteGetRandom.java @@ -0,0 +1,63 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Random; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : InsertDeleteGetRandom + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class InsertDeleteGetRandom { + /** + * 380. Insert Delete GetRandom O(1) + * Design a data structure that supports all following operations in average O(1) time. + + insert(val): Inserts an item val to the set if not already present. + remove(val): Removes an item val from the set if present. + getRandom: Returns a random element from current set of elements. Each element must have + the same probability of being returned. + + time : O(1); + */ + + HashMap map; + ArrayList list; + Random rmd; + + public InsertDeleteGetRandom() { + map = new HashMap<>(); + list = new ArrayList<>(); + rmd = new Random(); + } + + /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ + public boolean insert(int val) { + if (map.containsKey(val)) return false; + map.put(val, list.size()); + list.add(val); + return true; + } + + /** Removes a value from the set. Returns true if the set contained the specified element. */ + public boolean remove(int val) { + if (!map.containsKey(val)) return false; + + int index = map.remove(val); + int lastVal = list.remove(list.size() - 1); + if (index != list.size()) { + list.set(index, lastVal); + map.put(lastVal, index); + } + return true; + } + + /** Get a random element from the set. */ + public int getRandom() { + return list.get(rmd.nextInt(list.size())); + } +} diff --git a/InsertDeleteGetRandomDuplicatesallowed.java b/InsertDeleteGetRandomDuplicatesallowed.java new file mode 100644 index 0000000..67f1961 --- /dev/null +++ b/InsertDeleteGetRandomDuplicatesallowed.java @@ -0,0 +1,64 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Random; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : InsertDeleteGetRandomDuplicatesallowed + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class InsertDeleteGetRandomDuplicatesallowed { + /** + * 381. Insert Delete GetRandom O(1) - Duplicates allowed + * time : O(1) + */ + + HashMap> map; + ArrayList list; + Random rmd; + + public InsertDeleteGetRandomDuplicatesallowed() { + map = new HashMap<>(); + list = new ArrayList<>(); + rmd = new Random(); + } + + /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */ + public boolean insert(int val) { + boolean contain = map.containsKey(val); + if (!contain) { + map.put(val, new HashSet<>()); + } + map.get(val).add(list.size()); + list.add(val); + return !contain; + } + + /** Removes a value from the collection. Returns true if the collection contained the specified element. */ + public boolean remove(int val) { + if (!map.containsKey(val)) return false; + int index = map.get(val).iterator().next(); + map.get(val).remove(index); + if (map.get(val).size() == 0) { + map.remove(val); + } + int lastVal = list.remove(list.size() - 1); + if (index != list.size()) { + list.set(index, lastVal); + map.get(lastVal).remove(list.size()); + map.get(lastVal).add(index); + } + return true; + } + + /** Get a random element from the collection. */ + public int getRandom() { + return list.get(rmd.nextInt(list.size())); + } +} diff --git a/InsertInterval.java b/InsertInterval.java new file mode 100644 index 0000000..e504316 --- /dev/null +++ b/InsertInterval.java @@ -0,0 +1,48 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : InsertInterval + * Creator : Edward + * Date : Oct, 2017 + * Description : 57. Insert Interval + */ +public class InsertInterval { + /** + * Example 1: + Given intervals [1,3],[6,9], insert and merge [2,5] in as [1,5],[6,9]. + + Example 2: + Given [1,2],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] in as [1,2],[3,10],[12,16]. + + This is because the new interval [4,9] overlaps with [3,5],[6,7],[8,10]. + + time : O(n) + space : O(n) + + * @param intervals + * @param newInterval + * @return + */ + public List insert(List intervals, Interval newInterval) { + if (newInterval == null) return intervals; + List res = new ArrayList<>(); + int i = 0; + while (i < intervals.size() && intervals.get(i).end < newInterval.start) { + res.add(intervals.get(i++)); + } + while (i < intervals.size() && intervals.get(i).start <= newInterval.end) { + newInterval.start = Math.min(newInterval.start, intervals.get(i).start); + newInterval.end = Math.max(newInterval.end, intervals.get(i).end); + } + res.add(newInterval); + while (i < intervals.size()) { + res.add(intervals.get(i)); + } + return res; + } +} diff --git a/InsertionSortList.java b/InsertionSortList.java new file mode 100644 index 0000000..14984f6 --- /dev/null +++ b/InsertionSortList.java @@ -0,0 +1,41 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : InsertionSortList + * Creator : Edward + * Date : Nov, 2017 + * Description : 147. Insertion Sort List + */ +public class InsertionSortList { + /** + * time : O(n^2) + * space : O(1) + * + * @param head + * @return + */ + public ListNode insertionSortList(ListNode head) { + if (head == null || head.next == null) return head; + ListNode dummy = new ListNode(0); + dummy.next = head; + ListNode cur = head; + ListNode temp = null, prev = null; + while (cur != null && cur.next != null) { + if (cur.val <= cur.next.val) { + cur = cur.next; + } else { + temp = cur.next; + cur.next = temp.next; + prev = dummy; + while (prev.next.val <= temp.val) { + prev = prev.next; + } + temp.next = prev.next; + prev.next = temp; + } + } + return dummy.next; + } +} diff --git a/IntegerBreak.java b/IntegerBreak.java new file mode 100644 index 0000000..88813a3 --- /dev/null +++ b/IntegerBreak.java @@ -0,0 +1,43 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : IntegerBreak + * Creator : Edward + * Date : Jan, 2018 + * Description : 343. Integer Break + */ +public class IntegerBreak { + /** + * Given a positive integer n, break it into the sum of at least two positive integers and + * maximize the product of those integers. Return the maximum product you can get. + + For example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return 36 (10 = 3 + 3 + 4). + + 2 : 1 + 1 + 3 : 2 + 1 + 4 : 2 + 2 + 5 : 3 + 2 + 6 : 3 + 3 + 7 : 3 + 4 + 8 : 3 + 3 + 2 + 9 : 3 + 3 + 3 + 10 : 3 + 3 + 4 + + time : < O(n) O(1) + space : O(1) + + * @param n + * @return + */ + public int integerBreak(int n) { + if (n == 2 || n == 3) return n - 1; + int res = 1; + while (n > 4) { + res *= 3; + n -= 3; + } + return res * n; + } +} diff --git a/IntegerReplacement.java b/IntegerReplacement.java new file mode 100644 index 0000000..644baf8 --- /dev/null +++ b/IntegerReplacement.java @@ -0,0 +1,87 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : IntegerReplacement + * Creator : Edward + * Date : Dec, 2017 + * Description : 397. Integer Replacement + */ +public class IntegerReplacement { + /** + * Given a positive integer n and you can do operations as follow: + + If n is even, replace n with n/2. + If n is odd, you can replace n with either n + 1 or n - 1. + What is the minimum number of replacements needed for n to become 1? + + Example 1: + + Input: + 8 + + Output: + 3 + + Explanation: + 8 -> 4 -> 2 -> 1 + Example 2: + + Input: + 7 + + Output: + 4 + + Explanation: + 7 -> 8 -> 4 -> 2 -> 1 + or + 7 -> 6 -> 3 -> 2 -> 1 + + time : O(logn) + space : O(1) + * @param n + * @return + */ + public int integerReplacement(int n) { + long N = n; + int res = 0; + while (N != 1) { + if (N % 2 == 0) { + N >>= 1; + } else { + if (N == 3) { + res += 2; + break; + } + N = (N & 2) == 2 ? N + 1 : N - 1; + } + } + return res; + } + + /** + * time : O(logn) + * space : O(1) + + * @param n + * @return + */ + + public int integerReplacement2(int n) { + if (n == Integer.MAX_VALUE) return 32; + int res = 0; + while (n != 1) { + if (n % 2 == 0) { + n /= 2; + } else { + if ( (n + 1) % 4 == 0 && (n - 1 != 2)) { + n++; + } else n--; + } + res++; + } + return res; + } +} diff --git a/IntegertoEnglishWords.java b/IntegertoEnglishWords.java new file mode 100644 index 0000000..1367276 --- /dev/null +++ b/IntegertoEnglishWords.java @@ -0,0 +1,52 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : IntegertoEnglishWords + * Creator : Edward + * Date : Nov, 2017 + * Description : 273. Integer to English Words + */ +public class IntegertoEnglishWords { + /** + * Convert a non-negative integer to its english words representation. Given input is guaranteed to be less than 231 - 1. + + For example, + 123 -> "One Hundred Twenty Three" + 12345 -> "Twelve Thousand Three Hundred Forty Five" + 1234567 -> "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven" + + time : O(n) / O(1) + space : O(1) + + + */ + String[] less20={"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"}; + String[] tens={"", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"}; + String[] thousands={"", "Thousand", "Million", "Billion"}; + + public String numberToWords(int num) { + if (num == 0) return "Zero"; + String res = ""; + int i = 0; + while (num > 0) { + if (num % 1000 != 0) { + res = helper(num % 1000) + thousands[i] + " " + res; + } + num /= 1000; + i++; + } + return res.trim(); + } + public String helper(int num) { + if (num == 0) return ""; + if (num < 20) { + return less20[num % 20] + " "; + } else if (num < 100) { + return tens[num / 10] + " " + helper(num % 10); + } else { + return less20[num / 100] + " Hundred " + helper(num % 100); + } + } +} diff --git a/IntegertoRoman.java b/IntegertoRoman.java new file mode 100644 index 0000000..81ae35d --- /dev/null +++ b/IntegertoRoman.java @@ -0,0 +1,34 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : IntegertoRoman + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class IntegertoRoman { + /** + * 12. Integer to Roman + + time : O(n) + space : O(n) + * @param num + * @return + */ + public String intToRoman(int num) { + int[] values = {1000,900,500,400,100,90,50,40,10,9,5,4,1}; + String[] strs = {"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"}; + + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < values.length; i++) { + while (num >= values[i]) { + num -= values[i]; + sb.append(strs[i]); + } + } + return sb.toString(); + } +} diff --git a/InterleavingString.java b/InterleavingString.java new file mode 100644 index 0000000..d64d8be --- /dev/null +++ b/InterleavingString.java @@ -0,0 +1,70 @@ +package leetcode; + +import java.util.Arrays; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : InterleavingString + * Creator : Edward + * Date : Nov, 2017 + * Description : 97. Interleaving String + */ +public class InterleavingString { + /** + * Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. + + For example, + Given: + s1 = "aabcc", + s2 = "dbbca", + + When s3 = "aadbbcbcac", return true. + + When s3 = "aadbbbaccc", return false. + + [true, true, true, false, false, false] + [false, false, false, false, false, false] + [false, false, false, false, false, false] + [false, false, false, false, false, false] + [false, false, false, false, false, false] + [false, false, false, false, false, false] + + [true, true, true, false, false, false] + [false, false, true, true, false, false] + [false, false, true, true, true, false] + [false, false, true, false, true, true] + [false, false, true, true, true, false] + [false, false, false, false, true, true] + + time : O(m * n) + space : O(m * n) + + * @param s1 + * @param s2 + * @param s3 + * @return + */ + public static boolean isInterleave(String s1, String s2, String s3) { + if ((s1.length() + s2.length()) != s3.length()) return false; + + boolean[][] dp = new boolean[s2.length() + 1][s1.length() + 1]; + dp[0][0] = true; + + for (int i = 1; i < dp.length; i++) { + dp[i][0] = dp[i - 1][0] && (s2.charAt(i - 1) == s3.charAt(i - 1)); + } + for (int i = 1; i < dp[0].length; i++) { + dp[0][i] = dp[0][i - 1] && (s1.charAt(i - 1) == s3.charAt(i - 1)); + } + + for (int i = 1; i < dp.length; i++) { + for (int j = 1; j < dp[0].length; j++) { + dp[i][j] = (dp[i - 1][j] && s2.charAt(i - 1) == s3.charAt(i + j - 1)) + || (dp[i][j - 1] && s1.charAt(j - 1) == s3.charAt(i + j - 1)); + } + } + + return dp[s2.length()][s1.length()]; + } +} diff --git a/IntersectionofTwoArrays.java b/IntersectionofTwoArrays.java new file mode 100644 index 0000000..fbe9b75 --- /dev/null +++ b/IntersectionofTwoArrays.java @@ -0,0 +1,119 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * Created by Edward on 28/07/2017. + */ +public class IntersectionofTwoArrays { + /** + * 349. Intersection of Two Arrays + * Given two arrays, write a function to compute their intersection. + + Example: + Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2]. + + Note: + Each element in the result must be unique. + The result can be in any order. + + time : O(n); + space : O(n); + + * @param nums1 + * @param nums2 + * @return + */ + + // binary search time : O(nlogn) space : O(n) + public static int[] intersection(int[] nums1, int[] nums2) { + if (nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0) { + return new int[]{}; + } + HashSet set = new HashSet<>(); + Arrays.sort(nums2); + for (Integer num : nums1) { + if (binarySearch(nums2, num)) { + set.add(num); + } + } + int k = 0; + int[] res = new int[set.size()]; + for (Integer num : set) { + res[k++] = num; + } + return res; + } + + public static boolean binarySearch(int[] nums, int target) { + int start = 0; + int end = nums.length - 1; + while (start + 1 < end) { + int mid = (end - start) / 2 + start; + if (nums[mid] == target) { + return true; + } else if (nums[mid] > target) { + end = mid; + } else { + start = mid; + } + } + if (nums[start] == target || nums[end] == target) return true; + return false; + } + + // Arrays.sort time : O(nlogn) space : O(n); + public static int[] intersection2(int[] nums1, int[] nums2) { + if (nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0) { + return new int[]{}; + } + HashSet set = new HashSet<>(); + Arrays.sort(nums1); + Arrays.sort(nums2); + int i = 0; + int j = 0; + while (i < nums1.length && j < nums2.length) { + if (nums1[i] < nums2[j]) { + i++; + } else if (nums1[i] > nums2[j]) { + j++; + } else { + set.add(nums1[i]); + i++; + j++; + } + } + int k = 0; + int[] res = new int[set.size()]; + for (Integer num : set) { + res[k++] = num; + } + return res; + } + + // time : O(n) space : O(n); + public static int[] intersection3(int[] nums1, int[] nums2) { + if (nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0) { + return new int[]{}; + } + HashSet set = new HashSet<>(); + HashSet ret = new HashSet<>(); + for (Integer num : nums1) { + set.add(num); + } + for (Integer num : nums2) { + if (set.contains(num)) { + ret.add(num); + } + } + int k = 0; + int[] res = new int[ret.size()]; + for (Integer num : ret) { + res[k++] = num; + } + return res; + } +} diff --git a/IntersectionofTwoArraysII.java b/IntersectionofTwoArraysII.java new file mode 100644 index 0000000..8c95695 --- /dev/null +++ b/IntersectionofTwoArraysII.java @@ -0,0 +1,78 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +/** + * Created by Edward on 28/07/2017. + */ +public class IntersectionofTwoArraysII { + /** + * 350. Intersection of Two Arrays II + * Given two arrays, write a function to compute their intersection. + + Example: + Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2, 2]. + + + * @param nums1 + * @param nums2 + * @return + */ + + // HashMap, time : O(n), space : O(n); + public static int[] intersect(int[] nums1, int[] nums2) { + HashMap map = new HashMap<>(); + List ret = new ArrayList<>(); + for (int i = 0; i < nums1.length; i++) { + if (map.containsKey(nums1[i])) { + map.put(nums1[i],map.get(nums1[i]) + 1); + } else { + map.put(nums1[i], 1); + } + } + for (int i = 0; i < nums2.length; i++) { + if (map.containsKey(nums2[i])) { + if (map.get(nums2[i]) > 0) { + ret.add(nums2[i]); + map.put(nums2[i], map.get(nums2[i]) - 1); + } + } + } + int[] res = new int[ret.size()]; + int k = 0; + for (Integer num : ret) { + res[k++] = num; + } + return res; + } + + // Arrays.sort time : O(nlogn) space : O(n); + public static int[] intersect2(int[] nums1, int[] nums2) { + Arrays.sort(nums1); + Arrays.sort(nums2); + List ret = new ArrayList<>(); + int i = 0; + int j = 0; + while (i < nums1.length && j < nums2.length) { + if (nums1[i] < nums2[j]) { + i++; + } else if (nums1[i] > nums2[j]) { + j++; + } else { + ret.add(nums1[i]); + i++; + j++; + } + } + int[] res = new int[ret.size()]; + int k = 0; + for (Integer num : ret) { + res[k++] = num; + } + return res; + } +} + diff --git a/IntersectionofTwoLinkedLists.java b/IntersectionofTwoLinkedLists.java new file mode 100644 index 0000000..5474428 --- /dev/null +++ b/IntersectionofTwoLinkedLists.java @@ -0,0 +1,90 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : IntersectionofTwoLinkedLists + * Creator : Edward + * Date : Oct, 2017 + * Description : 160. Intersection of Two Linked Lists + */ +public class IntersectionofTwoLinkedLists { + /** + * For example, the following two linked lists: + + A: a1 → a2 + ↘ + c1 → c2 → c3 + ↗ + B: b1 → b2 → b3 + begin to intersect at node c1. + + time : O(n); + space : O(1); + + * @param headA + * @param headB + * @return + */ + public ListNode getIntersectionNode(ListNode headA, ListNode headB) { + if (headA == null || headB == null) return null; + int lenA = len(headA); + int lenB = len(headB); + if (lenA > lenB) { + while (lenA != lenB) { + headA = headA.next; + lenA--; + } + } else { + while (lenA != lenB) { + headB = headB.next; + lenB--; + } + } + while (headA != headB) { + headA = headA.next; + headB = headB.next; + } + return headA; + } + + public int len(ListNode head) { + int len = 1; + while (head != null) { + head = head.next; + len++; + } + return len; + } + + /** + * + A: a1 → a2 + ↘ + c1 → c2 → c3 + ↗ + B: b1 → b2 → b3 + begin to intersect at node c1. + + A : a1 → a2 -> c1 → c2 → c3 -> b1 → b2 → b3 -> c1 → c2 → c3 + B : b1 → b2 → b3 -> c1 → c2 → c3 -> a1 → a2 -> c1 → c2 → c3 + + time : O(m + n); + space : O(1); + + * @param headA + * @param headB + * @return + */ + + public ListNode getIntersectionNode2(ListNode headA, ListNode headB) { + if (headA == null || headB == null) return null; + ListNode a = headA; + ListNode b = headB; + while (a != b) { + a = a == null ? headB : a.next; + b = b == null ? headA : b.next; + } + return a; + } +} diff --git a/Interval.java b/Interval.java new file mode 100644 index 0000000..e56fbb9 --- /dev/null +++ b/Interval.java @@ -0,0 +1,22 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : Interval + * Creator : Edward + * Date : Oct, 2017 + * Description : TODO + */ +public class Interval { + int start; + int end; + Interval() { + start = 0; + end = 0; + } + Interval(int s, int e) { + start = s; + end = e; + } +} diff --git a/InvertBinaryTree.java b/InvertBinaryTree.java new file mode 100644 index 0000000..e914254 --- /dev/null +++ b/InvertBinaryTree.java @@ -0,0 +1,61 @@ +package leetcode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : InvertBinaryTree + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class InvertBinaryTree { + /** + * 226. Invert Binary Tree + * Invert a binary tree. + + 4 + / \ + 2 7 + / \ / \ + 1 3 6 9 + + to + 4 + / \ + 7 2 + / \ / \ + 9 6 3 1 + + time : O(n) + space : O(n); + * @param root + * @return + */ + + public TreeNode invertTree(TreeNode root) { + if (root == null) return root; + TreeNode left = invertTree(root.left); + TreeNode right = invertTree(root.right); + root.left = right; + root.right = left; + return root; + } + + public TreeNode invertTree2(TreeNode root) { + if (root == null) return root; + Queue queue = new LinkedList<>(); + queue.offer(root); + while (!queue.isEmpty()) { + TreeNode cur = queue.poll(); + TreeNode temp = cur.left; + cur.left = cur.right; + cur.right = temp; + if (cur.left != null) queue.offer(cur.left); + if (cur.right != null) queue.offer(cur.right); + } + return root; + } +} diff --git a/IsSubsequence.java b/IsSubsequence.java new file mode 100644 index 0000000..2ef0210 --- /dev/null +++ b/IsSubsequence.java @@ -0,0 +1,40 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : IsSubsequence + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class IsSubsequence { + /** + * 392. Is Subsequence + * Example 1: + s = "abc", t = "ahbgdc" + + Return true. + + Example 2: + s = "axc", t = "ahbgdc" + + Return false. + + time : O(n); + space : O(1); + * @param s + * @param t + * @return + */ + public boolean isSubsequence(String s, String t) { + if (s == null || s.length() == 0) return true; + int i = 0; + int j = 0; + while (i < s.length() && j < t.length()) { + if (s.charAt(i) == t.charAt(j)) i++; + j++; + } + return i == s.length(); + } +} diff --git a/IsomorphicStrings.java b/IsomorphicStrings.java new file mode 100644 index 0000000..2772c51 --- /dev/null +++ b/IsomorphicStrings.java @@ -0,0 +1,62 @@ +package leetcode; + +import java.util.HashMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : IsomorphicStrings + * Creator : Edward + * Date : Oct, 2017 + * Description : 205. Isomorphic Strings + */ +public class IsomorphicStrings { + /** + * For example, + Given "egg", "add", return true. + + Given "foo", "bar", return false. + + Given "paper", "title", return true. + + egg add + + * @param s + * @param t + * @return + */ + // time : O(n) space : O(n) + public boolean isIsomorphic(String s, String t) { + if (s == null || t == null) return true; + HashMap map = new HashMap<>(); + for (int i = 0; i < s.length(); i++) { + char a = s.charAt(i); + char b = t.charAt(i); + if (map.containsKey(a)) { + if (map.get(a).equals(b)) continue; + else return false; + } else { + if (!map.containsValue(b)) { + map.put(a, b); + } else return false; + } + } + return true; + } + + + // time : O(n) space : O(1) + public boolean isIsomorphic2(String s, String t) { + int[] sChars = new int[256]; + int[] tChars = new int[256]; + + for (int i = 0; i < s.length(); i++) { + if (sChars[s.charAt(i)] != tChars[t.charAt(i)]) { + return false; + } else { + sChars[s.charAt(i)] = tChars[t.charAt(i)] = t.charAt(i); + } + } + return true; + } +} diff --git a/JumpGame.java b/JumpGame.java new file mode 100644 index 0000000..6a8d31f --- /dev/null +++ b/JumpGame.java @@ -0,0 +1,32 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : JumpGame + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class JumpGame { + /** + * 55. Jump Game + * For example: + A = [2,3,1,1,4], return true. + + A = [3,2,1,0,4], return false. + + time : O(n) + space : O(1) + * @param nums + * @return + */ + public boolean canJump(int[] nums) { + int max = 0; + for (int i = 0; i < nums.length; i++) { + if (i > max) return false; + max = Math.max(nums[i] + i, max); + } + return true; + } +} diff --git a/JumpGameII.java b/JumpGameII.java new file mode 100644 index 0000000..ff73128 --- /dev/null +++ b/JumpGameII.java @@ -0,0 +1,70 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : JumpGameII + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class JumpGameII { + /** + * 45. Jump Game II + * For example: + Given array A = [2,3,1,1,4] + + The minimum number of jumps to reach the last index is 2. (Jump 1 res from index 0 to 1, + then 3 ress to the last index.) + + * @param nums + * @return + */ + + //time : O(n) space : O(1) + public int jump(int[] nums) { + if (nums == null || nums.length < 2) return 0; + int res = 0; + int curMaxArea = 0; + int maxNext = 0; + for (int i = 0; i < nums.length - 1; i++) { + maxNext = Math.max(maxNext, i + nums[i]); + if (i == curMaxArea) { + res++; + curMaxArea = maxNext; + } + } + return res; + } + + /** + [2,3,1,1,4] + + level = 2 + cur = 2 + max = 4 + i = 1 + + * @param nums + * @return + */ + // time : O(n) space : O(1) + public int jump2(int[] nums) { + if (nums == null || nums.length < 2) return 0; + int level = 0; + int curMaxArea = 0; + int maxNext = 0; + int i = 0; + while (curMaxArea - i + 1 > 0) { + level++; + for (; i <= curMaxArea; i++) { + maxNext = Math.max(maxNext, nums[i] + i); + if (maxNext >= nums.length - 1) { + return level; + } + } + curMaxArea = maxNext; + } + return 0; + } +} diff --git a/KthLargestElementinanArray.java b/KthLargestElementinanArray.java new file mode 100644 index 0000000..c582e58 --- /dev/null +++ b/KthLargestElementinanArray.java @@ -0,0 +1,91 @@ +package leetcode; + +import java.util.Arrays; +import java.util.PriorityQueue; +import java.util.Random; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : KthLargestElementinanArray + * Creator : Edward + * Date : Nov, 2017 + * Description : 215. Kth Largest Element in an Array + */ + +public class KthLargestElementinanArray { + + // time : O(n) space : O(1) + + public int findKthLargest(int[] nums, int k) { + if (nums == null || nums.length == 0) return 0; + int left = 0; + int right = nums.length - 1; + while (true) { + int pos = partition(nums, left, right); + if (pos + 1 == k) { + return nums[pos]; + } else if (pos + 1 > k) { + right = pos - 1; + } else { + left = pos + 1; + } + } + } + + /** + * 3,2,1,5,6,4 k = 3 + * 0 1 2 3 4 5 + pivot : 3 [3, 2, 1, 5, 6, 4] + [3, 4, 6, 5, 1, 2] 3 + + pivot : 5 [5, 4, 6, 3, 1, 2] + [5, 6, 4, 3, 1, 2] 1 + + pivot : 4 [6, 5, 4, 3, 1, 2] + [6, 5, 4, 3, 1, 2] 2 + */ + + private int partition(int[] nums, int left, int right) { + int pivot = nums[left]; + int l = left + 1; + int r = right; + while (l <= r) { + if (nums[l] < pivot && nums[r] > pivot) { + swap(nums, l++, r--); + } + if (nums[l] >= pivot) l++; + if (nums[r] <= pivot) r--; + } + swap(nums, left, r); + return r; + } + + private void swap(int[] nums, int i, int j) { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } + + /** + * time : O(nlogk) + * space : O(n) + * + * @param nums + * @param k + * @return + */ + + + public int findKthLargest2(int[] nums, int k) { + if (nums == null || nums.length == 0) return 0; + PriorityQueue minHeap = new PriorityQueue<>(); + for (int num : nums) { + minHeap.offer(num); + if (minHeap.size() > k) { + minHeap.poll(); + } + } + return minHeap.poll(); + } +} diff --git a/KthSmallestElementinaBST.java b/KthSmallestElementinaBST.java new file mode 100644 index 0000000..6b3058f --- /dev/null +++ b/KthSmallestElementinaBST.java @@ -0,0 +1,36 @@ +package leetcode; + +/** + * Created by Edward on 28/07/2017. + */ +public class KthSmallestElementinaBST { + /** + * 230. Kth Smallest Element in a BST + * Given a binary search tree, write a function kthSmallest to find the kth smallest element in it. + * + * + * time : O(n) + * space : O(n); + * @param root + * @param k + * @return + */ + + private static int count = 0; + private static int res = 0; + + public static int kthSmallest(TreeNode root, int k) { + count = k; + helper(root); + return res; + } + public static void helper(TreeNode root) { + if (root == null) return; + helper(root.left); + count--; + if (count == 0) { + res = root.val; + } + helper(root.right); + } +} diff --git a/KthSmallestElementinaSortedMatrix.java b/KthSmallestElementinaSortedMatrix.java new file mode 100644 index 0000000..bc02f7a --- /dev/null +++ b/KthSmallestElementinaSortedMatrix.java @@ -0,0 +1,87 @@ +package leetcode; + +import java.util.PriorityQueue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : KthSmallestElementinaSortedMatrix + * Creator : Edward + * Date : Jan, 2018 + * Description : 378. Kth Smallest Element in a Sorted Matrix + */ +public class KthSmallestElementinaSortedMatrix { + + /** + * Example: + + matrix = [ + [ 1, 5, 9], + [10, 11, 13], + [12, 13, 15] + ], + k = 8, + + return 13. + + min = 1 max = 15 mid = 8 + + 1, PriorityQueue : 链表 + 2, Binary Search : 数个数 + + * @param matrix + * @param k + * @return + */ + + // time : (nlogn) space : O(n) + public int kthSmallest(int[][] matrix, int k) { + PriorityQueue pq = new PriorityQueue<>(matrix.length, (a, b) -> (a.val - b.val)); + for (int i = 0; i < matrix.length; i++) { + pq.offer(new Tuple(0, i, matrix[0][i])); + } + for (int i = 0; i < k - 1; i++) { + Tuple tuple = pq.poll(); + if (tuple.x == matrix.length - 1) continue; + pq.offer(new Tuple(tuple.x + 1, tuple.y, matrix[tuple.x + 1][tuple.y])); + } + return pq.poll().val; + } + + class Tuple { + int x, y, val; + public Tuple(int x, int y, int val) { + this.x = x; + this.y = y; + this.val = val; + } + } + + // time : O(n * log(max - min)) space : O(1) + public int kthSmallest2(int[][] matrix, int k) { + int n = matrix.length; + int left = matrix[0][0]; + int right = matrix[n - 1][n - 1]; + while (left + 1 < right) { + int mid = (right - left) / 2 + left; + int num = count(matrix, mid); + if (num >= k) right = mid; + else left = mid; + } + if (count(matrix, right) <= k - 1) return right; + return left; + } + + private int count(int[][] matrix, int target) { + int n = matrix.length; + int res = 0; + int i = n - 1, j = 0; + while (i >= 0 && j < n) { + if (matrix[i][j] < target) { + res += i + 1; + j++; + } else i--; + } + return res; + } +} \ No newline at end of file diff --git a/LRUCache.java b/LRUCache.java new file mode 100644 index 0000000..8e8d3a0 --- /dev/null +++ b/LRUCache.java @@ -0,0 +1,130 @@ +package leetcode; + +import java.util.HashMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LRUCache + * Creator : Edward + * Date : Dec, 2017 + * Description : 146. LRU Cache + */ +public class LRUCache { + + /** + * Design and implement a data structure for Least Recently Used (LRU) cache. + * It should support the following operations: get and put. + + get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. + put(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, + it should invalidate the least recently used item before inserting a new item. + + Follow up: + Could you do both operations in O(1) time complexity? + + Example: + + LRUCache cache = new LRUCache( 2 capacity ); + + cache.put(1, 1); + cache.put(2, 2); + cache.get(1); // returns 1 + cache.put(3, 3); // evicts key 2 + cache.get(2); // returns -1 (not found) + cache.put(4, 4); // evicts key 1 + cache.get(1); // returns -1 (not found) + cache.get(3); // returns 3 + cache.get(4); // returns 4 + + HashMap + Double Linked List + + 插入:1,不存在 -> capacity -> 1,head = null 2,head != null + 2,存在 + 取出:1,不存在 + 2,存在 + => 排序 + + time : O(1) + **/ + + class Node { + int key; + int value; + Node next; + Node pre; + public Node(int key, int value) { + this.key = key; + this.value = value; + } + } + + private HashMap map; + private int capacity; + private Node head; + private Node tail; + + public LRUCache(int capacity) { + map = new HashMap<>(); + this.capacity = capacity; + head = null; + tail = null; + } + + public int get(int key) { + Node node = map.get(key); + if (node == null) { + return -1; + } + if (node != tail) { + if (node == head) { + head = head.next; + } else { + node.pre.next = node.next; + node.next.pre = node.pre; + } + tail.next = node; + node.pre = tail; + node.next = null; + tail = node; + } + return node.value; + } + + public void put(int key, int value) { + Node node = map.get(key); + if (node != null) { + node.value = value; + if (node != tail) { + if (node == head) { + head = head.next; + } else { + node.pre.next = node.next; + node.next.pre = node.pre; + } + tail.next = node; + node.pre = tail; + node.next = null; + tail = node; + } + } else { + Node newNode = new Node(key, value); + if (capacity == 0) { + Node temp = head; + head = head.next; + map.remove(temp.key); + capacity++; + } + if (head == null && tail == null) { + head = newNode; + } else { + tail.next = newNode; + newNode.pre = tail; + newNode.next = null; + } + tail = newNode; + map.put(key, newNode); + capacity--; + } + } +} diff --git a/LargestBSTSubtree.java b/LargestBSTSubtree.java new file mode 100644 index 0000000..6204be4 --- /dev/null +++ b/LargestBSTSubtree.java @@ -0,0 +1,77 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LargestBSTSubtree + * Creator : Edward + * Date : Jan, 2018 + * Description : 333. Largest BST Subtree + */ +public class LargestBSTSubtree { + /** + * Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), + * where largest means subtree with largest number of nodes in it. + + Note: + A subtree must include all of its descendants. + Here's an example: + 10 + / \ + 5 15 + / \ \ + 1 8 7 + / + null + The Largest BST Subtree in this case is the highlighted one. + The return value is the subtree's size, which is 3. + + 1, postorder + 2, BST + 3, decide BST + + 1 : 1,1,1 + 8 : 1,8,8 + 5 : 3,1,8 + 7 : 1,7,7 + 15 : -1,0,0 + + time : O(n) + space : O(n) + + */ + + int res = 0; + + public int largestBSTSubtree(TreeNode root) { + if (root == null) return 0; + helper(root); + return res; + } + + private SearchNode helper(TreeNode root) { + if (root == null) { + return new SearchNode(0, Integer.MAX_VALUE, Integer.MIN_VALUE); + } + SearchNode left = helper(root.left); + SearchNode right = helper(root.right); + if (left.size == -1 || right.size == -1 || root.val <= left.upper || root.val >= right.lower) { + return new SearchNode(-1, 0, 0); + } + int size = left.size + right.size + 1; + res = Math.max(size, res); + return new SearchNode(size, Math.min(left.lower, root.val), Math.max(right.upper, root.val)); + } + + class SearchNode { + int size; + int lower; + int upper; + + SearchNode(int size, int lower, int upper) { + this.size = size; + this.lower = lower; + this.upper = upper; + } + } +} diff --git a/LargestDivisibleSubset.java b/LargestDivisibleSubset.java new file mode 100644 index 0000000..60be725 --- /dev/null +++ b/LargestDivisibleSubset.java @@ -0,0 +1,88 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LargestDivisibleSubset + * Creator : Edward + * Date : Jan, 2018 + * Description : 368. Largest Divisible Subset + */ +public class LargestDivisibleSubset { + /** + * Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) + * of elements in this subset satisfies: Si % Sj = 0 or Sj % Si = 0. + + If there are multiple solutions, return any subset is fine. + + Example 1: + + nums: [1,2,3] + + Result: [1,2] (of course, [1,3] will also be ok) + Example 2: + + nums: [1,2,4,8] + + Result: [1,2,4,8] + + 1 2 4 6 8 + + 1 2 4 6 8 + pre : -1 0 1 1 2 + count: 1 2 3 3 4 + + Arrays.sort() + count[] + pre[] : index[] + + int index(4) max(4) + + a % b == 0 + b % c == 0 + a % c == 0 + + pre + + time : O(n^2) + space : O(n) + + * @param nums + * @return + */ + public List largestDivisibleSubset(int[] nums) { + if (nums == null || nums.length == 0) return new ArrayList<>(); + + Arrays.sort(nums); + int[] count = new int[nums.length]; + int[] pre = new int[nums.length]; + int max = 0, index = -1; + + for (int i = 0; i < nums.length; i++) { + count[i] = 1; + pre[i] = -1; + for (int j = i - 1; j >= 0; j--) { + if (nums[i] % nums[j] == 0) { + if (1 + count[j] > count[i]) { + count[i] = count[j] + 1; + pre[i] = j; + } + } + if (count[i] > max) { + max = count[i]; + index = i; + } + } + } + List res = new ArrayList<>(); + while (index != -1) { + res.add(nums[index]); + index = pre[index]; + } + return res; + } +} diff --git a/LargestNumber.java b/LargestNumber.java new file mode 100644 index 0000000..a683b4a --- /dev/null +++ b/LargestNumber.java @@ -0,0 +1,54 @@ +package leetcode; + +import java.lang.reflect.Array; +import java.util.Arrays; +import java.util.Comparator; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LargestNumber + * Creator : Edward + * Date : Nov, 2017 + * Description : 179. Largest Number + */ +public class LargestNumber { + /** + * Given a list of non negative integers, arrange them such that they form the largest number. + + For example, given [3, 30, 34, 5, 9], the largest formed number is 9534330. + + Note: The result may be very large, so you need to return a string instead of an integer. + + time : O(nlogn) + space : O(n) + + * @param nums + * @return + */ + public String largestNumber(int[] nums) { + if (nums == null || nums.length == 0) { + return ""; + } + String[] res = new String[nums.length]; + for (int i = 0; i < nums.length; i++) { + res[i] = String.valueOf(nums[i]); + } + Arrays.sort(res, new Comparator(){ + @Override + public int compare(String str1, String str2) { + String s1 = str1 + str2; + String s2 = str2 + str1; + return s2.compareTo(s1); + } + }); + if (res[0].charAt(0) == '0') { + return "0"; + } + StringBuilder sb = new StringBuilder(); + for (String s : res) { + sb.append(s); + } + return sb.toString(); + } +} diff --git a/LargestRectangleinHistogram.java b/LargestRectangleinHistogram.java new file mode 100644 index 0000000..afb78ce --- /dev/null +++ b/LargestRectangleinHistogram.java @@ -0,0 +1,59 @@ +package leetcode; + +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LargestRectangleinHistogram + * Creator : Edward + * Date : Dec, 2017 + * Description : 84. Largest Rectangle in Histogram + */ +public class LargestRectangleinHistogram { + /** + * For example, + Given heights = [2,1,5,6,2,3], + return 10. + + stack : 1,升序,2,小于,计算 + 0,1,2,3,4,5,6 + [2,1,5,6,2,3,0] + + stack : 1 + 2 : push + 1 : height = 2 start = -1 res = 2 + 5 : push + 6 : push + 2 : height = 6 start = 2 area = 6 res = 6 + height = 5 start = 1 area = 10 res = 10 + 3 push + 0 : height = 2 start = 1 area = 8 + height = 1 start = -1 area = 6 + + res = 10 + + time : O(n) + space : O(n) + + + * @param heights + * @return + */ + public int largestRectangleArea(int[] heights) { + if (heights == null || heights.length == 0) return 0; + Stack stack = new Stack<>(); + int res = 0; + for (int i = 0; i <= heights.length; i++) { + int h = i == heights.length ? 0 : heights[i]; + while (!stack.isEmpty() && h < heights[stack.peek()]) { + int height = heights[stack.pop()]; + int start = stack.isEmpty() ? -1 : stack.peek(); + int area = height * (i - start - 1); + res = Math.max(res, area); + } + stack.push(i); + } + return res; + } +} diff --git a/LengthofLastWord.java b/LengthofLastWord.java new file mode 100644 index 0000000..0490a2b --- /dev/null +++ b/LengthofLastWord.java @@ -0,0 +1,26 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LengthofLastWord + * Creator : Edward + * Date : Oct, 2017 + * Description : 58. Length of Last Word + */ +public class LengthofLastWord { + /** + * For example, + Given s = "Hello World", + return 5. + + time : O(1) + space : O(1) + + * @param s + * @return + */ + public int lengthOfLastWord(String s) { + return s.trim().length() - s.trim().lastIndexOf(" ") - 1; + } +} diff --git a/LetterCombinationsofaPhoneNumber.java b/LetterCombinationsofaPhoneNumber.java new file mode 100644 index 0000000..a7da1ec --- /dev/null +++ b/LetterCombinationsofaPhoneNumber.java @@ -0,0 +1,63 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LetterCombinationsofaPhoneNumber + * Creator : Edward + * Date : Oct, 2017 + * Description : 17. Letter Combinations of a Phone Number + */ +public class LetterCombinationsofaPhoneNumber { + /** + * time : O(3^n) + * space : O(n) + */ + + private String[] mapping = new String[] {"0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; + + public List letterCombinations(String digits) { + List res = new ArrayList<>(); + if (digits == null || digits.length() == 0) { + return res; + } + helper(res, digits, "", 0); + return res; + } + + public void helper(List res, String digits, String s, int index) { + if (index == digits.length()) { + res.add(s); + return; + } + String letters = mapping[s.charAt(index) - '0']; + for (int i = 0; i < letters.length(); i++) { + helper(res, digits, s + letters.charAt(i), index + 1); + } + } + + public List letterCombinations2(String digits) { + LinkedList res = new LinkedList<>(); + if (digits == null || digits.length() == 0) { + return res; + } + String[] mapping = new String[] {"0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; + res.add(""); + for (int i = 0; i < digits.length(); i++) { + int num = digits.charAt(i) - '0'; + while (res.peek().length() == i) { + String t = res.remove(); + for (char s : mapping[num].toCharArray()) { + res.add(t + s); + } + } + } + return res; + } + +} diff --git a/LexicographicalNumbers.java b/LexicographicalNumbers.java new file mode 100644 index 0000000..e31ae87 --- /dev/null +++ b/LexicographicalNumbers.java @@ -0,0 +1,46 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LexicographicalNumbers + * Creator : Edward + * Date : Oct, 2017 + * Description : 386. Lexicographical Numbers + */ +public class LexicographicalNumbers { + /** + * Given an integer n, return 1 - n in lexicographical order. + + For example, given 13, return: [1,10,11,12,13,2,3,4,5,6,7,8,9]. + + Please optimize your algorithm to use less time and space. The input size may be as large as 5,000,000. + + time : O(n); + space : O(n); + + * @param n + * @return + */ + public List lexicalOrder(int n) { + List res = new ArrayList<>(); + int cur = 1; + for (int i = 1; i <= n; i++) { + res.add(cur); + if (cur * 10 <= n) { + cur *= 10; + } else if (cur % 10 != 9 && cur + 1 <= n) { + cur++; + } else { + while ((cur / 10) % 10 == 9) { + cur /= 10; + } + cur = cur / 10 + 1; + } + } + return res; + } +} diff --git a/LineReflection.java b/LineReflection.java new file mode 100644 index 0000000..8851811 --- /dev/null +++ b/LineReflection.java @@ -0,0 +1,62 @@ +package leetcode; + +import java.util.HashSet; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LineReflection + * Creator : Edward + * Date : Jan, 2018 + * Description : 356. Line Reflection + */ +public class LineReflection { + /** + * Given n points on a 2D plane, find if there is such a line parallel to y-axis that reflect the given points. + + Example 1: + Given points = [[1,1],[-1,1]], return true. + + Example 2: + Given points = [[1,1],[-1,-1]], return false. + + x1 + x2 = c + min max + + x1 = c - x2 + + 平行于y轴 : x : 对称 (两个点) + y : 相同 + + HashSet + 1, 找出关于哪个轴对称 + 2, check + + "1,1" "-1,1" + + x2 = sum - pair + + time : O(n) + space : O(n) + + * @param points + * @return + */ + public boolean isReflected(int[][] points) { + HashSet set = new HashSet<>(); + int min = Integer.MAX_VALUE; + int max = Integer.MIN_VALUE; + for (int[] pair : points) { + set.add(pair[0] + "," + pair[1]); + min = Math.min(min, pair[0]); + max = Math.max(max, pair[0]); + } + int sum = min + max; + for (int[] pair : points) { + if (!set.contains(sum - pair[0] + "," + pair[1])) { + return false; + } + } + return true; + } +} diff --git a/LinkedListCycle.java b/LinkedListCycle.java new file mode 100644 index 0000000..167aa2c --- /dev/null +++ b/LinkedListCycle.java @@ -0,0 +1,33 @@ +package leetcode; + +import java.util.List; + +/** + * Created by Edward on 25/07/2017. + */ +public class LinkedListCycle { + + /** + * 141. Linked List Cycle + * Given a linked list, determine if it has a cycle in it. + * time : O(n); + * space : O(1); + * @param head + * @return + */ + public static boolean hasCycle(ListNode head) { + if (head == null || head.next == null) return false; + + ListNode slow = head; + ListNode fast = head; + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + if (slow == fast) { + return true; + } + } + + return false; + } +} diff --git a/LinkedListCycleII.java b/LinkedListCycleII.java new file mode 100644 index 0000000..b3d2e45 --- /dev/null +++ b/LinkedListCycleII.java @@ -0,0 +1,41 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LinkedListCycleII + * Creator : Edward + * Date : Oct, 2017 + * Description : 142. Linked List Cycle II + */ +public class LinkedListCycleII { + + /** + * Given a linked list, return the node where the cycle begins. If there is no cycle, return null. + * + * time : O(n) + * space : O(1) + * + * @param head + * @return + */ + + public ListNode detectCycle(ListNode head) { + if (head == null || head.next == null) return null; + ListNode slow = head; + ListNode fast = head; + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + if (fast == slow) { + ListNode slow2 = head; + while (slow != slow2) { + slow = slow.next; + slow2 = slow2.next; + } + return slow; + } + } + return null; + } +} diff --git a/LinkedListRandomNode.java b/LinkedListRandomNode.java new file mode 100644 index 0000000..4ad3042 --- /dev/null +++ b/LinkedListRandomNode.java @@ -0,0 +1,42 @@ +package leetcode; + +import java.util.Random; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LinkedListRandomNode + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class LinkedListRandomNode { + /** + * 382. Linked List Random Node + * + * time : O(n); + * @param head + */ + + private ListNode head; + private Random rmd; + + public LinkedListRandomNode(ListNode head) { + this.head = head; + rmd = new Random(); + } + + /** Returns a random node's value. */ + public int getRandom() { + ListNode temp = head; + int res = temp.val; + int i = 1; + while (temp.next != null) { + temp = temp.next; + if (rmd.nextInt(++i) == 0) { + res = temp.val; + } + } + return res; + } +} diff --git a/ListNode.java b/ListNode.java new file mode 100644 index 0000000..d8d5e53 --- /dev/null +++ b/ListNode.java @@ -0,0 +1,15 @@ +package leetcode; + +/** + * Created by Edward on 25/07/2017. + */ +public class ListNode { + + int val; + ListNode next; + + ListNode(int x) { + val = x; + next = null; + } +} diff --git a/LoggerRateLimiter.java b/LoggerRateLimiter.java new file mode 100644 index 0000000..d0c81b9 --- /dev/null +++ b/LoggerRateLimiter.java @@ -0,0 +1,57 @@ +package leetcode; + +import java.util.HashMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LoggerRateLimiter + * Creator : Edward + * Date : Oct, 2017 + * Description : 359. Logger Rate Limiter + */ +public class LoggerRateLimiter { + /** + * Example: + + Logger logger = new Logger(); + + // logging string "foo" at timestamp 1 + logger.shouldPrintMessage(1, "foo"); returns true; + + // logging string "bar" at timestamp 2 + logger.shouldPrintMessage(2,"bar"); returns true; + + // logging string "foo" at timestamp 3 + logger.shouldPrintMessage(3,"foo"); returns false; + + // logging string "bar" at timestamp 8 + logger.shouldPrintMessage(8,"bar"); returns false; + + // logging string "foo" at timestamp 10 + logger.shouldPrintMessage(10,"foo"); returns false; + + // logging string "foo" at timestamp 11 + logger.shouldPrintMessage(11,"foo"); returns true; + + time : O(1) + space : O(n) + + */ + /** Initialize your data structure here. */ + HashMap map; + + public LoggerRateLimiter() { + map = new HashMap<>(); + } + + /** Returns true if the message should be printed in the given timestamp, otherwise returns false. + If this method returns false, the message will not be printed. + The timestamp is in seconds granularity. */ + public boolean shouldPrintMessage(int timestamp, String message) { + if (!map.containsKey(message) || timestamp - map.get(message) >= 10) { + return true; + } + return false; + } +} diff --git a/LongestAbsoluteFilePath.java b/LongestAbsoluteFilePath.java new file mode 100644 index 0000000..4dfc36c --- /dev/null +++ b/LongestAbsoluteFilePath.java @@ -0,0 +1,56 @@ +package leetcode; + +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LongestAbsoluteFilePath + * Creator : Edward + * Date : Oct, 2017 + * Description : 388. Longest Absolute File Path + */ +public class LongestAbsoluteFilePath { + /** + * The string "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext" represents: + * dir + subdir1 + subdir2 + file.ext + dir\ subdir2\ file.ext + 3 7 8 = 20 + + dir \tsubdir1 \tsubdir2 \t\tfile.ext + + + stack : 0 4 12 21 + dir : level = 0 + \tsubdir1 \tsubdir2 : level = 1 + \t\tfile.ext ; level = 2 + + time : O(n) + space : O(n) + + + * @param input + * @return + */ + public static int lengthLongestPath(String input) { + Stack stack = new Stack<>(); + stack.push(0); + int res = 0; + for (String s : input.split("\n")) { + int level = s.lastIndexOf("\t") + 1; + while (level + 1 < stack.size()) { + stack.pop(); + } + int len = stack.peek() + s.length() - level + 1; + stack.push(len); + if (s.contains(".")) { + res = Math.max(res, len - 1); + } + } + return res; + } + +} diff --git a/LongestCommonPrefix.java b/LongestCommonPrefix.java new file mode 100644 index 0000000..bbfdd8d --- /dev/null +++ b/LongestCommonPrefix.java @@ -0,0 +1,29 @@ +package leetcode; + +/** + * Created by Edward on 25/07/2017. + */ +public class LongestCommonPrefix { + /** + * 14. Longest Common Prefix + * Write a function to find the longest common prefix string amongst an array of strings. + * + * + * case : "edwardshi", "edward", "edwar", "edwardshidd" + * time : O(n); + * space : O(1); + * + * @param strs + * @return + */ + public static String longestCommonPrefix(String[] strs) { + if (strs == null || strs.length == 0) return ""; + String res = strs[0]; + for (int i = 1; i < strs.length; i++) { + while (strs[i].indexOf(res) != 0) { + res = res.substring(0, res.length() - 1); + } + } + return res; + } +} diff --git a/LongestConsecutiveSequence.java b/LongestConsecutiveSequence.java new file mode 100644 index 0000000..c1b936b --- /dev/null +++ b/LongestConsecutiveSequence.java @@ -0,0 +1,53 @@ +package leetcode; + +import jdk.nashorn.internal.objects.NativeUint8Array; + +import java.util.HashSet; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LongestConsecutiveSequence + * Creator : Edward + * Date : Nov, 2017 + * Description : 128. Longest Consecutive Sequence + */ +public class LongestConsecutiveSequence { + /** + * Given an unsorted array of integers, find the length of the longest consecutive elements sequence. + + For example, + Given [100, 4, 200, 1, 3, 2], + The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4. + + Your algorithm should run in O(n) complexity. + + time : O(n) + space : O(n) + + * @param nums + * @return + */ + public int longestConsecutive(int[] nums) { + if (nums == null || nums.length == 0) return 0; + HashSet set = new HashSet<>(); + int res = 0; + for (int num : nums) { + set.add(num); + } + for (int i = 0; i < nums.length; i++) { + int down = nums[i] - 1; + while (set.contains(down)) { + set.remove(down); + down--; + } + int up = nums[i] + 1; + while (set.contains(up)) { + set.remove(up); + up++; + } + res = Math.max(res, up - down - 1); + } + return res; + } +} diff --git a/LongestIncreasingPathinaMatrix.java b/LongestIncreasingPathinaMatrix.java new file mode 100644 index 0000000..b3ba8b4 --- /dev/null +++ b/LongestIncreasingPathinaMatrix.java @@ -0,0 +1,73 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LongestIncreasingPathinaMatrix + * Creator : Edward + * Date : Jan, 2018 + * Description : 329. Longest Increasing Path in a Matrix + */ +public class LongestIncreasingPathinaMatrix { + /** + * Given an integer matrix, find the length of the longest increasing path. + + From each cell, you can either move to four directions: left, right, up or down. + You may NOT move diagonally or move outside of the boundary (i.e. wrap-around is not allowed). + + Example 1: + + nums = [ + [9,9,4], + [6,6,8], + [2,1,1] + ] + Return 4 + The longest increasing path is [1, 2, 6, 9]. + + Example 2: + + nums = [ + [3,4,5], + [3,2,6], + [2,2,1] + ] + Return 4 + The longest increasing path is [3, 4, 5, 6]. Moving diagonally is not allowed. + + time : O(m * n) + space : O(m * n) + + */ + + public int longestIncreasingPath(int[][] matrix) { + if (matrix == null || matrix.length == 0) return 0; + int res = 0; + int m = matrix.length, n = matrix[0].length; + int[][] cache = new int[m][n]; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + int max = dfs(matrix, Integer.MIN_VALUE, i, j, m, n, cache); + res = Math.max(res, max); + } + } + return res; + } + + private int dfs(int[][] matrix, int min, int i, int j, int m, int n, int[][] cache) { + if (i < 0 || j < 0 || i >= m || j >= n || matrix[i][j] <= min) { + return 0; + } + if (cache[i][j] != 0) { + return cache[i][j]; + } + min = matrix[i][j]; + int a = dfs(matrix, min, i - 1, j, n, m, cache) + 1; + int b = dfs(matrix, min, i + 1, j, n, m, cache) + 1; + int c = dfs(matrix, min, i, j - 1, n, m, cache) + 1; + int d = dfs(matrix, min, i, j + 1, n, m, cache) + 1; + int max = Math.max(a, Math.max(b, Math.max(c, d))); + cache[i][j] = max; + return max; + } +} diff --git a/LongestIncreasingSubsequence.java b/LongestIncreasingSubsequence.java new file mode 100644 index 0000000..51e2806 --- /dev/null +++ b/LongestIncreasingSubsequence.java @@ -0,0 +1,61 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LongestIncreasingSubsequence + * Creator : Edward + * Date : Sep, 2017 + * Description : 300. Longest Increasing Subsequence + */ +public class LongestIncreasingSubsequence { + /** + * Given an unsorted array of integers, find the length of longest increasing subsequence. + + For example, + Given [10, 9, 2, 5, 3, 7, 101, 18], + The longest increasing subsequence is [2, 3, 7, 101], therefore the length is 4. + Note that there may be more than one LIS combination, it is only necessary for you to return the length. + + [10, 9, 2, 5, 3, 7, 101, 18] + + res == size + + 10 res = 0 i = 0 j = 0 + 9 res = 1 i = 0 j = 0 mid = 0 + 2 res = 1 i = 0 j = 0 mid = 0 + 5 res = 1 i = 1 j = 1 mid = 0 + 3 res = 2 + 7 res = 2 i = 2 j = 2 mid = 1 + 101 res = 3 i = 2 j = 3 mid = 1 + 18 res = 4 i = 3 j = 3 mid = 3 + + + i, j 相当于tails的起点,终点 + tails : [2,3,7,18] + + time : O(nlogn) + space : O(n) + + * @param nums + * @return + */ + public int lengthOfLIS(int[] nums) { + int[] tails = new int[nums.length]; + int res = 0; + for (int num : nums) { + int i = 0, j = res; + while (i != j) { + int mid = (i + j) / 2; + if (tails[mid] < num) { + i = mid + 1; + } else { + j = mid; + } + } + tails[i] = num; + if (i == res) ++res; + } + return res; + } +} diff --git a/LongestPalindrome.java b/LongestPalindrome.java new file mode 100644 index 0000000..ed3317e --- /dev/null +++ b/LongestPalindrome.java @@ -0,0 +1,65 @@ +package leetcode; + +import java.util.HashSet; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LongestPalindrome + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class LongestPalindrome { + /** + * 409. Longest Palindrome + * Input: + "abccccdd" + + Output: + 7 + + Explanation: + One longest palindrome that can be built is "dccaccd", whose length is 7. + + time : O(n) + * @param s + * @return + */ + // space : O(n) + public int longestPalindrome(String s) { + if (s == null || s.length() == 0) return 0; + HashSet set = new HashSet<>(); + int count = 0; + for (char c : s.toCharArray()) { + if (set.contains(c)) { + set.remove(c); + count++; + } else { + set.add(c); + } + } + if (set.size() != 0) return count * 2 + 1; + return count * 2; + } + // space : O(1) + public int longestPalindrome2(String s) { + if (s == null || s.length() == 0) return 0; + char[] count = new char[256]; + int res = 0; + boolean bool = false; + for (char c : s.toCharArray()) { + if (count[c] > 0) { + count[c]--; + res++; + } else { + count[c]++; + } + } + for (int i = 0; i < count.length; i++) { + if (count[i] != 0) bool = true; + } + if (bool) return res * 2 + 1; + return res * 2; + } +} diff --git a/LongestPalindromicSubsequence.java b/LongestPalindromicSubsequence.java new file mode 100644 index 0000000..f9d82cd --- /dev/null +++ b/LongestPalindromicSubsequence.java @@ -0,0 +1,51 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LongestPalindromicSubsequence + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class LongestPalindromicSubsequence { + /** + * 516. Longest Palindromic Subsequence + * Given a string s, find the longest palindromic subsequence's length in s. You may assume that the maximum length of s is 1000. + + Example 1: + Input: + + "bbbab" + Output: + 4 + One possible longest palindromic subsequence is "bbbb". + Example 2: + Input: + + "cbbd" + Output: + 2 + One possible longest palindromic subsequence is "bb". + + time : O(n^2) + space : O(n^2) + * @param s + * @return + */ + public int longestPalindromeSubseq(String s) { + int[][] dp = new int[s.length()][s.length()]; + + for (int i = s.length() - 1; i >= 0; i--) { + dp[i][i] = 1; + for (int j = i + 1; j < s.length(); j++) { + if (s.charAt(i) == s.charAt(j)) { + dp[i][j] = dp[i + 1][j - 1] + 2; + } else { + dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]); + } + } + } + return dp[0][s.length()-1]; + } +} diff --git a/LongestPalindromicSubstring.java b/LongestPalindromicSubstring.java new file mode 100644 index 0000000..0b16b4a --- /dev/null +++ b/LongestPalindromicSubstring.java @@ -0,0 +1,75 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LongestPalindromicSubstring + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class LongestPalindromicSubstring { + /** + * 5. Longest Palindromic Substring + * Given a string s, find the longest palindromic substring in s. + * You may assume that the maximum length of s is 1000. + + Example: + + Input: "babad" + + Output: "bab" + + Note: "aba" is also a valid answer. + Example: + + Input: "cbbd" + + Output: "bb" + + + * @param s + * @return + */ + + // time : O(n^2) space : O(n^2); + public String longestPalindrome(String s) { + if (s == null || s.length() == 0) return s; + String res = ""; + boolean[][] dp = new boolean[s.length()][s.length()]; + int max = 0; + for (int j = 0; j < s.length(); j++) { + for (int i = 0; i <= j; i++) { + dp[i][j] = s.charAt(i) == s.charAt(j) && ((j - i <= 2) || dp[i + 1][j - 1]); + if (dp[i][j]) { + if (j - i + 1 > max) { + max = j - i + 1; + res = s.substring(i, j + 1); + } + } + } + } + return res; + } + + String res = ""; + // time : O(n^2) space : O(1) + public String longestPalindrome2(String s) { + if (s == null || s.length() == 0) return s; + for (int i = 0; i < s.length(); i++) { + helper(s, i, i); + helper(s, i, i + 1); + } + return res; + } + public void helper(String s, int left, int right) { + while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) { + left--; + right++; + } + String cur = s.substring(left + 1, right); + if (cur.length() > res.length()) { + res = cur; + } + } +} diff --git a/LongestSubstringWithoutRepeatingCharacters.java b/LongestSubstringWithoutRepeatingCharacters.java new file mode 100644 index 0000000..92d6b58 --- /dev/null +++ b/LongestSubstringWithoutRepeatingCharacters.java @@ -0,0 +1,60 @@ +package leetcode; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LongestSubstringWithoutRepeatingCharacters + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class LongestSubstringWithoutRepeatingCharacters { + /** + * 3. Longest Substring Without Repeating Characters + * Examples: + + Given "abcabcbb", the answer is "abc", which the length is 3. + + Given "bbbbb", the answer is "b", with the length of 1. + + Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, + "pwke" is a subsequence and not a substring. + + + time : O(n) + space : O(n) + * @param s + * @return + */ + public int lengthOfLongestSubstring(String s) { + if (s == null || s.length() == 0) return 0; + HashMap map = new HashMap<>(); + int res = 0; + for (int i = 0, j = 0; i < s.length(); i++) { + if (map.containsKey(s.charAt(i))) { + j = Math.max(j, map.get(s.charAt(i)) + 1); + } + map.put(s.charAt(i), i); + res = Math.max(res, i - j + 1); + } + return res; + } + + public int lengthOfLongestSubstring2(String s) { + if (s == null || s.length() == 0) return 0; + HashSet set = new HashSet<>(); + int res = 0; + for (int i = 0, j = 0; i < s.length(); i++) { + if (set.contains(s.charAt(i))) { + set.remove(s.charAt(j++)); + } else { + set.add(s.charAt(i)); + res = Math.max(res, set.size()); + } + } + return res; + } +} diff --git a/LongestSubstringwithAtLeastKRepeatingCharacters.java b/LongestSubstringwithAtLeastKRepeatingCharacters.java new file mode 100644 index 0000000..8efe18a --- /dev/null +++ b/LongestSubstringwithAtLeastKRepeatingCharacters.java @@ -0,0 +1,73 @@ +package leetcode; + +import java.util.Arrays; +import java.util.HashMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LongestSubstringwithAtLeastKRepeatingCharacters + * Creator : Edward + * Date : Jan, 2018 + * Description : 395. Longest Substring with At Least K Repeating Characters + */ +public class LongestSubstringwithAtLeastKRepeatingCharacters { + /** + * Find the length of the longest substring T of a given string (consists of lowercase letters only) + * such that every character in T appears no less than k times. + + Example 1: + + Input: + s = "aaabb", k = 3 + + Output: + 3 + + The longest substring is "aaa", as 'a' is repeated 3 times. + Example 2: + + Input: + s = "ababbc", k = 2 + + Output: + 5 + + The longest substring is "ababb", as 'a' is repeated 2 times and 'b' is repeated 3 times. + + + * @param s + * @param k + * @return + */ + + // time : O(n) space : O(1) + public int longestSubstring(String s, int k) { + int res = 0; + for (int numUniqueTarget = 1; numUniqueTarget <= 26; numUniqueTarget++) { + res = Math.max(res, helper(s, k, numUniqueTarget)); + } + return res; + } + + private int helper(String s, int k, int numUniqueTareget) { + int[] count = new int[128]; + int start = 0, end = 0; + int numUnqiue = 0, numNoLessThanK = 0; + int res = 0; + + while (end < s.length()) { + if (count[s.charAt(end)]++ == 0) numUnqiue++; + if (count[s.charAt(end++)] == k) numNoLessThanK++; + + while (numUnqiue > numUniqueTareget) { + if (count[s.charAt(start)]-- == k) numNoLessThanK--; + if (count[s.charAt(start++)] == 0) numUnqiue--; + } + if (numUnqiue == numUniqueTareget && numUnqiue == numNoLessThanK) { + res = Math.max(end - start, res); + } + } + return res; + } +} diff --git a/LongestSubstringwithAtMostKDistinctCharacters.java b/LongestSubstringwithAtMostKDistinctCharacters.java new file mode 100644 index 0000000..bb7ad53 --- /dev/null +++ b/LongestSubstringwithAtMostKDistinctCharacters.java @@ -0,0 +1,43 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LongestSubstringwithAtMostKDistinctCharacters + * Creator : Edward + * Date : Nov, 2017 + * Description : 340. Longest Substring with At Most K Distinct Characters + */ +public class LongestSubstringwithAtMostKDistinctCharacters { + /** + * Given a string, find the length of the longest substring T that contains + * at most k distinct characters. + + For example, Given s = “eceba” and k = 2, + + T is "ece" which its length is 3. + + sliding window + + time : O(n) + space : O(1) + + * @param s + * @param k + * @return + */ + + public int lengthOfLongestSubstringKDistinct(String s, int k) { + int[] count = new int[256]; + int res = 0, num = 0, j = 0; + for (int i = 0; i < s.length(); i++) { + if (count[s.charAt(i)]++ == 0) num++; + if (num > k) { + while (--count[s.charAt(j++)] > 0); + num--; + } + res = Math.max(res, i - j + 1); + } + return res; + } +} diff --git a/LongestSubstringwithAtMostTwoDistinctCharacters.java b/LongestSubstringwithAtMostTwoDistinctCharacters.java new file mode 100644 index 0000000..ffc66b7 --- /dev/null +++ b/LongestSubstringwithAtMostTwoDistinctCharacters.java @@ -0,0 +1,54 @@ +package leetcode; + +import java.util.HashMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LongestSubstringwithAtMostTwoDistinctCharacters + * Creator : Edward + * Date : Nov, 2017 + * Description : 159. Longest Substring with At Most Two Distinct Characters + */ +public class LongestSubstringwithAtMostTwoDistinctCharacters { + /** + * Given a string, find the length of the longest substring T that contains at most 2 distinct characters. + + For example, Given s = “eceba”, + + T is "ece" which its length is 3. + + sliding window + + “eceba” + + time : O(n) + space : O(n) + + * @param s + * @return + */ + + public int lengthOfLongestSubstringTwoDistinct(String s) { + if (s == null || s.length() == 0) return 0; + HashMap map = new HashMap<>(); + int start = 0, end = 0; + int res = 0; + while (end < s.length()) { + if (map.size() <= 2) { + map.put(s.charAt(end), end); + end++; + } + if (map.size() > 2) { + int leftMost = s.length(); + for (int num : map.values()) { + leftMost = Math.min(leftMost, num); + } + map.remove(s.charAt(leftMost)); + start = leftMost + 1; + } + res = Math.max(res, end - start); + } + return res; + } +} diff --git a/LongestValidParentheses.java b/LongestValidParentheses.java new file mode 100644 index 0000000..0fafadc --- /dev/null +++ b/LongestValidParentheses.java @@ -0,0 +1,55 @@ +package leetcode; + +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : LongestValidParentheses + * Creator : Edward + * Date : Dec, 2017 + * Description : 32. Longest Valid Parentheses + */ +public class LongestValidParentheses { + /** + * Given a string containing just the characters '(' and ')', + * find the length of the longest valid (well-formed) parentheses substring. + + For "(()", the longest valid parentheses substring is "()", which has length = 2. + + Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4. + + 0 1 2 3 4 5 + ( ( ) ) + + time : O(n) + space : O(n) + + + * @param s + * @return + */ + + public int longestValidParentheses(String s) { + Stack stack = new Stack<>(); + int res = 0; + int start = -1; + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == '(') { + stack.push(i); + } else { + if (stack.isEmpty()) { + start = i; + } else { + stack.pop(); + if (stack.isEmpty()) { + res = Math.max(res, i - start); + } else { + res = Math.max(res, i - stack.peek()); + } + } + } + } + return res; + } +} diff --git a/LowestCommonAncestorofaBinarySearchTree.java b/LowestCommonAncestorofaBinarySearchTree.java new file mode 100644 index 0000000..a1c6488 --- /dev/null +++ b/LowestCommonAncestorofaBinarySearchTree.java @@ -0,0 +1,30 @@ +package leetcode; + +/** + * Created by Edward on 28/07/2017. + */ +public class LowestCommonAncestorofaBinarySearchTree { + /** + * 235. Lowest Common Ancestor of a Binary Search Tree + * Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST. + + According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as + the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).” + + time : O(n); + space : O(n); + * @param root + * @param p + * @param q + * @return + */ + public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root.val > p.val && root.val > q.val) { + return lowestCommonAncestor(root.left, p, q); + } else if (root.val < p.val && root.val < q.val) { + return lowestCommonAncestor(root.right, p, q); + } else { + return root; + } + } +} diff --git a/LowestCommonAncestorofaBinaryTree.java b/LowestCommonAncestorofaBinaryTree.java new file mode 100644 index 0000000..244ee02 --- /dev/null +++ b/LowestCommonAncestorofaBinaryTree.java @@ -0,0 +1,33 @@ +package leetcode; + +/** + * Created by Edward on 28/07/2017. + */ +public class LowestCommonAncestorofaBinaryTree { + /** + * 236. Lowest Common Ancestor of a Binary Tree + * Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. + + According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v + and w as the lowest node in T that has both v and w as descendants (where we allow a node to be a descendant of itself).” + + time: O(n); + space : O(n); + + * @param root + * @param p + * @param q + * @return + */ + public static TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root == null || root == p || root == q) return root; + + TreeNode left = lowestCommonAncestor(root.left, p, q); + TreeNode right = lowestCommonAncestor(root.right, p, q); + + if (left != null && right != null) { + return root; + } + return left == null ? right : left; + } +} diff --git a/MajorityElement.java b/MajorityElement.java new file mode 100644 index 0000000..7d03eff --- /dev/null +++ b/MajorityElement.java @@ -0,0 +1,68 @@ +package leetcode; + +import java.util.Arrays; +import java.util.HashMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MajorityElement + * Creator : Edward + * Date : Nov, 2017 + * Description : 169. Majority Element + */ +public class MajorityElement { + + /** + * Given an array of size n, find the majority element. The majority element is the element + * that appears more than ⌊ n/2 ⌋ times. + + You may assume that the array is non-empty and the majority element always exist in the array + * @param nums + * @return + */ + + // time : O(nlogn) space : O(1) + public int majorityElement1(int[] nums) { + Arrays.sort(nums); + return nums[nums.length / 2]; + } + + // time : O(n) space : O(n) + public int majorityElement2(int[] nums) { + HashMap map = new HashMap<>(); + int res = 0; + for (int num : nums) { + if (!map.containsKey(num)) { + map.put(num, 1); + } else { + map.put(num, map.get(num) + 1); + } + if (map.get(num) > nums.length / 2) { + res = num; + break; + } + } + return res; + } + + // Moore voting algorithm + // 每次都找出一对不同的元素,从数组中删掉,直到数组为空或只有一种元素。 + // 不难证明,如果存在元素e出现频率超过半数,那么数组中最后剩下的就只有e。 + // [1,2,3,3,3] + // time : O(n) space : O(1) + public int majorityElement3(int[] nums) { + int count = 0; + int res = 0; + for (int num : nums) { + if (count == 0) { + res = num; + } + if (num != res) { + count--; + } else count++; + } + return res; + } + +} diff --git a/MajorityElementII.java b/MajorityElementII.java new file mode 100644 index 0000000..5dd9d18 --- /dev/null +++ b/MajorityElementII.java @@ -0,0 +1,66 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MajorityElementII + * Creator : Edward + * Date : Nov, 2017 + * Description : 229. Majority Element II + */ +public class MajorityElementII { + /** + * Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. + * The algorithm should run in linear time and in O(1) space. + * + * time : O(n) + * space : O(1) + * + * @param nums + * @return + */ + public static List majorityElement(int[] nums) { + if (nums == null || nums.length == 0) { + return new ArrayList<>(); + } + List res = new ArrayList<>(); + int number1 = 0, number2 = 0; + int count1 = 0, count2 = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i] == number1) { + count1++; + } else if (nums[i] == number2) { + count2++; + } else if (count1 == 0) { + number1 = nums[i]; + count1 = 1; + } else if (count2 == 0) { + number2 = nums[i]; + count2 = 1; + } else { + count1--; + count2--; + } + } + count1 = 0; + count2 = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i] == number1) { + count1++; + } else if (nums[i] == number2) { + count2++; + } + } + if (count1 > nums.length / 3) { + res.add(number1); + } + if (count2 > nums.length / 3) { + res.add(number2); + } + return res; + } + +} diff --git a/MaxConsecutiveOnes.java b/MaxConsecutiveOnes.java new file mode 100644 index 0000000..dda2854 --- /dev/null +++ b/MaxConsecutiveOnes.java @@ -0,0 +1,39 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MaxConsecutiveOnes + * Creator : Edward + * Date : Nov, 2017 + * Description : 485. Max Consecutive Ones + */ +public class MaxConsecutiveOnes { + /** + * Given a binary array, find the maximum number of consecutive 1s in this array. + + Example 1: + Input: [1,1,0,1,1,1] + Output: 3 + Explanation: The first two digits or the last three digits are consecutive 1s. + The maximum number of consecutive 1s is 3. + + time : O(n) + space : O(1) + + * @param nums + * @return + */ + public int findMaxConsecutiveOnes(int[] nums) { + int res = 0; + int count = 0; + + for (int i = 0; i < nums.length; i++) { + if (nums[i] == 1) { + count++; + res = Math.max(res, count); + } else count = 0; + } + return res; + } +} diff --git a/MaxPointsonaLine.java b/MaxPointsonaLine.java new file mode 100644 index 0000000..ca2d979 --- /dev/null +++ b/MaxPointsonaLine.java @@ -0,0 +1,60 @@ +package leetcode; + +import java.util.HashMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MaxPointsonaLine + * Creator : Edward + * Date : Aug, 2017 + * Description : 149. Max Points on a Line + */ +public class MaxPointsonaLine { + /** + * Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. + + 1,在x轴 + 2,相同点 + 3,精度问题(GCD) 1/3 1/3 + + * time : O(n^2); + * space : O(n); + * @param points + * @return + */ + + public int maxPoints(Point[] points) { + if (points == null || points.length == 0) return 0; + if (points.length < 2) return points.length; + int res = 0; + for (int i = 0; i < points.length; i++) { + HashMap map = new HashMap<>(); + int samePoint = 0; + int sameXAxis = 1; + for (int j = 0; j < points.length; j++) { + if (i != j) { + if (points[i].x == points[j].x && points[i].y == points[j].y) { + samePoint++; + } + if (points[i].x == points[j].x) { + sameXAxis++; + continue; + } + int numerator = points[i].y - points[j].y; + int denominator = points[i].x - points[j].x; + int gcd = gcd(numerator, denominator); + String hashStr = (numerator / gcd) + "/" + (denominator / gcd); + map.put(hashStr, map.getOrDefault(hashStr, 1) + 1); + res = Math.max(res, map.get(hashStr) + samePoint); + } + } + res = Math.max(res, sameXAxis); + } + return res; + } + private int gcd(int a, int b) { + if (a == 0) return b; + return gcd(b % a, a); + } +} diff --git a/MaxSumofRectangleNoLargerThanK.java b/MaxSumofRectangleNoLargerThanK.java new file mode 100644 index 0000000..b3d86ef --- /dev/null +++ b/MaxSumofRectangleNoLargerThanK.java @@ -0,0 +1,98 @@ +package leetcode; + +import java.util.TreeSet; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MaxSumofRectangleNoLargerThanK + * Creator : Edward + * Date : Jan, 2018 + * Description : 363. Max Sum of Rectangle No Larger Than K + */ +public class MaxSumofRectangleNoLargerThanK { + + /** + * Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle + * in the matrix such that its sum is no larger than k. + + Example: + Given matrix = [ + [1, 0, 1], + [0, -2, 3] + ] + k = 2 + The answer is 2. Because the sum of rectangle [[0, 1], [-2, 3]] is 2 and 2 is the max number no larger than k (k = 2). + + Note: + The rectangle inside the matrix must have an area > 0. + What if the number of rows is much larger than the number of columns? + + + 1, 求matrix中和最大的那个矩形,返回最大值 + 2, 一维 array, 找出其中连续的一段,其和最大,但是不大于 k + + 1 0 1 2 + 0 -2 3 1 + 2 4 1 -2 + 3 1 2 -1 + + + sums = [1 -2 6 4] + + reference: https://www.jianshu.com/p/e9ff87d6bf8e + + time : O[min(m,n)^2 * max(m,n) * log(max(m,n))] + space : O(max(m, n)) + + * @param matrix + * @param k + * @return + */ + + public int maxSumSubmatrix(int[][] matrix, int k) { + if (matrix.length == 0) return 0; + + int m = matrix.length; + int n = matrix[0].length; + int res = Integer.MIN_VALUE; + + for (int left = 0; left < n; left++) { + int[] sums = new int[m]; + for (int right = left; right < n; right++) { + for (int i = 0; i < m; i++) { + sums[i] += matrix[i][right]; + } + TreeSet set = new TreeSet<>(); + set.add(0); + int cur = 0; + for (int sum : sums) { + cur += sum; + Integer num = set.ceiling(cur - k); + if (num != null) { + res = Math.max(res, cur - num); + } + set.add(cur); + } + } + } + return res; + } + + + private int helper(int[] nums, int k) { + TreeSet set = new TreeSet<>(); + set.add(0); + int res = 0, sum = 0; + for (int i = 0; i < nums.length; i++) { + sum += nums[i]; + Integer num = set.ceiling(sum - k); + if (num != null) { + res = Math.max(res, sum - num); + } + set.add(sum); + } + return res; + } + +} diff --git a/MaximalRectangle.java b/MaximalRectangle.java new file mode 100644 index 0000000..1b94bca --- /dev/null +++ b/MaximalRectangle.java @@ -0,0 +1,133 @@ +package leetcode; + +import java.util.Arrays; +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MaximalRectangle + * Creator : Edward + * Date : Dec, 2017 + * Description : 85. Maximal Rectangle + */ +public class MaximalRectangle { + /** + * Given a 2D binary matrix filled with 0's and 1's, + * find the largest rectangle containing only 1's and return its area. + + For example, given the following matrix: + + 1 0 1 0 0 + 1 0 1 1 1 + 1 1 1 1 1 + 1 0 0 1 0 + Return 6. + + + left[] :从左到右,出现连续‘1’的string的第一个座标 + right[] :从右到左, 出现连续‘1’的string的最后一个座标, + height[] : 从上到下的高度。 + res : (right[j] - left[j]) * heights[j] + + height: + 1 0 1 0 0 + 2 0 2 1 1 + 3 1 3 2 2 + 4 0 0 3 0 + + left: + 0 0 2 0 0 + 0 0 2 2 2 + 0 0 2 2 2 + 0 0 0 3 0 + + right: + 1 5 3 5 5 + 1 5 3 5 5 + 1 5 3 5 5 + 1 5 5 4 5 + + time : O(m * n) + space : O(n) + + * @param matrix + * @return + */ + + public int maximalRectangle(char[][] matrix) { + int m = matrix.length; + if (matrix == null || m == 0) return 0; + int n = matrix[0].length; + int res = 0; + int[] height = new int[n]; + int[] left = new int[n]; + int[] right = new int[n]; + Arrays.fill(right, n); + + for (int i = 0; i < m; i++) { + int curLeft = 0, curRight = n; + for (int j = 0; j < n; j++) { + if (matrix[i][j] == '1') height[j]++; + else height[j] = 0; + } + for (int j = 0; j < n; j++) { + if (matrix[i][j] == '1') { + left[j] = Math.max(curLeft, left[j]); + } else { + left[j] = 0; + curLeft = j + 1; + } + } + for (int j = n - 1; j >= 0; j--) { + if (matrix[i][j] == '1') { + right[j] = Math.min(curRight, right[j]); + } else { + right[j] = n; + curRight = j; + } + } + for (int j = 0; j < n; j++) { + res = Math.max(res, (right[j] - left[j]) * height[j]); + } + } + return res; + } + + /** + time : O(m * n) + space : O(n) + + * @param matrix + * @return + */ + + public int maximalRectangle2(char[][] matrix) { + if (matrix == null || matrix.length == 0) return 0; + int n = matrix[0].length; + int[] height = new int[n + 1]; + height[n] = 0; + int res = 0; + + for (int row = 0; row < matrix.length; row++) { + Stack stack = new Stack<>(); + for (int i = 0; i < n + 1; i++) { + if (i < n) { + if (matrix[row][i] == '1') { + height[i]++; + } else height[i] = 0; + } + if (stack.isEmpty() || height[stack.peek()] <= height[i]) { + stack.push(i); + } else { + while (!stack.isEmpty() && height[i] < height[stack.peek()]) { + int cur = height[stack.pop()] * (stack.isEmpty() ? i : (i - stack.peek() - 1)); + res = Math.max(res, cur); + } + stack.push(i); + } + } + } + return res; + } +} diff --git a/MaximalSquare.java b/MaximalSquare.java new file mode 100644 index 0000000..2a530f0 --- /dev/null +++ b/MaximalSquare.java @@ -0,0 +1,47 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MaximalSquare + * Creator : Edward + * Date : Dec, 2017 + * Description : 221. Maximal Square + */ +public class MaximalSquare { + + /** + * Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area. + + For example, given the following matrix: + + 1 0 1 0 0 + 1 0 1 1 1 + 1 1 1 1 1 + 1 0 0 1 0 + Return 4. + + time : O(m * n) + space : O(m * n) + + * @param matrix + * @return + */ + + public int maximalSquare(char[][] matrix) { + if (matrix.length == 0) return 0; + int m = matrix.length; + int n = matrix[0].length; + int res = 0; + int[][] dp = new int[m + 1][n + 1]; + for (int i = 1; i <= m; i++) { + for (int j = 1; j <= n; j++) { + if (matrix[i - 1][j - 1] == '1') { + dp[i][j] = Math.min(Math.min(dp[i][j - 1], dp[i - 1][j - 1]), dp[i - 1][j]) + 1; + res = Math.max(res, dp[i][j]); + } + } + } + return res * res; + } +} diff --git a/MaximumDepthofBinaryTree.java b/MaximumDepthofBinaryTree.java new file mode 100644 index 0000000..16d35d6 --- /dev/null +++ b/MaximumDepthofBinaryTree.java @@ -0,0 +1,31 @@ +package leetcode; + + +/** + * Created by Edward on 28/07/2017. + */ +public class MaximumDepthofBinaryTree { + /** + * 104. Maximum Depth of Binary Tree + * Given a binary tree, find its maximum depth. + + The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. + + time : O(n); + space : O(n); + * @param root + * @return + */ + + public static int maxDepth(TreeNode root) { + if (root == null) return 0; + return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1; + } + + public static int maxDepth2(TreeNode root) { + if (root == null) return 0; + int l = maxDepth2(root.left) + 1; + int r = maxDepth2(root.right) + 1; + return Math.max(l, r); + } +} diff --git a/MaximumGap.java b/MaximumGap.java new file mode 100644 index 0000000..cd4ef8c --- /dev/null +++ b/MaximumGap.java @@ -0,0 +1,63 @@ +package leetcode; + +import java.util.Arrays; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MaximumGap + * Creator : Edward + * Date : Dec, 2017 + * Description : 164. Maximum Gap + */ +public class MaximumGap { + /** + * Given an unsorted array, find the maximum difference between the successive elements in its sorted form. + + Try to solve it in linear time/space. + + Return 0 if the array contains less than 2 elements. + + time : O(n) + space : O(n) + + + * @param nums + * @return + */ + public static int maximumGap(int[] nums) { + if (nums == null || nums.length < 2) return 0; + + int len = nums.length; + int max = nums[0]; + int min = nums[0]; + for (int i = 0; i < nums.length; i++) { + max = Math.max(max, nums[i]); + min = Math.min(min, nums[i]); + } + + int gap = (int)Math.ceil((double)(max - min) / (len - 1)); + int[] bucketsMin = new int[len - 1]; + int[] bucketsMax = new int[len - 1]; + Arrays.fill(bucketsMax, Integer.MIN_VALUE); + Arrays.fill(bucketsMin, Integer.MAX_VALUE); + for (int num : nums) { + if (num == min || num == max) continue; + int bucket = (num - min) / gap; + bucketsMin[bucket] = Math.min(num, bucketsMin[bucket]); + bucketsMax[bucket] = Math.max(num, bucketsMax[bucket]); + } + + int res = 0; + int pre = min; + for (int i = 0; i < len - 1; i++) { + if (bucketsMin[i] == Integer.MAX_VALUE && bucketsMax[i] == Integer.MIN_VALUE) { + continue; + } + res = Math.max(res, bucketsMin[i] - pre); + pre = bucketsMax[i]; + } + res = Math.max(res, max - pre); + return res; + } +} diff --git a/MaximumProductSubarray.java b/MaximumProductSubarray.java new file mode 100644 index 0000000..7bc0677 --- /dev/null +++ b/MaximumProductSubarray.java @@ -0,0 +1,35 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MaximumProductSubarray + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class MaximumProductSubarray { + /** + * 152. Maximum Product Subarray + * For example, given the array [2,3,-2,4], + the contiguous subarray [2,3] has the largest product = 6. + + time : O(n) + space : O(1) + * @param nums + * @return + */ + public int maxProduct(int[] nums) { + if (nums == null || nums.length == 0) return 0; + int max = nums[0]; + int min = nums[0]; + int res = nums[0]; + for (int i = 1; i < nums.length; i++) { + int temp = max; + max = Math.max(Math.max(max * nums[i], min * nums[i]), nums[i]); + min = Math.min(Math.min(min * nums[i], temp * nums[i]), nums[i]); + res = Math.max(res, max); + } + return res; + } +} diff --git a/MaximumProductofThreeNumbers.java b/MaximumProductofThreeNumbers.java new file mode 100644 index 0000000..03ab751 --- /dev/null +++ b/MaximumProductofThreeNumbers.java @@ -0,0 +1,65 @@ +package leetcode; + +import java.util.Arrays; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MaximumProductofThreeNumbers + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class MaximumProductofThreeNumbers { + /** + * 628. Maximum Product of Three Numbers + * Example 1: + Input: [1,2,3] + Output: 6 + Example 2: + Input: [1,2,3,4] + Output: 24 + + -4, -3, -2, -1 60 + -80, -1, 1, 2, 3, 4 + + 绝对值最大:1,全正数,2,一正数,两负数 + + * @param nums + * @return + */ + + // time : O(nlogn) space : O(nlogn) + public int maximumProduct(int[] nums) { + Arrays.sort(nums); + return Math.max(nums[nums.length - 1] * nums[nums.length - 2] * nums[nums.length - 3], nums[0] * nums[1] * nums[nums.length - 1]); + } + + // time : O(n) space : O(1) + public int maximumProduct2(int[] nums) { + int min1 = Integer.MAX_VALUE; + int min2 = Integer.MAX_VALUE; + int max1 = Integer.MIN_VALUE; + int max2 = Integer.MIN_VALUE; + int max3 = Integer.MIN_VALUE; + for (int n : nums) { + if (n <= min1) { // min1 第一小 + min2 = min1; + min1 = n; + } else if (n <= min2) { //min2 第二小 + min2 = n; + } + if (n >= max1) { // n 大于 max1,2,3 + max3 = max2; + max2 = max1; + max1 = n; + } else if (n >= max2) { // n 大于 max2,3 + max3 = max2; + max2 = n; + } else { // n 大于 max3 + max3 = n; + } + } + return Math.max(min1 * min2 * max1, max1 * max2 * max3); + } +} diff --git a/MaximumProductofWordLengths.java b/MaximumProductofWordLengths.java new file mode 100644 index 0000000..edcbecd --- /dev/null +++ b/MaximumProductofWordLengths.java @@ -0,0 +1,70 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MaximumProductofWordLengths + * Creator : Edward + * Date : Oct, 2017 + * Description : 318. Maximum Product of Word Lengths + */ +public class MaximumProductofWordLengths { + /** + * Given a string array words, find the maximum value of length(word[i]) * length(word[j]) + * where the two words do not share common letters. You may assume that each word will contain only lower case letters. + * If no such two words exist, return 0. + + Example 1: + Given ["abcw", "baz", "foo", "bar", "xtfn", "abcdef"] + Return 16 + The two words can be "abcw", "xtfn". + + Example 2: + Given ["a", "ab", "abc", "d", "cd", "bcd", "abcd"] + Return 4 + The two words can be "ab", "cd". + + Example 3: + Given ["a", "aa", "aaa", "aaaa"] + Return 0 + No such pair of words. + + val |= 1 << (words[i].charAt(j) - 'a'); + + 1 << 0 00001 = 1 a + 1 << 1 00010 = 2 b + 1 << 2 00100 = 4 c + 1 << 3 01000 = 8 + + abc = 00111 = 7 ab = 00011 = 3 + + bytes[i] & bytes[j] == 0 + + "abc", "ba", "ef" + + time : O(n^2) + space : O(n) + + * @param words + * @return + */ + public int maxProduct(String[] words) { + int res = 0; + int[] bytes = new int[words.length]; + for (int i = 0; i < words.length; i++) { + int val = 0; + for (int j = 0; j < words[i].length(); j++) { + val |= 1 << (words[i].charAt(j) - 'a'); + } + bytes[i] = val; + } + for (int i = 0; i < bytes.length; i++) { + for (int j = i + 1; j < bytes.length; j++) { + if ((bytes[i] & bytes[j]) == 0) { + res = Math.max(res, words[i].length() * words[j].length()); + } + } + } + return res; + } +} diff --git a/MaximumSizeSubarraySumEqualsk.java b/MaximumSizeSubarraySumEqualsk.java new file mode 100644 index 0000000..9b00f89 --- /dev/null +++ b/MaximumSizeSubarraySumEqualsk.java @@ -0,0 +1,53 @@ +package leetcode; + +import java.util.HashMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MaximumSizeSubarraySumEqualsk + * Creator : Edward + * Date : Oct, 2017 + * Description : 325. Maximum Size Subarray Sum Equals k + */ +public class MaximumSizeSubarraySumEqualsk { + /** + * Example 1: + Given nums = [1, -1, 5, -2, 3], k = 3, + return 4. (because the subarray [1, -1, 5, -2] sums to 3 and is the longest) + + Example 2: + Given nums = [-2, -1, 2, 1], k = 1, + return 2. (because the subarray [-1, 2] sums to 1 and is the longest) + + [1, -1, 5, -2, 3] k = 3 + + 1, 0, 5, 3, 6 k = 3 + + time : O(n) + space : O(n) + + * @param nums + * @param k + * @return + */ + public int maxSubArrayLen(int[] nums, int k) { + if (nums == null || nums.length == 0) return 0; + int res = 0; + HashMap map = new HashMap<>(); + map.put(0, -1); + + for (int i = 1; i < nums.length; i++) { + nums[i] += nums[i - 1]; + } + for (int i = 0; i < nums.length; i++) { + if (map.containsKey(nums[i] - k)) { + res = Math.max(res, i - map.get(nums[i] - k)); + } + if (!map.containsKey(nums[i])) { + map.put(nums[i], i); + } + } + return res; + } +} diff --git a/MaximumSubarray.java b/MaximumSubarray.java new file mode 100644 index 0000000..bb3ec75 --- /dev/null +++ b/MaximumSubarray.java @@ -0,0 +1,46 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MaximumSubarray + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class MaximumSubarray { + /** + * 53. Maximum Subarray + * + * Find the contiguous subarray within an array (containing at least one number) which has the largest sum. + + For example, given the array [-2,1,-3,4,-1,2,1,-5,4], + the contiguous subarray [4,-1,2,1] has the largest sum = 6. + + * @param nums + * @return + */ + + // time : O(n) space : O(n); + public int maxSubArray(int[] nums) { + int[] dp = new int[nums.length]; + dp[0] = nums[0]; + int res = nums[0]; + for (int i = 1; i < nums.length; i++) { + dp[i] = nums[i] + (dp[i - 1] < 0 ? 0 : dp[i - 1]); + res = Math.max(res, dp[i]); + } + return res; + } + + // time : O(n) space : O(1); + public int maxSubArray2(int[] nums) { + int res = nums[0]; + int sum = nums[0]; + for (int i = 1; i < nums.length; i++) { + sum = Math.max(nums[i], sum + nums[i]); + res = Math.max(res, sum); + } + return res; + } +} diff --git a/MedianofTwoSortedArrays.java b/MedianofTwoSortedArrays.java new file mode 100644 index 0000000..2d8ef6b --- /dev/null +++ b/MedianofTwoSortedArrays.java @@ -0,0 +1,107 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MedianofTwoSortedArrays + * Creator : Edward + * Date : Dec, 2017 + * Description : 4. Median of Two Sorted Arrays + */ +public class MedianofTwoSortedArrays { + + /** + * 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)). + + Example 1: + nums1 = [1, 3] + nums2 = [2] + + The median is 2.0 + Example 2: + nums1 = [1, 2] + nums2 = [3, 4] + + The median is (2 + 3)/2 = 2.5 + + + O(log(min(m,n))) + + 参考博客:http://blog.csdn.net/chen_xinjia/article/details/69258706 + + index: 0 1 2 3 4 5 + L1 R1 + num1: 3 5 | 8 9 4 cut1:左有几个元素 + num2: 1 2 7 | 10 11 12 6 cut2:左有几个元素 + L2 R2 + + num3: 1 2 3 5 7 | 8 9 10 11 12 + + num3 -> num1 + num2 -> num1 + + L1 <= R2 + L2 <= R1 + + (cutL, cutR) + + L1 > R2 cut1 << (cutL, cut1 - 1) + L2 > R1 cut2 >> (cut1 + 1, cutR) + + index: 0 1 2 3 4 5 + L1 R1 + num1: 3 5 | 8 9 | 4 cut1:左有几个元素 + num2: 1 2 7 | 10 11 12 6 cut2:左有几个元素 + L2 R2 + + num3: 1 2 3 5 7 | 8 9 10 11 12 + + int cut1 = 2; + int cut2 = 3; + int cutL = 0; + int cutR = 4; + + + time : O(log(min(m,n))) + space : O(1) + + * @param nums1 + * @param nums2 + * @return + */ + + public double findMedianSortedArrays(int[] nums1, int[] nums2) { + if (nums1.length > nums2.length) { + return findMedianSortedArrays(nums2, nums1); + } + int len = nums1.length + nums2.length; + int cut1 = 0; + int cut2 = 0; + int cutL = 0; + int cutR = nums1.length; + while (cut1 <= nums1.length) { + cut1 = (cutR - cutL) / 2 + cutL; + cut2 = len / 2 - cut1; + double L1 = (cut1 == 0) ? Integer.MIN_VALUE : nums1[cut1 - 1]; + double L2 = (cut2 == 0) ? Integer.MIN_VALUE : nums2[cut2 - 1]; + double R1 = (cut1 == nums1.length) ? Integer.MAX_VALUE : nums1[cut1]; + double R2 = (cut2 == nums2.length) ? Integer.MAX_VALUE : nums2[cut2]; + if (L1 > R2) { + cutR = cut1 - 1; + } else if (L2 > R1) { + cutL = cut1 + 1; + } else { + if (len % 2 == 0) { + L1 = L1 > L2 ? L1 : L2; + R1 = R1 < R2 ? R1 : R2; + return (L1 + R1) / 2; + } else { + R1 = (R1 < R2) ? R1 : R2; + return R1; + } + } + } + return -1; + } +} diff --git a/MeetingRooms.java b/MeetingRooms.java new file mode 100644 index 0000000..07c6ac0 --- /dev/null +++ b/MeetingRooms.java @@ -0,0 +1,38 @@ +package leetcode; + +import java.lang.reflect.Array; +import java.util.Arrays; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MeetingRooms + * Creator : Edward + * Date : Oct, 2017 + * Description : 252. Meeting Rooms + */ +public class MeetingRooms { + /** + * Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), + * determine if a person could attend all meetings. + + For example, + Given [[0, 30],[5, 10],[15, 20]], + return false. + + time : O(nlogn) + space : O(1) + + * @param intervals + * @return + */ + public boolean canAttendMeetings(Interval[] intervals) { + Arrays.sort(intervals, (x, y) -> x.start - y.start); + for (int i = 1; i intervals[i].start) { + return false; + } + } + return true; + } +} diff --git a/MeetingRoomsII.java b/MeetingRoomsII.java new file mode 100644 index 0000000..dbf2437 --- /dev/null +++ b/MeetingRoomsII.java @@ -0,0 +1,68 @@ +package leetcode; + +import java.util.Arrays; +import java.util.PriorityQueue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MeetingRoomsII + * Creator : Edward + * Date : Oct, 2017 + * Description : 253. Meeting Rooms II + */ +public class MeetingRoomsII { + /** + + + |___| |____| + |_____| |___| + + start: + | | | | + i + end : + | | | | + end + + time : O(nlogn) space : O(n) + + * @param intervals + * @return + */ + public int minMeetingRooms(Interval[] intervals) { + int[] starts = new int[intervals.length]; + int[] ends = new int[intervals.length]; + for (int i = 0; i < intervals.length; i++) { + starts[i] = intervals[i].start; + ends[i] = intervals[i].end; + } + Arrays.sort(starts); + Arrays.sort(ends); + int res = 0; + int end = 0; + for (int i = 0; i < intervals.length; i++) { + if (starts[i] < ends[end]) { + res++; + } else end++; + } + return res; + } + + + public int minMeetingRooms2(Interval[] intervals) { + Arrays.sort(intervals, (a, b) -> a.start - b.start); + PriorityQueue heap = new PriorityQueue<>(intervals.length, (a, b) -> a.end - b.end); + heap.offer(intervals[0]); + for (int i = 1; i < intervals.length; i++) { + Interval interval = heap.poll(); + if (intervals[i].start >= interval.end) { + interval.end = intervals[i].end; + } else { + heap.offer(intervals[i]); + } + heap.offer(interval); + } + return heap.size(); + } +} diff --git a/MergeIntervals.java b/MergeIntervals.java new file mode 100644 index 0000000..edf793e --- /dev/null +++ b/MergeIntervals.java @@ -0,0 +1,48 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MergeIntervals + * Creator : Edward + * Date : Oct, 2017 + * Description : 56. Merge Intervals + */ +public class MergeIntervals { + /** + * For example, + Given [1,3],[2,6],[8,10],[15,18], + return [1,6],[8,10],[15,18]. + + sta end + |___| |____| + |_____| |___| + + time : O(nlogn) space : O(n) + + * @param intervals + * @return + */ + public List merge(List intervals) { + if (intervals == null || intervals.size() <= 1) return intervals; + Collections.sort(intervals, (a, b) -> a.start - b.start); + int start = intervals.get(0).start; + int end = intervals.get(0).end; + List res = new ArrayList<>(); + for (Interval interval : intervals) { + if (interval.start <= end) { + end = Math.max(end, interval.end); + } else { + res.add(new Interval(start, end)); + start = interval.start; + end = interval.end; + } + } + res.add(new Interval(start, end)); + return res; + } +} diff --git a/MergeSortedArray.java b/MergeSortedArray.java new file mode 100644 index 0000000..ee7cac1 --- /dev/null +++ b/MergeSortedArray.java @@ -0,0 +1,33 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MergeSortedArray + * Creator : Edward + * Date : Oct, 2017 + * Description : 88. Merge Sorted Array + */ +public class MergeSortedArray { + /** + + time : O(m + n) + space : O(1) + + * @param nums1 + * @param m + * @param nums2 + * @param n + */ + public void merge(int[] nums1, int m, int[] nums2, int n) { + int i = m - 1; + int j = n - 1; + int k = m + n - 1; + while (i >= 0 && j >= 0) { + nums1[k--] = nums1[i] >= nums2[j] ? nums1[i--] : nums2[j--]; + } + while (j >= 0) { + nums1[k--] = nums2[j--]; + } + } +} diff --git a/MergeTwoBinaryTrees.java b/MergeTwoBinaryTrees.java new file mode 100644 index 0000000..5e947e1 --- /dev/null +++ b/MergeTwoBinaryTrees.java @@ -0,0 +1,52 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MergeTwoBinaryTrees + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class MergeTwoBinaryTrees { + /** + * 617. Merge Two Binary Trees + * Given two binary trees and imagine that when you put one of them to cover the other, + * some nodes of the two trees are overlapped while the others are not. + + You need to merge them into a new binary tree. The merge rule is that if two nodes overlap, + then sum node values up as the new value of the merged node. Otherwise, the NOT null node + will be used as the node of new tree. + + Example 1: + Input: + Tree 1 Tree 2 + 1 2 + / \ / \ + 3 2 1 3 + / \ \ + 5 4 7 + Output: + Merged tree: + 3 + / \ + 4 5 + / \ \ + 5 4 7 + + time : O(n); + space : O(n); + * @param t1 + * @param t2 + * @return + */ + + public TreeNode mergeTrees(TreeNode t1, TreeNode t2) { + if (t1 == null) return t2; + if (t2 == null) return t1; + TreeNode newNode = new TreeNode(t1.val + t2.val); + newNode.left = mergeTrees(t1.left, t2.left); + newNode.right = mergeTrees(t1.right, t2.right); + return newNode; + } +} diff --git a/MergeTwoSortedLists.java b/MergeTwoSortedLists.java new file mode 100644 index 0000000..5709fff --- /dev/null +++ b/MergeTwoSortedLists.java @@ -0,0 +1,47 @@ +package leetcode; + +public class MergeTwoSortedLists { + /** + * 21. Merge Two Sorted Lists + * Merge two sorted linked lists and return it as a new list. The new list should be made + * by splicing together the nodes of the first two lists. + + time : O(n); + space :O(1) / O(n); + * @param l1 + * @param l2 + * @return + */ + public static ListNode mergeTwoLists(ListNode l1, ListNode l2) { + ListNode dummy = new ListNode(0); + ListNode cur = dummy; + while (l1 != null && l2 != null) { + if (l1.val < l2.val) { + cur.next = new ListNode(l1.val); + l1 = l1.next; + } else { + cur.next = new ListNode(l2.val); + l2= l2.next; + } + cur = cur.next; + } + if (l1 != null) { + cur.next = l1; + } else { + cur.next = l2; + } + return dummy.next; + } + + public static ListNode mergeTwoLists2(ListNode l1, ListNode l2) { + if (l1 == null) return l2; + if (l2 == null) return l1; + if (l1.val < l2.val) { + l1.next = mergeTwoLists2(l1.next, l2); + return l1; + } else { + l2.next = mergeTwoLists2(l1, l2.next); + return l2; + } + } +} diff --git a/MergekSortedLists.java b/MergekSortedLists.java new file mode 100644 index 0000000..95c701c --- /dev/null +++ b/MergekSortedLists.java @@ -0,0 +1,69 @@ +package leetcode; + +import java.util.List; +import java.util.PriorityQueue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MergekSortedLists + * Creator : Edward + * Date : Oct, 2017 + * Description : 23. Merge k Sorted Lists + */ +public class MergekSortedLists { + /** + * + time : O(nlogk) where k is the number of linked lists + space : O(n) + + + * @param lists + * @return + */ + public ListNode mergeKLists(ListNode[] lists) { + if (lists == null || lists.length == 0) return null; + return sort(lists, 0, lists.length - 1); + } + + public ListNode sort(ListNode[] lists, int lo, int hi) { + if (lo >= hi) return lists[lo]; + int mid = (hi - lo) / 2 + lo; + ListNode l1 = sort(lists, lo, mid); + ListNode l2 = sort(lists, mid + 1, hi); + return merge(l1, l2); + } + + public ListNode merge(ListNode l1, ListNode l2) { + if (l1 == null) return l2; + if (l2 == null) return l1; + if (l1.val < l2.val) { + l1.next = merge(l1.next, l2); + return l1; + } + l2.next = merge(l1, l2.next); + return l2; + } + + + public ListNode mergeKLists2(ListNode[] lists) { + if (lists == null || lists.length == 0) return null; + PriorityQueue queue = new PriorityQueue<>(lists.length, (a, b) -> a.val - b.val); + ListNode dummy = new ListNode(0); + ListNode cur = dummy; + + for (ListNode list : lists) { + if (list != null) { + queue.add(list); + } + } + while (!queue.isEmpty()) { + cur.next = queue.poll(); + cur = cur.next; + if (cur.next != null) { + queue.add(cur.next); + } + } + return dummy.next; + } +} diff --git a/MinStack.java b/MinStack.java new file mode 100644 index 0000000..5c0ddbf --- /dev/null +++ b/MinStack.java @@ -0,0 +1,125 @@ +package leetcode; + +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MinStack + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class MinStack { + + /** initialize your data structure here. */ + /** + * 155. Min Stack + * Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. + + push(x) -- Push element x onto stack. + pop() -- Removes the element on top of the stack. + top() -- Get the top element. + getMin() -- Retrieve the minimum element in the stack. + + Example: + MinStack minStack = new MinStack(); + minStack.push(-2); + minStack.push(0); + minStack.push(-3); + minStack.getMin(); --> Returns -3. + minStack.pop(); + minStack.top(); --> Returns 0. + minStack.getMin(); --> Returns -2. + + 在-128~127的Integer值并且以Integer x = value;的方式赋值的Integer值在进行==和equals比较时,都会返回true, + 因为Java里面对处在在-128~127之间的Integer值,用的是原生数据类型int,会在内存里供重用, + 也就是说这之间的Integer值进行==比较时只是进行int原生数据类型的数值比较,而超出-128~127的范围,进行==比较时是进行地址及数值比较 + + time : O(1) + space : O(n) + */ + + private Stack stack; + private Stack minStack; + + + public MinStack() { + stack = new Stack<>(); + minStack = new Stack<>(); + } + + public void push(int x) { + stack.push(x); + if (!minStack.isEmpty()) { + int min = minStack.peek(); + if (x <= min) { + minStack.push(x); + } + } else { + minStack.push(x); + } + } + + public void pop() { + int x = stack.pop(); + if (!minStack.isEmpty()) { + if (x == minStack.peek()) { + minStack.pop(); + } + } + } + + public int top() { + return stack.peek(); + } + + public int getMin() { + return minStack.peek(); + } +} + +class MinStack2 { + + /** + minStack.push(-2); + minStack.push(0); + minStack.push(-3); + minStack.getMin(); --> Returns -3. + minStack.pop(); + minStack.top(); --> Returns 0. + minStack.getMin(); --> Returns -2. + + */ + + Stack stack; + int min; + + public MinStack2() { + stack = new Stack<>(); + min = Integer.MAX_VALUE; + } + + public void push(int x) { + if (x <= min) { + stack.push(min); + min = x; + } + stack.push(x); + } + + public void pop() { + if (stack.pop() == min) { + min = stack.pop(); + } + } + + public int top() { + return stack.peek(); + } + + public int getMin() { + return min; + } +} + diff --git a/MiniParser.java b/MiniParser.java new file mode 100644 index 0000000..2371ead --- /dev/null +++ b/MiniParser.java @@ -0,0 +1,85 @@ +package leetcode; + +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MiniParser + * Creator : Edward + * Date : Jan, 2018 + * Description : 385. Mini Parser + */ +public class MiniParser { + /** + * Given a nested list of integers represented as a string, implement a parser to deserialize it. + + Each element is either an integer, or a list -- whose elements may also be integers or other lists. + + Note: You may assume that the string is well-formed: + + String is non-empty. + String does not contain white spaces. + String contains only digits 0-9, [, - ,, ]. + Example 1: + + Given s = "324", + + You should return a NestedInteger object which contains a single integer 324. + Example 2: + + Given s = "[123,[456,[789]]]", + + Return a NestedInteger object containing a nested list with 2 elements: + + 1. An integer containing value 123. + 2. A nested list containing two elements: + i. An integer containing value 456. + ii. A nested list with one element: + a. An integer containing value 789. + + Stack : [: push + , ] : pop + Integer + number : s.substring valueOf + + s = "[123,[456,[789]]]" + + res : [123,[456,[789]]] + stack: 123 [456,[789]] + + time : O(n) + space : O(n) + + * @param s + * @return + */ + public NestedInteger deserialize(String s) { + if (!s.startsWith("[")) { + return new NestedInteger(Integer.valueOf(s)); + } + + Stack stack = new Stack<>(); + NestedInteger res = new NestedInteger(); + stack.push(res); + int start = 1; + for (int i = 1; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '[') { + NestedInteger nestedInteger = new NestedInteger(); + stack.peek().add(nestedInteger); + stack.push(nestedInteger); + start = i + 1; + } else if (c == ',' || c == ']') { + if (i > start) { + Integer val = Integer.valueOf(s.substring(start, i)); + stack.peek().add(new NestedInteger(val)); + } + start = i + 1; + if (c == ']') { + stack.pop(); + } + } + } + return res; + } +} diff --git a/MinimumDepthofBinaryTree.java b/MinimumDepthofBinaryTree.java new file mode 100644 index 0000000..604c84d --- /dev/null +++ b/MinimumDepthofBinaryTree.java @@ -0,0 +1,26 @@ +package leetcode; + +/** + * Created by Edward on 28/07/2017. + */ +public class MinimumDepthofBinaryTree { + /** + * 111. Minimum Depth of Binary Tree + * Given a binary tree, find its minimum depth. + + The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. + + time : O(n); + space : O(n); + + * @param root + * @return + */ + public static int minDepth(TreeNode root) { + if (root == null) return 0; + if (root.left == null || root.right == null) { + return Math.max(minDepth(root.left), minDepth(root.right)) + 1; + } + return Math.min(minDepth(root.left), minDepth(root.right)) + 1; + } +} diff --git a/MinimumHeightTrees.java b/MinimumHeightTrees.java new file mode 100644 index 0000000..2ef8778 --- /dev/null +++ b/MinimumHeightTrees.java @@ -0,0 +1,78 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MinimumHeightTrees + * Creator : Edward + * Date : Jan, 2018 + * Description : 310. Minimum Height Trees + */ +public class MinimumHeightTrees { + /** + * Given n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]] + + 0 1 2 + \ | / + 3 + | + 4 + | + 5 + return [3, 4] + + 0 : 3 + 1 : 3 + 2 : 3 + 3 : 4 + 4 : 3 + 5 : 4 + + 1 -- 2 -- 3 + + time : O(n) + space : O(n) + + * @param n + * @param edges + * @return + */ + public List findMinHeightTrees(int n, int[][] edges) { + List res = new ArrayList<>(); + if (n == 1) { + res.add(0); + return res; + } + List> adj = new ArrayList<>(); + for (int i = 0; i < n; i++) { + adj.add(new HashSet<>()); + } + for (int[] edge : edges) { + adj.get(edge[0]).add(edge[1]); + adj.get(edge[1]).add(edge[0]); + } + for (int i = 0; i < n; i++) { + if (adj.get(i).size() == 1) { + res.add(i); + } + } + while (n > 2) { + n -= res.size(); + List leaves = new ArrayList<>(); + for (int i : res) { + for (int j : adj.get(i)) { + adj.get(j).remove(i); + if (adj.get(j).size() == 1) { + leaves.add(j); + } + } + } + res = leaves; + } + return res; + } +} diff --git a/MinimumMovestoEqualArrayElements.java b/MinimumMovestoEqualArrayElements.java new file mode 100644 index 0000000..cfa678a --- /dev/null +++ b/MinimumMovestoEqualArrayElements.java @@ -0,0 +1,63 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MinimumMovestoEqualArrayElements + * Creator : Edward + * Date : Nov, 2017 + * Description : 453. Minimum Moves to Equal Array Elements + */ +public class MinimumMovestoEqualArrayElements { + /** + * Given a non-empty integer array of size n, find the minimum number of moves required to + * make all array elements equal, where a move is incrementing n - 1 elements by 1. + + Example: + + Input: + [1,2,3] + + Output: + 3 + + Explanation: + Only three moves are needed (remember each move increments two elements): + + [1,2,3] => [2,3,3] => [3,4,3] => [4,4,4] + [1,2,2] + + len * (min + k) = sum + k * (len - 1) * 1. + ==> k = sum - min * len; + + time : O(n) + space : O(1) + + + * @param nums + * @return + */ + public int minMoves(int[] nums) { + if (nums == null || nums.length == 0) return 0; + int min = nums[0]; + for (int num : nums) { + min = Math.min(min, num); + } + int res = 0; + for (int num : nums) { + res += num - min; + } + return res; + } + + public int minMoves2(int[] nums) { + if (nums == null || nums.length == 0) return 0; + int min = nums[0]; + long sum = 0; + for (int num : nums) { + sum += num; + min = Math.min(min, num); + } + return (int)(sum - min * nums.length); + } +} diff --git a/MinimumPathSum.java b/MinimumPathSum.java new file mode 100644 index 0000000..517674e --- /dev/null +++ b/MinimumPathSum.java @@ -0,0 +1,42 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MinimumPathSum + * Creator : Edward + * Date : Nov, 2017 + * Description : 64. Minimum Path Sum + */ +public class MinimumPathSum { + /** + * Given a m x n grid filled with non-negative numbers, + * find a path from top left to bottom right which minimizes the sum of all numbers along its path. + + Note: You can only move either down or right at any point in time. + + Example 1: + [[1,3,1], + [1,5,1], + [4,2,1]] + Given the above grid map, return 7. Because the path 1→3→1→1→1 minimizes the sum. + + time : O(m * n) + space : O(1) + + * @param grid + * @return + */ + public int minPathSum(int[][] grid) { + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (i == 0 && j != 0) grid[i][j] += grid[i][j - 1]; + if (i != 0 && j == 0) grid[i][j] += grid[i - 1][j]; + if (i != 0 && j != 0) { + grid[i][j] += Math.min(grid[i - 1][j], grid[i][j - 1]); + } + } + } + return grid[grid.length - 1][grid[0].length - 1]; + } +} diff --git a/MinimumSizeSubarraySum.java b/MinimumSizeSubarraySum.java new file mode 100644 index 0000000..6f1a91c --- /dev/null +++ b/MinimumSizeSubarraySum.java @@ -0,0 +1,38 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MinimumSizeSubarraySum + * Creator : Edward + * Date : Nov, 2017 + * Description : 209. Minimum Size Subarray Sum + */ +public class MinimumSizeSubarraySum { + /** + * Given an array of n positive integers and a positive integer s, find the + * minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead. + + For example, given the array [2,3,1,2,4,3] and s = 7, + the subarray [4,3] has the minimal length under the problem constraint. + + time : O(n) + space : O(1) + + * @param s + * @param nums + * @return + */ + public int minSubArrayLen(int s, int[] nums) { + int res = Integer.MAX_VALUE; + int left = 0, sum = 0; + for (int i = 0; i < nums.length; i++) { + sum += nums[i]; + while (left <= i && sum >= s) { + res = Math.min(res, i -left + 1); + sum -= nums[left++]; + } + } + return res == Integer.MAX_VALUE ? 0 : res; + } +} diff --git a/MinimumWindowSubstring.java b/MinimumWindowSubstring.java new file mode 100644 index 0000000..9b31ab3 --- /dev/null +++ b/MinimumWindowSubstring.java @@ -0,0 +1,79 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MinimumWindowSubstring + * Creator : Edward + * Date : Nov, 2017 + * Description : 76. Minimum Window Substring + */ +public class MinimumWindowSubstring { + /** + * sliding window + * Given a string S and a string T, find the minimum window in S which will contain all the characters + * in T in complexity O(n). + + For example, + S = "ADOBECODEBANC" + T = "ABC" + Minimum window is "BANC". + + Note: + If there is no such window in S that covers all characters in T, return the empty string "". + + If there are multiple such windows, you are guaranteed that there will always be only one unique + minimum window in S. + + test case: + S = "ADOBECODEBANC" + T = "ABC" + + ADOBEC + DOBECODEBA + OBECODEBA + BECODEBA + ECODEBA + CODEBA + ODEBANC + DEBANC + EBANC + BANC + + A B C D E F G H O + count: 0 0 0 -1-1 -1 + 0 1 2 3 4 5 6 7 ... + + A D O B E C O D E B A N C + i + CODEBA + total = 1 + + time : O(n) + space : O(1) + + * @param s + * @param t + * @return + */ + public static String minWindow(String s, String t) { + int[] cnt = new int[128]; + for (char c : t.toCharArray()) { + cnt[c]++; + } + int from = 0; + int total = t.length(); + int min = Integer.MAX_VALUE; + for (int i = 0, j = 0; i < s.length(); i++) { + if (cnt[s.charAt(i)]-- > 0) total--; + while (total == 0) { + if (i - j + 1 < min) { + min = i - j + 1; + from = j; + } + if (++cnt[s.charAt(j++)] > 0) total++; + } + } + return (min == Integer.MAX_VALUE) ? "" : s.substring(from, from + min); + } +} diff --git a/MissingNumber.java b/MissingNumber.java new file mode 100644 index 0000000..198eb7d --- /dev/null +++ b/MissingNumber.java @@ -0,0 +1,45 @@ +package leetcode; + +import java.util.Arrays; +import java.util.HashSet; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MissingNumber + * Creator : Edward + * Date : Nov, 2017 + * Description : 268. Missing Number + */ +public class MissingNumber { + /** + * Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array. + + For example, + Given nums = [0, 1, 3] return 2. + + time : O(n) + space : O(1) + + * @param nums + * @return + */ + + public int missingNumber(int[] nums) { + int res = nums.length; + for (int i = 0; i < nums.length; i++) { + res ^= i ^ nums[i]; + } + return res; + } + + public int missingNumber2(int[] nums) { + int expectedSum = (nums.length + 1) / 2 * nums.length; + int actualSum = 0; + for (int num : nums) { + actualSum += num; + } + return expectedSum - actualSum; + } + +} diff --git a/MissingRanges.java b/MissingRanges.java new file mode 100644 index 0000000..e036f7f --- /dev/null +++ b/MissingRanges.java @@ -0,0 +1,52 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MissingRanges + * Creator : Edward + * Date : Sep, 2017 + * Description : 163. Missing Ranges + */ +public class MissingRanges { + /** + * 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"]. + + [2147483647] 0 2147483647 + ["0->2147483646"] + ["0->2147483646","-2147483648->2147483647"] + + time : O(n) + space : O(1) + + * @param nums + * @param lower + * @param upper + * @return + */ + public List findMissingRanges(int[] nums, int lower, int upper) { + List res = new ArrayList<>(); + long alower = (long)lower, aupper = (long)upper; + for (int num : nums) { + if (num == alower) { + alower++; + } else if (alower < num) { + if (alower + 1 == num) { + res.add(String.valueOf(alower)); + } else { + res.add(alower + "->" + (num - 1)); + } + alower = (long)num + 1; + } + } + if (alower == aupper) res.add(String.valueOf(alower)); + else if (alower < aupper) res.add(alower + "->" + aupper); + return res; + } +} diff --git a/MoveZeroes.java b/MoveZeroes.java new file mode 100644 index 0000000..5d78a68 --- /dev/null +++ b/MoveZeroes.java @@ -0,0 +1,65 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MoveZeroes + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class MoveZeroes { + /** + * 283. Move Zeroes + * Given an array nums, write a function to move all 0's to the end of it + * while maintaining the relative order of the non-zero elements. + + For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0]. + Note: + You must do this in-place without making a copy of the array. + Minimize the total number of operations. + + [0, 1, 0, 3, 12] + start = 3 + i = 1 [1, 1, 0, 3, 12] + i = 3 [1, 3, 0, 3, 12] + i = 4 [1, 3, 12, 0, 0] + + [0, 1, 0, 3, 12] + j = 1 + i = 1 [1, 0, 0, 3, 12] + i = 3 [1, 3, 0, 0, 12] + i = 4 [1, 3, 12, 0, 0] + + + time : O(n); + space : O(1); + * @param nums + */ + // num of operation : nums.length; + public void moveZeroes1(int[] nums) { + if (nums == null || nums.length == 0) return; + int start = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i] != 0) { + nums[start++] = nums[i]; + } + } + while (start < nums.length) { + nums[start++] = 0; + } + } + + // num of operation : 2 * num of non-zero + // lots of zeros + public void moveZeroes2(int[] nums) { + if (nums == null || nums.length == 0) return; + for (int i = 0, j = 0; i < nums.length; i++) { + if (nums[i] != 0) { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j++] = temp; + } + } + } +} diff --git a/MovingAveragefromDataStream.java b/MovingAveragefromDataStream.java new file mode 100644 index 0000000..ef8fbd9 --- /dev/null +++ b/MovingAveragefromDataStream.java @@ -0,0 +1,44 @@ +package leetcode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MovingAveragefromDataStream + * Creator : Edward + * Date : Oct, 2017 + * Description : 346. Moving Average from Data Stream + */ +public class MovingAveragefromDataStream { + /** + * MovingAverage m = new MovingAverage(3); + m.next(1) = 1 + m.next(10) = (1 + 10) / 2 + m.next(3) = (1 + 10 + 3) / 3 + m.next(5) = (10 + 3 + 5) / 3 + + time : O(n) + space : O(n) + + */ + + private Queue queue; + private double sum = 0; + private int size; + + public MovingAveragefromDataStream(int size) { + queue = new LinkedList<>(); + this.size = size; + } + + public double next(int val) { + if (queue.size() == size) { + sum -= queue.remove(); + } + sum += val; + queue.offer(val); + return sum / queue.size(); + } +} diff --git a/MultiplyStrings.java b/MultiplyStrings.java new file mode 100644 index 0000000..1f20bb3 --- /dev/null +++ b/MultiplyStrings.java @@ -0,0 +1,49 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : MultiplyStrings + * Creator : Edward + * Date : Nov, 2017 + * Description : 43. Multiply Strings + */ +public class MultiplyStrings { + /** + * Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2. + + Note: + + The length of both num1 and num2 is < 110. + Both num1 and num2 contains only digits 0-9. + Both num1 and num2 does not contain any leading zero. + You must not use any built-in BigInteger library or convert the inputs to integer directly. + + time : O(n * m) + space : O(n + m) + + * @param num1 + * @param num2 + * @return + */ + public String multiply(String num1, String num2) { + if (num1 == null || num2 == null) return "0"; + int[] digits = new int[num1.length() + num2.length()]; + for (int i = num1.length() - 1; i >= 0; i--) { + for (int j = num2.length() - 1; j >= 0; j--) { + int product = (num1.charAt(i) - '0') * (num2.charAt(j) - '0'); + int p1 = i + j, p2 = i + j + 1; + int sum = product + digits[p2]; + digits[p1] += sum / 10; + digits[p2] = sum % 10; + } + } + StringBuilder res = new StringBuilder(); + for (int digit : digits) { + if (!(digit == 0 && res.length() == 0)) { + res.append(digit); + } + } + return res.length() == 0 ? "0" : res.toString(); + } +} diff --git a/NQueens.java b/NQueens.java new file mode 100644 index 0000000..e08c26b --- /dev/null +++ b/NQueens.java @@ -0,0 +1,79 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : NQueens + * Creator : Edward + * Date : Nov, 2017 + * Description : 51. N-Queens + */ +public class NQueens { + /** + * [ + [".Q..", // Solution 1 + "...Q", + "Q...", + "..Q."], + + ["..Q.", // Solution 2 + "Q...", + "...Q", + ".Q.."] + ] + * time : O(n^n) 不是很确定 + * space : O(n) + + * @param n + * @return + */ + + public List> solveNQueens(int n) { + List> res = new ArrayList<>(); + if (n <= 0) return res; + helper(res, new int[n], 0); + return res; + } + public void helper(List> res, int[] queens, int pos) { + if (pos == queens.length) { + addSolution(res, queens); + return; + } + for (int i = 0; i < queens.length; i++) { + queens[pos] = i; + if (isValid(queens, pos)) { + helper(res, queens, pos + 1); + } + } + } + + public boolean isValid(int[] queens, int pos) { + for (int i = 0; i < pos; i++) { + if (queens[i] == queens[pos]) { // 同一列 + return false; + } else if (Math.abs(queens[pos] - queens[i]) == Math.abs(i - pos)) { //是否在对角线上 + return false; + } + } + return true; + } + + public void addSolution(List> res, int[] queens) { + List list = new ArrayList<>(); + for (int i = 0; i < queens.length; i++) { + StringBuilder sb = new StringBuilder(); + for (int j = 0; j < queens.length; j++) { + if (queens[i] == j) { + sb.append('Q'); + } else { + sb.append('.'); + } + } + list.add(sb.toString()); + } + res.add(list); + } +} diff --git a/NQueensII.java b/NQueensII.java new file mode 100644 index 0000000..c226f45 --- /dev/null +++ b/NQueensII.java @@ -0,0 +1,49 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : NQueensII + * Creator : Edward + * Date : Nov, 2017 + * Description : 52. N-Queens II + */ +public class NQueensII { + /** + * + + time : O(n^n) + space : O(n) + + * @param n + * @return + */ + + int res = 0; + + public int totalNQueens(int n) { + boolean[] cols = new boolean[n]; + boolean[] d1 = new boolean[2 * n]; // \ + boolean[] d2 = new boolean[2 * n]; // / + helper(0, cols, d1, d2, n); + return res; + } + public void helper(int row, boolean[] cols, boolean[] d1, boolean[] d2, int n) { + if (row == n) { + res++; + return; + } + for (int col = 0; col < n; col++) { + int id1 = col - row + n; + int id2 = col + row; + if (cols[col] || d1[id1] || d2[id2]) continue; + + cols[col] = true; d1[id1] = true; d2[id2] = true; + helper(row + 1, cols, d1, d2, n); + cols[col] = false; d1[id1] = false; d2[id2] = false; + } + } +} diff --git a/NestedInteger.java b/NestedInteger.java new file mode 100644 index 0000000..eca626d --- /dev/null +++ b/NestedInteger.java @@ -0,0 +1,56 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : NestedInteger + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class NestedInteger { + + Integer value; + List list; + + NestedInteger() { + value = new Integer(0); + list = new ArrayList<>(); + } + NestedInteger(int value) { + this.value = value; + } + NestedInteger(int value, List list) { + this.value = value; + this.list = list; + } + public void add(NestedInteger nestedInteger){} + + // @return true if this NestedInteger holds a single integer, + // rather than a nested list. + public boolean isInteger() { + return value != null; + } + // @return the single integer that this NestedInteger holds, + // if it holds a single integer + // Return null if this NestedInteger holds a nested list + public Integer getInteger() { + return value; + } + // @return the nested list that this NestedInteger holds, + // if it holds a nested list + // Return null if this NestedInteger holds a single integer + public List getList() { + return list; + } + + public Integer next() { + return value; // 例子,真正函数不是这么写的 + } + public boolean hasNext() { + return true; // 例子,真正函数不是这么写的 + } +} diff --git a/NestedListWeightSum.java b/NestedListWeightSum.java new file mode 100644 index 0000000..f5aa2e2 --- /dev/null +++ b/NestedListWeightSum.java @@ -0,0 +1,95 @@ +package leetcode; + +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : NestedListWeightSum + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class NestedListWeightSum { + /** + * 339. Nested List Weight Sum + * Given a nested list of integers, return the sum of all integers in the list weighted by their depth. + + Each element is either an integer, or a list -- whose elements may also be integers or other lists. + + Example 1: + Given the list [[1,1],2,[1,1]], return 10. (four 1's at depth 2, one 2 at depth 1) + + Example 2: + Given the list [1,[4,[6]]], return 27. + (one 1 at depth 1, one 4 at depth 2, and one 6 at depth 3; 1 + 4*2 + 6*3 = 27) + + + time : O(n) + space : O(n); + * @param nestedList + * @return + */ + + + // DFS + public int depthSum(List nestedList) { + if (nestedList == null) return 0; + return helper(nestedList, 1); + } + + public int helper(List nestedList, int depth) { + int res = 0; + for (NestedInteger nest : nestedList) { + if (nest.isInteger()) { + res += nest.getInteger() * depth; + } else { + res += helper(nest.getList(), depth + 1); + } + } + return res; + } + + // BFS + public int depthSum2(List nestedList) { + if (nestedList == null) return 0; + int depth = 1; + int res = 0; + Queue queue = new LinkedList<>(nestedList); + while (!queue.isEmpty()) { + int size = queue.size(); + for (int i = 0; i < size; i++) { + NestedInteger nest = queue.poll(); + if (nest.isInteger()) { + res += nest.getInteger() * depth; + } else { + queue.addAll(nest.getList()); + } + } + depth++; + } + return res; + } + + + public int depthSum3(List nestedList) { + if (nestedList == null) return 0; + int depth = 1; + int res = 0; + while (nestedList.size() != 0) { + List nextList = new LinkedList<>(); + for (NestedInteger nest : nestedList) { + if (nest.isInteger()) { + res += nest.getInteger() * depth; + } else { + nextList.addAll(nest.getList()); + } + } + depth++; + nestedList = nextList; + } + return res; + } +} diff --git a/NestedListWeightSumII.java b/NestedListWeightSumII.java new file mode 100644 index 0000000..0d9d628 --- /dev/null +++ b/NestedListWeightSumII.java @@ -0,0 +1,78 @@ +package leetcode; + +import java.util.LinkedList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : NestedListWeightSumII + * Creator : Edward + * Date : Aug, 2017 + * Description : 364. Nested List Weight Sum II + */ +public class NestedListWeightSumII { + /** + * Given a nested list of integers, return the sum of all integers in the list weighted by their depth. + + Each element is either an integer, or a list -- whose elements may also be integers or other lists. + + Different from the previous question where weight is increasing from root to leaf, now the weight is defined from bottom up. i.e., the leaf level integers have weight 1, and the root level integers have the largest weight. + + Example 1: + Given the list [[1,1],2,[1,1]], return 8. (four 1's at depth 1, one 2 at depth 2) + + Example 2: + Given the list [1,[4,[6]]], return 17. + (one 1 at depth 3, one 4 at depth 2, and one 6 at depth 1; 1*3 + 4*2 + 6*1 = 17) + + DFS 2 + DFS(2, Nest) + DFS 2 + + + nextList : 1, 1, 1, 1 + + res = 2 + 2 + 4 + dfs(next, 2) res = 2 + 4 + + time : O(n); + space : O(n); + * @param nestedList + * @return + */ + public int depthSumInverse(List nestedList) { + if (nestedList == null) return 0; + return helper(nestedList, 0); + } + + private int helper(List nestedList, int res) { + List nextList = new LinkedList<>(); + for (NestedInteger nest : nestedList) { + if (nest.isInteger()) { + res += nest.getInteger(); + } else { + nextList.addAll(nest.getList()); + } + } + res += nextList.isEmpty() ? 0 : helper(nestedList, res); + return res; + } + + public int depthSumInverse2(List nestedList) { + if (nestedList == null) return 0; + int sum = 0; + int res = 0; + while (!nestedList.isEmpty()) { + List nextList = new LinkedList<>(); + for (NestedInteger nest : nestedList) { + if (nest.isInteger()) { + sum += nest.getInteger(); + } else { + nextList.addAll(nest.getList()); + } + } + res += sum; + nestedList = nextList; + } + return res; + } +} diff --git a/NextGreaterElementI.java b/NextGreaterElementI.java new file mode 100644 index 0000000..5bb627b --- /dev/null +++ b/NextGreaterElementI.java @@ -0,0 +1,69 @@ +package leetcode; + +import java.util.HashMap; +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : NextGreaterElementI + * Creator : Edward + * Date : Nov, 2017 + * Description : 496. Next Greater Element I + */ +public class NextGreaterElementI { + /** + * You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of nums2. Find all the next greater numbers for nums1's elements in the corresponding places of nums2. + + The Next Greater Number of a number x in nums1 is the first greater number to its right in nums2. If it does not exist, output -1 for this number. + + Example 1: + Input: [4,1,2], nums2 = [1,3,4,2]. + Output: [-1,3,-1] + Explanation: + For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1. + For number 1 in the first array, the next greater number for it in the second array is 3. + For number 2 in the first array, there is no next greater number for it in the second array, so output -1. + Example 2: + Input: nums1 = [2,4], nums2 = [1,2,3,4]. + Output: [3,-1] + Explanation: + For number 2 in the first array, the next greater number for it in the second array is 3. + For number 4 in the first array, there is no next greater number for it in the second array, so output -1. + + map : num , res + stack : num + + [4,1,2], [1,3,4,2] + + 1 3 4 2 + i + stack : 4 2 + + map : 1 3 + 3 4 + + time : O(n) + space : O(n) + + * @param nums1 + * @param nums2 + * @return + */ + + public int[] nextGreaterElement(int[] nums1, int[] nums2) { + HashMap map = new HashMap<>(); + Stack stack = new Stack<>(); + for (int num : nums2) { + while (!stack.isEmpty() && stack.peek() < num) { + map.put(stack.pop(), num); + } + stack.push(num); + } + int[] res = new int[nums1.length]; + for (int i = 0; i < res.length; i++) { + res[i] = map.getOrDefault(nums1[i], -1); + } + return res; + } +} diff --git a/NextPermutation.java b/NextPermutation.java new file mode 100644 index 0000000..75179d8 --- /dev/null +++ b/NextPermutation.java @@ -0,0 +1,73 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : NextPermutation + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class NextPermutation { + /** + * 31. Next Permutation + * Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column. + 1,2,3 → 1,3,2 + 3,2,1 → 1,2,3 + 1,1,5 → 1,5,1 + + // 1  2  7  4  3  1 + ^ + // 1  2  7  4  3  1 + ^ + // 1  3  7  4  2  1 + ^ ^ + // 1  3  1  2  4  7 + ^ ^ ^ ^ + + 7 4 3 2 1 1 + + time : O(n); + space : O(1); + * @param nums + */ + public void nextPermutation(int[] nums) { + if (nums == null || nums.length == 0) return; + + int firstSmall = -1; + for (int i = nums.length - 2; i >= 0; i--) { + if (nums[i] < nums[i + 1]) { + firstSmall = i; + break; + } + } + + if (firstSmall == -1) { + reverse(nums, 0, nums.length - 1); + return; + } + + int firstLarge = -1; + for (int i = nums.length - 1; i > firstSmall; i--) { + if (nums[i] > nums[firstSmall]) { + firstLarge = i; + break; + } + } + swap(nums, firstSmall, firstLarge); + reverse(nums, firstSmall + 1, nums.length - 1); + return; + } + + public void swap(int[] nums, int i, int j) { + int temp = nums[i]; + nums[i++] = nums[j]; + nums[j--] = temp; + } + + public void reverse(int[] nums, int i, int j) { + while (i < j) { + swap(nums, i++, j--); + } + } +} diff --git a/NimGame.java b/NimGame.java new file mode 100644 index 0000000..3a314ad --- /dev/null +++ b/NimGame.java @@ -0,0 +1,38 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : NimGame + * Creator : Edward + * Date : Dec, 2017 + * Description : 292. Nim Game + */ +public class NimGame { + /** + * You are playing the following Nim Game with your friend: There is a heap of stones on the table, + * each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. + * You will take the first turn to remove the stones. + + Both of you are very clever and have optimal strategies for the game. Write a function to determine + whether you can win the game given the number of stones in the heap. + + 1-true + 2-true + 3-true + 4-false + 5-true + 6-true + 7-true + 8-false + + time : O(1) + space : O(1) + + * @param n + * @return + */ + public boolean canWinNim(int n) { + return n % 4 != 0; + } +} diff --git a/NonoverlappingIntervals.java b/NonoverlappingIntervals.java new file mode 100644 index 0000000..2c42d69 --- /dev/null +++ b/NonoverlappingIntervals.java @@ -0,0 +1,85 @@ +package leetcode; + +import java.util.Arrays; +import java.util.Comparator; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : NonoverlappingIntervals + * Creator : Edward + * Date : Nov, 2017 + * Description : 435. Non-overlapping Intervals + */ +public class NonoverlappingIntervals { + /** + * Given a collection of intervals, find the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping. + + Note: + You may assume the interval's end point is always bigger than its start point. + Intervals like [1,2] and [2,3] have borders "touching" but they don't overlap each other. + Example 1: + Input: [ [1,2], [2,3], [3,4], [1,3] ] + + Output: 1 + + Explanation: [1,3] can be removed and the rest of intervals are non-overlapping. + Example 2: + Input: [ [1,2], [1,2], [1,2] ] + + Output: 2 + + Explanation: You need to remove two [1,2] to make the rest of intervals non-overlapping. + Example 3: + Input: [ [1,2], [2,3] ] + + Output: 0 + + Explanation: You don't need to remove any of the intervals since they're already non-overlapping. + + [ [1,2], [2,3], [3,4], [1,3] ] + + + time : O(nlogn) + space : O(1) + + * @param intervals + * @return + */ + + public int eraseOverlapIntervals(Interval[] intervals) { + if (intervals.length == 0) return 0; + + Arrays.sort(intervals, (a, b) -> a.end - b.end); + int end = intervals[0].end; + int count = 1; + for (int i = 1; i < intervals.length; i++) { + if (intervals[i].start >= end) { + end = intervals[i].end; + count++; + } + } + return intervals.length - count; + } + + public int eraseOverlapIntervals2(Interval[] intervals) { + if (intervals.length == 0) return 0; + Arrays.sort(intervals, new Comparator() { + @Override + public int compare(Interval o1, Interval o2) { + if (o1.end != o2.end) return o1.end - o2.end; + return o2.start - o1.start; + } + }); + int end = Integer.MIN_VALUE; + int res = 0; + for (Interval interval : intervals) { + if (interval.start >= end) { + end = interval.end; + } else { + res++; + } + } + return res; + } +} diff --git a/NthDigit.java b/NthDigit.java new file mode 100644 index 0000000..93b9a58 --- /dev/null +++ b/NthDigit.java @@ -0,0 +1,55 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : NthDigit + * Creator : Edward + * Date : Oct, 2017 + * Description : 400. Nth Digit + */ +public class NthDigit { + /** + *Example 2: + + Input: + 11 + + Output: + 0 + + Explanation: + The 11th digit of the sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... is a 0, which is part of the number 10. + + + 10 - 99 : 90 * 2 = 180 + + 13: + n = 13 - 9 = 4; + len = 2; + count = 90 + start = 11 + + time : < O(n) + space : O(1) + + + * @param n + * @return + */ + + public int findNthDigit(int n) { + int len = 1; + long count = 9; + int start = 1; + while (n > len * count) { + n -= len * count; + len += 1; + count *= 10; + start *= 10; + } + start += (n - 1) / len; + String s = Integer.toString(start); + return s.charAt((n - 1) % len) - '0'; + } +} diff --git a/Numberof1Bits.java b/Numberof1Bits.java new file mode 100644 index 0000000..318af4f --- /dev/null +++ b/Numberof1Bits.java @@ -0,0 +1,48 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : Numberof1Bits + * Creator : Edward + * Date : Nov, 2017 + * Description : 191. Number of 1 Bits + */ +public class Numberof1Bits { + /** + * Write a function that takes an unsigned integer and returns the number of ’1' bits it has + * (also known as the Hamming weight). + + For example, the 32-bit integer ’11' has binary representation 00000000000000000000000000001011, + so the function should return 3. + + 使用n&(n-1)的方法:n&(n-1)作用:将n的二进制表示中的最低位为1的改为0 + n n-1 n&(n-1) + step1: 110101 110100 110100 + step2: 110100 110011 110000 + step3: 110000 101111 100000 + step4: 100000 011111 000000 + + time : O(1) / O(n) + space : O(1) + + * @param n + * @return + */ + public int hammingWeight(int n) { + int res = 0; + for (int i = 0; i < 32; i++) { + res += n & 1; + n >>= 1; + } + return res; + } + public int hammingWeight2(int n) { + int res = 0; + while (n != 0) { + n &= (n - 1); + res++; + } + return res; + } +} diff --git a/NumberofBoomerangs.java b/NumberofBoomerangs.java new file mode 100644 index 0000000..00380f1 --- /dev/null +++ b/NumberofBoomerangs.java @@ -0,0 +1,65 @@ +package leetcode; + +import java.util.HashMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : NumberofBoomerangs + * Creator : Edward + * Date : Nov, 2017 + * Description : 447. Number of Boomerangs + */ +public class NumberofBoomerangs { + /** + * Given n points in the plane that are all pairwise distinct, a "boomerang" is a tuple of points (i, j, k) + * such that the distance between i and j equals the distance between i and k (the order of the tuple matters). + + Find the number of boomerangs. You may assume that n will be at most 500 and coordinates of + points are all in the range [-10000, 10000] (inclusive). + + Example: + Input: + [[0,0],[1,0],[2,0]] + + Output: + 2 + + Explanation: + The two boomerangs are [[1,0],[0,0],[2,0]] and [[1,0],[2,0],[0,0]] + + time : O(n^2) + space : O(n) + + + * @param points + * @return + */ + + public int numberOfBoomerangs(int[][] points) { + int res = 0; + HashMap map = new HashMap<>(); + for (int i = 0; i < points.length; i++) { + for (int j = 0; j < points.length; j++) { + if (i == j) { + continue; + } + int distance = getDistance(points[i], points[j]); + map.put(distance, map.getOrDefault(distance, 0) + 1); + } + + for (int val : map.values()) { + res += val * (val - 1); + } + map.clear(); + } + return res; + } + + public int getDistance(int[] a, int[] b) { + int dx = a[0] - b[0]; + int dy = a[1] - b[1]; + return dx * dx + dy * dy; + } + +} diff --git a/NumberofConnectedComponentsinanUndirectedGraph.java b/NumberofConnectedComponentsinanUndirectedGraph.java new file mode 100644 index 0000000..612a710 --- /dev/null +++ b/NumberofConnectedComponentsinanUndirectedGraph.java @@ -0,0 +1,69 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : NumberofConnectedComponentsinanUndirectedGraph + * Creator : Edward + * Date : Jan, 2018 + * Description : 323. Number of Connected Components in an Undirected Graph + */ +public class NumberofConnectedComponentsinanUndirectedGraph { + /** + * Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), + * write a function to find the number of connected components in an undirected graph. + + Example 1: + 0 3 + | | + 1 --- 2 4 + Given n = 5 and edges = [[0, 1], [1, 2], [3, 4]], return 2. + + Example 2: + 0 4 + | | + 1 --- 2 --- 3 + Given n = 5 and edges = [[0, 1], [1, 2], [2, 3], [3, 4]], return 1. + + Note: + You can assume that no duplicate edges will appear in edges. Since all edges are undirected, + [0, 1] is the same as [1, 0] and thus will not appear together in edges. + + 图 : 点 - 边 = 1 + + n = 5 4 edges n-- = 1 + + time : O(edges * nodes) + space : O(n) + + * @param n + * @param edges + * @return + */ + public int countComponents(int n, int[][] edges) { + + int res = n; + + int[] roots = new int[n]; + for (int i = 0; i < n; i++) { + roots[i] = -1; + } + + for (int[] pair : edges) { + int x = find(roots, pair[0]); + int y = find(roots, pair[1]); + if (x != y) { + roots[x] = y; + res--; + } + } + return res; + } + + private int find(int[] roots, int i) { + while (roots[i] != -1) { + i = roots[i]; + } + return i; + } +} diff --git a/NumberofDigitOne.java b/NumberofDigitOne.java new file mode 100644 index 0000000..0fdfcc1 --- /dev/null +++ b/NumberofDigitOne.java @@ -0,0 +1,48 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : NumberofDigitOne + * Creator : Edward + * Date : Dec, 2017 + * Description : 233. Number of Digit One + */ +public class NumberofDigitOne { + /** + * Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n. + + For example: + Given n = 13, + Return 6, because digit 1 occurred in the following numbers: 1, 10, 11, 12, 13. + + 10 : 1 个位 + 100 : 10 十位 + 1000: 100 百位 + + 例子: + 以算百位上1为例子: 假设百位上是0, 1, 和 >=2 三种情况: + case 1: n=3141092, a= 31410, b=92. 计算百位上1的个数应该为 3141 *100 次. + case 2: n=3141192, a= 31411, b=92. 计算百位上1的个数应该为 3141 *100 + (92+1) 次. + case 3: n=3141592, a= 31415, b=92. 计算百位上1的个数应该为 (3141+1) *100 次. + + http://blog.csdn.net/xudli/article/details/46798619 + + time : < O(n) + space : O(1) + + * @param n + * @return + */ + + public int countDigitOne(int n) { + int res = 0; + for (long m = 1; m <= n; m *= 10) { + long a = n / m; + long b = n % m; + res += (a + 8) / 10 * m; + if (a % 10 == 1) res += b + 1; + } + return res; + } +} diff --git a/NumberofIslands.java b/NumberofIslands.java new file mode 100644 index 0000000..bbf6a9a --- /dev/null +++ b/NumberofIslands.java @@ -0,0 +1,122 @@ +package leetcode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : NumberofIslands + * Creator : Edward + * Date : Nov, 2017 + * Description : 200. Number of Islands + */ +public class NumberofIslands { + + /** + * Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. + * An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. + * You may assume all four edges of the grid are all surrounded by water. + + Example 1: + + 11110 + 11010 + 11000 + 00000 + Answer: 1 + + Example 2: + + 11000 + 11000 + 00100 + 00011 + Answer: 3 + + time : O(m * n) + space : O(n) + + * @param grid + * @return + */ + + private int m; + private int n; + + public int numIslands(char[][] grid) { + int res = 0; + m = grid.length; + if (m == 0) return 0; + n = grid[0].length; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (grid[i][j] == '1') { + dfs(grid, i, j); + res++; + } + } + } + return res; + } + + /** + time : O(m * n) + space : O(m * n) + * @param grid + * @param i + * @param j + */ + + private void dfs(char[][] grid, int i, int j) { + if (i < 0 || j < 0 || i >= m || j >= n || grid[i][j] == '0') return; + grid[i][j] = '0'; + dfs(grid, i, j + 1); + dfs(grid, i, j - 1); + dfs(grid, i + 1, j); + dfs(grid, i - 1, j); + } + + public int numIslands2(char[][] grid) { + int res = 0; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; i++) { + if (grid[i][j] == '1') { + bfs(grid, i, j); + res++; + } + } + } + return res; + } + + private void bfs(char[][] grid, int x, int y) { + grid[x][y] = '0'; + int n = grid.length; + int m = grid[0].length; + Queue queue = new LinkedList<>(); + int code = x * m + y; + queue.offer(code); + while (!queue.isEmpty()) { + code = queue.poll(); + int i = code / m; + int j = code % m; + if (i > 0 && grid[i - 1][j] == '1') { + queue.offer((i - 1) * m + j); + grid[i - 1][j] = '0'; + } + if (i < n - 1 && grid[i + 1][j] == '1') { + queue.offer((i + 1) * m + j); + grid[i + 1][j] = '0'; + } + if (j > 0 && grid[i][j - 1] == '1') { + queue.offer((i * m) + j - 1); + grid[i][j - 1] = '0'; + } + if (j < m - 1 && grid[i][j + 1] == '1') { + queue.offer((i * m) + j + 1); + grid[i][j + 1] = '0'; + } + } + } +} diff --git a/NumberofIslandsII.java b/NumberofIslandsII.java new file mode 100644 index 0000000..351dff4 --- /dev/null +++ b/NumberofIslandsII.java @@ -0,0 +1,97 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : NumberofIslandsII + * Creator : Edward + * Date : Jan, 2018 + * Description : 305. Number of Islands II + */ +public class NumberofIslandsII { + /** + * A 2d grid map of m rows and n columns is initially filled with water. + * We may perform an addLand operation which turns the water at position (row, col) into a land. + * Given a list of positions to operate, count the number of islands after each addLand operation. + * An island is surrounded by water and is formed by connecting + * adjacent lands horizontally or vertically. + * You may assume all four edges of the grid are all surrounded by water. + + Example: + + Given m = 3, n = 3, positions = [[0,0], [0,1], [1,2], [2,1]]. + Initially, the 2d grid grid is filled with water. (Assume 0 represents water and 1 represents land). + + 0 0 0 + 0 0 0 + 0 0 0 + Operation #1: addLand(0, 0) turns the water at grid[0][0] into a land. + + 1 0 0 + 0 0 0 Number of islands = 1 + 0 0 0 + Operation #2: addLand(0, 1) turns the water at grid[0][1] into a land. + + 1 1 0 + 0 0 0 Number of islands = 1 + 0 0 0 + Operation #3: addLand(1, 2) turns the water at grid[1][2] into a land. + + 1 1 0 + 0 0 1 Number of islands = 2 + 0 0 0 + Operation #4: addLand(2, 1) turns the water at grid[2][1] into a land. + + 1 1 0 + 0 0 1 Number of islands = 3 + 0 1 0 + We return the result as an array: [1, 1, 2, 3] + + time : O(k^2) + space : O(m * n) + */ + int[][] dirs = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; + + public List numIslands2(int m, int n, int[][] positions) { + List res = new ArrayList<>(); + if (m <= 0 || n <= 0) return res; + + int count = 0; + int[] roots = new int[m * n]; + Arrays.fill(roots, -1); + + for (int[] pair : positions) { + int position = n * pair[0] + pair[1]; + roots[position] = position; + count++; + + for (int[] dir : dirs) { + int x = pair[0] + dir[0]; + int y = pair[1] + dir[1]; + int curPos = n * x + y; + if (x < 0 || x >= m || y < 0 || y >= n || roots[curPos] == -1) { + continue; + } + int anoIsland = find(roots, curPos); + if (position != anoIsland) { + roots[position] = anoIsland; + position = anoIsland; + count--; + } + } + res.add(count); + } + return res; + } + + private int find(int[] roots, int i) { + while (i != roots[i]) { + i = roots[i]; + } + return i; + } +} diff --git a/NumberofSegmentsinaString.java b/NumberofSegmentsinaString.java new file mode 100644 index 0000000..f336ca4 --- /dev/null +++ b/NumberofSegmentsinaString.java @@ -0,0 +1,33 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : NumberofSegmentsinaString + * Creator : Edward + * Date : Nov, 2017 + * Description : 434. Number of Segments in a String + */ +public class NumberofSegmentsinaString { + /** + * Count the number of segments in a string, where a segment is defined to be a contiguous sequence of non-space characters. + + Please note that the string does not contain any non-printable characters. + + Example: + + Input: "Hello, my name is John" + Output: 5 + + time : O(n) + space : O(1) + + * @param s + * @return + */ + public int countSegments(String s) { + s = s.trim(); + if (s.length() == 0) return 0; + return s.split("\\s+").length; + } +} diff --git a/OddEvenLinkedList.java b/OddEvenLinkedList.java new file mode 100644 index 0000000..cafbe98 --- /dev/null +++ b/OddEvenLinkedList.java @@ -0,0 +1,43 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : OddEvenLinkedList + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class OddEvenLinkedList { + /** + * 328. Odd Even Linked List + * Example: + * + Given 1->2->3->4->5->NULL, + return 1->3->5->2->4->NULL. + + 1 -> 3 2 -> 4 + + 3 -> 4 -> 5 -> 6 + + + time : O(n); + space : O(1); + * @param head + * @return + */ + public ListNode oddEvenList(ListNode head) { + if (head == null || head.next == null) return head; + ListNode odd = head; + ListNode even = head.next; + ListNode evenHead = even; + while (even != null && even.next != null) { + odd.next = odd.next.next; + even.next = even.next.next; + odd = odd.next; + even = even.next; + } + odd.next = evenHead; + return head; + } +} diff --git a/OneEditDistance.java b/OneEditDistance.java new file mode 100644 index 0000000..d315422 --- /dev/null +++ b/OneEditDistance.java @@ -0,0 +1,39 @@ +package leetcode; + +/** + * Created by Edward on 28/07/2017. + */ +public class OneEditDistance { + /** + * 161. One Edit Distance + * Given two strings S and T, determine if they are both one edit distance apart. + + 1, abcre abere + 2, abdc abc + 3, abc abdc + + abc + abcd + + time : O(n^2) + space : O(1) + + * @param s + * @param t + * @return + */ + public static boolean isOneEditDistance(String s, String t) { + for (int i = 0; i < Math.min(s.length(), t.length()); i++) { + if (s.charAt(i) != t.charAt(i)) { + if (s.length() == t.length()) { + return s.substring(i + 1).equals(t.substring(i + 1)); + } else if (s.length() > t.length()) { + return s.substring(i + 1).equals(t.substring(i)); + } else { + return t.substring(i + 1).equals(s.substring(i)); + } + } + } + return Math.abs(s.length() - t.length()) == 1; + } +} diff --git a/PaintFence.java b/PaintFence.java new file mode 100644 index 0000000..a140804 --- /dev/null +++ b/PaintFence.java @@ -0,0 +1,42 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PaintFence + * Creator : Edward + * Date : Dec, 2017 + * Description : 276. Paint Fence + */ +public class PaintFence { + /** + * There is a fence with n posts, each post can be painted with one of the k colors. + + You have to paint all the posts such that no more than two adjacent fence posts have the same color. + + Return the total number of ways you can paint the fence. + + 1 2 3 + + 不同: (k - 1) * total + 相同: 2 3 相同,= 2和1 不同的种类 + + time : O(n) + space : O(1) + + * @param n + * @param k + * @return + */ + public int numWays(int n, int k) { + if (n == 0) return 0; + if (n == 1) return k; + int same = 0, diff = k, total = k; + for (int i = 2; i <= n; i++) { + same = diff; + diff = (k - 1) * total; + total = same + diff; + } + return total; + } +} diff --git a/PaintHouse.java b/PaintHouse.java new file mode 100644 index 0000000..5a9570d --- /dev/null +++ b/PaintHouse.java @@ -0,0 +1,42 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PaintHouse + * Creator : Edward + * Date : Nov, 2017 + * Description : 256. Paint House + */ +public class PaintHouse { + /** + * There are a row of n houses, each house can be painted with one of the three colors: + * red, blue or green. The cost of painting each house with a certain color is different. + * You have to paint all the houses such that no two adjacent houses have the same color. + + The cost of painting each house with a certain color is represented by a n x 3 cost matrix. For example, + costs[0][0] is the cost of painting house 0 with color red; costs[1][2] is the cost of painting house 1 with + color green, and so on... Find the minimum cost to paint all houses. + + costs[i][j] + i : house + j : color : 3 + + time : O(n) + space : O(1) + + + * @param costs + * @return + */ + public int minCost(int[][] costs) { + if (costs == null || costs[0].length == 0) return 0; + for (int i = 1; i < costs.length; i++) { + costs[i][0] += Math.min(costs[i - 1][1], costs[i - 1][2]); + costs[i][1] += Math.min(costs[i - 1][0], costs[i - 1][2]); + costs[i][2] += Math.min(costs[i - 1][0], costs[i - 1][1]); + } + int n = costs.length - 1; + return Math.min(Math.min(costs[n][0], costs[n][1]), costs[n][2]); + } +} diff --git a/PaintHouseII.java b/PaintHouseII.java new file mode 100644 index 0000000..6c9b378 --- /dev/null +++ b/PaintHouseII.java @@ -0,0 +1,59 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PaintHouseII + * Creator : Edward + * Date : Dec, 2017 + * Description : 265. Paint House II + */ +public class PaintHouseII { + /** + * There are a row of n houses, each house can be painted with one of the k colors. + * The cost of painting each house with a certain color is different. + * You have to paint all the houses such that no two adjacent houses have the same color. + + The cost of painting each house with a certain color is represented by a n x k cost matrix. + For example, costs[0][0] is the cost of painting house 0 with color 0; + costs[1][2] is the cost of painting house 1 with color 2, and so on... Find the minimum cost to paint all houses. + + Note: + All costs are positive integers. + + + time : O(n * k) + space : O(1) + + + * @param costs + * @return + */ + + public int minCostII(int[][] costs) { + if (costs == null || costs.length == 0) return 0; + int n = costs.length; + int k = costs[0].length; + + int min1 = -1, min2 = -1; + for (int i = 0; i < n; i++) { + int last1 = min1, last2 = min2; + min1 = -1; min2 = -1; + for (int j = 0; j < k; j++) { + if (j != last1) { + costs[i][j] += last1 < 0 ? 0 : costs[i - 1][last1]; + } else { + costs[i][j] += last2 < 0 ? 0 : costs[i - 1][last2]; + } + + if (min1 < 0 || costs[i][j] < costs[i][min1]) { + min2 = min1; + min1 = j; + } else if (min2 < 0 || costs[i][j] < costs[i][min2]) { + min2 = j; + } + } + } + return costs[n - 1][min1]; + } +} diff --git a/PalindromeLinkedList.java b/PalindromeLinkedList.java new file mode 100644 index 0000000..2b2438a --- /dev/null +++ b/PalindromeLinkedList.java @@ -0,0 +1,54 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PalindromeLinkedList + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class PalindromeLinkedList { + /** + * 234. Palindrome Linked List + + * time : O(n) + * space : O(1) + * @param head + * @return + */ + public boolean isPalindrome(ListNode head) { + if (head == null) return true; + ListNode middle = findMiddle(head); + middle.next = reverse(middle.next); + + ListNode p = head; + ListNode q = middle.next; + while (p != null && q != null) { + if (p.val != q.val) return false; + p = p.next; + q = q.next; + } + return true; + } + public ListNode findMiddle(ListNode head) { + ListNode slow = head; + ListNode fast = head.next; + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + } + return slow; + } + + public ListNode reverse(ListNode head) { + ListNode prev = null; + while (head != null) { + ListNode temp = head.next; + head.next = prev; + prev = head; + head = temp; + } + return prev; + } +} diff --git a/PalindromeNumber.java b/PalindromeNumber.java new file mode 100644 index 0000000..5c78d16 --- /dev/null +++ b/PalindromeNumber.java @@ -0,0 +1,30 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PalindromeNumber + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class PalindromeNumber { + + /** + * 9. Palindrome Number + + time : O(n) space : O(1) + * @param x + * @return + */ + public boolean isPalindrome(int x) { + if (x < 0 || x != 0 && x % 10 == 0) return false; + int palind = x; + int rev = 0; + while (x > 0) { + rev = rev * 10 + x % 10; + x /= 10; + } + return palind == rev; + } +} diff --git a/PalindromePairs.java b/PalindromePairs.java new file mode 100644 index 0000000..d3725cc --- /dev/null +++ b/PalindromePairs.java @@ -0,0 +1,82 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PalindromePairs + * Creator : Edward + * Date : Jan, 2018 + * Description : 336. Palindrome Pairs + */ +public class PalindromePairs { + /** + * Given a list of unique words, find all pairs of distinct indices (i, j) in the given list, + * so that the concatenation of the two words, i.e. words[i] + words[j] is a palindrome. + + Example 1: + Given words = ["bat", "tab", "cat"] + Return [[0, 1], [1, 0]] + The palindromes are ["battab", "tabbat"] + Example 2: + Given words = ["abcd", "dcba", "lls", "s", "sssll"] + Return [[0, 1], [1, 0], [3, 2], [2, 4]] + The palindromes are ["dcbaabcd", "abcddcba", "slls", "llssssll"] + + "abcdc" "ab" + + ab"cdc ab" + "a" a + + time : O(n * k^2) + space : O(n) + + * @param words + * @return + */ + public List> palindromePairs(String[] words) { + List> res = new ArrayList<>(); + if (words == null || words.length < 2) return res; + HashMap map = new HashMap<>(); + for (int i = 0; i < words.length; i++) { + map.put(words[i], i); + } + + for (int i = 0; i < words.length; i++) { + for (int j = 0; j <= words[i].length(); j++) { + String str1 = words[i].substring(0, j); + String str2 = words[i].substring(j); + if (isPalindrome(str1)) { + String str2rvs = new StringBuilder(str2).reverse().toString(); + if (map.containsKey(str2rvs) && map.get(str2rvs) != i) { + res.add(Arrays.asList(map.get(str2rvs), i)); + } + } + if (str2.length() != 0 && isPalindrome(str2)) { + String str1rvs = new StringBuilder(str1).reverse().toString(); + if (map.containsKey(str1rvs) && map.get(str1rvs) != i) { + res.add(Arrays.asList(i, map.get(str1rvs))); + } + } + } + } + return res; + } + + private boolean isPalindrome(String s) { + int left = 0; + int right = s.length() - 1; + while (left <= right) { + if (s.charAt(left) != s.charAt(right)) { + return false; + } + left++; + right--; + } + return true; + } +} diff --git a/PalindromePartitioning.java b/PalindromePartitioning.java new file mode 100644 index 0000000..b26c180 --- /dev/null +++ b/PalindromePartitioning.java @@ -0,0 +1,61 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PalindromePartitioning + * Creator : Edward + * Date : Nov, 2017 + * Description : 131. Palindrome Partitioning + */ +public class PalindromePartitioning { + /** + * Given a string s, partition s such that every substring of the partition is a palindrome. + + Return all possible palindrome partitioning of s. + + For example, given s = "aab", + Return + + [ + ["aa","b"], + ["a","a","b"] + ] + + time: O(2^n) space O(n) + + * @param s + * @return + */ + + public List> partition(String s) { + List> res = new ArrayList<>(); + if (s == null || s.length() == 0) return res; + helper(res, new ArrayList<>(), s); + return res; + } + public void helper(List> res, List list, String s) { + if (s.length() == 0) { + res.add(new ArrayList<>(list)); + return; + } + for (int i = 0; i < s.length(); i++) { + if (isPalindrome(s.substring(0, i + 1))) { + list.add(s.substring(0, i + 1)); + helper(res, list, s.substring(i + 1)); + list.remove(list.size() - 1); + } + } + } + public boolean isPalindrome(String s) { + for (int i = 0; i < s.length() / 2; i++) { + if (s.charAt(i) != s.charAt(s.length() - i - 1)) { + return false; + } + } + return true; + } +} diff --git a/PalindromePartitioningII.java b/PalindromePartitioningII.java new file mode 100644 index 0000000..699c3d3 --- /dev/null +++ b/PalindromePartitioningII.java @@ -0,0 +1,51 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PalindromePartitioningII + * Creator : Edward + * Date : Dec, 2017 + * Description : 132. Palindrome Partitioning II + */ +public class PalindromePartitioningII { + /** + * Given a string s, partition s such that every substring of the partition is a palindrome. + + Return the minimum cuts needed for a palindrome partitioning of s. + + For example, given s = "aab", + Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut. + + [][] isPalindrome + [] cuts + i j + abcba s.charAt(i) = s.charAt(j) && isPalindrome[i+1][j-1] + + + time : O(n^2) + space : O(n^2) + + * @param s + * @return + */ + + public int minCut(String s) { + if (s == null || s.length() == 0) return 0; + int len = s.length(); + int[] cuts = new int[len]; + boolean[][] isPalindrome = new boolean[len][len]; + + for (int i = 0; i < len; i++) { + int min = i; + for (int j = 0; j <= i; j++) { + if (s.charAt(i) == s.charAt(j) && (i - j < 2 || isPalindrome[j + 1][i - 1])) { + isPalindrome[j][i] = true; + min = j == 0 ? 0 : Math.min(min, cuts[j - 1] + 1); + } + } + cuts[i] = min; + } + return cuts[len - 1]; + } +} diff --git a/PalindromePermutation.java b/PalindromePermutation.java new file mode 100644 index 0000000..d4ded67 --- /dev/null +++ b/PalindromePermutation.java @@ -0,0 +1,55 @@ +package leetcode; + +import java.util.HashSet; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PalindromePermutation + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class PalindromePermutation { + /** + * 266. Palindrome Permutation + * Given a string, determine if a permutation of the string could form a palindrome. + + For example, + "code" -> False, "aab" -> True, "carerac" -> True. + + time : O(n) + * @param s + * @return + */ + + //space : O(n) + public boolean canPermutePalindrome(String s) { + HashSet set = new HashSet<>(); + for (char c : s.toCharArray()) { + if (set.contains(c)) { + set.remove(c); + } else { + set.add(c); + } + } + return set.size() <= 1; + } + + //space : O(1) + public boolean canPermutePalindrome2(String s) { + char[] count = new char[256]; + int res = 0; + for (char c : s.toCharArray()) { + if (count[c] > 0) { + count[c]--; + } else { + count[c]++; + } + } + for (int i = 0; i < count.length; i++) { + if (count[i] != 0) res++; + } + return res <= 1; + } +} diff --git a/PalindromePermutationII.java b/PalindromePermutationII.java new file mode 100644 index 0000000..a126a56 --- /dev/null +++ b/PalindromePermutationII.java @@ -0,0 +1,76 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PalindromePermutationII + * Creator : Edward + * Date : Dec, 2017 + * Description : 267. Palindrome Permutation II + */ +public class PalindromePermutationII { + /** + * Given a string s, return all the palindromic permutations (without duplicates) of it. Return an empty list if no palindromic permutation could be form. + + For example: + + Given s = "aabb", return ["abba", "baab"]. + + Given s = "abc", return []. + + time : 不知道 + space : O(n) + + * @param s + * @return + */ + + public List generatePalindromes(String s) { + int odd = 0; + String mid = ""; + List res = new ArrayList<>(); + List list = new ArrayList<>(); + HashMap map = new HashMap<>(); + + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + map.put(c, map.getOrDefault(c, 0) + 1); + odd += map.get(c) % 2 != 0 ? 1 : -1; + } + if (odd > 1) return res; + + for (HashMap.Entry entry : map.entrySet()) { + char key = entry.getKey(); + int val = entry.getValue(); + if (val % 2 != 0) mid += key; + for (int i = 0; i < val / 2; i++) { + list.add(key); + } + } + helper(list, mid, new boolean[list.size()], new StringBuilder(), res); + return res; + } + + private void helper(List list, String mid, boolean[] used, StringBuilder sb, List res) { + if (sb.length() == list.size()) { + res.add(sb.toString() + mid + sb.reverse().toString()); + sb.reverse(); + return; + } + + for (int i = 0; i < list.size(); i++) { + if (i > 0 && list.get(i) == list.get(i - 1) && !used[i - 1]) continue; + if (!used[i]) { + used[i] = true; + sb.append(list.get(i)); + helper(list, mid, used, sb, res); + used[i] = false; + sb.deleteCharAt(sb.length() - 1); + } + } + } +} diff --git a/PalindromicSubstrings.java b/PalindromicSubstrings.java new file mode 100644 index 0000000..d8c9642 --- /dev/null +++ b/PalindromicSubstrings.java @@ -0,0 +1,62 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PalindromicSubstrings + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class PalindromicSubstrings { + /** + * 647. Palindromic Substrings + * Example 1: + Input: "abc" + Output: 3 + Explanation: Three palindromic strings: "a", "b", "c". + Example 2: + Input: "aaa" + Output: 6 + Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa". + + time : O(n^2); + + * @param s + * @return + */ + + // space : O(n^2); + public int countSubstrings(String s) { + if (s == null || s.length() == 0) return 0; + boolean[][] dp = new boolean[s.length()][s.length()]; + int res = 0; + for (int j = 0; j < s.length(); j++) { + for (int i = 0; i <= j; i++) { + dp[i][j] = s.charAt(i) == s.charAt(j) && ((j - i <= 2) || dp[i + 1][j - 1]); + if (dp[i][j]) res++; + } + } + return res; + } + + int count = 0; + + // space : O(1) + public int countSubstrings2(String s) { + if (s == null || s.length() == 0) return 0; + for (int i = 0; i < s.length(); i++) { + helper(s, i, i); + helper(s, i, i + 1); + } + return count; + } + + public void helper(String s, int left, int right) { + while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) { + count++; + left--; + right++; + } + } +} diff --git a/PartitionEqualSubsetSum.java b/PartitionEqualSubsetSum.java new file mode 100644 index 0000000..80a3e18 --- /dev/null +++ b/PartitionEqualSubsetSum.java @@ -0,0 +1,12 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PartitionEqualSubsetSum + * Creator : Edward + * Date : Nov, 2017 + * Description : 416. Partition Equal Subset Sum + */ +public class PartitionEqualSubsetSum { +} diff --git a/PartitionList.java b/PartitionList.java new file mode 100644 index 0000000..92216d5 --- /dev/null +++ b/PartitionList.java @@ -0,0 +1,56 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PartitionList + * Creator : Edward + * Date : Nov, 2017 + * Description : 86. Partition List + */ +public class PartitionList { + /** + * Given a linked list and a value x, partition it such that all nodes less than x come before nodes + * greater than or equal to x. + + You should preserve the original relative order of the nodes in each of the two partitions. + + For example, + Given 1->4->3->2->5->2 and x = 3, + return 1->2->2->4->3->5. + + + 1->4->3->2->5->2 and x = 3 + smallHead -> 1 -> 2 -> 2 -> + small + bigHead -> 4 -> 3 -> 5 -> + big + + time : O(n) + space : O(n) + + + * @param head + * @param x + * @return + */ + public ListNode partition(ListNode head, int x) { + ListNode smallHead = new ListNode(0), + bigHead = new ListNode(0), + small = smallHead, + big = bigHead; + while (head != null) { + ListNode temp = new ListNode(head.val); + if (head.val < x) { + small.next = temp; + small = small.next; + } else { + big.next = temp; + big = big.next; + } + head = head.next; + } + small.next = bigHead.next; + return smallHead.next; + } +} diff --git a/PascalTriangle.java b/PascalTriangle.java new file mode 100644 index 0000000..94f4db5 --- /dev/null +++ b/PascalTriangle.java @@ -0,0 +1,46 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PascalTriangle + * Creator : Edward + * Date : Oct, 2017 + * Description : 118. Pascal's Triangle + */ +public class PascalTriangle { + /** + * For example, given numRows = 5, + Return + + [ + [1], + [1,1], + [1,2,1], + [1,3,3,1], + [1,4,6,4,1] + ] + + + time : O(n^2) + space : O(n) + + * @param numRows + * @return + */ + public List> generate(int numRows) { + List> res = new ArrayList<>(); + List list = new ArrayList<>(); + for (int i = 0; i < numRows; i++) { + list.add(0, 1); + for (int j = 1; j < list.size() - 1; j++) { + list.set(j, list.get(j) + list.get(j + 1)); + } + res.add(new ArrayList<>(list)); + } + return res; + } +} diff --git a/PascalTriangleII.java b/PascalTriangleII.java new file mode 100644 index 0000000..ee457df --- /dev/null +++ b/PascalTriangleII.java @@ -0,0 +1,44 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PascalTriangleII + * Creator : Edward + * Date : Oct, 2017 + * Description : 119. Pascal's Triangle II + */ +public class PascalTriangleII { + /** + * + * [ + [1], + [1,1], + [1,2,1], + [1,3,3,1], + [1,4,6,4,1] + ] + * For example, given k = 3, + Return [1,3,3,1]. + + time : O(n^2) + space : O(n) + + * @param rowIndex + * @return + */ + public List getRow(int rowIndex) { + List res = new ArrayList<>(); + if (rowIndex < 0) return res; + for (int i = 0; i < rowIndex + 1; i++) { + res.add(0, 1); + for (int j = 1; j < res.size() - 1; j++) { + res.set(j, res.get(j) + res.get(j + 1)); + } + } + return res; + } +} diff --git a/PatchingArray.java b/PatchingArray.java new file mode 100644 index 0000000..42af02f --- /dev/null +++ b/PatchingArray.java @@ -0,0 +1,74 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PatchingArray + * Creator : Edward + * Date : Jan, 2018 + * Description : 330. Patching Array + */ +public class PatchingArray { + /** + * Given a sorted positive integer array nums and an integer n, + * add/patch elements to the array such that any number in range [1, n] inclusive can be formed + * by the sum of some elements in the array. Return the minimum number of patches required. + + Example 1: + nums = [1, 3], n = 6 + Return 1. + + Combinations of nums are [1], [3], [1,3], which form possible sums of: 1, 3, 4. + Now if we add/patch 2 to nums, the combinations are: [1], [2], [3], [1,3], [2,3], [1,2,3]. + Possible sums are 1, 2, 3, 4, 5, 6, which now covers the range [1, 6]. + So we only need 1 patch. + + Example 2: + nums = [1, 5, 10], n = 20 + Return 2. + The two patches can be [2, 4]. + + Example 3: + nums = [1, 2, 2], n = 5 + Return 0. + + [1, 2, 5, 13, 24] + + miss: 表示[0,n]之间最小的不能表示的值 + num <= miss => [0, miss+num) + + nums = [1, 2, 5, 13, 24], n = 50 + + miss = 1 + + 1 + 2 + 4 + 5 = 12 + + 1 : miss = 2 + 2 : miss = 4 + 5 : miss = 8 res = 1 + 5 : miss = 13 + 13 : miss = 26 + 24 : miss = 50 res = 2 + + time : O(n) + space : O(1) + + * @param nums + * @param n + * @return + */ + + public int minPatches(int[] nums, int n) { + int i = 0, res = 0; + long miss = 1; + while (miss <= n) { + if (i < nums.length && nums[i] <= miss) { + miss += nums[i++]; + } else { + miss += miss; + res++; + } + } + return res; + } +} diff --git a/PathSum.java b/PathSum.java new file mode 100644 index 0000000..ebcb334 --- /dev/null +++ b/PathSum.java @@ -0,0 +1,60 @@ +package leetcode; + +import java.util.Stack; + +/** + * Created by Edward on 27/07/2017. + */ +public class PathSum { + /** + * 112. Path Sum + * Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. + + For example: + Given the below binary tree and sum = 22, + 5 + / \ + 4 8 + / / \ + 11 13 4 + / \ \ + 7 2 1 + return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22. + + time : O(n); + space : O(n); + * @param root + * @param sum + * @return + */ + public static boolean hasPathSum(TreeNode root, int sum) { + if (root == null) return false; + if (root.left == null && root.right == null) { + return sum == root.val; + } + return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val); + } + + public static boolean hasPathSum2(TreeNode root, int sum) { + if (root == null) return false; + Stack stack = new Stack<>(); + stack.push(root); + while (!stack.isEmpty()) { + TreeNode cur = stack.pop(); + if (cur.left == null && cur.right == null) { + if (cur.val == sum) { + return true; + } + } + if (cur.right != null) { + stack.push(cur.right); + cur.right.val += cur.val; + } + if (cur.left != null) { + stack.push(cur.left); + cur.left.val += cur.val; + } + } + return false; + } +} diff --git a/PathSumII.java b/PathSumII.java new file mode 100644 index 0000000..4df258a --- /dev/null +++ b/PathSumII.java @@ -0,0 +1,51 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Edward on 28/07/2017. + */ +public class PathSumII { + /** + * 113. Path Sum II + * Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum. + + For example: + Given the below binary tree and sum = 22, + 5 + / \ + 4 8 + / / \ + 11 13 4 + / \ / \ + 7 2 5 1 + [ + [5,4,11,2], + [5,8,4,5] + ] + time : O(n); + space : O(n); + * @param root + * @param sum + * @return + */ + public static List> pathSum(TreeNode root, int sum) { + List> res = new ArrayList<>(); + if (root == null) return res; + helper(res, new ArrayList<>(), root, sum); + return res; + } + public static void helper(List> res, List list, TreeNode root, int sum) { + if (root == null) return; + list.add(root.val); + if (root.left == null && root.right == null) { + if (sum == root.val) { + res.add(new ArrayList<>(list)); + } + } + helper(res, list, root.left, sum - root.val); + helper(res, list, root.right, sum - root.val); + list.remove(list.size() - 1); + } +} diff --git a/PathSumIII.java b/PathSumIII.java new file mode 100644 index 0000000..2e4ac5c --- /dev/null +++ b/PathSumIII.java @@ -0,0 +1,84 @@ +package leetcode; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PathSumIII + * Creator : Edward + * Date : Jan, 2018 + * Description : 437. Path Sum III + */ +public class PathSumIII { + /** + * You are given a binary tree in which each node contains an integer value. + + Find the number of paths that sum to a given value. + + The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes). + + The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000. + + Example: + + root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8 + + 10 + / \ + 5 -3 + / \ \ + 3 2 11 + / \ \ + 3 -2 1 + + Return 3. The paths that sum to 8 are: + + 1. 5 -> 3 + 2. 5 -> 2 -> 1 + 3. -3 -> 11 + + 1, DFS + 2, DFS + Memoization : HashMap + + 10 + -3 + 11 = 18 -3 + 11 = 8 + (10,1) (7,1) 18 - 8 = 10 (a,b,c) = x (d,e) = 8 x = curSum - 8 + + * @param root + * @param sum + * @return + */ + + // time : O(n ^ 2) space : O(n) + public int pathSum(TreeNode root, int sum) { + if (root == null) return 0; + return helper(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum); + } + + private int helper(TreeNode root, int sum) { + int res = 0; + if (root == null) return res; + if (sum == root.val) res++; + res += helper(root.left, sum - root.val) + helper(root.right, sum - root.val); + return res; + } + + // time : O(n) space : O(n) + public int pathSum2(TreeNode root, int sum) { + HashMap map = new HashMap<>(); + map.put(0, 1); + return helper(root, 0, sum, map); + } + + private int helper(TreeNode root, int curSum, int sum, HashMap map) { + if (root == null) return 0; + curSum += root.val; + int res = map.getOrDefault(curSum - sum, 0); + map.put(curSum, map.getOrDefault(curSum, 0) + 1); + + res += helper(root.left, curSum, sum, map) + helper(root.right, curSum, sum, map); + map.put(curSum, map.get(curSum) - 1); + return res; + } +} diff --git a/PeekingIterator.java b/PeekingIterator.java new file mode 100644 index 0000000..051e079 --- /dev/null +++ b/PeekingIterator.java @@ -0,0 +1,55 @@ +package leetcode; + +import java.util.Iterator; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PeekingIterator + * Creator : Edward + * Date : Dec, 2017 + * Description : 284. Peeking Iterator + */ +public class PeekingIterator { + /** + Here is an example. Assume that the iterator is initialized to the beginning of the list: [1, 2, 3]. + + Call next() gets you 1, the first element in the list. + + Now you call peek() and it returns 2, the next element. Calling next() after that still return 2. + + You call next() the final time and it returns 3, the last element. Calling hasNext() after that should return false. + + + * @param iterator + */ + + private Iterator iter; + private Integer next = null; + + public PeekingIterator(Iterator iterator) { + iter = iterator; + if (iter.hasNext()) { + next = iter.next(); + } + } + + // Returns the next element in the iteration without advancing the iterator. + public Integer peek() { + return next; + } + + // hasNext() and next() should behave the same as in the Iterator interface. + // Override them if needed. + //@Override + public Integer next() { + Integer res = next; + next = iter.hasNext() ? iter.next() : null; + return res; + } + + //@Override + public boolean hasNext() { + return next != null; + } +} diff --git a/PerfectRectangle.java b/PerfectRectangle.java new file mode 100644 index 0000000..6808967 --- /dev/null +++ b/PerfectRectangle.java @@ -0,0 +1,55 @@ +package leetcode; + +import java.util.HashSet; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PerfectRectangle + * Creator : Edward + * Date : Jan, 2018 + * Description : 391. Perfect Rectangle + */ +public class PerfectRectangle { + /** + * time : O(n) + * space : O(n) + * @param rectangles + * @return + */ + public boolean isRectangleCover(int[][] rectangles) { + if (rectangles.length == 0 || rectangles[0].length == 0) return false; + + int x1 = Integer.MAX_VALUE; + int x2 = Integer.MIN_VALUE; + int y1 = Integer.MAX_VALUE; + int y2 = Integer.MIN_VALUE; + + HashSet set = new HashSet<>(); + int area = 0; + + for (int[] rect : rectangles) { + x1 = Math.min(rect[0], x1); + y1 = Math.min(rect[1], y1); + x2 = Math.max(rect[2], x2); + y2 = Math.max(rect[3], y2); + + area += (rect[2] - rect[0]) * (rect[3] - rect[1]); + + String s1 = rect[0] + " " + rect[1]; + String s2 = rect[0] + " " + rect[3]; + String s3 = rect[2] + " " + rect[3]; + String s4 = rect[2] + " " + rect[1]; + + if (!set.add(s1)) set.remove(s1); + if (!set.add(s2)) set.remove(s2); + if (!set.add(s3)) set.remove(s3); + if (!set.add(s4)) set.remove(s4); + } + if (!set.contains(x1 + " " + y1) || !set.contains(x1 + " " + y2) + || !set.contains(x2 + " " + y1) || !set.contains(x2 + " " + y2) || set.size() != 4) { + return false; + } + return area == (x2 - x1) * (y2 - y1); + } +} diff --git a/PerfectSquares.java b/PerfectSquares.java new file mode 100644 index 0000000..f53f86c --- /dev/null +++ b/PerfectSquares.java @@ -0,0 +1,39 @@ +package leetcode; + +import java.util.Arrays; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PerfectSquares + * Creator : Edward + * Date : Dec, 2017 + * Description : 279. Perfect Squares + */ +public class PerfectSquares { + + /** + * Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) + * which sum to n. + + For example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13, return 2 because 13 = 4 + 9. + + time : O(n * sqrt(n)) + space: O(n) + + * @param n + * @return + */ + + public int numSquares(int n) { + int[] res = new int[n + 1]; + Arrays.fill(res, Integer.MAX_VALUE); + res[0] = 0; + for (int i = 0; i <= n; i++) { + for (int j = 1; j * j <= i; j++) { + res[i] = Math.min(res[i], res[i - j * j] + 1); + } + } + return res[n]; + } +} diff --git a/PermutationSequence.java b/PermutationSequence.java new file mode 100644 index 0000000..2ba3c3d --- /dev/null +++ b/PermutationSequence.java @@ -0,0 +1,79 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PermutationSequence + * Creator : Edward + * Date : Nov, 2017 + * Description : 60. Permutation Sequence + */ +public class PermutationSequence { + /** + * The set [1,2,3,…,n] contains a total of n! unique permutations. + + By listing and labeling all of the permutations in order, + We get the following sequence (ie, for n = 3): + + "123" + "132" + "213" + "231" + "312" + "321" + Given n and k, return the kth permutation sequence. + + Note: Given n will be between 1 and 9 inclusive. + + 1, 2, 3, 4: + + 1 + {2, 3, 4} + 2 + {1, 3, 4} + 3 + {1, 2, 4} + 4 + {1, 2, 3} + + 18 : 3421 + + res : + fact : 1 1 2 6 + + k = 17 + + i = 4 index = 17 / 6 = 2 k = 17 % 6 = 5 + i = 3 index = 5 / 2 = 2 k = 5 % 2 = 1 + i = 2 index = 1 / 1 = 1 k = 1 % 1 = 0 + + 4 3 2 1 + 3 4 2 1 + + time : O(n) + space : O(n) + + * @param n + * @param k + * @return + */ + public static String getPermutation(int n, int k) { + List res = new ArrayList<>(); + for (int i = 1; i <= n; i++) { + res.add(i); + } + int[] fact = new int[n]; + fact[0] = 1; + for (int i = 1; i < n; i++) { + fact[i] = i * fact[i - 1]; + } + k = k - 1; + StringBuilder sb = new StringBuilder(); + for (int i = n; i > 0; i--) { + int index = k / fact[i - 1]; + k = k % fact[i - 1]; + sb.append(res.get(index)); + res.remove(index); + } + return sb.toString(); + } +} diff --git a/Permutations.java b/Permutations.java new file mode 100644 index 0000000..5dda976 --- /dev/null +++ b/Permutations.java @@ -0,0 +1,81 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +public class Permutations { + /** + * 46. Permutations + * Given a collection of distinct numbers, return all possible permutations. + + For example, + [1,2,3] have the following permutations: + [ + [1,2,3], + [1,3,2], + [2,1,3], + [2,3,1], + [3,1,2], + [3,2,1] + ] + + time : O(n!) + space : O(n); + + reference : http://www.1point3acres.com/bbs/thread-117602-1-1.html + + The number of recursive calls, T(n) satisfies the recurrence T(n) = T(n - 1) + T(n - 2) + ... + T(1) + T(0), + which solves to T(n) = O(2^n). Since we spend O(n) time within a call, the time complexity is O(n2^n); + + * @param nums + * @return + */ + // time : O(n! * n) space : O(n); + public static List> permute(int[] nums) { + List> res = new ArrayList<>(); + if (nums == null || nums.length == 0) return res; + helper(res, new ArrayList<>(), nums); + return res; + } + + public static void helper(List> res, List list, int[] nums) { + if (list.size() == nums.length) { + res.add(new ArrayList<>(list)); + return; + } + for (int i = 0; i < nums.length; i++) { + if (list.contains(nums[i])) continue; // O(n) + list.add(nums[i]); + helper(res, list, nums); + list.remove(list.size() - 1); + } + } + + // time : O(n!) space : O(n); + public static List> permute2(int[] nums) { + List> res = new ArrayList<>(); + if (nums == null || nums.length == 0) return res; + helper2(res, 0, nums); + return res; + } + public static void helper2(List> res, int start, int[] nums) { + if (start == nums.length) { + List list = new ArrayList<>(); + for (int num : nums) { + list.add(num); + } + res.add(new ArrayList<>(list)); + return; + } + for (int i = start; i < nums.length; i++) { + swap(nums, start, i); + helper2(res, start + 1, nums); + swap(nums, start, i); + } + } + public static void swap(int[] nums, int l, int r) { + int temp = nums[l]; + nums[l] = nums[r]; + nums[r] = temp; + } +} diff --git a/PermutationsII.java b/PermutationsII.java new file mode 100644 index 0000000..bc71e7e --- /dev/null +++ b/PermutationsII.java @@ -0,0 +1,91 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PermutationsII + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class PermutationsII { + /** + * 47. Permutations II + * For example, + [1,1,2] have the following unique permutations: + [ + [1,1,2], + [1,2,1], + [2,1,1] + ] + + + * @param nums + * @return + */ + // time : O(n!) space : O(n); + public List> permuteUnique(int[] nums) { + List> res = new ArrayList<>(); + if (nums == null || nums.length == 0) return res; + Arrays.sort(nums); + helper(res, new ArrayList<>(), nums, new boolean[nums.length]); + return res; + } + + public void helper(List> res, List list, int[] nums, boolean[] used) { + if (list.size() == nums.length) { + res.add(new ArrayList<>(list)); + } + for (int i = 0; i < nums.length; i++) { + if (used[i] || i > 0 && nums[i] == nums[i - 1] && !used[i - 1]) continue; + used[i] = true; + list.add(nums[i]); + helper(res, list, nums, used); + used[i] = false; + list.remove(list.size() - 1); + } + } + + // time : O(n!) space : O(n); + public List> permuteUnique2(int[] nums) { + List> res = new ArrayList<>(); + if (nums == null || nums.length == 0) return res; + Arrays.sort(nums); + helper2(res, nums, 0); + return res; + } + public void helper2(List> res, int[] nums, int start) { + if (start == nums.length) { + List list = new ArrayList<>(); + for (int num : nums) { + list.add(num); + } + res.add(list); + return; + } + + for (int i = start; i < nums.length; i++) { + if (isUsed(nums,start, i)) continue; + swap(nums, start, i); + helper2(res, nums, start + 1); + swap(nums, start, i); + } + } + + public void swap(int[] nums, int i, int j) { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } + + public boolean isUsed(int[] nums, int i, int j) { + for (int x = i; x < j; x++) { + if (nums[x] == nums[j]) return true; + } + return false; + } +} diff --git a/PlusOne.java b/PlusOne.java new file mode 100644 index 0000000..2fefb9e --- /dev/null +++ b/PlusOne.java @@ -0,0 +1,41 @@ +package leetcode; + +/** + * Created by Edward on 24/07/2017. + */ +public class PlusOne { + /** + * 66. Plus One + * Given a non-negative integer represented as a non-empty array of digits, plus one to the integer. + + You may assume the integer do not contain any leading zero, except the number 0 itself. + + The digits are stored such that the most significant digit is at the head of the list. + + case1 : 1011 1012 + case2 : 1099 1100 + case3 : 9999 10000 + + time : O(n); + space : O(n); + * @param digits + * @return + */ + public static int[] plusOne(int[] digits) { + + if (digits == null || digits.length == 0) return digits; + + for (int i = digits.length - 1; i >= 0; i--) { + if (digits[i] < 9) { + digits[i]++; + return digits; + } else { + digits[i] = 0; + } + } + int[] res = new int[digits.length + 1]; + res[0] = 1; + + return res; + } +} diff --git a/PlusOneLinkedList.java b/PlusOneLinkedList.java new file mode 100644 index 0000000..a0517cf --- /dev/null +++ b/PlusOneLinkedList.java @@ -0,0 +1,87 @@ +package leetcode; + +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PlusOneLinkedList + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class PlusOneLinkedList { + /** + * 369. Plus One Linked List + * Input: + 1->2->3 + + Output: + 1->2->4 + + time : O(n) + space : O(1) + * @param head + * @return + */ + + public ListNode plusOne(ListNode head) { + ListNode dummy = new ListNode(0); + dummy.next = head; + ListNode i = dummy; + ListNode j = dummy; + + while (j.next != null) { + j = j.next; + if (j.val != 9) i = j; + } + i.val++; + i = i.next; + while (i != null) { + i.val = 0; + i = i.next; + } + if (dummy.val == 0) return dummy.next; + return dummy; + } + + /** + + 1 -> 0 -> 0 -> 0 + + * @param head + * @return + */ + public ListNode plusOne2(ListNode head) { + head = reverse(head); + ListNode dummy = new ListNode(0); + dummy.next = head; + ListNode cur = dummy; + int carry = 1; + while (carry > 0 || cur.next != null) { + if (cur.next != null) { + cur = cur.next; + carry += cur.val; + cur.val = carry % 10; + carry /= 10; + } else { + cur.next = new ListNode(carry); + cur = cur.next; + carry = 0; + } + } + return reverse(dummy.next); + } + + public ListNode reverse(ListNode head) { + ListNode prev = null; + while (head != null) { + ListNode temp = head.next; + head.next = prev; + prev = head; + head = temp; + } + return prev; + } + +} diff --git a/Point.java b/Point.java new file mode 100644 index 0000000..0f44a68 --- /dev/null +++ b/Point.java @@ -0,0 +1,22 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : Point + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class Point { + int x; + int y; + Point() { + x = 0; + y = 0; + } + Point(int a, int b) { + x = a; + y = b; + } +} diff --git a/PopulatingNextRightPointersinEachNode.java b/PopulatingNextRightPointersinEachNode.java new file mode 100644 index 0000000..62e7b7e --- /dev/null +++ b/PopulatingNextRightPointersinEachNode.java @@ -0,0 +1,61 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PopulatingNextRightPointersinEachNode + * Creator : Edward + * Date : Oct, 2017 + * Description : 116. Populating Next Right Pointers in Each Node + */ +public class PopulatingNextRightPointersinEachNode { + /** + * For example, + Given the following perfect binary tree, + 1 + / \ + 2 3 + / \ / \ + 4 5 6 7 + After calling your function, the tree should look like: + 1 -> NULL + / \ + 2 -> 3 -> NULL + / \ / \ + 4->5->6->7 -> NULL + + time : O(n); + space : O(n); + + * @param root + */ + public void connect(TreeLinkNode root) { + if (root == null) return; + if (root.left != null) { + root.left.next = root.right; + } + if (root.next != null && root.right != null) { + root.right.next = root.next.left; + } + connect(root.left); + connect(root.right); + } + + //space : O(1) + public void connect2(TreeLinkNode root) { + TreeLinkNode start = root; + while (start != null) { + TreeLinkNode cur = start; + while (cur != null) { + if (cur.left != null) { + cur.left.next = cur.right; + } + if (cur.right != null && cur.next != null) { + cur.right.next = cur.next.left; + } + cur = cur.next; + } + start = start.left; + } + } +} diff --git a/PopulatingNextRightPointersinEachNodeII.java b/PopulatingNextRightPointersinEachNodeII.java new file mode 100644 index 0000000..27d95b7 --- /dev/null +++ b/PopulatingNextRightPointersinEachNodeII.java @@ -0,0 +1,57 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PopulatingNextRightPointersinEachNodeII + * Creator : Edward + * Date : Oct, 2017 + * Description : 117. Populating Next Right Pointers in Each Node II + */ +public class PopulatingNextRightPointersinEachNodeII { + /** + * For example, + Given the following binary tree, + 1 + / \ + 2 3 + / \ \ + 4 5 7 + After calling your function, the tree should look like: + 1 -> NULL + / \ + 2 -> 3 -> NULL + / \ \ + 4-> 5 -> 7 -> NULL + + time : O(n); + space : O(1); + + * @param root + */ + public void connect(TreeLinkNode root) { + TreeLinkNode head = null; + TreeLinkNode pre = null; + TreeLinkNode cur = null; + while (cur != null) { + while (cur != null) { + if (cur.left != null) { + if (pre != null) { + pre.next = cur.left; + } else head = cur.left; + pre = cur.left; + } + if (cur.right != null) { + if (pre != null) { + pre.next = cur.right; + } else head = cur.right; + pre = cur.right; + } + cur = cur.next; + } + cur = head; + pre = null; + head = null; + } + } +} diff --git a/Pow.java b/Pow.java new file mode 100644 index 0000000..e70e1d9 --- /dev/null +++ b/Pow.java @@ -0,0 +1,59 @@ +package leetcode; + +/** + * Created by Edward on 27/07/2017. + */ +public class Pow { + /** + * 50. Pow(x, n) + * Implement pow(x, n). + + + eg. 2^2 = 2^1 * 2^1 = (2^0 * 2^0 * 2) * (2^0 * 2^0 * 2) = (1 * 1 * 2) * (1 * 1 * 2) = 4 + + eg. 2^3 = 2^1 * 2^1 * 2 = (2^0 * 2^0 * 2) * (2^0 * 2^0 * 2) * 2 = (1 * 1 * 2) * (1 * 1 * 2) * 2 = 8 + + time : O(logn); + space : O(n)/O(1) + + * @param x + * @param n + * @return + */ + public static double myPow1(double x, int n) { + if (n > 0) { + return pow(x, n); + } else { + return 1.0 / pow(x, n); + } + } + public static double pow (double x, int n) { + if (n == 0) { + return 1; + } + double y = pow(x, n / 2); + if (n % 2 == 0) { + return y * y; + } else { + return y * y * x; + } + } + + public static double myPow2(double x, int n) { + if (n == 0) return 1; + double res = 1; + // int : -6.. ~ +6.. -2^32 ~ 2 ^32-1 Integer.MIN_VALUE + long abs = Math.abs((long)n); + while (abs > 0) { + if (abs % 2 != 0) { + res *= x; + } + x *= x; + abs /= 2; + } + if (n < 0) { + return 1.0 / res; + } + return res; + } +} diff --git a/PowerofFour.java b/PowerofFour.java new file mode 100644 index 0000000..0061fd5 --- /dev/null +++ b/PowerofFour.java @@ -0,0 +1,40 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : PowerofFour + * Creator : Edward + * Date : Jan, 2018 + * Description : 342. Power of Four + */ +public class PowerofFour { + + /** + * Given an integer (signed 32 bits), write a function to check whether it is a power of 4. + + Example: + Given num = 16, return true. Given num = 5, return false. + + Follow up: Could you solve it without loops/recursion? + + + * @param n + * @return + */ + + // time : < O(n) + public boolean isPowerOfFour(int n) { + if (n > 1) { + while (n % 4 == 0) { + n /= 4; + } + } + return n == 1; + } + + // time : O(1) + public boolean isPowerOfFour2(int num) { + return (Math.log(num) / Math.log(4)) % 1 == 0; + } +} diff --git a/PowerofThree.java b/PowerofThree.java new file mode 100644 index 0000000..e67fb62 --- /dev/null +++ b/PowerofThree.java @@ -0,0 +1,37 @@ +package leetcode; + +import sun.nio.cs.ext.MacHebrew; + +/** + * Created by Edward on 28/07/2017. + */ +public class PowerofThree { + /** + * 326. Power of Three + * Given an integer, write a function to determine if it is a power of three. + + Follow up: + Could you do it without using any loop / recursion? + + space : O(1); + + * @param n + * @return + */ + + // time : O(n); + + public static boolean isPowerOfThree(int n) { + if (n <= 0) return false; + while (n % 3 == 0) { + n /= 3; + } + return n == 1; + } + + // time : O(1); + + public static boolean isPowerOfThree2(int n) { + return (Math.log10(n) / Math.log10(3)) % 1 == 0; + } +} diff --git a/PowerofTwo.java b/PowerofTwo.java new file mode 100644 index 0000000..0f8b5e5 --- /dev/null +++ b/PowerofTwo.java @@ -0,0 +1,31 @@ +package leetcode; + +/** + * Created by Edward on 25/07/2017. + */ +public class PowerofTwo { + /** + * 231. Power of Two + * Given an integer, write a function to determine if it is a power of two. + * + * + * 2, 4, 8, 16... + * + * 2 : 10 + * 4 : 100 + * 8 : 1000 + * 16: 10000 + * + * + * n : 16 : 10001 + * n - 1 : 10000 + * + * time : O(1); + * space : O(1); + * @param n + * @return + */ + public static boolean isPowerOfTwo(int n) { + return n > 0 && ((n & (n - 1)) == 0); + } +} diff --git a/ProductofArrayExceptSelf.java b/ProductofArrayExceptSelf.java new file mode 100644 index 0000000..4de304f --- /dev/null +++ b/ProductofArrayExceptSelf.java @@ -0,0 +1,35 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ProductofArrayExceptSelf + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class ProductofArrayExceptSelf { + /** + * 238. Product of Array Except Self + * For example, given [1,2,3,4], return [24,12,8,6]. + + time : O(n); + space : O(n); + * @param nums + * @return + */ + public int[] productExceptSelf(int[] nums) { + if (nums == null || nums.length == 0) return nums; + int[] res = new int[nums.length]; + res[0] = 1; + for (int i = 1; i < nums.length; i++) { + res[i] = res[i - 1] * nums[i - 1]; + } + int right = 1; + for (int i = nums.length - 1; i >= 0; i--) { + res[i] *= right; + right *= nums[i]; + } + return res; + } +} diff --git a/QueueReconstructionbyHeight.java b/QueueReconstructionbyHeight.java new file mode 100644 index 0000000..145029d --- /dev/null +++ b/QueueReconstructionbyHeight.java @@ -0,0 +1,28 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : QueueReconstructionbyHeight + * Creator : Edward + * Date : Jan, 2018 + * Description : 406. Queue Reconstruction by Height + */ +public class QueueReconstructionbyHeight { + public int[][] reconstructQueue(int[][] people) { + if (people == null || people.length == 0 || people[0].length == 0) { + return new int[0][0]; + } + List res = new ArrayList<>(); + Arrays.sort(people, (a, b) -> (a[0] == b[0] ? a[1] - b[1] : b[0] - a[0])); + for(int[] cur : people){ + res.add(cur[1],cur); + } + + return res.toArray(new int[people.length][]); + } +} diff --git a/RandomPickIndex.java b/RandomPickIndex.java new file mode 100644 index 0000000..b0bbd9e --- /dev/null +++ b/RandomPickIndex.java @@ -0,0 +1,56 @@ +package leetcode; + +import java.util.Random; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RandomPickIndex + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class RandomPickIndex { + /** + * 398. Random Pick Index + * Given an array of integers with possible duplicates, randomly output the index of a given target + * number. You can assume that the given target number must exist in the array. + + Note: + The array size can be very large. Solution that uses too much extra space will not pass the judge. + + Example: + + int[] nums = new int[] {1,2,3,3,3}; + Solution solution = new Solution(nums); + + // pick(3) should return either index 2, 3, or 4 randomly. Each index should have equal probability of returning. + solution.pick(3); + + // pick(1) should return 0. Since in the array only nums[0] is equal to 1. + solution.pick(1); + + time : O(n); + * @param nums + */ + + private int[] nums; + Random rmd; + + public RandomPickIndex(int[] nums) { + this.nums = nums; + rmd = new Random(); + } + + public int pick(int target) { + int res = -1; + int count = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i] != target) continue; + if (rmd.nextInt(++count) == 0) { + res = i; + } + } + return res; + } +} diff --git a/RangeAddition.java b/RangeAddition.java new file mode 100644 index 0000000..e2faa66 --- /dev/null +++ b/RangeAddition.java @@ -0,0 +1,71 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RangeAddition + * Creator : Edward + * Date : Oct, 2017 + * Description : 370. Range Addition + */ +public class RangeAddition { + /** + * Assume you have an array of length n initialized with all 0's and are given k update operations. + + Each operation is represented as a triplet: [startIndex, endIndex, inc] + which increments each element of subarray A[startIndex ... endIndex] (startIndex and endIndex inclusive) with inc. + + Return the modified array after all k operations were executed. + * Example: + + Given: + + length = 5, + updates = [ + [1, 3, 2], + [2, 4, 3], + [0, 2, -2] + ] + + Output: + + [-2, 0, 3, 5, 3] + Explanation: + + Initial state: + [ 0, 0, 0, 0, 0 ] + + After applying operation [1, 3, 2]: + [ 0, 2, 2, 2, 0 ] + + After applying operation [2, 4, 3]: + [ 0, 2, 5, 5, 3 ] + + After applying operation [0, 2, -2]: + [-2, 0, 3, 5, 3 ] + + time : O(K + N); + space : O(n) + + + * @param length + * @param updates + * @return + */ + public int[] getModifiedArray(int length, int[][] updates) { + int[] res = new int[length]; + for (int[] update : updates) { + int value = update[2]; + int start = update[0]; + int end = update[1]; + res[start] += value; + if (end + 1 < length) { + res[end + 1] -= value; + } + } + for (int i = 1; i < length; i++) { + res[i] += res[i - 1]; + } + return res; + } +} diff --git a/RangeSumQuery2DImmutable.java b/RangeSumQuery2DImmutable.java new file mode 100644 index 0000000..64a5b25 --- /dev/null +++ b/RangeSumQuery2DImmutable.java @@ -0,0 +1,58 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RangeSumQuery2DImmutable + * Creator : Edward + * Date : Nov, 2017 + * Description : 304. Range Sum Query 2D - Immutable + */ +public class RangeSumQuery2DImmutable { + /** + * Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper left corner (row1, col1) and lower right corner (row2, col2). + + Range Sum Query 2D + The above rectangle (with the red border) is defined by (row1, col1) = (2, 1) and (row2, col2) = (4, 3), which contains sum = 8. + + Example: + Given matrix = [ + [3, 0, 1, 4, 2], + [5, 6, 3, 2, 1], + [1, 2, 0, 1, 5], + [4, 1, 0, 1, 7], + [1, 0, 3, 0, 5] + ] + + sumRegion(2, 1, 4, 3) -> 8 + sumRegion(1, 1, 2, 2) -> 11 + sumRegion(1, 2, 2, 4) -> 12 + + time : O(m * n) + space : O(m * n) + + */ + + private int[][] sum; + + public RangeSumQuery2DImmutable(int[][] matrix) { + if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return; + int m = matrix.length; + int n = matrix[0].length; + sum = new int[m + 1][n + 1]; + for (int i = 1; i <= m; i++) { + for (int j = 1; j <= n; j++) { + sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + matrix[i - 1][j - 1]; + } + } + + } + + public int sumRegion(int row1, int col1, int row2, int col2) { + int iMin = Math.min(row1, row2); + int iMax = Math.max(row1, row2); + int jMin = Math.min(col1, col2); + int jMax = Math.max(col1, col2); + return sum[iMax + 1][jMax + 1] - sum[iMax + 1][jMin] - sum[iMin][jMax + 1] + sum[iMin][jMin]; + } +} diff --git a/RangeSumQuery2DMutable.java b/RangeSumQuery2DMutable.java new file mode 100644 index 0000000..0d1769e --- /dev/null +++ b/RangeSumQuery2DMutable.java @@ -0,0 +1,60 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RangeSumQuery2DMutable + * Creator : Edward + * Date : Jan, 2018 + * Description : 308. Range Sum Query 2D - Mutable + */ +public class RangeSumQuery2DMutable { + + int[][] tree; + int[][] nums; + int m; + int n; + + // time : O(m * logm * n * logn) + public RangeSumQuery2DMutable(int[][] matrix) { + if (matrix.length == 0 || matrix[0].length == 0) return; + m = matrix.length; + n = matrix[0].length; + tree = new int[m + 1][n + 1]; + nums = new int[m][n]; + for (int i = 0; i < m; i ++) { + for (int j = 0; j < n; j++) { + update(i, j, matrix[i][j]); + } + } + } + + // time : O(logm * logn) + public void update(int row, int col, int val) { + if (m == 0 || n == 0) return; + int diff = val - nums[row][col]; + nums[row][col] = val; + for (int i = row + 1; i <= m; i += i & (-i)) { + for (int j = col + 1; j <= n; j += j & (-j)) { + tree[i][j] += diff; + } + } + } + + // time : O(logm * logn) + public int sumRegion(int row1, int col1, int row2, int col2) { + if (m == 0 || n == 0) return 0; + return sum(row2 + 1, col2 + 1) + sum(row1, col1) + - sum(row1, col2 + 1) - sum(row2 + 1, col1); + } + + private int sum(int row, int col) { + int sum = 0; + for (int i = row; i > 0; i -= i & (-i)) { + for (int j = col; j > 0; j -= j & (-j)) { + sum += tree[i][j]; + } + } + return sum; + } +} diff --git a/RangeSumQueryImmutable.java b/RangeSumQueryImmutable.java new file mode 100644 index 0000000..5e01f96 --- /dev/null +++ b/RangeSumQueryImmutable.java @@ -0,0 +1,47 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RangeSumQueryImmutable + * Creator : Edward + * Date : Nov, 2017 + * Description : 303. Range Sum Query - Immutable + */ +public class RangeSumQueryImmutable { + /** + * Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive. + + Example: + Given nums = [-2, 0, 3, -5, 2, -1] + + sumRange(0, 2) -> 1 + sumRange(2, 5) -> -1 + sumRange(0, 5) -> -3 + Note: + You may assume that the array does not change. + There are many calls to sumRange function. + + [-2, 0, 3, -5, 2, -1] + + time : O(n) + space : O(n) + + + + */ + + private int[] sum; + + public RangeSumQueryImmutable(int[] nums) { + sum = new int[nums.length + 1]; + for (int i = 0; i < nums.length; i++) { + sum[i + 1] = sum[i] + nums[i]; + } + } + + public int sumRange(int i, int j) { + return sum[j + 1] - sum[i]; + } + +} diff --git a/RangeSumQueryMutable.java b/RangeSumQueryMutable.java new file mode 100644 index 0000000..c398e55 --- /dev/null +++ b/RangeSumQueryMutable.java @@ -0,0 +1,94 @@ +package leetcode; + +import java.util.Arrays; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RangeSumQueryMutable + * Creator : Edward + * Date : Jan, 2018 + * Description : 307. Range Sum Query - Mutable + */ +public class RangeSumQueryMutable { + + int[] nums; + int[] tree; + int n; + + // time : O(n * logn) + public RangeSumQueryMutable(int[] nums) { + n = nums.length; + tree = new int[n + 1]; + this.nums = new int[n]; + for (int i = 0; i < n; i++) { + update(i, nums[i]); + } + } + + // time : O(logn) + public void update(int i, int val) { + if (n == 0) return; + int diff = val - nums[i]; + nums[i] = val; + for (int j = i + 1; j <= n; j += j & (-j)) { + tree[j] += diff; + } + } + + // time : O(logn) + public int sumRange(int i, int j) { + return sum(j + 1) - sum(i); + } + + private int sum(int k) { + int sum = 0; + for (int i = k; i > 0; i -= i & (-i)) { + sum += tree[i]; + } + return sum; + } + + /** + * 解法2 + */ + //private int[] tree; + //private int[] nums; + + public void NumArray(int[] nums) { + this.nums = nums; + int sum; + int lowbit; + tree = new int[nums.length + 1]; + for (int i = 1; i < tree.length; i++) { + sum = 0; + lowbit = i & (-i); + for (int j = i; j > i - lowbit; j--) { + sum = sum + nums[j - 1]; + } + tree[i] = sum; + } + } + + public void update2(int i, int val) { + int diff = val - nums[i]; + nums[i] = val; + i++; + for (; i < tree.length; i += (i & (-i))) { + tree[i] += diff; + } + } + + public int sumRange2(int i, int j) { + return sum2(j + 1) - sum2(i); + } + + private int sum2(int k) { + int sum = 0; + for (int i = k; i > 0; i -= i & (-i)) { + sum += tree[i]; + } + return sum; + } + +} diff --git a/RansomNote.java b/RansomNote.java new file mode 100644 index 0000000..d0f055a --- /dev/null +++ b/RansomNote.java @@ -0,0 +1,38 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RansomNote + * Creator : Edward + * Date : Dec, 2017 + * Description : 383. Ransom Note + */ +public class RansomNote { + /** + * You may assume that both strings contain only lowercase letters. + + canConstruct("a", "b") -> false + canConstruct("aa", "ab") -> false + canConstruct("aa", "aab") -> true + + time : O(n) + space : O(1) + + * @param ransomNote + * @param magazine + * @return + */ + public boolean canConstruct(String ransomNote, String magazine) { + int[] count = new int[26]; + for (int i = 0; i < magazine.length(); i++) { + count[magazine.charAt(i) - 'a']++; + } + for (int i = 0; i < ransomNote.length(); i++) { + if (--count[ransomNote.charAt(i) - 'a'] < 0) { + return false; + } + } + return true; + } +} diff --git a/ReadNCharactersGivenRead4.java b/ReadNCharactersGivenRead4.java new file mode 100644 index 0000000..70466a4 --- /dev/null +++ b/ReadNCharactersGivenRead4.java @@ -0,0 +1,64 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ReadNCharactersGivenRead4 + * Creator : Edward + * Date : Oct, 2017 + * Description : 157. Read N Characters Given Read4 + */ +public class ReadNCharactersGivenRead4 { + /** + * + case : + abcd efgh igk 11 + case 1 : n = 8 first time read 4 next count == 4 index == n + case 2 : n = 7 first time read 4 next count == 3 index == n + + case : + abc 3 + case 1 : n = 4 count = 3 count < 4 + + time : O(n); + space : O(1); + + + * @param buf Destination buffer + * @param n Maximum number of characters to read + * @return The number of characters read + */ + public int read(char[] buf, int n) { + char[] temp = new char[4]; + int index = 0; + while (true) { + int count = read4(temp); + count = Math.min(count, n - index); + for (int i = 0; i < count; i++) { + buf[index++] = temp[i]; + } + if (index == n || count < 4) return index; + } + } + + /** + * abcdefghijk + * char[] temp = new char[4]; temp : ijk 3 + * + * @param temp + * @return + */ + + //辅助函数,正常不是这么写 + public int read4(char[] temp) { + char[] res = new char[10]; + char[] ret = new char[4]; + int index = 0; + for (int i = 0; i < res.length; i++) { + if (index < 4){ + ret[index++] = temp[i]; + } + } + return index; + } +} diff --git a/ReadNCharactersGivenRead4II_Callmultipletimes.java b/ReadNCharactersGivenRead4II_Callmultipletimes.java new file mode 100644 index 0000000..731e257 --- /dev/null +++ b/ReadNCharactersGivenRead4II_Callmultipletimes.java @@ -0,0 +1,65 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ReadNCharactersGivenRead4II_Callmultipletimes + * Creator : Edward + * Date : Oct, 2017 + * Description : 158. Read N Characters Given Read4 II - Call multiple times + */ +public class ReadNCharactersGivenRead4II_Callmultipletimes { + /** + * + case : + abcd efgh igk 11 + case 1 : n = 8 first time read 4 next count == 4 index == n + case 2 : n = 7 first time read 4 next count == 3 index == n + + abcd efgh igk 11 + n = 2 count = 4 buf[ab] pointer = 2 temp[abcd] + n = 3 index = 3 buf[cd] pointer = 0 + temp[efgh] count = 4 buf[cde] pointer = 1 + + + time : O(n); + space : O(1); + + + * @param buf Destination buffer + * @param n Maximum number of characters to read + * @return The number of characters read + */ + + private int count = 0; + private int pointer = 0; + private char[] temp = new char[4]; + + public int read(char[] buf, int n) { + int index = 0; + while (index < n) { + if (pointer == 0) { + count = read4(temp); + } + if (count == 0) break; + while (index < n && pointer < count) { + buf[index++] = temp[pointer++]; + } + if (pointer == count) pointer = 0; + } + return index; + } + + //辅助函数,正常不是这么写 + public int read4(char[] temp) { + char[] res = new char[10]; + char[] ret = new char[4]; + int index = 0; + for (int i = 0; i < res.length; i++) { + if (index < 4){ + ret[index++] = temp[i]; + } + } + return index; + } +} diff --git a/RearrangeStringkDistanceApart.java b/RearrangeStringkDistanceApart.java new file mode 100644 index 0000000..7f37dad --- /dev/null +++ b/RearrangeStringkDistanceApart.java @@ -0,0 +1,110 @@ +package leetcode; + +import jdk.nashorn.internal.ir.IdentNode; + +import java.util.*; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RearrangeStringkDistanceApart + * Creator : Edward + * Date : Jan, 2018 + * Description : 358. Rearrange String k Distance Apart + */ +public class RearrangeStringkDistanceApart { + + /** + * Given a non-empty string s and an integer k, rearrange the string such that the same characters are at least distance k from each other. + + All input strings are given in lowercase letters. If it is not possible to rearrange the string, return an empty string "". + + Example 1: + s = "aabbcc", k = 3 + + Result: "abcabc" + + The same letters are at least distance 3 from each other. + Example 2: + s = "aaabc", k = 3 + + Answer: "" + + It is not possible to rearrange the string. + Example 3: + s = "aaadbbcc", k = 2 + + Answer: "abacabcd" + + Another possible answer is: "abcabcda" + + The same letters are at least distance 2 from each other. + + + * @param s + * @param k + * @return + */ + + // time : O(n) space : O(n) + public String rearrangeString(String s, int k) { + if (s == null || s.length() == 0) { + return s; + } + int[] count = new int[26]; + int[] valid = new int[26]; + for (char c : s.toCharArray()) { + count[c - 'a']++; + } + StringBuilder res = new StringBuilder(); + for (int i = 0; i < s.length(); i++) { + int nextLetter = findNext(count, valid, i); + if (nextLetter == -1) { + return ""; + } + res.append((char)('a' + nextLetter)); + valid[nextLetter] = i + k; + count[nextLetter]--; + } + return res.toString(); + } + + private int findNext(int[] count, int[] valid, int index) { + int max = 0, res = -1; + for (int i = 0; i < count.length; i++) { + if (count[i] > max && valid[i] <= index) { + res = i; + max = count[i]; + } + } + return res; + } + + // time : O(nlogn) space : O(n) + public String rearrangeString2(String s, int k) { + HashMap map = new HashMap<>(); + for (char c : s.toCharArray()) { + map.put(c, map.getOrDefault(c, 0) + 1); + } + + PriorityQueue> pq = + new PriorityQueue<>((a, b) -> Integer.compare(b.getValue(), a.getValue())); + pq.addAll(map.entrySet()); + + Queue> queue = new LinkedList<>(); + StringBuilder res = new StringBuilder(); + + while (!pq.isEmpty()) { + Map.Entry cur = pq.poll(); + res.append(cur.getKey()); + cur.setValue(cur.getValue() - 1); + queue.offer(cur); + if (queue.size() < k) continue; + Map.Entry front = queue.poll(); + if (front.getValue() > 0) { + pq.offer(front); + } + } + return res.length() == s.length() ? res.toString() : ""; + } +} diff --git a/ReconstructItinerary.java b/ReconstructItinerary.java new file mode 100644 index 0000000..85dd9ff --- /dev/null +++ b/ReconstructItinerary.java @@ -0,0 +1,91 @@ +package leetcode; + +import java.util.*; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ReconstructItinerary + * Creator : Edward + * Date : Nov, 2017 + * Description : 332. Reconstruct Itinerary + */ +public class ReconstructItinerary { + + /** + * Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], + * reconstruct the itinerary in order. All of the tickets belong to a man who departs from JFK. + * Thus, the itinerary must begin with JFK. + + Note: + If there are multiple valid itineraries, you should return the itinerary that + has the smallest lexical order when read as a single string. For example, + the itinerary ["JFK", "LGA"] has a smaller lexical order than ["JFK", "LGB"]. + All airports are represented by three capital letters (IATA code). + You may assume all tickets form at least one valid itinerary. + + Example 1: + tickets = [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]] + Return ["JFK", "MUC", "LHR", "SFO", "SJC"]. + + Example 2: + tickets = [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]] + Return ["JFK","ATL","JFK","SFO","ATL","SFO"]. + + Another possible reconstruction is ["JFK","SFO","ATL","JFK","ATL","SFO"]. + But it is larger in lexical order. + + + DFS(HashMap) + PriorityQueue + + JFK SFO + | + ATL + + + time : O(nlogn) + space : O(n) + + */ + + HashMap> map; + List res; + + public List findItinerary(String[][] tickets) { + map = new HashMap<>(); + res = new LinkedList<>(); + for (String[] ticket : tickets) { + map.computeIfAbsent(ticket[0], k -> new PriorityQueue<>()).add(ticket[1]); + } + helper("JFK"); + return res; + } + + private void helper(String airport) { + while (map.containsKey(airport) && !map.get(airport).isEmpty()) { + helper(map.get(airport).poll()); + } + res.add(0, airport); + } + + public List findItinerary2(String[][] tickets) { + HashMap> map = new HashMap<>(); + + for (String[] ticket : tickets) { + map.computeIfAbsent(ticket[0], k -> new PriorityQueue()).add(ticket[1]); + } + + List res = new LinkedList(); + Stack stack = new Stack<>(); + stack.push("JFK"); + + while (!stack.empty()) { + while (map.containsKey(stack.peek()) && !map.get(stack.peek()).isEmpty()) { + stack.push(map.get(stack.peek()).poll()); + } + res.add(0, stack.pop()); + } + + return res; + } +} diff --git a/ReconstructOriginalDigitsfromEnglish.java b/ReconstructOriginalDigitsfromEnglish.java new file mode 100644 index 0000000..4bec5b6 --- /dev/null +++ b/ReconstructOriginalDigitsfromEnglish.java @@ -0,0 +1,68 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ReconstructOriginalDigitsfromEnglish + * Creator : Edward + * Date : Jan, 2018 + * Description : 423. Reconstruct Original Digits from English + */ +public class ReconstructOriginalDigitsfromEnglish { + /** + * Given a non-empty string containing an out-of-order English representation of digits 0-9, + * output the digits in ascending order. + + Note: + Input contains only lowercase English letters. + Input is guaranteed to be valid and can be transformed to its original digits. + That means invalid inputs such as "abc" or "zerone" are not permitted. + Input length is less than 50,000. + Example 1: + Input: "owoztneoer" + + Output: "012" + + zero one two three four five six seven eight nine + + char c = s.charAt(i) + + s(6) + s(7) = 5 + s(6) = 2 x = 2 + + time : O(n) + space : O(n) + + * @param s + * @return + */ + public String originalDigits(String s) { + int[] count = new int[10]; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == 'z') count[0]++; + if (c == 'w') count[2]++; + if (c == 'x') count[6]++; + if (c == 's') count[7]++; //7-6 + if (c == 'g') count[8]++; + if (c == 'u') count[4]++; + if (c == 'f') count[5]++; //5-4 + if (c == 'h') count[3]++; //3-8 + if (c == 'i') count[9]++; //9-8-5-6 + if (c == 'o') count[1]++; //1-0-2-4 + } + count[7] -= count[6]; + count[5] -= count[4]; + count[3] -= count[8]; + count[9] = count[9] - count[8] - count[5] - count[6]; + count[1] = count[1] - count[0] - count[2] - count[4]; + + StringBuilder res = new StringBuilder(); + for (int i = 0; i <= 9; i++) { + for (int j = 0; j < count[i]; j++) { + res.append(i); + } + } + return res.toString(); + } +} diff --git a/RecoverBinarySearchTree.java b/RecoverBinarySearchTree.java new file mode 100644 index 0000000..e6b9952 --- /dev/null +++ b/RecoverBinarySearchTree.java @@ -0,0 +1,80 @@ +package leetcode; + +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RecoverBinarySearchTree + * Creator : Edward + * Date : Nov, 2017 + * Description : 99. Recover Binary Search Tree + */ +public class RecoverBinarySearchTree { + /** + * Two elements of a binary search tree (BST) are swapped by mistake. + + Recover the tree without changing its structure. + 6 + / \ + 8 1 + / \ + 0 3 + / \ + 2 5 + + time : O(n) + space : O(n) + + + */ + + TreeNode first = null; + TreeNode second = null; + TreeNode prev = null; + + public void recoverTree(TreeNode root) { + if (root == null) return; + helper(root); + int temp = first.val; + first.val = second.val; + second.val = temp; + } + public void helper(TreeNode root) { + if (root == null) return; + helper(root.left); + if (prev != null && prev.val >= root.val) { + if (first == null) first = prev; + second = root; + } + prev = root; + helper(root.right); + } + + public void recoverTree2(TreeNode root) { + if (root == null) return; + TreeNode first = null; + TreeNode second = null; + TreeNode prev = null; + + TreeNode cur = root; + Stack stack = new Stack<>(); + while (!stack.isEmpty() || cur != null) { + if (cur != null) { + stack.push(cur); + cur = cur.left; + } else { + cur = stack.pop(); + if (prev != null && cur.val <= prev.val) { + if (first == null) first = prev; + second = cur; + } + prev = cur; + cur = cur.right; + } + } + int temp = first.val; + first.val = second.val; + second.val = temp; + } +} diff --git a/RectangleArea.java b/RectangleArea.java new file mode 100644 index 0000000..ab93e56 --- /dev/null +++ b/RectangleArea.java @@ -0,0 +1,44 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RectangleArea + * Creator : Edward + * Date : Nov, 2017 + * Description : 223. Rectangle Area + */ +public class RectangleArea { + + /** + * + * time : O(1) + * space : O(1) + * + * @param A + * @param B + * @param C + * @param D + * @param E + * @param F + * @param G + * @param H + * @return + */ + + public int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) { + int areaA = (C - A) * (D - B); + int areaB = (G - E) * (H - F); + + int left = Math.max(A, E); + int right = Math.min(C, G); + int top = Math.min(D, H); + int bottom = Math.max(B, F); + + int overlap = 0; + if (right > left && top > bottom) { + overlap = (right - left) * (top - bottom); + } + return areaA + areaB - overlap; + } +} diff --git a/RegularExpressionMatching.java b/RegularExpressionMatching.java new file mode 100644 index 0000000..cb0fddd --- /dev/null +++ b/RegularExpressionMatching.java @@ -0,0 +1,90 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RegularExpressionMatching + * Creator : Edward + * Date : Dec, 2017 + * Description : 10. Regular Expression Matching + */ +public class RegularExpressionMatching { + /** + * Implement regular expression matching with support for '.' and '*'. + + '.' Matches any single character. + '*' Matches zero or more of the preceding element. + + The matching should cover the entire input string (not partial). + + The function prototype should be: + bool isMatch(const char *s, const char *p) + + Some examples: + isMatch("aa","a") → false + isMatch("aa","aa") → true + isMatch("aaa","aa") → false + isMatch("aa", "a*") → true + isMatch("aa", ".*") → true + isMatch("ab", ".*") → true + isMatch("aab", "c*a*b") → true + + "aa", ".*" + "ab", ".*" + "aab", "c*a*b" + + + boolean dp[i][j]的含义是s[0-i] 与 p[0-j]是否匹配。 + + c* = empty + + 1,p.charAt(j) == s.charAt(i) : dp[i][j] = dp[i-1][j-1] + 2,If p.charAt(j) == ‘.’ : dp[i][j] = dp[i-1][j-1]; + 3,If p.charAt(j) == ‘*’: + here are two sub conditions: + 1,if p.charAt(j-1) != s.charAt(i) : dp[i][j] = dp[i][j-2] //in this case, a* only counts as empty + 2,if p.charAt(j-1) == s.charAt(i) or p.charAt(j-1) == ‘.’: + dp[i][j] = dp[i][j-1] // in this case, a* counts as single a + dp[i][j] = dp[i-1][j] //in this case, a* counts as multiple a + dp[i][j] = dp[i][j-2] // in this case, a* counts as empty + + "aab", "c*aab" + + i = 1 dp[0][2] = true + + time : O(m * n) + space : O(m * n) + + * @param s + * @param p + * @return + */ + public boolean isMatch(String s, String p) { + if (s == null || p == null) return false; + boolean[][] dp = new boolean[s.length() + 1][p.length() + 1]; + dp[0][0] = true; + for (int i = 0; i < p.length(); i++) { + if (p.charAt(i) == '*' && dp[0][i - 1]) { + dp[0][i + 1] = true; + } + } + for (int i = 0; i < s.length(); i++) { + for (int j = 0; j < p.length(); j++) { + if (p.charAt(j) == s.charAt(i)) { + dp[i + 1][j + 1] = dp[i][j]; + } + if (p.charAt(j) == '.') { + dp[i + 1][j + 1] = dp[i][j]; + } + if (p.charAt(j) == '*') { + if (p.charAt(j - 1) != s.charAt(i) && p.charAt(j - 1) != '.') { + dp[i + 1][j + 1] = dp[i + 1][j - 1]; + } else { + dp[i + 1][j + 1] = (dp[i + 1][j] || dp[i][j + 1] || dp[i + 1][j - 1]); + } + } + } + } + return dp[s.length()][p.length()]; + } +} diff --git a/RemoveDuplicateLetters.java b/RemoveDuplicateLetters.java new file mode 100644 index 0000000..2bb1d28 --- /dev/null +++ b/RemoveDuplicateLetters.java @@ -0,0 +1,77 @@ +package leetcode; + +import java.util.HashMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RemoveDuplicateLetters + * Creator : Edward + * Date : Nov, 2017 + * Description : 316. Remove Duplicate Letters + */ +public class RemoveDuplicateLetters { + /** + * Given a string which contains only lowercase letters, remove duplicate letters + * so that every letter appear once and only once. You must make sure your result is the smallest + * in lexicographical order among all possible results. + + Example: + Given "bcabc" + Return "abc" + + Given "cbacdcbc" + Return "acdb" + + c b a c d c b c + 0 1 2 3 4 5 6 7 + + map : + + + + cba start = 3 end = 4 a + cd start = 4 end = 4 ac + d start = 5 end = 6 acd + cb start = 7 end acdb + + time : O(n) + space : O(n) + + + * @param s + * @return + */ + public String removeDuplicateLetters(String s) { + if (s == null || s.length() == 0) return s; + HashMap map = new HashMap<>(); + for (int i = 0; i < s.length(); i++) { + map.put(s.charAt(i), i); + } + char[] res = new char[map.size()]; + int start = 0, end = findMinLastPos(map); + for (int i = 0; i < res.length; i++) { + char minChar = 'z' + 1; + for (int k = start; k <= end; k++) { + if (map.containsKey(s.charAt(k)) && s.charAt(k) < minChar) { + minChar = s.charAt(k); + start = k + 1; + } + } + res[i] = minChar; + map.remove(minChar); + if (s.charAt(end) == minChar) { + end = findMinLastPos(map); + } + } + return new String(res); + } + + public int findMinLastPos(HashMap map) { + int res = Integer.MAX_VALUE; + for (int num : map.values()) { + res = Math.min(res, num); + } + return res; + } +} diff --git a/RemoveDuplicatesfromSortedArray.java b/RemoveDuplicatesfromSortedArray.java new file mode 100644 index 0000000..0c3fcd9 --- /dev/null +++ b/RemoveDuplicatesfromSortedArray.java @@ -0,0 +1,40 @@ +package leetcode; + +/** + * Created by Edward on 25/07/2017. + */ +public class RemoveDuplicatesfromSortedArray { + /** + * 26. Remove Duplicates from Sorted Array + * Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length. + + Do not allocate extra space for another array, you must do this in place with constant memory. + + For example, + Given input array nums = [1,1,2], + + Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length. + + case : [1,1,2,2,3,4,5,6] + 1,2,3,4,5,6 + c + i + result : [1,2,3,4,5,6] + + time : O(n); + space : O(1); + + * @param nums + * @return + */ + public static int removeDuplicates(int[] nums) { + if (nums == null || nums.length == 0) return 0; + int count = 1; + for (int i = 1; i < nums.length; i++) { + if (nums[i - 1] != nums[i]) { + nums[count++] = nums[i]; + } + } + return count; + } +} diff --git a/RemoveDuplicatesfromSortedArrayII.java b/RemoveDuplicatesfromSortedArrayII.java new file mode 100644 index 0000000..69202bc --- /dev/null +++ b/RemoveDuplicatesfromSortedArrayII.java @@ -0,0 +1,39 @@ +package leetcode; + +/** + * Created by Edward on 25/07/2017. + */ +public class RemoveDuplicatesfromSortedArrayII { + /** + * 80. Remove Duplicates from Sorted Array II (26. Remove Duplicates from Sorted Array: follow up) + * Follow up for "Remove Duplicates": + What if duplicates are allowed at most twice? + + For example, + Given sorted array nums = [1,1,1,2,2,3], + + Your function should return length = 5, with the first five elements of nums being 1, 1, 2, 2 and 3. It doesn't matter what you leave beyond the new length. + + case : [1,1,1,2,2,3] + 1,1,2,2,3 + c + i + result : [1,1,2,2,3] + + time: O(n); + space: O(1); + + * @param nums + * @return + */ + public static int removeDuplicates(int[] nums) { + if (nums.length <= 2) return nums.length; + int count = 2; + for (int i = 2; i < nums.length; i++) { + if (nums[i] != nums[count - 2]) { + nums[count++] = nums[i]; + } + } + return count; + } +} diff --git a/RemoveDuplicatesfromSortedList.java b/RemoveDuplicatesfromSortedList.java new file mode 100644 index 0000000..2bcb008 --- /dev/null +++ b/RemoveDuplicatesfromSortedList.java @@ -0,0 +1,32 @@ +package leetcode; + +/** + * Created by Edward on 25/07/2017. + */ +public class RemoveDuplicatesfromSortedList { + /** + * 83. Remove Duplicates from Sorted List + * Given a sorted linked list, delete all duplicates such that each element appear only once. + + For example, + Given 1->1->2, return 1->2. + Given 1->1->2->3->3, return 1->2->3. + + time : O(n); + space : O(1); + * @param head + * @return + */ + public static ListNode deleteDuplicates(ListNode head) { + if (head == null || head.next == null) return head; + ListNode cur = head; + while (cur.next != null) { + if (cur.next.val == cur.val) { + cur.next = cur.next.next; + } else { + cur = cur.next; + } + } + return head; + } +} diff --git a/RemoveDuplicatesfromSortedListII.java b/RemoveDuplicatesfromSortedListII.java new file mode 100644 index 0000000..77b5f7e --- /dev/null +++ b/RemoveDuplicatesfromSortedListII.java @@ -0,0 +1,37 @@ +package leetcode; + +/** + * Created by Edward on 25/07/2017. + */ +public class RemoveDuplicatesfromSortedListII { + + /** + * 82. Remove Duplicates from Sorted List II (83. Remove Duplicates from Sorted List: follow up) + * Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. + + For example, + Given 0->1->2->3->3->4->4->5, return 1->2->5. + Given 0->1->1->1->2->3, return 2->3. + time : O(n); + space : O(1); + * @param head + * @return + */ + public ListNode deleteDuplicates(ListNode head) { + if (head == null || head.next == null) return head; + ListNode dummy = new ListNode(0); + dummy.next = head; + ListNode p = dummy; + while (p.next != null && p.next.next !=null) { + if (p.next.val == p.next.next.val) { + int sameNum = p.next.val; + while (p.next != null && p.next.val == sameNum) { + p.next = p.next.next; + } + } else { + p = p.next; + } + } + return dummy.next; + } +} diff --git a/RemoveElement.java b/RemoveElement.java new file mode 100644 index 0000000..08bf4bc --- /dev/null +++ b/RemoveElement.java @@ -0,0 +1,49 @@ +package leetcode; + +import java.util.Arrays; + +/** + * Created by Edward on 25/07/2017. + */ +public class RemoveElement { + /** + * 27. Remove Element (26, 80) + * Given an array and a value, remove all instances of that value in place and return the new length. + + Do not allocate extra space for another array, you must do this in place with constant memory. + + The order of elements can be changed. It doesn't matter what you leave beyond the new length. + + Example: + Given input array nums = [3,2,2,3], val = 3 + + Your function should return length = 2, with the first two elements of nums being 2. + + case : [3,2,2,3] 3 + 2,2 + r + i + res : [2,2] + time : O(n); + space : O(1); + * @param nums + * @param val + * @return + */ + public static int removeElement(int[] nums, int val) { + if (nums == null || nums.length == 0) return 0; + int res = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i] != val) { + nums[res++] = nums[i]; + } + } + System.out.println(Arrays.toString(nums)); + return res; + } + + public static void main(String[] args) { + int[] nums = new int[]{1, 2, 3, 3, 4}; + removeElement(nums,3); + } +} diff --git a/RemoveInvalidParentheses.java b/RemoveInvalidParentheses.java new file mode 100644 index 0000000..b8c81fb --- /dev/null +++ b/RemoveInvalidParentheses.java @@ -0,0 +1,60 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RemoveInvalidParentheses + * Creator : Edward + * Date : Nov, 2017 + * Description : 301. Remove Invalid Parentheses + */ +public class RemoveInvalidParentheses { + /** + * Remove the minimum number of invalid parentheses in order to make the input string valid. + * Return all possible results. + + Note: The input string may contain letters other than the parentheses ( and ). + + Examples: + "()())()" -> ["()()()", "(())()"] + "(a)())()" -> ["(a)()()", "(a())()"] + ")(" -> [""] + Credits: + Special thanks to @hpplayer for adding this problem and creating all test cases. + + time : 不知道 + space : O(n) + + + + * @param s + * @return + */ + public List removeInvalidParentheses(String s) { + List res = new ArrayList<>(); + helper(res, s, 0, 0, new char[]{'(', ')'}); + return res; + } + public void helper(List res, String s, int last_i, int last_j, char[] pair) { + for (int count = 0, i = last_i; i < s.length(); i++) { + if (s.charAt(i) == pair[0]) count++; + if (s.charAt(i) == pair[1]) count--; + if (count >= 0) continue; + for (int j = last_j; j <= i; j++) { + if (s.charAt(j) == pair[1] && (j == last_j || s.charAt(j - 1) != pair[1])) { + helper(res, s.substring(0, j) + s.substring(j + 1), i, j, pair); + } + } + return; + } + String reversed = new StringBuilder(s).reverse().toString(); + if (pair[0] == '(') { + helper(res, reversed, 0, 0, new char[]{')', '('}); + } else { + res.add(reversed); + } + } +} diff --git a/RemoveLinkedListElements.java b/RemoveLinkedListElements.java new file mode 100644 index 0000000..e2fe838 --- /dev/null +++ b/RemoveLinkedListElements.java @@ -0,0 +1,58 @@ +package leetcode; + +/** + * Created by Edward on 25/07/2017. + */ +public class RemoveLinkedListElements { + /** + * 203. Remove Linked List Elements + * Remove all elements from a linked list of integers that have value val. + + Example + Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6 + Return: 1 --> 2 --> 3 --> 4 --> 5 + + Credits: + Special thanks to @mithmatt for adding this problem and creating all test cases. + + time : O(n); + space : O(1); + * @param head + * @param val + * @return + */ + public static ListNode removeElements(ListNode head, int val) { + if (head == null) return head; + ListNode dummy = new ListNode(0); + dummy.next = head; + ListNode p = dummy; + while (p.next != null) { + if (p.next.val == val) { + p.next = p.next.next; + } else { + p = p.next; + } + } + return dummy.next; + } + + public static ListNode removeElements2(ListNode head, int val) { + if (head == null) return head; + ListNode p = head; + while (p.next != null) { + if (p.next.val == val) { + p.next = p.next.next; + } else { + p = p.next; + } + } + return head.val == val ? head.next : head; + } + + public static ListNode removeElements3(ListNode head, int val) { + if (head == null) return head; + head.next = removeElements3(head.next, val); + return head.val == val ? head.next : head; + } +} + diff --git a/RemoveNthNodeFromEndofList.java b/RemoveNthNodeFromEndofList.java new file mode 100644 index 0000000..c02661d --- /dev/null +++ b/RemoveNthNodeFromEndofList.java @@ -0,0 +1,39 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RemoveNthNodeFromEndofList + * Creator : Edward + * Date : Oct, 2017 + * Description : 19. Remove Nth Node From End of List + */ +public class RemoveNthNodeFromEndofList { + /** + * Given linked list: 1->2->3->4->5, and n = 2. + + After removing the second node from the end, the linked list becomes 1->2->3->5. + + time : O(n) + space : O(1) + + * @param head + * @param n + * @return + */ + public ListNode removeNthFromEnd(ListNode head, int n) { + ListNode dummy = new ListNode(0); + ListNode slow = dummy; + ListNode fast = dummy; + dummy.next = head; + for (int i = 0; i <= n; i++) { + fast = fast.next; + } + while (fast != null) { + fast = fast.next; + slow = slow.next; + } + slow.next = slow.next.next; + return dummy.next; + } +} diff --git a/ReorderList.java b/ReorderList.java new file mode 100644 index 0000000..a621846 --- /dev/null +++ b/ReorderList.java @@ -0,0 +1,65 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ReorderList + * Creator : Edward + * Date : Oct, 2017 + * Description : 143. Reorder List + */ +public class ReorderList { + /** + * Given a singly linked list L: L0→L1→…→Ln-1→Ln, + reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… + + You must do this in-place without altering the nodes' values. + + For example, + Given {1,2,3,4}, reorder it to {1,4,2,3}. + + time : O(n) + space : O(1) + + * @param head + */ + public void reorderList(ListNode head) { + if (head == null || head.next == null) return; + ListNode dummy = new ListNode(0); + dummy.next = head; + ListNode temp = null; + ListNode slow = head, fast = head; + ListNode l1 = head; + while (fast != null && fast.next != null) { + temp = slow; + slow = slow.next; + fast = fast.next.next; + } + temp.next = null; + ListNode l2 = reverse(slow); + merge(l1, l2); + } + + private ListNode reverse(ListNode head) { + ListNode prev = null; + while (head != null) { + ListNode temp = head.next; + head.next = prev; + prev = head; + head = temp; + } + return prev; + } + + private void merge(ListNode l1, ListNode l2) { + while (l1 != l2) { + ListNode n1 = l1.next; + ListNode n2 = l2.next; + l1.next = l2; + if (n1 == null) break; + l2.next = n1; + l1 = n1; + l2 = n2; + } + } +} diff --git a/RepeatedDNASequences.java b/RepeatedDNASequences.java new file mode 100644 index 0000000..c99068f --- /dev/null +++ b/RepeatedDNASequences.java @@ -0,0 +1,46 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RepeatedDNASequences + * Creator : Edward + * Date : Dec, 2017 + * Description : 187. Repeated DNA Sequences + */ +public class RepeatedDNASequences { + /** + * All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, + * for example: "ACGAATTCCG". When studying DNA, it is sometimes useful to identify repeated sequences within the DNA. + + Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule. + + For example, + + Given s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT", + + Return: + ["AAAAACCCCC", "CCCCCAAAAA"]. + + time : O(n) + space : O(n) + + * @param s + * @return + */ + public List findRepeatedDnaSequences(String s) { + HashSet seen = new HashSet<>(); + HashSet repeated = new HashSet<>(); + for (int i = 0; i < s.length() - 9; i++) { + String temp = s.substring(i, i + 10); + if (!seen.add(temp)) { + repeated.add(temp); + } + } + return new ArrayList<>(repeated); + } +} diff --git a/RestoreIPAddresses.java b/RestoreIPAddresses.java new file mode 100644 index 0000000..58fce13 --- /dev/null +++ b/RestoreIPAddresses.java @@ -0,0 +1,47 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : helperAddresses + * Creator : Edward + * Date : Dec, 2017 + * Descrstion : 93. Restore IP Addresses + */ +public class RestoreIPAddresses { + /** + * Given a string containing only digits, restore it by returning all possible valid s address combinations. + + For example: + Given "25525511135", + + return ["255.255.11.135", "255.255.111.35"]. (Order does not matter) + + time : O(3^4) => O(1) => O(3^n) + space : O(n) + + * @param s + * @return + */ + public List restoreIpAddresses(String s) { + List res = new ArrayList<>(); + helper(res, s, 0, "", 0); + return res; + } + public void helper(List res, String s, int index, String ret, int count) { + if (count > 4) return; + if (count == 4 && index == s.length()) { + res.add(ret); + return; + } + for (int i = 1; i < 4; i++) { + if (index + i > s.length()) break; + String temp = s.substring(index, index + i); + if ((temp.startsWith("0") && temp.length() > 1) || (i == 3 && Integer.parseInt(temp) >= 256)) continue; + helper(res, s, index + i, ret + temp + (count == 3 ? "" : "."), count + 1); + } + } +} diff --git a/ReverseBits.java b/ReverseBits.java new file mode 100644 index 0000000..7c0caa1 --- /dev/null +++ b/ReverseBits.java @@ -0,0 +1,34 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ReverseBits + * Creator : Edward + * Date : Nov, 2017 + * Description : 190. Reverse Bits + */ +public class ReverseBits { + /** + * Reverse bits of a given 32 bits unsigned integer. + + For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), + return 964176192 (represented in binary as 00111001011110000010100101000000). + + time : O(1) / O(n) + space : O(1) + + * @param n + * @return + */ + public int reverseBits(int n) { + if (n == 0) return 0; + int res = 0; + for (int i = 0; i < 32; i++) { + res <<= 1; + if ((n & 1) == 1) res++; + n >>= 1; + } + return res; + } +} diff --git a/ReverseInteger.java b/ReverseInteger.java new file mode 100644 index 0000000..6576b58 --- /dev/null +++ b/ReverseInteger.java @@ -0,0 +1,35 @@ +package leetcode; + +/** + * Created by Edward on 25/07/2017. + */ +public class ReverseInteger { + + /** + * 7. Reverse Integer + * Reverse digits of an integer. + + Example1: x = 123, return 321 + Example2: x = -123, return -321 + + int : + -2147483648 ~ 2147483647 + + corner case : 越界 + time : O(n); + space : O(1); + * @param x + * @return + */ + + public static int reverse(int x) { + + long res = 0; + while (x != 0) { + res = res * 10 + x % 10; + x /= 10; + if (res > Integer.MAX_VALUE || res < Integer.MIN_VALUE) return 0; + } + return (int)res; + } +} diff --git a/ReverseLinkedList.java b/ReverseLinkedList.java new file mode 100644 index 0000000..3c0394d --- /dev/null +++ b/ReverseLinkedList.java @@ -0,0 +1,28 @@ +package leetcode; + +/** + * Created by Edward on 28/07/2017. + */ +public class ReverseLinkedList { + /** + * 206. Reverse Linked List + + + time : O(n); + space : O(1); + + * @param head + * @return + */ + public static ListNode reverseList(ListNode head) { + if (head == null || head.next == null) return head; + ListNode pre = null; + while (head != null) { + ListNode temp = head.next; + head.next = pre; + pre = head; + head = temp; + } + return pre; + } +} diff --git a/ReverseLinkedListII.java b/ReverseLinkedListII.java new file mode 100644 index 0000000..b682b14 --- /dev/null +++ b/ReverseLinkedListII.java @@ -0,0 +1,47 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ReverseLinkedListII + * Creator : Edward + * Date : Oct, 2017 + * Description : 92. Reverse Linked List II + */ +public class ReverseLinkedListII { + /** + * For example: + Given 1->2->3->4->5->NULL, m = 2 and n = 4, + + return 1->4->3->2->5->NULL. + + 1->2->3->4->5 + p c t + + + time : O(n); + space : O(1); + + * @param head + * @param m + * @param n + * @return + */ + public ListNode reverseBetween(ListNode head, int m, int n) { + ListNode dummy = new ListNode(0); + dummy.next = head; + ListNode pre = dummy; + ListNode cur = dummy.next; + for (int i = 1; i < m; i++) { + cur = cur.next; + pre = pre.next; + } + for (int i = 0; i < n - m; i++) { + ListNode temp = cur.next; + cur.next = temp.next; + temp.next = pre.next; + pre.next = temp; + } + return dummy.next; + } +} diff --git a/ReverseNodesinkGroup.java b/ReverseNodesinkGroup.java new file mode 100644 index 0000000..6074877 --- /dev/null +++ b/ReverseNodesinkGroup.java @@ -0,0 +1,49 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ReverseNodesinkGroup + * Creator : Edward + * Date : Nov, 2017 + * Description : 25. Reverse Nodes in k-Group + */ +public class ReverseNodesinkGroup { + /** + * For example, + Given this linked list: 1->2->3->4->5 + + For k = 2, you should return: 2->1->4->3->5 + + For k = 3, you should return: 3->2->1->4->5 + + 2->1->4->3->5 k = 2 + + time : O(n) + space : O(n) + + * @param head + * @param k + * @return + */ + public ListNode reverseKGroup(ListNode head, int k) { + if (head == null || head.next == null) return head; + int count = 0; + ListNode cur = head; + while (cur != null && count != k) { + cur = cur.next; + count++; + } + if (count == k) { + cur = reverseKGroup(cur, k); + while (count-- > 0) { + ListNode temp = head.next; + head.next = cur; + cur = head; + head = temp; + } + head = cur; + } + return head; + } +} diff --git a/ReverseString.java b/ReverseString.java new file mode 100644 index 0000000..4845ad1 --- /dev/null +++ b/ReverseString.java @@ -0,0 +1,31 @@ +package leetcode; + +/** + * Created by Edward on 28/07/2017. + */ +public class ReverseString { + /** + * 344. Reverse String + * Write a function that takes a string as input and returns the string reversed. + + Example: + Given s = "hello", return "olleh". + + time : O(n); + space : O(n); + * @param s + * @return + */ + public static String reverseString(String s) { + if (s == null || s.length() == 0) return s; + int left = 0; + int right = s.length() - 1; + char[] str = s.toCharArray(); + while (left < right) { + char temp = str[left]; + str[left++] = str[right]; + str[right--] = temp; + } + return new String(str); + } +} diff --git a/ReverseStringII.java b/ReverseStringII.java new file mode 100644 index 0000000..e0a1564 --- /dev/null +++ b/ReverseStringII.java @@ -0,0 +1,43 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ReverseStringII + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class ReverseStringII { + /** + * 541. Reverse String II + * Given a string and an integer k, you need to reverse the first k characters for every 2k + * characters counting from the start of the string. If there are less than k characters left, + * reverse all of them. If there are less than 2k but greater than or equal to k characters, then + * reverse the first k characters and left the other as original. + + + time : O(n); + space : O(n); + * @param s + * @param k + * @return + */ + public String reverseStr(String s, int k) { + char[] arr = s.toCharArray(); + int i = 0; + while (i < s.length()) { + int j = Math.min(i + k - 1, s.length() - 1); + swap(arr, i, j); + i += 2 * k; + } + return String.valueOf(arr); + } + public void swap(char[] arr, int i, int j) { + while (i < j) { + char temp = arr[i]; + arr[i++] = arr[j]; + arr[j--] = temp; + } + } +} diff --git a/ReverseVowelsofaString.java b/ReverseVowelsofaString.java new file mode 100644 index 0000000..8ac0bcb --- /dev/null +++ b/ReverseVowelsofaString.java @@ -0,0 +1,46 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ReverseVowelsofaString + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class ReverseVowelsofaString { + /** + * 345. Reverse Vowels of a String + * Write a function that takes a string as input and reverse only the vowels of a string. + + Example 1: + Given s = "hello", return "holle". + + Example 2: + Given s = "leetcode", return "leotcede". + + time : O(n); + space : O(n); + * @param s + * @return + */ + public String reverseVowels(String s) { + if (s == null || s.length() == 0) return s; + String vowels = "aeiouAEIOU"; + char[] array = s.toCharArray(); + int start = 0; + int end = s.length() - 1; + while (start < end) { + while (start < end && vowels.indexOf(array[start]) == -1) { + start++; + } + while (start < end && vowels.indexOf(array[end]) == -1) { + end--; + } + char temp = array[start]; + array[start++] = array[end]; + array[end--] = temp; + } + return String.valueOf(array); + } +} diff --git a/ReverseWordsinaString.java b/ReverseWordsinaString.java new file mode 100644 index 0000000..45f9c96 --- /dev/null +++ b/ReverseWordsinaString.java @@ -0,0 +1,69 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ReverseWordsinaString + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class ReverseWordsinaString { + /** + * 151. Reverse Words in a String + * For example, + Given s = "the sky is blue", + return "blue is sky the". + + * @param s + * @return + */ + + //time : O(n), space : O(n) + public String reverseWords(String s) { + if (s == null || s.length() == 0) return s; + StringBuilder sb = new StringBuilder(); + String[] words = s.trim().split("\\s+"); + for (int i = words.length - 1; i >=0; i--) { + sb.append(words[i] + " "); + } + return sb.toString().trim(); + } + + // time : O(n) space : O(n) + public String reverseWords2(String s) { + if (s == null || s.length() == 0) return s; + char[] ch = s.toCharArray(); + reverse(ch, 0, s.length() - 1); + reverseWord(ch, s.length()); + return cleanSpaces(ch, s.length()); + } + + private void reverse(char[] ch, int i, int j) { + while (i < j) { + char temp = ch[i]; + ch[i++] = ch[j]; + ch[j--] = temp; + } + } + private void reverseWord(char[] ch, int len) { + int i = 0; + int j = 0; + while (i < len) { + while (i < j || i < len && ch[i] == ' ') i++; + while (j < i || j < len && ch[j] != ' ') j++; + reverse(ch, i, j - 1); + } + } + private String cleanSpaces(char[] ch, int len) { + int i = 0; + int j = 0; + while (j < len) { + while (j < len && ch[j] == ' ') j++; + while (j < len && ch[j] != ' ') ch[i++] = ch[j++]; + while (j < len && ch[j] == ' ') j++; + if (j < len) ch[i++] = ' '; + } + return String.valueOf(ch).substring(0, i); + } +} diff --git a/ReverseWordsinaStringII.java b/ReverseWordsinaStringII.java new file mode 100644 index 0000000..ed1697c --- /dev/null +++ b/ReverseWordsinaStringII.java @@ -0,0 +1,40 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ReverseWordsinaStringII + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class ReverseWordsinaStringII { + /** + * 186. Reverse Words in a String II + * For example, + Given s = "the sky is blue", + return "blue is sky the" + + time : O(n) space : O(1) + * @param s + */ + public void reverseWords(char[] s) { + reverse(s, 0, s.length - 1); + int r = 0; + while (r < s.length) { + int l = r; + while (r < s.length && s[r] != ' ') { + r++; + } + reverse(s, l, r - 1); + r++; + } + } + private void reverse(char[] s, int i, int j) { + while (i < j) { + char temp = s[i]; + s[i++] = s[j]; + s[j--] = temp; + } + } +} diff --git a/ReverseWordsinaStringIII.java b/ReverseWordsinaStringIII.java new file mode 100644 index 0000000..45957fe --- /dev/null +++ b/ReverseWordsinaStringIII.java @@ -0,0 +1,56 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ReverseWordsinaStringIII + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class ReverseWordsinaStringIII { + /** + * 557. Reverse Words in a String III + * Example 1: + Input: "Let's take LeetCode contest" + Output: "s'teL ekat edoCteeL tsetnoc" + + time : O(n); + space : O(n); + * @param s + * @return + */ + public String reverseWords(String s) { + if (s == null || s.length() == 0) return s; + char[] arr = s.toCharArray(); + int i = 0; + for (int j = 0; j < arr.length; j++) { + if (arr[j] == ' ') { + reverse(arr, i, j - 1); + i = j + 1; + } + } + reverse(arr, i, arr.length - 1); + return String.valueOf(arr); + } + public void reverse(char[] arr, int i, int j) { + while (i < j) { + char temp = arr[i]; + arr[i++] = arr[j]; + arr[j--] = temp; + } + } + + public String reverseWords2(String s) { + if (s == null || s.length() == 0) return s; + String[] str = s.split(" "); + for (int i = 0; i < str.length; i++) { + str[i] = new StringBuilder(str[i]).reverse().toString(); + } + StringBuilder sb = new StringBuilder(); + for (String st : str) { + sb.append(st + " "); + } + return sb.toString().trim(); + } +} diff --git a/RomantoInteger.java b/RomantoInteger.java new file mode 100644 index 0000000..e35b951 --- /dev/null +++ b/RomantoInteger.java @@ -0,0 +1,43 @@ +package leetcode; + +public class RomantoInteger { + /** + * 13. Roman to Integer + * Given a roman numeral, convert it to an integer. + + Input is guaranteed to be within the range from 1 to 3999. + + 规律:左边的数字如果小于右边的数字 = 右 - 左 + + time : O(n); + space : O(1); + * @param s + * @return + */ + public static int romanToInt(String s) { + if (s == null || s.length() == 0) return 0; + int res = toNumber(s.charAt(0)); + for (int i = 1; i < s.length(); i++) { + if (toNumber(s.charAt(i)) > toNumber(s.charAt(i - 1))) { + res += toNumber(s.charAt(i)) - 2 * toNumber(s.charAt(i - 1)); + } else { + res += toNumber(s.charAt(i)); + } + } + return res; + } + + public static int toNumber(char c) { + int res = 0; + switch (c) { + case 'I' : return 1; + case 'V' : return 5; + case 'X' : return 10; + case 'L' : return 50; + case 'C' : return 100; + case 'D' : return 500; + case 'M' : return 1000; + } + return res; + } +} diff --git a/RotateArray.java b/RotateArray.java new file mode 100644 index 0000000..5f24a6e --- /dev/null +++ b/RotateArray.java @@ -0,0 +1,59 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RotateArray + * Creator : Edward + * Date : Sep, 2017 + * Description : 189. Rotate Array + */ +public class RotateArray { + /** + * Rotate an array of n elements to the right by k steps. + + For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4]. + + Note: + Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem. + + * @param nums + * @param k + */ + //time : O(n) space : O(n) + public void rotate(int[] nums, int k) { + int[] temp = new int[nums.length]; + for (int i = 0; i < nums.length; i++) { + temp[(i + k) % nums.length] = nums[i]; + } + for (int i = 0; i < nums.length; i++) { + nums[i] = temp[i]; + } + } + + //time : O(n) space : O(1) + + /** + Original List : 1 2 3 4 5 6 7 + After reversing all numbers : 7 6 5 4 3 2 1 + After reversing first k numbers : 5 6 7 4 3 2 1 + After revering last n-k numbers : 5 6 7 1 2 3 4 --> Result + * @param nums + * @param k + */ + public void rotate2(int[] nums, int k) { + k %= nums.length; + reverse(nums, 0, nums.length - 1); + reverse(nums, 0, k - 1); + reverse(nums, k, nums.length - 1); + } + public void reverse(int[] nums, int start, int end) { + while (start < end) { + int temp = nums[start]; + nums[start] = nums[end]; + nums[end] = temp; + start++; + end--; + } + } +} diff --git a/RotateFunction.java b/RotateFunction.java new file mode 100644 index 0000000..879dcf5 --- /dev/null +++ b/RotateFunction.java @@ -0,0 +1,75 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RotateFunction + * Creator : Edward + * Date : Oct, 2017 + * Description : 396. Rotate Function + */ +public class RotateFunction { + /** + * Given an array of integers A and let n to be its length. + + Assume Bk to be an array obtained by rotating the array A k positions clock-wise, we define a "rotation function" F on A as follow: + + F(k) = 0 * Bk[0] + 1 * Bk[1] + ... + (n-1) * Bk[n-1]. + + Calculate the maximum value of F(0), F(1), ..., F(n-1). + + Note: + n is guaranteed to be less than 105. + + Example: + + A = [4, 3, 2, 6] + 6 4 3 2 + Ak-1 2 6 4 3 + Ak 3 2 6 4 + + F(0) = (0 * 4) + (1 * 3) + (2 * 2) + (3 * 6) = 0 + 3 + 4 + 18 = 25 + F(1) = (0 * 6) + (1 * 4) + (2 * 3) + (3 * 2) = 0 + 4 + 6 + 6 = 16 + F(2) = (0 * 2) + (1 * 6) + (2 * 4) + (3 * 3) = 0 + 6 + 8 + 9 = 23 + F(3) = (0 * 3) + (1 * 2) + (2 * 6) + (3 * 4) = 0 + 2 + 12 + 12 = 26 + + So the maximum value of F(0), F(1), F(2), F(3) is F(3) = 26. + + F(k) = 0 * Bk[0] + 1 * Bk[1] + ... + (n-1) * Bk[n-1] + F(k-1) = 0 * Bk-1[0] + 1 * Bk-1[1] + ... + (n-1) * Bk-1[n-1] + = 0 * Bk[1] + 1 * Bk[2] + ... + (n-2) * Bk[n-1] + (n-1) * Bk[0] + Then, + + F(k) - F(k-1) = Bk[1] + Bk[2] + ... + Bk[n-1] + (1-n)Bk[0] + = (Bk[0] + ... + Bk[n-1]) - nBk[0] + = sum - nBk[0] + Thus, + + F(k) = F(k-1) + sum - nBk[0] + What is Bk[0]? + + k = 0; B[0] = A[0]; + k = 1; B[0] = A[len-1]; + k = 2; B[0] = A[len-2]; + + time : O(n) + space : O(1) + + * @param A + * @return + */ + public int maxRotateFunction(int[] A) { + int sum = 0; + int candidate = 0; + for (int i = 0; i < A.length; i++) { + sum += A[i]; + candidate += A[i] * i; + } + int res = candidate; + for (int i = A.length - 1; i > 0; i--) { + candidate = candidate + sum - A[i] * A.length; + res = Math.max(res, candidate); + } + return res; + } +} diff --git a/RotateImage.java b/RotateImage.java new file mode 100644 index 0000000..9231671 --- /dev/null +++ b/RotateImage.java @@ -0,0 +1,55 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RotateImage + * Creator : Edward + * Date : Oct, 2017 + * Description : 48. Rotate Image + */ +public class RotateImage { + /** + * Example 1: + + Given input matrix = + [ + [1,2,3], + [4,5,6], + [7,8,9] + ], + + rotate the input matrix in-place such that it becomes: + [ + [7,4,1], + [8,5,2], + [9,6,3] + ] + + [ + [1,4,7], + [2,5,8], + [3,6,9] + ] + + time : O(n * m) + space : O(1) + * @param matrix + */ + public void rotate(int[][] matrix) { + for (int i = 0; i < matrix.length; i++) { + for (int j = i; j < matrix[0].length; j++) { + int temp = matrix[i][j]; + matrix[i][j] = matrix[j][i]; + matrix[j][i] = temp; + } + } + for (int i = 0; i < matrix.length; i++) { + for (int j = 0; j < matrix.length / 2; j++) { + int temp = matrix[i][j]; + matrix[i][j] = matrix[i][matrix.length - 1 - j]; + matrix[i][matrix.length - 1 - j] = temp; + } + } + } +} diff --git a/RotateList.java b/RotateList.java new file mode 100644 index 0000000..046e77d --- /dev/null +++ b/RotateList.java @@ -0,0 +1,40 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RotateList + * Creator : Edward + * Date : Oct, 2017 + * Description : 61. Rotate List + */ +public class RotateList { + /** + * For example: + Given 1->2->3->4->5->NULL and k = 2, + return 4->5->1->2->3->NULL. + + time : O(n); + space : O(1); + + * @param head + * @param k + * @return + */ + public ListNode rotateRight(ListNode head, int k) { + if (head == null || head.next == null) return head; + ListNode index = head; + int len = 1; + while (index.next != null) { + index = index.next; + len++; + } + index.next = head; + for (int i = 1; i < len - k % len; i++) { + head = head.next; + } + ListNode res = head.next; + head.next = null; + return res; + } +} diff --git a/RussianDollEnvelopes.java b/RussianDollEnvelopes.java new file mode 100644 index 0000000..a759632 --- /dev/null +++ b/RussianDollEnvelopes.java @@ -0,0 +1,72 @@ +package leetcode; + +import java.util.Arrays; +import java.util.Comparator; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : RussianDollEnvelopes + * Creator : Edward + * Date : Jan, 2018 + * Description : 354. Russian Doll Envelopes + */ +public class RussianDollEnvelopes { + /** + * You have a number of envelopes with widths and heights given as a pair of integers (w, h). + * One envelope can fit into another if and only if both the width and height of one envelope + * is greater than the width and height of the other envelope. + + What is the maximum number of envelopes can you Russian doll? (put one inside other) + + Example: + Given envelopes = [[5,4],[6,4],[6,7],[2,3]], the maximum number of envelopes you can Russian doll + is 3 ([2,3] => [5,4] => [6,7]). + + 排序 + weight -> + height <- + + [6 4][6 7] + + [2, 3] -> [5, 4] -> [6, 7] -> [6, 4] + + 3 4 7 4 -> 3 4 7 + + time : O(nlogn) + space : O(n) + + * @param envelopes + * @return + */ + + public int maxEnvelopes(int[][] envelopes) { + if (envelopes == null || envelopes.length == 0) return 0; + Arrays.sort(envelopes, (a, b) -> a[0] == b[0] ? b[1] - a[1] : a[0] - b[0]); + int[] dp = new int[envelopes.length]; + int res = 0; + for (int[] envelope : envelopes) { + int i = binarySearch(dp, 0, res, envelope[1]); + dp[i] = envelope[1]; + if (i == res) { + res++; + } + } + return res; + } + + public int binarySearch(int[] dp, int start, int end, int target) { + while (start + 1 < end) { + int mid = start + (end - start) / 2; + if (dp[mid] == target) { + return mid; + } else if (dp[mid] < target) { + start = mid; + } else { + end = mid; + } + } + if (dp[start] >= target) return start; + return end; + } +} diff --git a/SameTree.java b/SameTree.java new file mode 100644 index 0000000..5b744f8 --- /dev/null +++ b/SameTree.java @@ -0,0 +1,29 @@ +package leetcode; + +/** + * Created by Edward on 23/07/2017. + */ +public class SameTree { + + /** + * 100. Same Tree + + Given two binary trees, write a function to check if they are equal or not. + + Two binary trees are considered equal if they are structurally identical and the nodes have the same value. + + time : O(n); + space : O(n); + * @param p + * @param q + * @return + */ + public static boolean isSameTree(TreeNode p, TreeNode q) { + + if (p == null && q == null) return true; + if (p == null || q == null) return false; + if (p.val != q.val) return false; + + return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); + } +} diff --git a/ScrambleString.java b/ScrambleString.java new file mode 100644 index 0000000..1235fb9 --- /dev/null +++ b/ScrambleString.java @@ -0,0 +1,44 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ScrambleString + * Creator : Edward + * Date : Dec, 2017 + * Description : 87. Scramble String + */ +public class ScrambleString { + + /** + + time : O(n!) + space : O(n) + + * @param s1 + * @param s2 + * @return + */ + + public boolean isScramble(String s1, String s2) { + if (s1 == null || s2 == null) return false; + if (s1.equals(s2)) return true; + + int[] letters = new int[26]; + int len = s1.length(); + for (int i = 0; i < len; i++) { + letters[s1.charAt(i) - 'a']++; + letters[s2.charAt(i) - 'a']--; + } + for (int i = 0; i < 26; i++) { + if (letters[i] != 0) return false; + } + for (int i = 1; i < len; i++) { + if (isScramble(s1.substring(0, i), s2.substring(0, i)) + && isScramble(s1.substring(i), s2.substring(i))) return true; + if (isScramble(s1.substring(0, i), s2.substring(len - i)) + && isScramble(s1.substring(i), s2.substring(0, len - i))) return true; + } + return false; + } +} diff --git a/SearchInsertPosition.java b/SearchInsertPosition.java new file mode 100644 index 0000000..e16a83e --- /dev/null +++ b/SearchInsertPosition.java @@ -0,0 +1,50 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SearchInsertPosition + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class SearchInsertPosition { + + /** + * 35. Search Insert Position + * Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. + + You may assume no duplicates in the array. + + Here are few examples. + [1,3,5,6], 5 → 2 + [1,3,5,6], 2 → 1 + [1,3,5,6], 7 → 4 + [1,3,5,6], 0 → 0 + + __target___target + + time : O(logn); + space : O(1); + * @param nums + * @param target + * @return + */ + public int searchInsert(int[] nums, int target) { + int start = 0; + int end = nums.length - 1; + while (start + 1 < end) { + int mid = (end - start) / 2 + start; + if (target == nums[mid]) return mid; + else if (target < nums[mid]) end = mid; + else start = mid; + } + if (target <= nums[start]) { + return start; + } else if (target <= nums[end]) { + return end; + } else { + return end + 1; + } + } +} diff --git a/Searcha2DMatrix.java b/Searcha2DMatrix.java new file mode 100644 index 0000000..6dc956e --- /dev/null +++ b/Searcha2DMatrix.java @@ -0,0 +1,56 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : Searcha2DMatrix + * Creator : Edward + * Date : Nov, 2017 + * Description : 74. Search a 2D Matrix + */ +public class Searcha2DMatrix { + /** + * Write an efficient algorithm that searches for a value in an m x n matrix. + * This matrix has the following properties: + + Integers in each row are sorted from left to right. + The first integer of each row is greater than the last integer of the previous row. + For example, + + Consider the following matrix: + + [ + [1, 3, 5, 7], + [10, 11, 16, 20], + [23, 30, 34, 50] + ] + Given target = 3, return true. + + end = 11 mid = 5 col = 4 + + time : O(log(n * m)); + space : O(1) + + * @param matrix + * @param target + * @return + */ + public boolean searchMatrix(int[][] matrix, int target) { + if (matrix == null || matrix.length == 0) return false; + int row = matrix.length; + int col = matrix[0].length; + int begin = 0, end = row * col - 1; + while (begin <= end) { + int mid = (end - begin) / 2 + begin; + int value = matrix[mid / col][mid % col]; + if (value == target) { + return true; + } else if (value < target) { + begin = mid + 1; + } else { + end = mid - 1; + } + } + return false; + } +} diff --git a/Searcha2DMatrixII.java b/Searcha2DMatrixII.java new file mode 100644 index 0000000..f3978bd --- /dev/null +++ b/Searcha2DMatrixII.java @@ -0,0 +1,56 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : Searcha2DMatrixII + * Creator : Edward + * Date : Nov, 2017 + * Description : 240. Search a 2D Matrix II + */ +public class Searcha2DMatrixII { + /** + * Write an efficient algorithm that searches for a value in an m x n matrix. + * This matrix has the following properties: + + Integers in each row are sorted in ascending from left to right. + Integers in each column are sorted in ascending from top to bottom. + For example, + + Consider the following matrix: + + [ + [1, 4, 7, 11, 15], + [2, 5, 8, 12, 19], + [3, 6, 9, 16, 22], + [10, 13, 14, 17, 24], + [18, 21, 23, 26, 30] + ] + Given target = 5, return true. + + Given target = 20, return false. + + time : O(m + n) + space : O(1) + + * @param matrix + * @param target + * @return + */ + public boolean searchMatrix(int[][] matrix, int target) { + if (matrix == null || matrix.length == 0) return false; + int row = 0; + int col = matrix[0].length - 1; + + while (col >= 0 && row <= matrix.length - 1) { + if (target == matrix[row][col]) { + return true; + } else if (target < matrix[row][col]) { + col--; + } else { + row++; + } + } + return false; + } +} diff --git a/SearchforaRange.java b/SearchforaRange.java new file mode 100644 index 0000000..2e6f7d8 --- /dev/null +++ b/SearchforaRange.java @@ -0,0 +1,70 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SearchforaRange + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class SearchforaRange { + /** + * 34. Search for a Range + * Given an array of integers sorted in ascending order, find the starting and ending + * position of a given target value. + + Your algorithm's runtime complexity must be in the order of O(log n). + + If the target is not found in the array, return [-1, -1]. + + For example, + Given [5, 7, 7, 8, 8, 10] and target value 8, + return [3, 4]. + + time : O(logn) + space : O(1); + * @param nums + * @param target + * @return + */ + public int[] searchRange(int[] nums, int target) { + if (nums == null || nums.length == 0) return new int[]{-1, -1}; + int start = findFirst(nums, target); + if (start == -1) return new int[]{-1, -1}; + int end = findLast(nums, target); + return new int[]{start, end}; + } + + public int findFirst(int[] nums, int target) { + int start = 0; + int end = nums.length - 1; + while (start + 1 < end) { + int mid = (end - start) / 2 + start; + if (nums[mid] < target) { + start = mid; + } else { + end = mid; + } + } + if (nums[start] == target) return start; + if (nums[end] == target) return end; + return -1; + } + + public int findLast(int[] nums, int target) { + int start = 0; + int end = nums.length - 1; + while (start + 1 < end) { + int mid = (end - start) / 2 + start; + if (nums[mid] > target) { + end = mid; + } else { + start = mid; + } + } + if (nums[end] == target) return end; + if (nums[start] == target) return start; + return -1; + } +} diff --git a/SearchinRotatedSortedArray.java b/SearchinRotatedSortedArray.java new file mode 100644 index 0000000..860684b --- /dev/null +++ b/SearchinRotatedSortedArray.java @@ -0,0 +1,54 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SearchinRotatedSortedArray + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class SearchinRotatedSortedArray { + + /** + * 33. Search in Rotated Sorted Array + * Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. + + (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). + + You are given a target value to search. If found in the array return its index, otherwise return -1. + + You may assume no duplicate exists in the array. + + 4 5 6 7 0 1 2 + + 4 5 6 0 1 2 3 + + time : O(logn); + space : O(1); + * @param nums + * @param target + * @return + */ + public int search(int[] nums, int target) { + if (nums == null || nums.length == 0) return -1; + int start = 0; + int end = nums.length - 1; + while (start + 1 < end) { + int mid = (end - start) / 2 + start; + if (nums[mid] == target) return mid; + if (nums[start] < nums[mid]) { + if (nums[start] <= target && target <= nums[mid]) { + end = mid; + } else start = mid; + } else { + if (nums[mid] <= target && target <= nums[end]) { + start = mid; + } else end = mid; + } + } + if (nums[start] == target) return start; + if (nums[end] == target) return end; + return -1; + } +} diff --git a/SearchinRotatedSortedArrayII.java b/SearchinRotatedSortedArrayII.java new file mode 100644 index 0000000..266bd74 --- /dev/null +++ b/SearchinRotatedSortedArrayII.java @@ -0,0 +1,49 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SearchinRotatedSortedArrayII + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class SearchinRotatedSortedArrayII { + + /** + * 81. Search in Rotated Sorted Array II + * Follow up for "Search in Rotated Sorted Array": + What if duplicates are allowed? + + 1 1 1 3 1 + + time : O(logn) (worst : O(n)) + space : O(1); + * @param nums + * @param target + * @return + */ + + public boolean search(int[] nums, int target) { + if (nums == null || nums.length == 0) return false; + int start = 0; + int end = nums.length - 1; + while (start + 1 < end) { + int mid = (end - start) / 2 + start; + if (nums[mid] == target) return true; + if (nums[start] == nums[mid] && nums[mid] == nums[end]) { + start++; + end--; + } else if (nums[start] <= nums[mid]) { + if (nums[start] <= target && target <= nums[mid]) end = mid; + else start = mid; + } else { + if (nums[mid] <= target && target <= nums[end]) start = mid; + else end = mid; + } + } + if (nums[start] == target) return true; + if (nums[end] == target) return true; + return false; + } +} diff --git a/SelfCrossing.java b/SelfCrossing.java new file mode 100644 index 0000000..81bfdb1 --- /dev/null +++ b/SelfCrossing.java @@ -0,0 +1,83 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SelfCrossing + * Creator : Edward + * Date : Jan, 2018 + * Description : 335. Self Crossing + */ +public class SelfCrossing { + /** + * You are given an array x of n positive numbers. You start at point (0,0) + * and moves x[0] metres to the north, then x[1] metres to the west, + * x[2] metres to the south, x[3] metres to the east and so on. + * In other words, after each move your direction changes counter-clockwise. + + Write a one-pass algorithm with O(1) extra space to determine, if your path crosses itself, or not. + + Example 1: + Given x = [2, 1, 1, 2], + ????? + ? ? + ???????> + ? + + Return true (self crossing) + Example 2: + Given x = [1, 2, 3, 4], + ???????? + ? ? + ? + ? + ?????????????> + + Return false (not self crossing) + Example 3: + Given x = [1, 1, 1, 1], + ????? + ? ? + ?????> + + Return true (self crossing) + + time : O(n) + space : O(1) + + * @param x + * @return + */ + + /* i-2 + case 1 : i-1┌─┐ + └─┼─>i + i-3 + + i-2 + case 2 : i-1 ┌────┐ + └─══>┘i-3 + i i-4 (i overlapped i-4) + + case 3 : i-4 + ┌──┐ + │i<┼─┐ + i-3│ i-5│i-1 + └────┘ + i-2 + + */ + public boolean isSelfCrossing(int[] x) { + for (int i = 3, l = x.length; i < l; i++) { + if (x[i] >= x[i - 2] && x[i - 1] <= x[i - 3]) { + return true; + } else if (i >= 4 && x[i - 1] == x[i - 3] && x[i] + x[i - 4] >= x[i - 2]) { + return true; + } else if (i >= 5 && x[i - 2] >= x[i - 4] && x[i] + x[i - 4] >= x[i - 2] + && x[i - 1] <= x[i - 3] && x[i - 1] + x[i - 5] >= x[i - 3]) { + return true; + } + } + return false; + } +} diff --git a/SerializeandDeserializeBST.java b/SerializeandDeserializeBST.java new file mode 100644 index 0000000..2851ac6 --- /dev/null +++ b/SerializeandDeserializeBST.java @@ -0,0 +1,68 @@ +package leetcode; + +import java.util.LinkedList; +import java.util.Queue; +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SerializeandDeserializeBST + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class SerializeandDeserializeBST { + /** + * 449. Serialize and Deserialize BST + * + 5 + / \ + 4 6 + / \ + 1 8 + + time : O(n); + space : O(n); + * @param root + * @return + */ + + // Encodes a tree to a single string. + public String serialize(TreeNode root) { + if (root == null) return ""; + StringBuilder res = new StringBuilder(); + Stack stack = new Stack<>(); + stack.push(root); + while (!stack.isEmpty()) { + TreeNode cur = stack.pop(); + res.append(cur.val + " "); + if (cur.right != null) stack.push(cur.right); + if (cur.left != null) stack.push(cur.left); + } + return res.toString(); + } + + // Decodes your encoded data to tree. + public TreeNode deserialize(String data) { + if (data == "") return null; + String[] str = data.split(" "); + Queue queue = new LinkedList<>(); + for (String s : str) { + queue.offer(Integer.parseInt(s)); + } + return getNode(queue); + } + + public TreeNode getNode(Queue queue) { + if (queue.isEmpty()) return null; + TreeNode root = new TreeNode(queue.poll()); + Queue smallerQ = new LinkedList<>(); + while (!queue.isEmpty() && queue.peek() < root.val) { + smallerQ.offer(queue.poll()); + } + root.left = getNode(smallerQ); + root.right = getNode(queue); + return root; + } +} diff --git a/SerializeandDeserializeBinaryTree.java b/SerializeandDeserializeBinaryTree.java new file mode 100644 index 0000000..617909f --- /dev/null +++ b/SerializeandDeserializeBinaryTree.java @@ -0,0 +1,70 @@ +package leetcode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SerializeandDeserializeBinaryTree + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class SerializeandDeserializeBinaryTree { + + /** + * 297. Serialize and Deserialize Binary Tree + * + * + 1 + / \ + 2 3 + / \ + 4 5 + as "[1,2,3,null,null,4,5]" + * time : O(n); + * space : O(n); + * @param root + * @return + */ + // Encodes a tree to a single string. + public String serialize(TreeNode root) { + if (root == null) return ""; + StringBuilder res = new StringBuilder(); + Queue queue = new LinkedList<>(); + queue.offer(root); + while (!queue.isEmpty()) { + TreeNode cur = queue.poll(); + if (cur == null) { + res.append("null "); + continue; + } + res.append(cur.val + " "); + queue.offer(cur.left); + queue.offer(cur.right); + } + return res.toString(); + } + + // Decodes your encoded data to tree. + public TreeNode deserialize(String data) { + if (data == "") return null; + String[] str = data.split(" "); + TreeNode root = new TreeNode(Integer.parseInt(str[0])); + Queue queue = new LinkedList<>(); + queue.offer(root); + for (int i = 1; i < str.length; i++) { + TreeNode cur = queue.poll(); + if (!str[i].equals("null")) { + cur.left = new TreeNode(Integer.parseInt(str[i])); + queue.offer(cur.left); + } + if (!str[++i].equals("null")) { + cur.right = new TreeNode(Integer.parseInt(str[i])); + queue.offer(cur.right); + } + } + return root; + } +} diff --git a/SetMatrixZeroes.java b/SetMatrixZeroes.java new file mode 100644 index 0000000..7265328 --- /dev/null +++ b/SetMatrixZeroes.java @@ -0,0 +1,67 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SetMatrixZeroes + * Creator : Edward + * Date : Oct, 2017 + * Description : 73. Set Matrix Zeroes + */ +public class SetMatrixZeroes { + /** + + [ + [1, 0, 1, 1], + [1, 1, 0, 0], + [0, 1, 1, 1], + [1, 1, 1, 1] + ] + + time : O(n * m) + space : O(1) + + * @param matrix + */ + public void setZeroes(int[][] matrix) { + if (matrix == null || matrix.length == 0) return; + int m = matrix.length; + int n = matrix[0].length; + boolean row = false; + boolean col = false; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (matrix[i][j] == 0) { + matrix[0][j] = 0; + matrix[i][0] = 0; + if (i == 0) row = true; + if (j == 0) col = true; + } + } + } + for (int i = 1; i < m; i++) { + if (matrix[i][0] == 0) { + for (int j = 1; j < n; j++) { + matrix[i][j] = 0; + } + } + } + for (int j = 1; j < n; j++) { + if (matrix[0][j] == 0) { + for (int i = 1; i < m; i++) { + matrix[i][j] = 0; + } + } + } + if (row) { + for (int j = 0; j < n; j++) { + matrix[0][j] = 0; + } + } + if (col) { + for (int i = 0; i < m; i++) { + matrix[i][0] = 0; + } + } + } +} diff --git a/ShortestDistancefromAllBuildings.java b/ShortestDistancefromAllBuildings.java new file mode 100644 index 0000000..2419d59 --- /dev/null +++ b/ShortestDistancefromAllBuildings.java @@ -0,0 +1,146 @@ +package leetcode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ShortestDistancefromAllBuildings + * Creator : Edward + * Date : Jan, 2018 + * Description : 317. Shortest Distance from All Buildings + */ +public class ShortestDistancefromAllBuildings { + /** + * You want to build a house on an empty land which reaches all buildings + * in the shortest amount of distance. You can only move up, down, left and right. + * You are given a 2D grid of values 0, 1 or 2, where: + + Each 0 marks an empty land which you can pass by freely. + Each 1 marks a building which you cannot pass through. + Each 2 marks an obstacle which you cannot pass through. + For example, given three buildings at (0,0), (0,4), (2,2), and an obstacle at (0,2): + + 1 - 0 - 2 - 0 - 1 + | | | | | + 0 - 0 - 0 - 0 - 0 + | | | | | + 0 - 0 - 1 - 0 - 0 + + The point (1,2) is an ideal empty land to build a house, + as the total travel distance of 3+3+1=7 is minimal. So return 7. + + + int[][] dist + int[][] nums + + for + for + if (grid[i][j] == '1') + BFS + + * time: O(m^2 * n^2) + * space: O(mn) + * @param grid + * @return + */ + + public int shortestDistance(int[][] grid) { + if (grid == null || grid.length == 0) return -1; + int m = grid.length; + int n = grid[0].length; + int[][] dist = new int[m][n]; + int[][] nums = new int[m][n]; + int buildingNum = 0; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (grid[i][j] == 1) { + buildingNum++; + bfs(grid, i, j, dist, nums); + } + } + } + + int res = Integer.MAX_VALUE; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (grid[i][j] == 0 && dist[i][j] != 0 && nums[i][j] == buildingNum) { + res = Math.min(res, dist[i][j]); + } + } + } + return res == Integer.MAX_VALUE ? -1 : res; + } + + /** + 1 - 0 - 2 - 0 - 1 + | | | | | + 0 - 0 - 0 - 0 - 0 + | | | | | + 0 - 0 - 1 - 0 - 0 + + visited : + 1 - 0 - 0 - 0 - 0 + | | | | | + 0 - 0 - 0 - 0 - 0 + | | | | | + 0 - 0 - 0 - 0 - 0 + + dist : + 0 - 1 - 0 - 0 - 0 + | | | | | + 1 - 0 - 0 - 0 - 0 + | | | | | + 0 - 0 - 0 - 0 - 0 + + nums : + 0 - 1 - 0 - 0 - 0 + | | | | | + 1 - 0 - 0 - 0 - 0 + | | | | | + 0 - 0 - 0 - 0 - 0 + queue : (0,0) + queue : (0,1) (1,0) + queue : () + + + * @param grid + * @param row + * @param col + * @param dist + * @param nums + */ + + private void bfs(int[][] grid, int row, int col, int[][] dist, int[][] nums) { + int m = grid.length; + int n = grid[0].length; + + Queue queue = new LinkedList<>(); + queue.offer(new int[]{row, col}); + + int[][] dirs = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; + boolean[][] visited = new boolean[m][n]; + int distance = 0; + + while (!queue.isEmpty()) { + distance++; + int size = queue.size(); + for (int i = 0; i < size; i++) { + int[] cur = queue.poll(); + for (int k = 0; k < dirs.length; k++) { + int x = cur[0] + dirs[k][0]; + int y = cur[1] + dirs[k][1]; + if (x >= 0 && x < m && y >= 0 && y < n && !visited[x][y] && grid[x][y] == 0) { + visited[x][y] = true; + dist[x][y] += distance; + nums[x][y]++; + queue.offer(new int[]{x, y}); + } + } + } + } + + + } +} diff --git a/ShortestPalindrome.java b/ShortestPalindrome.java new file mode 100644 index 0000000..a04fcac --- /dev/null +++ b/ShortestPalindrome.java @@ -0,0 +1,52 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ShortestPalindrome + * Creator : Edward + * Date : Dec, 2017 + * Description : 214. Shortest Palindrome + */ +public class ShortestPalindrome { + /** + * Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. + * Find and return the shortest palindrome you can find by performing this transformation. + + For example: + + Given "aacecaaa", return "aaacecaaa". + + Given "abcd", return "dcbabcd". + + I agree for smaller strings charAt function may be fast. But when coming to big strings, + I think the scenario is different. Because when I see the code for string last night + I have found that toCharArray uses function System.arraycopy. + We know System.arraycopy(I think it is native call) is faster. + + So when we use for loop based operations on String, we are directly moving to index for char array whereas + we need to call the function for charAt. So for Bigger strings calling the function multiple times + may reduce the performance of the method. + + + * @param s + * @return + */ + + // time : O(n^2) for aaaaabcaaaaa + public String shortestPalindrome(String s) { + int i = 0, j = s.length() - 1; + int end = s.length() - 1; + while (i < j) { + if (s.charAt(i) == s.charAt(j)) { + i++; + j--; + } else { + i = 0; + end--; + j = end; + } + } + return new StringBuilder(s.substring(end + 1)).reverse().toString() + s; + } +} diff --git a/ShortestWordDistance.java b/ShortestWordDistance.java new file mode 100644 index 0000000..9955be8 --- /dev/null +++ b/ShortestWordDistance.java @@ -0,0 +1,67 @@ +package leetcode; + +import sun.nio.cs.ext.MacHebrew; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ShortestWordDistance + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class ShortestWordDistance { + /** + * 243. Shortest Word Distance + * Given a list of words and two words word1 and word2, return the shortest distance + * between these two words in the list. + + For example, + Assume that words = ["practice", "makes", "perfect", "coding", "makes"]. + + Given word1 = “coding”, word2 = “practice”, return 3. + Given word1 = "makes", word2 = "coding", return 1. + + Note: + You may assume that word1 does not equal to word2, and word1 and word2 are both in the list. + + space : O(1); + * @param words + * @param word1 + * @param word2 + * @return + */ + + //time : O(n^2); + public static int shortestDistance(String[] words, String word1, String word2) { + int res = words.length; + for (int i = 0; i < words.length; i++) { + if (words[i].equals(word1)) { + for (int j = 0; j < words.length; j++) { + if (words[j].equals(word2)) { + res = Math.min(res, Math.abs(i - j)); + } + } + } + } + return res; + } + + //time : O(n); + public static int shortestDistance2(String[] words, String word1, String word2) { + int res = words.length; + int a = -1; + int b = -1; + for (int i = 0; i < words.length; i++) { + if (words[i].equals(word1)) { + a = i; + } else if (words[i].equals(word2)) { + b = i; + } + if (a != -1 && b != -1) { + res = Math.min(res, Math.abs(a - b)); + } + } + return res; + } +} diff --git a/ShortestWordDistanceII.java b/ShortestWordDistanceII.java new file mode 100644 index 0000000..e327326 --- /dev/null +++ b/ShortestWordDistanceII.java @@ -0,0 +1,83 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ShortestWordDistanceII + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class ShortestWordDistanceII { + + /** + * 244. Shortest Word Distance II + *This is a follow up of Shortest Word Distance. The only difference is now you are given the list of words and your method will be called repeatedly many times with different parameters. How would you optimize it? + + Design a class which receives a list of words in the constructor, and implements a method that takes two words word1 and word2 and return the shortest distance between these two words in the list. + + For example, + Assume that words = ["practice", "makes", "perfect", "coding", "makes"]. + + Given word1 = “coding”, word2 = “practice”, return 3. + Given word1 = "makes", word2 = "coding", return 1. + + + space : O(n); + * @param words + */ + + //ShortestWordDistanceII 这个题在leetcode中构造函数是 WordDistance + + private HashMap> map; + + + public ShortestWordDistanceII(String[] words) { + map = new HashMap<>(); + for (int i = 0; i < words.length; i++) { + if (map.containsKey(words[i])) { + map.get(words[i]).add(i); + } else { + List list = new ArrayList<>(); + list.add(i); + map.put(words[i], list); + } + } + } + + //time : O(n * m) + public int shortest(String word1, String word2) { + List l1 = map.get(word1); + List l2 = map.get(word2); + int res = Integer.MAX_VALUE; + for (Integer num1 : l1) { + for (Integer num2 : l2) { + res = Math.min(res, Math.abs(num1 - num2)); + } + } + return res; + } + + //time : O(n + m) + public int shortest2(String word1, String word2) { + List l1 = map.get(word1); + List l2 = map.get(word2); + int res = Integer.MAX_VALUE; + int i = 0; + int j = 0; + while (i < l1.size() && j < l2.size()) { + res = Math.min(res, Math.abs(l1.get(i) - l2.get(j))); + if (l1.get(i) < l2.get(j)) { + i++; + } else { + j++; + } + } + return res; + } + +} diff --git a/ShortestWordDistanceIII.java b/ShortestWordDistanceIII.java new file mode 100644 index 0000000..dd6f460 --- /dev/null +++ b/ShortestWordDistanceIII.java @@ -0,0 +1,54 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ShortestWordDistanceIII + * Creator : Edward + * Date : Dec, 2017 + * Description : 245. Shortest Word Distance III + */ +public class ShortestWordDistanceIII { + /** + * This is a follow up of Shortest Word Distance. The only difference is now word1 could be the same as word2. + + Given a list of words and two words word1 and word2, return the shortest distance between these two words in the list. + + word1 and word2 may be the same and they represent two individual words in the list. + + For example, + Assume that words = ["practice", "makes", "perfect", "coding", "makes"]. + + Given word1 = “makes”, word2 = “coding”, return 1. + Given word1 = "makes", word2 = "makes", return 3. + + time : O(n) + space : O(1) + + + * @param words + * @param word1 + * @param word2 + * @return + */ + public int shortestWordDistance(String[] words, String word1, String word2) { + int res = words.length; + int a = -1; + int b = -1; + for (int i = 0; i < words.length; i++) { + if (words[i].equals(word1)) { + a = i; + } + if (words[i].equals(word2)) { + if (word1.equals(word2)) { + a = b; + } + b = i; + } + if (a != -1 && b != -1) { + res = Math.min(res, Math.abs(a - b)); + } + } + return res; + } +} diff --git a/ShuffleanArray.java b/ShuffleanArray.java new file mode 100644 index 0000000..d81d2f1 --- /dev/null +++ b/ShuffleanArray.java @@ -0,0 +1,62 @@ +package leetcode; + +import java.util.Random; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ShuffleanArray + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class ShuffleanArray { + /** + * 384. Shuffle an Array + * // Init an array with set 1, 2, and 3. + int[] nums = {1,2,3}; + Solution solution = new Solution(nums); + + // Shuffle the array [1,2,3] and return its result. Any permutation of [1,2,3] must equally likely to be returned. + solution.shuffle(); + + // Resets the array back to its original configuration [1,2,3]. + solution.reset(); + + // Returns the random shuffling of array [1,2,3]. + solution.shuffle(); + + time : O(n) + * @param nums + */ + + private int[] nums; + private Random rmd; + + // 题中第构造函数时Solution + public ShuffleanArray(int[] nums) { + this.nums = nums; + rmd = new Random(); + } + + /** Resets the array to its original configuration and return it. */ + public int[] reset() { + return nums; + } + + /** Returns a random shuffling of the array. */ + public int[] shuffle() { + if (nums == null) return null; + int[] clone = nums.clone(); + for (int i = 1; i < clone.length; i++) { + int random = rmd.nextInt(i + 1); + swap(clone, i, random); + } + return clone; + } + private void swap(int[] clone, int i, int j) { + int temp = clone[i]; + clone[i] = clone[j]; + clone[j] = temp; + } +} diff --git a/SimplifyPath.java b/SimplifyPath.java new file mode 100644 index 0000000..80a5056 --- /dev/null +++ b/SimplifyPath.java @@ -0,0 +1,49 @@ +package leetcode; + +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SimplifyPath + * Creator : Edward + * Date : Nov, 2017 + * Description : 71. Simplify Path + */ +public class SimplifyPath { + /** + * Given an absolute path for a file (Unix-style), simplify it. + + For example, + path = "/home/", => "/home" + path = "/a/./b/../../c/", => "/c" + + time : O(n) + space :O(n) + + + * @param path + * @return + */ + public String simplifyPath(String path) { + Stack stack = new Stack<>(); + String[] paths = path.split("/+"); + for (String s : paths) { + if (s.equals("..")) { + if (!stack.isEmpty()) { + stack.pop(); + } + } else if (!s.equals(".") && !s.equals("")) { + stack.push(s); + } + } + String res = ""; + while (!stack.isEmpty()) { + res = "/" + stack.pop() + res; + } + if (res.length() == 0) { + return "/"; + } + return res; + } +} diff --git a/SingleNumber.java b/SingleNumber.java new file mode 100644 index 0000000..0dccd65 --- /dev/null +++ b/SingleNumber.java @@ -0,0 +1,33 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SingleNumber + * Creator : Edward + * Date : Oct, 2017 + * Description : 136. Single Number + */ +public class SingleNumber { + /** + * Given an array of integers, every element appears twice except for one. Find that single one. + * + * ^ : 异或 : 相同为0,不同为1 + * 1 1 : 0 + * 0 0 : 0 + * 1 0 : 1 + * 0 1 : 1 + * + * time : O(n) space : O(1) + * + * @param nums + * @return + */ + public int singleNumber(int[] nums) { + int res = 0; + for (int i = 0; i < nums.length; i++) { + res ^= nums[i]; + } + return res; + } +} diff --git a/SingleNumberII.java b/SingleNumberII.java new file mode 100644 index 0000000..32bf8f5 --- /dev/null +++ b/SingleNumberII.java @@ -0,0 +1,45 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SingleNumberII + * Creator : Edward + * Date : Nov, 2017 + * Description : 137. Single Number II + */ +public class SingleNumberII { + /** + * Given an array of integers, every element appears three times except for one, which appears exactly once. + * Find that single one + + 0 -> 1 -> 2 -> 0 + 00 -> 01 -> 10 -> 00 + 00 -> 10 -> 01 -> 00 + + ones twos + 0 0 + 0 -> 1 0 -> 0 + 1 -> 0 0 -> 1 + 0 -> 0 1 -> 0 + + 1, 存入ones里 + 2,清空ones 存入twos + 3,twos进行清空 + + time : O(n) + space : O(1) + + + * @param nums + * @return + */ + public int singleNumber(int[] nums) { + int ones = 0, twos = 0; + for (int i = 0; i < nums.length; i++) { + ones = (ones ^ nums[i]) & ~twos; + twos = (twos ^ nums[i]) & ~ones; + } + return ones; + } +} diff --git a/SingleNumberIII.java b/SingleNumberIII.java new file mode 100644 index 0000000..2d1dd2d --- /dev/null +++ b/SingleNumberIII.java @@ -0,0 +1,56 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SingleNumberIII + * Creator : Edward + * Date : Dec, 2017 + * Description : 260. Single Number III + */ +public class SingleNumberIII { + /** + * Given an array of numbers nums, in which exactly two elements appear only once and + * all the other elements appear exactly twice. Find the two elements that appear only once. + + For example: + + Given nums = [1, 2, 1, 3, 2, 5], return [3, 5]. + + A B : 二进制数字有且至少有一位是不相同 + + 3 : 011 + 5 : 101 + + 3 ^ 5 : 110 -- 6 + -6 : 11111111111111111111111111111010 + 6 & -6 : 000010 + + 1, 2, 1, 3, 2, 5 + + diff = 3 ^ 5 + + time : O(n) + space : O(1) + + + * @param nums + * @return + */ + public int[] singleNumber(int[] nums) { + int diff = 0; + for (int num : nums) { + diff ^= num; + } + diff &= -diff; + int[] res = new int[2]; + for (int num : nums) { + if ((num & diff) == 0) { + res[0] ^= num; + } else { + res[1] ^= num; + } + } + return res; + } +} diff --git a/SlidingWindowMaximum.java b/SlidingWindowMaximum.java new file mode 100644 index 0000000..e562e6e --- /dev/null +++ b/SlidingWindowMaximum.java @@ -0,0 +1,59 @@ +package leetcode; + +import java.util.Deque; +import java.util.LinkedList; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SlidingWindowMaximum + * Creator : Edward + * Date : Nov, 2017 + * Description : 239. Sliding Window Maximum + */ +public class SlidingWindowMaximum { + /** + * For example, + Given nums = [1,3,-1,-3,5,3,6,7], and k = 3. + + Window position Max + --------------- ----- + [1 3 -1] -3 5 3 6 7 3 + 1 [3 -1 -3] 5 3 6 7 3 + 1 3 [-1 -3 5] 3 6 7 5 + 1 3 -1 [-3 5 3] 6 7 5 + 1 3 -1 -3 [5 3 6] 7 6 + 1 3 -1 -3 5 [3 6 7] 7 + Therefore, return the max sliding window as [3,3,5,5,6,7]. + + Deque : 存的是index 从大到小排序 + + time : O(n) + space : O(n) + + * @param nums + * @param k + * @return + */ + + public int[] maxSlidingWindow(int[] nums, int k) { + if (nums == null || nums.length == 0) { + return new int[0]; + } + Deque deque = new LinkedList<>(); + int[] res = new int[nums.length + 1 - k]; + for (int i = 0; i < nums.length; i++) { + if (!deque.isEmpty() && deque.peekFirst() == i - k) { + deque.poll(); + } + while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) { + deque.removeLast(); + } + deque.offerLast(i); + if ((i + 1) >= k) { + res[i + 1 - k] = nums[deque.peek()]; + } + } + return res; + } +} diff --git a/SmallestRectangleEnclosingBlackPixels.java b/SmallestRectangleEnclosingBlackPixels.java new file mode 100644 index 0000000..b4185bd --- /dev/null +++ b/SmallestRectangleEnclosingBlackPixels.java @@ -0,0 +1,97 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SmallestRectangleEnclosingBlackPixels + * Creator : Edward + * Date : Jan, 2018 + * Description : 302. Smallest Rectangle Enclosing Black Pixels + */ +public class SmallestRectangleEnclosingBlackPixels { + /** + * An image is represented by a binary matrix with 0 as a white pixel and 1 as a black pixel. + * The black pixels are connected, i.e., there is only one black region. + * Pixels are connected horizontally and vertically. Given the location (x, y) of + * one of the black pixels, return the area of the smallest (axis-aligned) rectangle + * that encloses all black pixels. + + For example, given the following image: + + [ + "0010", + "0110", + "0100" + ] + + 011 + 011 + 011 + + and x = 0, y = 2, + Return 6. + + time : O(m log n + n log m) + space : O(1) + + * @param image + * @param x + * @param y + * @return + */ + public int minArea(char[][] image, int x, int y) { + int row = image.length; + int col = image[0].length; + + int left = binarySearchLeft(image, 0, y, true); + int right = binarySearchRight(image, y, col - 1, true); + + int top = binarySearchLeft(image, 0, x, false); + int bottom = binarySearchRight(image, x, row - 1, false); + + return (right - left + 1) * (bottom - top + 1); + } + + private int binarySearchLeft(char[][] image, int left, int right, boolean isHor) { + while (left + 1 < right) { + int mid = (right - left) / 2 + left; + if (hasBlack(image, mid, isHor)) { + right = mid; + } else { + left = mid; + } + } + if (hasBlack(image, left, isHor)) { + return left; + } + return right; + } + + private int binarySearchRight(char[][] image, int left, int right, boolean isHor) { + while (left + 1 < right) { + int mid = (right - left) / 2 + left; + if (hasBlack(image, mid, isHor)) { + left = mid; + } else { + right = mid; + } + } + if (hasBlack(image, right, isHor)) { + return right; + } + return left; + } + + private boolean hasBlack(char[][] image, int x, boolean isHor) { + if (isHor) { + for (int i = 0; i < image.length; i++) { + if (image[i][x] == '1') return true; + } + } else { + for (int i = 0; i < image[0].length; i++) { + if (image[x][i] == '1') return true; + } + } + return false; + } +} diff --git a/SortColors.java b/SortColors.java new file mode 100644 index 0000000..49b5ddb --- /dev/null +++ b/SortColors.java @@ -0,0 +1,45 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SortColors + * Creator : Edward + * Date : Dec, 2017 + * Description : 75. Sort Colors + */ +public class SortColors { + /** + * Given an array with n objects colored red, white or blue, + * sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue. + + Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively. + + time : O(n) + space : O(1) + + * @param nums + */ + + public void sortColors(int[] nums) { + if (nums == null || nums.length == 0) return; + int left = 0; + int right = nums.length - 1; + int index = 0; + while (index <= right) { + if (nums[index] == 0) { + swap(nums, index++, left++); + } else if (nums[index] == 1) { + index++; + } else { + swap(nums, index, right--); + } + } + } + + public void swap(int[] nums, int i, int j) { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } +} diff --git a/SortList.java b/SortList.java new file mode 100644 index 0000000..12b6459 --- /dev/null +++ b/SortList.java @@ -0,0 +1,56 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SortList + * Creator : Edward + * Date : Oct, 2017 + * Description : 148. Sort List + */ +public class SortList { + /** + * Sort a linked list in O(n log n) time using constant space complexity. + * + * time : O(nlogn) + * space : O(n) + * + * @param head + * @return + */ + + public ListNode sortList(ListNode head) { + if (head == null || head.next == null) return head; + ListNode middle = getMiddle(head); + ListNode next = middle.next; + middle.next = null; + return merge(sortList(head), sortList(next)); + } + + private ListNode getMiddle(ListNode head) { + ListNode slow = head; + ListNode fast = head; + while (fast.next != null && fast.next.next != null) { + slow = slow.next; + fast = fast.next.next; + } + return slow; + } + private ListNode merge(ListNode a, ListNode b) { + ListNode dummy = new ListNode(0); + ListNode cur = dummy; + while (a != null && b != null) { + if (a.val <= b.val) { + cur.next = a; + a = a.next; + } else { + cur.next = b; + b = b.next; + } + cur = cur.next; + } + if (a == null) cur.next = b; + else cur.next = a; + return dummy.next; + } +} diff --git a/SortTransformedArray.java b/SortTransformedArray.java new file mode 100644 index 0000000..66b5ecb --- /dev/null +++ b/SortTransformedArray.java @@ -0,0 +1,70 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SortTransformedArray + * Creator : Edward + * Date : Jan, 2018 + * Description : 360. Sort Transformed Array + */ +public class SortTransformedArray { + /** + * Given a sorted array of integers nums and integer values a, b and c. + * Apply a quadratic function of the form f(x) = ax2 + bx + c to each element x in the array. + + The returned array must be in sorted order. + + Expected time complexity: O(n) + + Example: + nums = [-4, -2, 2, 4], a = 1, b = 3, c = 5, + + Result: [3, 9, 15, 33] + + nums = [-4, -2, 2, 4], a = -1, b = 3, c = 5 + + Result: [-23, -5, 1, 7] + + time : O(n) + space : O(n) + + * @param nums + * @param a + * @param b + * @param c + * @return + */ + public int[] sortTransformedArray(int[] nums, int a, int b, int c) { + int[] res = new int[nums.length]; + int start = 0; + int end = nums.length - 1; + int i = a >= 0 ? nums.length - 1 : 0; + while (start <= end) { + int startNum = getNum(nums[start], a, b, c); + int endNum = getNum(nums[end], a, b, c); + if (a >= 0) { + if (startNum >= endNum) { + res[i--] = startNum; + start++; + } else { + res[i--] = endNum; + end--; + } + } else { + if (startNum <= endNum) { + res[i++] = startNum; + start++; + } else { + res[i--] = endNum; + end--; + } + } + } + return res; + } + + private int getNum(int x, int a, int b, int c) { + return a * x * x + b * x + c; + } +} diff --git a/SparseMatrixMultiplication.java b/SparseMatrixMultiplication.java new file mode 100644 index 0000000..aca9b92 --- /dev/null +++ b/SparseMatrixMultiplication.java @@ -0,0 +1,53 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SparseMatrixMultiplication + * Creator : Edward + * Date : Oct, 2017 + * Description : 311. Sparse Matrix Multiplication + */ +public class SparseMatrixMultiplication { + /** + * Example: + + A = [ + [ 1, 0, 0], + [-1, 0, 3] + ] + + B = [ + [ 7, 0, 0 ], + [ 0, 0, 0 ], + [ 0, 0, 1 ] + ] + + | 1 0 0 | | 7 0 0 | | 7 0 0 | + AB = | -1 0 3 | x | 0 0 0 | = | -7 0 3 | + | 0 0 1 | + + time : O(m * n *nB) + space : O(m * nB) + + * @param A + * @param B + * @return + */ + public int[][] multiply(int[][] A, int[][] B) { + int m = A.length, n = A[0].length; + int nB = B[0].length; + int[][] res = new int[m][nB]; + + for (int i = 0; i < m; i++) { + for (int k = 0; k < n; k++) { + if (A[i][k] != 0) { + for (int j = 0; j < nB; j++) { + if (B[k][j] != 0) res[i][j] += A[i][k] * B[k][j]; + } + } + } + } + return res; + } +} diff --git a/SpiralMatrix.java b/SpiralMatrix.java new file mode 100644 index 0000000..f094b55 --- /dev/null +++ b/SpiralMatrix.java @@ -0,0 +1,71 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SpiralMatrix + * Creator : Edward + * Date : Sep, 2017 + * Description : 54. Spiral Matrix + */ +public class SpiralMatrix { + /** + * For example, + Given the following matrix: + + [ + [ 1, 2, 3 ], + [ 4, 5, 6 ], + [ 7, 8, 9 ] + ] + You should return [1,2,3,6,9,8,7,4,5]. + + time : O(n * m) n * m : 总元素个数 + space : O(n * m) + + * @param matrix + * @return + */ + + public List spiralOrder(int[][] matrix) { + List res = new ArrayList<>(); + if (matrix == null || matrix.length == 0 || matrix[0] == null || matrix[0].length == 0) { + return res; + } + int rowBegin = 0; + int rowEnd = matrix.length - 1; + int colBegin = 0; + int colEnd = matrix[0].length - 1; + + while (rowBegin <= rowEnd && colBegin <= colEnd) { + for (int i = colBegin; i <= colEnd; i++) { + res.add(matrix[rowBegin][i]); + } + rowBegin++; + + for (int i = rowBegin; i <= rowEnd; i++) { + res.add(matrix[i][colEnd]); + } + colEnd--; + + if (rowBegin <= rowEnd) { + for (int i = colEnd; i >= colBegin; i--) { + res.add(matrix[rowEnd][i]); + } + } + rowEnd--; + + if (colBegin <= colEnd) { + for (int i = rowEnd; i >= rowBegin; i--) { + res.add(matrix[i][colBegin]); + } + } + colBegin++; + } + + return res; + } +} diff --git a/SpiralMatrixII.java b/SpiralMatrixII.java new file mode 100644 index 0000000..dfb01d7 --- /dev/null +++ b/SpiralMatrixII.java @@ -0,0 +1,65 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SpiralMatrixII + * Creator : Edward + * Date : Sep, 2017 + * Description : 59. Spiral Matrix II + */ +public class SpiralMatrixII { + + /** + *Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. + + For example, + Given n = 3, + + You should return the following matrix: + [ + [ 1, 2, 3 ], + [ 8, 9, 4 ], + [ 7, 6, 5 ] + ] + + time : O(n) n : 总元素个数 + space : O(n) + + * @param n + * @return + */ + + public int[][] generateMatrix(int n) { + + int[][] matrix = new int[n][n]; + int rowBegin = 0; + int rowEnd = n - 1; + int colBegin = 0; + int colEnd = n - 1; + int num = 1; + + while (rowBegin <= rowEnd && colBegin <= colEnd) { + for (int i = colBegin; i <= colEnd; i++) { + matrix[rowBegin][i] = num++; + } + rowBegin++; + + for (int i = rowBegin; i <= rowEnd; i++) { + matrix[i][colEnd] = num++; + } + colEnd--; + + for (int i = colEnd; i >= colBegin; i--) { + matrix[rowEnd][i] = num++; + } + rowEnd--; + + for (int i = rowEnd; i >= rowBegin; i--) { + matrix[i][colBegin] = num++; + } + colBegin++; + } + return matrix; + } +} diff --git a/Sqrt.java b/Sqrt.java new file mode 100644 index 0000000..de324bb --- /dev/null +++ b/Sqrt.java @@ -0,0 +1,47 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : Sqrt + * Creator : Edward + * Date : Oct, 2017 + * Description : 69. Sqrt(x) + */ +public class Sqrt { + // 367 Valid Perfect Square + + /** + * time : O(logn) space : O(1) + * @param x + * @return + */ + public int mySqrt(int x) { + if (x <= 0) return 0; + int low = 1, high = x; + while (low <= high) { + long mid = (high - low) / 2 + low; + if (mid * mid == x) { + return (int) mid; + } else if (mid * mid < x) { + low = (int) mid + 1; + } else { + high = (int) mid - 1; + } + } + if (high * high < x) { + return (int) high; + } else { + return (int) low; + } + } + + // Newton Method time : 不知道 space : O(1); + public int mySqrt2(int x) { + long res = x; + while (res * res > x) { + res = (res + x / res) / 2; + } + return (int) res; + } +} diff --git a/StringCompression.java b/StringCompression.java new file mode 100644 index 0000000..01a4bfe --- /dev/null +++ b/StringCompression.java @@ -0,0 +1,80 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : StringCompression + * Creator : Edward + * Date : Nov, 2017 + * Description : 443. String Compression + */ +public class StringCompression { + /** + * Given an array of characters, compress it in-place. + + The length after compression must always be smaller than or equal to the original array. + + Every element of the array should be a character (not int) of length 1. + + After you are done modifying the input array in-place, return the new length of the array. + + + Follow up: + Could you solve it using only O(1) extra space? + + + Example 1: + Input: + ["a","a","b","b","c","c","c"] + + Output: + Return 6, and the first 6 characters of the input array should be: ["a","2","b","2","c","3"] + + Explanation: + "aa" is replaced by "a2". "bb" is replaced by "b2". "ccc" is replaced by "c3". + Example 2: + Input: + ["a"] + + Output: + Return 1, and the first 1 characters of the input array should be: ["a"] + + Explanation: + Nothing is replaced. + Example 3: + Input: + ["a","b","b","b","b","b","b","b","b","b","b","b","b"] + + Output: + Return 4, and the first 4 characters of the input array should be: ["a","b","1","2"]. + + Explanation: + Since the character "a" does not repeat, it is not compressed. "bbbbbbbbbbbb" is replaced by "b12". + Notice each digit has it's own entry in the array. + + time : O(n) + space : O(1) + + * @param chars + * @return + */ + + public int compress(char[] chars) { + int res = 0, index = 0; + while (index < chars.length) { + char cur = chars[index]; + int count = 0; + while (index < chars.length && chars[index] == cur) { + index++; + count++; + } + chars[res++] = cur; + if (count != 1) { + for (char c : String.valueOf(count).toCharArray()) { + chars[res++] = c; + } + } + } + return res; + } +} diff --git a/StringtoInteger.java b/StringtoInteger.java new file mode 100644 index 0000000..09c88ed --- /dev/null +++ b/StringtoInteger.java @@ -0,0 +1,42 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : StringtoInteger + * Creator : Edward + * Date : Oct, 2017 + * Description : 8. String to Integer (atoi) + */ +public class StringtoInteger { + /** + * time : O(n) + * space : O(1) + * @param str + * @return + */ + public int myAtoi(String str) { + if (str == null || str.length() == 0) return 0; + str = str.trim(); + char firstChar = str.charAt(0); + int sign = 1; + int start = 0; + long res = 0; + if (firstChar == '+') { + sign = 1; + start++; + } else if (firstChar == '-') { + sign = -1; + start++; + } + for (int i = start; i < str.length(); i++) { + if (!Character.isDigit(str.charAt(i))) { + return (int) res * sign; + } + res = res * 10 + str.charAt(i) - '0'; + if (sign == 1 && res > Integer.MAX_VALUE) return Integer.MAX_VALUE; + if (sign == -1 && res > Integer.MAX_VALUE) return Integer.MIN_VALUE; + } + return (int) res * sign; + } +} diff --git a/StrobogrammaticNumber.java b/StrobogrammaticNumber.java new file mode 100644 index 0000000..b3db2da --- /dev/null +++ b/StrobogrammaticNumber.java @@ -0,0 +1,47 @@ +package leetcode; + +import java.util.HashMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : StrobogrammaticNumber + * Creator : Edward + * Date : Nov, 2017 + * Description : 246. Strobogrammatic Number + */ +public class StrobogrammaticNumber { + /** + * A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down). + + Write a function to determine if a number is strobogrammatic. The number is represented as a string. + + For example, the numbers "69", "88", and "818" are all strobogrammatic. + + time : O(n) + space : O(n) + + * @param num + * @return + */ + public boolean isStrobogrammatic(String num) { + HashMap map = new HashMap<>(); + map.put('6', '9'); + map.put('9', '6'); + map.put('0', '0'); + map.put('8', '8'); + map.put('1', '1'); + int left = 0, right = num.length() - 1; + while (left <= right) { + if (!map.containsKey(num.charAt(left))) { + return false; + } + if (map.get(num.charAt(left)) != num.charAt(right)) { + return false; + } + left++; + right--; + } + return true; + } +} diff --git a/StrobogrammaticNumberII.java b/StrobogrammaticNumberII.java new file mode 100644 index 0000000..82eecba --- /dev/null +++ b/StrobogrammaticNumberII.java @@ -0,0 +1,55 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : StrobogrammaticNumberII + * Creator : Edward + * Date : Nov, 2017 + * Description : 247. Strobogrammatic Number II + */ +public class StrobogrammaticNumberII { + /** + * A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down). + + Find all strobogrammatic numbers that are of length = n. + + For example, + Given n = 2, return ["11","69","88","96"]. + + n = 3 : ["101","609","808","906","111","619","818","916","181","689","888","986"] + + + time : O(n^2) 不确定 + space : O(n) + + * @param n + * @return + */ + public List findStrobogrammatic(int n) { + return helper(n, n); + } + public List helper(int n, int m) { + if (n == 0) return new ArrayList<>(Arrays.asList("")); + if (n == 1) return new ArrayList<>(Arrays.asList("0", "1", "8")); + + List list = helper(n - 2, m); + List res = new ArrayList<>(); + + for (int i = 0; i < list.size(); i++) { + String s = list.get(i); + if (n != m) { + res.add("0" + s + "0"); + } + res.add("1" + s + "1"); + res.add("6" + s + "9"); + res.add("8" + s + "8"); + res.add("9" + s + "6"); + } + return res; + } +} diff --git a/StrobogrammaticNumberIII.java b/StrobogrammaticNumberIII.java new file mode 100644 index 0000000..0398da2 --- /dev/null +++ b/StrobogrammaticNumberIII.java @@ -0,0 +1,61 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : StrobogrammaticNumberIII + * Creator : Edward + * Date : Dec, 2017 + * Description : 248. Strobogrammatic Number III + */ +public class StrobogrammaticNumberIII { + /** + * A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down). + + Write a function to count the total strobogrammatic numbers that exist in the range of low <= num <= high. + + For example, + Given low = "50", high = "100", return 3. Because 69, 88, and 96 are three strobogrammatic numbers. + + time : 不知道 + space : O(n) + + */ + + public int strobogrammaticInRange(String low, String high){ + int res = 0; + List list = new ArrayList<>(); + for (int i = low.length(); i <= high.length(); i++) { + list.addAll(helper(i, i)); + } + for (String num : list) { + if ((num.length() == low.length() && num.compareTo(low) < 0) || (num.length() == high.length() && num.compareTo(high) > 0)) { + continue; + } + res++; + } + return res; + } + + private List helper(int cur, int max) { + if (cur == 0) return new ArrayList<>(Arrays.asList("")); + if (cur == 1) return new ArrayList<>(Arrays.asList("1", "8", "0")); + + List res = new ArrayList<>(); + List center = helper(cur - 2, max); + + for (int i = 0; i < center.size(); i++) { + String tmp = center.get(i); + if (cur != max) res.add("0" + tmp + "0"); + res.add("1" + tmp + "1"); + res.add("8" + tmp + "8"); + res.add("6" + tmp + "9"); + res.add("9" + tmp + "6"); + } + return res; + } +} diff --git a/SubarraySumEqualsK.java b/SubarraySumEqualsK.java new file mode 100644 index 0000000..c953487 --- /dev/null +++ b/SubarraySumEqualsK.java @@ -0,0 +1,58 @@ +package leetcode; + +import java.util.HashMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SubarraySumEqualsK + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class SubarraySumEqualsK { + /** + * 560. Subarray Sum Equals K + * Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k. + + Example 1: + Input:nums = [1,1,1], k = 2 + Output: 2 + + + * @param nums + * @param k + * @return + */ + // time : O(n^2) space : O(1) + public int subarraySum(int[] nums, int k) { + int res = 0; + for (int i = 0; i < nums.length; i++) { + int sum = 0; + for (int j = i; j < nums.length; j++) { + sum += nums[j]; + if (sum == k) { + res++; + } + } + } + return res; + } + + // time : O(n) space : O(n); + public int subarraySum2(int[] nums, int k) { + int res = 0; + int sum = 0; + HashMap map = new HashMap<>(); + map.put(0, 1); + + for (int i = 0; i < nums.length; i++) { + sum += nums[i]; + if (map.containsKey(sum - k)) { + res += map.get(sum - k); + } + map.put(sum, map.getOrDefault(sum, 0) + 1); + } + return res; + } +} diff --git a/Subsets.java b/Subsets.java new file mode 100644 index 0000000..f949f8d --- /dev/null +++ b/Subsets.java @@ -0,0 +1,67 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by Edward on 28/07/2017. + */ +public class Subsets { + /** + * 78. Subsets + * Given a set of distinct integers, nums, return all possible subsets. + + Note: The solution set must not contain duplicate subsets. + + For example, + If nums = [1,2,3], a solution is: + [ + [3], + [1], + [2], + [1,2,3], + [1,3], + [2,3], + [1,2], + [] + ] + + test : [1,2,3] + + [] + [1] + [1, 2] + [1, 2, 3] + [1, 3] + [2] + [2, 3] + [3] + + 1 — 2 - 3 + | | + 2 3 + | + 3 + + + + time : O(2^n); + space : O(n); + * @param nums + * @return + */ + public static List> subsets(int[] nums) { + List> res = new ArrayList<>(); + if (nums == null || nums.length == 0) return res; + helper(res, new ArrayList<>(), nums, 0); + return res; + } + public static void helper(List> res, List list, int[] nums, int index) { + res.add(new ArrayList<>(list)); + for (int i = index; i < nums.length; i++) { + list.add(nums[i]); + helper(res, list, nums, i + 1); + list.remove(list.size() - 1); + } + } +} diff --git a/SubsetsII.java b/SubsetsII.java new file mode 100644 index 0000000..9f32dfe --- /dev/null +++ b/SubsetsII.java @@ -0,0 +1,54 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by Edward on 28/07/2017. + */ +public class SubsetsII { + /** + * 90. Subsets II + * Given a collection of integers that might contain duplicates, nums, return all possible subsets. + + Note: The solution set must not contain duplicate subsets. + + + For example, + If nums = [1,2,2], a solution is: + + [ + [2], + [1], + [1,2,2], + [2,2], + [1,2], + [] + ] + + test: [1,2,2] + + + time : O(2^n); + space : O(n); + * @param nums + * @return + */ + public static List> subsetsWithDup(int[] nums) { + List> res = new ArrayList<>(); + if (nums == null || nums.length == 0) return res; + Arrays.sort(nums); + helper(res, new ArrayList<>(), nums, 0); + return res; + } + public static void helper(List> res, List list, int[] nums, int index) { + res.add(new ArrayList<>(list)); + for (int i = index; i < nums.length; i++) { + if (i != index && nums[i] == nums[i - 1]) continue; + list.add(nums[i]); + helper(res, list, nums, i + 1); + list.remove(list.size() - 1); + } + } +} diff --git a/SubstringwithConcatenationofAllWords.java b/SubstringwithConcatenationofAllWords.java new file mode 100644 index 0000000..6755837 --- /dev/null +++ b/SubstringwithConcatenationofAllWords.java @@ -0,0 +1,64 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SubstringwithConcatenationofAllWords + * Creator : Edward + * Date : Dec, 2017 + * Description : 30. Substring with Concatenation of All Words + */ +public class SubstringwithConcatenationofAllWords { + /** + * You are given a string, s, and a list of words, words, that are all of the same length. + * Find all starting indices of substring(s) in s that is a concatenation of each word + * in words exactly once and without any intervening characters. + + For example, given: + s: "barfoothefoobarman" + words: ["foo", "bar"] + + You should return the indices: [0,9]. + (order does not matter). + + time : O(n ^ 2) + space : O(n) + + * @param s + * @param words + * @return + */ + public List findSubstring(String s, String[] words) { + if (s == null || words == null) return new ArrayList<>(); + + List res = new ArrayList<>(); + int n = words.length; + int m = words[0].length(); + HashMap map = new HashMap<>(); + + for (String str : words) { + map.put(str, map.getOrDefault(str, 0) + 1); + } + + for (int i = 0; i <= s.length() - n * m; i++) { + HashMap copy = new HashMap<>(map); + int k = n; + int j = i; + while (k > 0) { + String str = s.substring(j, j + m); + if (!copy.containsKey(str) || copy.get(str) < 1) { + break; + } + copy.put(str, copy.get(str) - 1); + k--; + j += m; + } + if (k == 0) res.add(i); + } + return res; + } +} diff --git a/SudokuSolver.java b/SudokuSolver.java new file mode 100644 index 0000000..36b70c6 --- /dev/null +++ b/SudokuSolver.java @@ -0,0 +1,49 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SudokuSolver + * Creator : Edward + * Date : Oct, 2017 + * Description : 37. Sudoku Solver + */ +public class SudokuSolver { + + // time : 不知道 space : 不知道 + + public void solveSudoku(char[][] board) { + if (board == null || board.length == 0) return; + solve(board); + } + + public boolean solve(char[][] board) { + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + if (board[i][j] == '.') { + for (char c = '1'; c <= '9'; c++) { + if (isValid(board, i, j, c)) { + board[i][j] = c; + if (solve(board)) return true; + else board[i][j] = '.'; + } + } + return false; + } + } + } + return true; + } + + public boolean isValid(char[][] board, int row, int col, char c) { + for (int i = 0; i < 9; i++) { + if (board[i][col] != '.' && board[i][col] == c) return false; + if (board[row][i] != '.' && board[row][i] == c) return false; + if (board[3 * (row / 3) + i / 3][3 * (col / 3) + i / 3] != '.' + && board[3 * (row / 3) + i / 3][3 * (col / 3) + i / 3] == c) { + return false; + } + } + return true; + } +} diff --git a/SumRoottoLeafNumbers.java b/SumRoottoLeafNumbers.java new file mode 100644 index 0000000..a5dad45 --- /dev/null +++ b/SumRoottoLeafNumbers.java @@ -0,0 +1,42 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SumRoottoLeafNumbers + * Creator : Edward + * Date : Oct, 2017 + * Description : 129. Sum Root to Leaf Numbers + */ +public class SumRoottoLeafNumbers { + /** + * For example, + + 1 + / \ + 2 3 + The root-to-leaf path 1->2 represents the number 12. + The root-to-leaf path 1->3 represents the number 13. + + Return the sum = 12 + 13 = 25. + + time : O(n) + space : O(n) + + * @param root + * @return + */ + + public int sumNumbers(TreeNode root) { + return helper(root, 0); + } + + public int helper(TreeNode root, int num) { + if (root == null) return 0; + if (root.left == null && root.right == null) { + return num * 10 + root.val; + } + return helper(root.left, num * 10 + root.val) + + helper(root.right, num * 10 + root.val); + } +} diff --git a/SummaryRanges.java b/SummaryRanges.java new file mode 100644 index 0000000..f0d15bf --- /dev/null +++ b/SummaryRanges.java @@ -0,0 +1,47 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SummaryRanges + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class SummaryRanges { + /** + * 228. Summary Ranges + * Given a sorted integer array without duplicates, return the summary of its ranges. + + Example 1: + Input: [0,1,2,4,5,7] + Output: ["0->2","4->5","7"] + Example 2: + Input: [0,2,3,4,6,8,9] + Output: ["0","2->4","6","8->9"] + + time : O(n) + space : O(n) + * @param nums + * @return + */ + public List summaryRanges(int[] nums) { + List res = new ArrayList<>(); + if (nums == null || nums.length == 0) return res; + for (int i = 0; i < nums.length; i++) { + int num = nums[i]; + while (i < nums.length - 1 && nums[i] + 1 == nums[i + 1]) { + i++; + } + if (num != nums[i]) { + res.add(num + "->" + nums[i]); + } else { + res.add(num + ""); + } + } + return res; + } +} diff --git a/SumofLeftLeaves.java b/SumofLeftLeaves.java new file mode 100644 index 0000000..34adc11 --- /dev/null +++ b/SumofLeftLeaves.java @@ -0,0 +1,67 @@ +package leetcode; + +import java.util.LinkedList; +import java.util.Queue; +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SumofLeftLeaves + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class SumofLeftLeaves { + + /** + * 404. Sum of Left Leaves + * Find the sum of all left leaves in a given binary tree. + + Example: + + 3 + / \ + 9 20 + / \ + 15 7 + + There are two left leaves in the binary tree, with values 9 and 15 respectively. Return 24. + + time : O(n); + space : O(n); + * @param root + * @return + */ + + public int sumOfLeftLeaves(TreeNode root) { + if (root == null) return 0; + int res = 0; + if (root.left != null) { + if (root.left.left == null && root.left.right == null) { + res += root.left.val; + } else res += sumOfLeftLeaves(root.left); + } + res += sumOfLeftLeaves(root.right); + return res; + } + public int sumOfLeftLeaves2(TreeNode root) { + if (root == null) return 0; + int res = 0; + Queue queue = new LinkedList<>(); + queue.offer(root); + while (!queue.isEmpty()) { + TreeNode cur = queue.poll(); + if (cur.left != null) { + if (cur.left.left == null && cur.left.right == null) { + res += cur.left.val; + } else queue.offer(cur.left); + } + if (cur.right != null) { + queue.offer(cur.right); + } + } + return res; + } + +} diff --git a/SumofTwoIntegers.java b/SumofTwoIntegers.java new file mode 100644 index 0000000..ea62e22 --- /dev/null +++ b/SumofTwoIntegers.java @@ -0,0 +1,37 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SumofTwoIntegers + * Creator : Edward + * Date : Nov, 2017 + * Description : 371. Sum of Two Integers + */ +public class SumofTwoIntegers { + /** + * Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -. + + Example: + Given a = 1 and b = 2, return 3. + + time : O(1) / O(n) + space : O(1) + + * @param a + * @param b + * @return + */ + public int getSum(int a, int b) { + if (a == 0) return b; + if (b == 0) return a; + + while (b != 0) { + int carry = a & b; + a = a ^ b; + b = carry << 1; + } + + return a; + } +} diff --git a/SuperPow.java b/SuperPow.java new file mode 100644 index 0000000..b4fcf71 --- /dev/null +++ b/SuperPow.java @@ -0,0 +1,64 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SuperPow + * Creator : Edward + * Date : Jan, 2018 + * Description : 372. Super Pow + */ +public class SuperPow { + /** + * Your task is to calculate ab mod 1337 where a is a positive integer and b is an extremely + * large positive integer given in the form of an array. + + a^b%1337 + + Example1: + + a = 2 + b = [3] + + Result: 8 + Example2: + + a = 2 + b = [1,0] + + Result: 1024 + + (a*a)%c=(a%c)*(a%c)%c + + [3,2] + 30 2 + + a^32 = a^30 * a^2 % k + + time : O(1) 不确定 + space : O(n) + + * @param a + * @param b + * @return + */ + public int superPow(int a, int[] b) { + return superPow(a, b, b.length, 1337); + } + + private int superPow(int a, int[] b, int length, int k) { + if (length == 1) { + return powMod(a, b[0], k); + } + return powMod(superPow(a, b, length - 1, k), 10, k) * powMod(a, b[length - 1], k) % k; + } + + private int powMod(int x, int y, int k) { + x %= k; + int pow = 1; + for (int i = 0; i < y; i++) { + pow = pow * x % k; + } + return pow; + } +} diff --git a/SuperUglyNumber.java b/SuperUglyNumber.java new file mode 100644 index 0000000..e6d4060 --- /dev/null +++ b/SuperUglyNumber.java @@ -0,0 +1,62 @@ +package leetcode; + +import java.util.PriorityQueue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SuperUglyNumber + * Creator : Edward + * Date : Jan, 2018 + * Description : 313. Super Ugly Number + */ +public class SuperUglyNumber { + /** + * Write a program to find the nth super ugly number. + + Super ugly numbers are positive numbers whose all prime factors are in the given prime list + primes of size k. For example, [1, 2, 4, 7, 8, 13, 14, 16, 19, 26, 28, 32] + is the sequence of the first 12 super ugly numbers given primes = [2, 7, 13, 19] of size 4. + + PriorityQueue kth + + time : O(n * logk) + space : O(max(n,k)) + + * @param n + * @param primes + * @return + */ + + public int nthSuperUglyNumber(int n, int[] primes) { + int[] res = new int[n]; + res[0] = 1; + + PriorityQueue pq = new PriorityQueue<>((a, b) -> (a.val - b.val)); + for (int i = 0; i < primes.length; i++) { + pq.add(new Num(primes[i], 1, primes[i])); + } + + for (int i = 1; i < n; i++) { + res[i] = pq.peek().val; + while (pq.peek().val == res[i]) { + Num next = pq.poll(); + pq.add(new Num(next.prime * res[next.index], next.index + 1, next.prime)); + } + } + + return res[n - 1]; + } + + class Num { + int val; + int index; + int prime; + + public Num(int val, int index, int prime) { + this.val = val; + this.index = index; + this.prime = prime; + } + } +} diff --git a/SurroundedRegions.java b/SurroundedRegions.java new file mode 100644 index 0000000..697a280 --- /dev/null +++ b/SurroundedRegions.java @@ -0,0 +1,154 @@ +package leetcode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SurroundedRegions + * Creator : Edward + * Date : Dec, 2017 + * Description : 130. Surrounded Regions + */ +public class SurroundedRegions { + + /** + * Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'. + + A region is captured by flipping all 'O's into 'X's in that surrounded region. + + For example, + X X X X + X O O X + X X O X + X O X X + + After running your function, the board should be: + + X X X X + X X X X + X X X X + X O X X + + time : O(m * n) + space : O(n) + + * @param board + */ + + public void solve(char[][] board){ + if (board == null || board.length == 0 || board[0].length == 0) return; + + int m = board.length - 1; + int n = board[0].length - 1; + + for (int i = 0; i <= m; i++) { + if (board[i][0] == 'O') { + dfs(board, i, 0); + } + if (board[i][n] == 'O') { + dfs(board, i, n); + } + } + for (int i = 0; i <= n; i++) { + if (board[0][i] == 'O') { + dfs(board, 0, i); + } + if (board[m][i] == 'O') { + dfs(board, m, i); + } + } + + for (int i = 0; i <= m; i++) { + for (int j = 0; j <= n; j++) { + if (board[i][j] == 'O') { + board[i][j] = 'X'; + } else if (board[i][j] == '1') { + board[i][j] = 'O'; + } + } + } + } + + private void dfs(char[][] board, int i, int j) { + if (i < 0 || j < 0 || i >= board.length || j >= board[0].length || board[i][j] != 'O') { + return; + } + board[i][j] = '1'; + dfs(board, i, j + 1); + dfs(board, i, j - 1); + dfs(board, i + 1, j); + dfs(board, i - 1, j); + } + + class Point { + int x; + int y; + + Point(int a, int b) { + x = a; + y = b; + } + } + + public void solve2(char[][] board) { + if (board == null || board.length == 0 || board[0].length == 0) return; + + int m = board.length - 1; + int n = board[0].length - 1; + Queue queue = new LinkedList<>(); + + //get all 'O's on the edge first + for (int r = 0; r <= m; r++) { + if (board[r][0] == 'O') { + board[r][0] = '1'; + queue.add(new Point(r, 0)); + } + if (board[r][n] == 'O') { + board[r][n] = '1'; + queue.add(new Point(r, n)); + } + } + + for (int i = 0; i < n; i++){ + if (board[0][i] == 'O') { + board[0][i] = '1'; + queue.add(new Point(0, i)); + } + if (board[m][i] == 'O') { + board[m][i] = '1'; + queue.add(new Point(m, i)); + } + } + + while (!queue.isEmpty()) { + Point p = queue.poll(); + int row = p.x; + int col = p.y; + if (row - 1 >= 0 && board[row - 1][col] == 'O') { + board[row - 1][col] = '1'; + queue.add(new Point(row - 1, col)); + } + if (row + 1 < m && board[row + 1][col] == 'O') { + board[row + 1][col] = '1'; queue.add(new Point(row + 1, col)); + } + if (col - 1 >= 0 && board[row][col - 1] == 'O') { + board[row][col - 1] = '1'; + queue.add(new Point(row, col - 1)); + } + if (col + 1 < n && board[row][col + 1] == 'O') { + board[row][col + 1] = '1'; + queue.add(new Point(row, col + 1)); + } + } + + for (int i = 0; i<= m; i++){ + for (int j=0; j<= n; j++){ + if (board[i][j] == 'O') board[i][j] = 'X'; + if (board[i][j] == '1') board[i][j] = 'O'; + } + } + } + +} diff --git a/SwapNodesinPairs.java b/SwapNodesinPairs.java new file mode 100644 index 0000000..fcfc4f7 --- /dev/null +++ b/SwapNodesinPairs.java @@ -0,0 +1,41 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : SwapNodesinPairs + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class SwapNodesinPairs { + /** + * 24. Swap Nodes in Pairs + * Given a linked list, swap every two adjacent nodes and return its head. + + For example, + Given 1->2->3->4, you should return the list as 2->1->4->3. + + + time : O(n); + space : O(1); + * @param head + * @return + */ + public ListNode swapPairs(ListNode head) { + if (head == null || head.next == null) return head; + ListNode dummy = new ListNode(0); + dummy.next = head; + ListNode l1 = dummy; + ListNode l2 = head; + while (l2 != null && l2.next != null) { + ListNode nextStart = l2.next.next; + l1.next = l2.next; + l2.next.next = l2; + l2.next = nextStart; + l1 = l2; + l2 = l2.next; + } + return dummy.next; + } +} diff --git a/SymmetricTree.java b/SymmetricTree.java new file mode 100644 index 0000000..5077bd6 --- /dev/null +++ b/SymmetricTree.java @@ -0,0 +1,37 @@ +package leetcode; + +/** + * Created by Edward on 24/07/2017. + */ +public class SymmetricTree { + /** + * 101. Symmetric Tree + *Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). + + For example, this binary tree [1,2,2,3,4,4,3] is symmetric: + 1 + / \ + 2 2 + / \ / \ + 3 4 4 3 + time : O(n) + space : O(n) + * @param root + * @return + */ + + public static boolean isSymmetric(TreeNode root) { + + if (root == null) return true; + return helper(root.left, root.right); + } + + public static boolean helper(TreeNode p, TreeNode q) { + + if (p == null && q == null) return true; + if (p == null || q == null) return false; + if (p.val != q.val) return false; + + return helper(p.left, q.right) && helper(p.right, q.left); + } +} diff --git a/TextJustification.java b/TextJustification.java new file mode 100644 index 0000000..6c07ef9 --- /dev/null +++ b/TextJustification.java @@ -0,0 +1,88 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : TextJustification + * Creator : Edward + * Date : Dec, 2017 + * Description : 68. Text Justification + */ +public class TextJustification { + /** + * 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. + Pad extra spaces ' ' when necessary so that each line has exactly L characters. + + Extra spaces between words should be distributed as evenly as possible. If the number of spaces on + a line do not divide evenly between words, the empty slots on the left will be assigned more spaces + than the slots on the right. + + For the last line of text, it should be left justified and no extra space is inserted between words. + + For example, + words: ["This", "is", "an", "example", "of", "text", "justification."] + L: 16. + + Return the formatted lines as: + [ + "This is an", + "example of text", + "justification. " + ] + + time : O(n) + space : O(n) + + * @param words + * @param L + * @return + */ + public List fullJustify(String[] words, int L) { + List res = new ArrayList<>(); + int index = 0; + while (index < words.length) { + int count = words[index].length(); + int last = index + 1; + while (last < words.length) { + if (words[last].length() + count + 1 > L) break; + count += 1 + words[last].length(); + last++; + } + StringBuilder builder = new StringBuilder(); + builder.append(words[index]); + int diff = last - index - 1; + if (last == words.length || diff == 0) { + for (int i = index + 1; i < last; i++) { + builder.append(" "); + builder.append(words[i]); + } + for (int i = builder.length(); i < L; i++) { + builder.append(" "); + } + } else { + int spaces = (L - count) / diff; + int r = (L - count) % diff; + for (int i = index + 1; i < last; i++) { + for (int k = spaces; k > 0; k--) { + builder.append(" "); + } + if (r > 0) { + builder.append(" "); + r--; + } + builder.append(" "); + builder.append(words[i]); + } + } + res.add(builder.toString()); + index = last; + } + return res; + } +} diff --git a/TheSkylineProblem.java b/TheSkylineProblem.java new file mode 100644 index 0000000..7a24fbf --- /dev/null +++ b/TheSkylineProblem.java @@ -0,0 +1,84 @@ +package leetcode; + +import java.util.*; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : TheSkylineProblem + * Creator : Edward + * Date : Dec, 2017 + * Description : 218. The Skyline Problem + */ +public class TheSkylineProblem { + /** + * time : O(n^2) + * space : O(n) + * @param buildings + * @return + */ + public List getSkyline(int[][] buildings) { + List res = new ArrayList<>(); + List heights = new ArrayList<>(); + for(int[] b:buildings) { + heights.add(new int[]{b[0], -b[2]}); + heights.add(new int[]{b[1], b[2]}); + } + Collections.sort(heights, (a, b) -> (a[0] == b[0]) ? a[1] - b[1] : a[0] - b[0]); + PriorityQueue pq = new PriorityQueue<>((a, b) -> (b - a)); + pq.offer(0); + int prev = 0; + for(int[] h:heights) { + if(h[1] < 0) { + pq.offer(-h[1]); + } else { + pq.remove(h[1]); + } + int cur = pq.peek(); + if(prev != cur) { + res.add(new int[]{h[0], cur}); + prev = cur; + } + } + return res; + } + + /** + * time : O(nlogn) + * space : O(n) + * @param buildings + * @return + */ + + public List getSkyline2(int[][] buildings) { + List res = new ArrayList<>(); + List heights = new ArrayList<>(); + for (int[] b: buildings) { + heights.add(new int[]{b[0], - b[2]}); + heights.add(new int[]{b[1], b[2]}); + } + Collections.sort(heights, (a, b) -> (a[0] == b[0]) ? a[1] - b[1] : a[0] - b[0]); + TreeMap map = new TreeMap<>(Collections.reverseOrder()); + map.put(0,1); + int prev = 0; + + for (int[] h: heights) { + if (h[1] < 0) { + map.put(-h[1], map.getOrDefault(-h[1], 0) + 1); + } else { + int cnt = map.get(h[1]); + if (cnt == 1) { + map.remove(h[1]); + } else { + map.put(h[1], cnt - 1); + } + } + int cur = map.firstKey(); + if (prev != cur) { + res.add(new int[]{h[0], cur}); + prev = cur; + } + } + return res; + } +} diff --git a/ThirdMaximumNumber.java b/ThirdMaximumNumber.java new file mode 100644 index 0000000..232c73e --- /dev/null +++ b/ThirdMaximumNumber.java @@ -0,0 +1,87 @@ +package leetcode; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.PriorityQueue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ThirdMaximumNumber + * Creator : Edward + * Date : Nov, 2017 + * Description : 414. Third Maximum Number + */ +public class ThirdMaximumNumber { + /** + * Given a non-empty array of integers, return the third maximum number in this array. If it does not exist, return the maximum number. The time complexity must be in O(n). + + Example 1: + Input: [3, 2, 1] + + Output: 1 + + Explanation: The third maximum is 1. + Example 2: + Input: [1, 2] + + Output: 2 + + Explanation: The third maximum does not exist, so the maximum (2) is returned instead. + Example 3: + Input: [2, 2, 3, 1] + + Output: 1 + + Explanation: Note that the third maximum here means the third maximum distinct number. + Both numbers with value 2 are both considered as second maximum. + + time : O(n) + space : O(1) + + + * @param nums + * @return + */ + public int thirdMax(int[] nums) { + Integer max1 = null; + Integer max2 = null; + Integer max3 = null; + for (Integer num : nums) { + if (num.equals(max1) || num.equals(max2) || num.equals(max3)) continue; + if (max1 == null || num > max1) { + max3 = max2; + max2 = max1; + max1 = num; + } else if (max2 == null || num > max2) { + max3 = max2; + max2 = num; + } else if (max3 == null || num > max3) { + max3 = num; + } + } + return max3 == null ? max1 : max3; + } + + /** + * time : O(n) + * space : O(1) + * + * @param nums + * @return + */ + + public int thirdMax2(int[] nums) { + PriorityQueue priorityQueue = new PriorityQueue<>(); + HashSet set = new HashSet<>(); + for (int num : nums) { + if (set.add(num)) { + priorityQueue.offer(num); + if (priorityQueue.size() > 3) priorityQueue.poll(); + } + } + if (priorityQueue.size() == 2) priorityQueue.poll(); + return priorityQueue.peek(); + } + +} diff --git a/ThreeSum.java b/ThreeSum.java new file mode 100644 index 0000000..53f53fb --- /dev/null +++ b/ThreeSum.java @@ -0,0 +1,56 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ThreeSum + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class ThreeSum { + /** + * 15. 3Sum + * Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? + * Find all unique triplets in the array which gives the sum of zero. + + Note: The solution set must not contain duplicate triplets. + + For example, given array S = [-1, 0, 1, 2, -1, -4], + + A solution set is: + [ + [-1, 0, 1], + [-1, -1, 2] + ] + + time : O(n^2); + space : O(n); + * @param nums + * @return + */ + public List> threeSum(int[] nums) { + List> res = new ArrayList<>(); + Arrays.sort(nums); + for (int i = 0; i < nums.length - 2; i++) { + if (i > 0 && nums[i] == nums[i - 1]) continue; + int low = i + 1, high = nums.length - 1, sum = 0 - nums[i]; + while (low < high) { + if (nums[low] + nums[high] == sum) { + res.add(Arrays.asList(nums[i], nums[low], nums[high])); + while (low < high && nums[low] == nums[low + 1]) low++; + while (low < high && nums[high] == nums[high - 1]) high--; + low++; + high--; + } else if (nums[low] + nums[high] < sum) { + low++; + } else high--; + } + } + return res; + } +} diff --git a/ThreeSumClosest.java b/ThreeSumClosest.java new file mode 100644 index 0000000..914f60e --- /dev/null +++ b/ThreeSumClosest.java @@ -0,0 +1,43 @@ +package leetcode; + +import java.util.Arrays; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ThreeSumClosest + * Creator : Edward + * Date : Oct, 2017 + * Description : 16. 3Sum Closest + */ +public class ThreeSumClosest { + /** + * For example, given array S = {-1 2 1 -4}, and target = 1. + + The sum that is closest to the target is 2. (-1 + 2 + 1 = 2). + + time : O(n^2); + space : O(1); + + * @param nums + * @param target + * @return + */ + public int threeSumClosest(int[] nums, int target) { + int res = nums[0] + nums[1] + nums[nums.length - 1]; + Arrays.sort(nums); + for (int i = 0; i < nums.length - 2; i++) { + int start = i + 1, end = nums.length - 1; + while (start < end) { + int sum = nums[i] + nums[start] + nums[end]; + if (sum > target) { + end--; + } else start++; + if (Math.abs(sum - target) < Math.abs(res - target)) { + res = sum; + } + } + } + return res; + } +} diff --git a/ThreeSumSmaller.java b/ThreeSumSmaller.java new file mode 100644 index 0000000..00da5db --- /dev/null +++ b/ThreeSumSmaller.java @@ -0,0 +1,50 @@ +package leetcode; + +import java.lang.reflect.Array; +import java.util.Arrays; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ThreeSumSmaller + * Creator : Edward + * Date : Oct, 2017 + * Description : 259. 3Sum Smaller + */ +public class ThreeSumSmaller { + /** + * nums[i] + nums[j] + nums[k] < target. + * For example, given nums = [-2, 0, 1, 3], and target = 2. + + Return 2. Because there are two triplets which sums are less than 2: + + [-2, 0, 1] + [-2, 0, 3] + + time : O(n^2); + space : O(1); + + + nums = [-2, 0, 1, 3], and target = 2. + + * @param nums + * @param target + * @return + */ + + public int threeSumSmaller(int[] nums, int target) { + int res = 0; + Arrays.sort(nums); + for (int i = 0; i < nums.length - 2; i++) { + int left = i + 1; + int right = nums.length - 1; + while (left < right) { + if (nums[i] + nums[left] + nums[right] < target) { + res += right - left; + left++; + } else right--; + } + } + return res; + } +} diff --git a/TopKFrequentElements.java b/TopKFrequentElements.java new file mode 100644 index 0000000..afaf22c --- /dev/null +++ b/TopKFrequentElements.java @@ -0,0 +1,105 @@ +package leetcode; + +import java.util.*; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : TopKFrequentElements + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class TopKFrequentElements { + /** + * 347. Top K Frequent Elements + * Given a non-empty array of integers, return the k most frequent elements. + + For example, + Given [1,1,1,2,2,3] and k = 2, return [1,2]. + + * @param nums + * @param k + * @return + */ + + // PriorityQueue : time : O(nlogn) space : O(n) + public List topKFrequent2(int[] nums, int k) { + HashMap map = new HashMap<>(); + for (int num : nums) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + + PriorityQueue> maxHeap = + new PriorityQueue<>((a, b) -> (b.getValue() - a.getValue())); + for (Map.Entry entry : map.entrySet()) { + maxHeap.add(entry); + } + + List res = new ArrayList<>(); + while (res.size() < k) { // O(klogn) + Map.Entry entry = maxHeap.poll(); + res.add(entry.getKey()); + } + return res; + } + + // TreeMap : time : O(nlogn) space : O(n) + public List topKFrequent3(int[] nums, int k) { + HashMap map = new HashMap<>(); + for (int num : nums) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + + TreeMap> freqMap = new TreeMap<>(); + for (int num : map.keySet()) { + int freq = map.get(num); + if (freqMap.containsKey(freq)) { + freqMap.get(freq).add(num); + } else { + freqMap.put(freq, new LinkedList<>()); + freqMap.get(freq).add(num); + } + } + + List res = new ArrayList<>(); + while (res.size() < k) { // O(klogn) + Map.Entry> entry = freqMap.pollLastEntry(); + res.addAll(entry.getValue()); + } + return res; + } + + // Bucket sort : time : O(n) space : O(n) + public List topKFrequent(int[] nums, int k) { + HashMap map = new HashMap<>(); + for (int num : nums) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + + List[] bucket = new List[nums.length + 1]; + for (int num : map.keySet()) { + int freq = map.get(num); + if (bucket[freq] == null) { + bucket[freq] = new LinkedList<>(); + } + bucket[freq].add(num); + } + + List res = new ArrayList<>(); + for (int i = bucket.length - 1; i >= 0 && res.size() < k; i--) { + if (bucket[i] != null) { + res.addAll(bucket[i]); + } + } + /* + for (int i = bucket.length - 1; i >= 0; i--) { + int j = 0; + while (bucket[i] != null && j < bucket[i].size() && k > 0) { + res.add(bucket[i].get(j++)); + k--; + } + }*/ + return res; + } +} diff --git a/TrappingRainWater.java b/TrappingRainWater.java new file mode 100644 index 0000000..3ac84bc --- /dev/null +++ b/TrappingRainWater.java @@ -0,0 +1,51 @@ +package leetcode; + +import java.util.Arrays; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : TrappingRainWater + * Creator : Edward + * Date : Nov, 2017 + * Description : 42. Trapping Rain Water + */ +public class TrappingRainWater { + /** + * + + 0,1,0,2,1,0,1,3,2,1,2,1 + + * + * * * * + * * * * * * * * * + 0 1 2 3 4 5 6 7 8 9 0 1 + l r + + time : O(n) + space : O(1) + + * + * @param height + * @return + */ + public int trap(int[] height) { + int left = 0; + int right = height.length - 1; + int res = 0; + int leftMax = 0; + int rightMax = 0; + while (left < right) { + if (height[left] < height[right]) { + leftMax = Math.max(height[left], leftMax); + res += leftMax - height[left]; + left++; + } else { + rightMax = Math.max(height[right], rightMax); + res += rightMax - height[right]; + right--; + } + } + return res; + } +} diff --git a/TreeLinkNode.java b/TreeLinkNode.java new file mode 100644 index 0000000..3f555cf --- /dev/null +++ b/TreeLinkNode.java @@ -0,0 +1,17 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : TreeLinkNode + * Creator : Edward + * Date : Oct, 2017 + * Description : TODO + */ +public class TreeLinkNode { + int val; + TreeLinkNode left, right, next; + TreeLinkNode(int x) { + val = x; + } +} diff --git a/TreeNode.java b/TreeNode.java new file mode 100644 index 0000000..47b8aba --- /dev/null +++ b/TreeNode.java @@ -0,0 +1,16 @@ +package leetcode; + +/** + * Created by Edward on 23/07/2017. + */ +public class TreeNode { + + int val; + TreeNode left; + TreeNode right; + + TreeNode (int x) { + val = x; + } + +} diff --git a/Triangle.java b/Triangle.java new file mode 100644 index 0000000..8d9e76c --- /dev/null +++ b/Triangle.java @@ -0,0 +1,52 @@ +package leetcode; + +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : Triangle + * Creator : Edward + * Date : Oct, 2017 + * Description : 120. Triangle + */ +public class Triangle { + /** + * Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers + * on the row below. + + For example, given the following triangle + [ + [2], + [3,4], + [6,5,7], + [4,1,8,3] + ] + The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11). + + i : j + i + 1 : j, j + 1 + + res = [4, 1, 8, 3, 0] + res = [7, 6, 10] + res = [9, 10] + res = [2] + + time : O(n^2) + space : O(n) + + + * @param triangle + * @return + */ + public int minimumTotal(List> triangle) { + int[] res = new int[triangle.size() + 1]; + for (int i = triangle.size() - 1; i >= 0; i--) { + for (int j = 0; j < triangle.get(i).size(); j++) { + res[j] = Math.min(res[j], res[j + 1]) + triangle.get(i).get(j); + } + } + return res[0]; + } + +} diff --git a/1. Two Sum.java b/TwoSum.java similarity index 89% rename from 1. Two Sum.java rename to TwoSum.java index e411612..bc1bed7 100644 --- a/1. Two Sum.java +++ b/TwoSum.java @@ -1,3 +1,11 @@ +package leetcode; + +import java.util.Arrays; +import java.util.HashMap; + +/** + * Created by Edward on 23/07/2017. + */ public class TwoSum { /** diff --git a/TwoSumII.java b/TwoSumII.java new file mode 100644 index 0000000..aab800d --- /dev/null +++ b/TwoSumII.java @@ -0,0 +1,48 @@ +package leetcode; + +/** + * Created by Edward on 23/07/2017. + */ +public class TwoSumII { + + /** + * 167. Two Sum II - Input array is sorted + + Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number. + + The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based. + + You may assume that each input would have exactly one solution and you may not use the same element twice. + + Input: numbers={2, 7, 11, 15}, target=9 + Output: index1=1, index2=2 + + time : O(logn) + space : O(1) + * @param numbers + * @param target + * @return + */ + + public static int[] twoSum(int[] numbers, int target) { + + if (numbers == null || numbers.length < 2) { + return new int[]{-1, -1}; + } + + int left = 0; + int right = numbers.length - 1; + while (left < right) { + int sum = numbers[left] + numbers[right]; + if (target == sum) { + return new int[]{left + 1, right + 1}; + } else if (sum > target) { + right--; + } else { + left++; + } + } + + return new int[]{-1, -1}; + } +} diff --git a/TwoSumIII_Datastructuredesign.java b/TwoSumIII_Datastructuredesign.java new file mode 100644 index 0000000..9bd756b --- /dev/null +++ b/TwoSumIII_Datastructuredesign.java @@ -0,0 +1,92 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : TwoSumIII_Datastructuredesign + * Creator : Edward + * Date : Aug, 2017 + * Description : 170. Two Sum III - Data structure design + */ +public class TwoSumIII_Datastructuredesign { + + /** + * Design and implement a TwoSum class. It should support the following operations: add and find. + + add - Add the number to an internal data structure. + find - Find if there exists any pair of numbers which sum is equal to the value. + + For example, + add(1); add(3); add(5); + find(4) -> true + find(7) -> false + + */ + + /** Initialize your data structure here. */ + + private HashMap map; + + // 构造函数,leetcode中是TwoSum + public TwoSumIII_Datastructuredesign() { + map = new HashMap<>(); + } + + /** Add the number to an internal data structure.. */ + public void add(int number) { + if (!map.containsKey(number)) { + map.put(number, 1); + } else { + map.put(number, map.get(number) + 1); + } + } + + // time : O(n) + /** Find if there exists any pair of numbers which sum is equal to the value. */ + public boolean find(int value) { + for (Map.Entry entry : map.entrySet()) { + int i = entry.getKey(); + int j = value - i; + if ((i == j && entry.getValue() > 1) || (i != j && map.containsKey(j))) { + return true; + } + } + return false; + } + + /**------------------------------------------分割线--------------------------------------------------**/ + + //构造函数,leetcode中是TwoSum, map 在上一个解法中有 + + private List list; + + public void TwoSum() { + map = new HashMap<>(); + list = new ArrayList<>(); + } + + public void add2(int number) { + if (!map.containsKey(number)) { + map.put(number, 1); + list.add(number); + } else { + map.put(number, map.get(number) + 1); + } + } + + // time : O(n) + public boolean find2(int value) { + for (Integer num1 : list) { + int num2 = value - num1; + if ((num1 == num2 && map.get(num1) > 1) || (num1 != num2 && map.containsKey(num2))) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/TwoSumIVInputisaBST.java b/TwoSumIVInputisaBST.java new file mode 100644 index 0000000..9fb8e74 --- /dev/null +++ b/TwoSumIVInputisaBST.java @@ -0,0 +1,73 @@ +package leetcode; + +import java.io.Serializable; +import java.util.HashSet; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : TwoSumIVInputisaBST + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class TwoSumIVInputisaBST { + + /** + * 653. Two Sum IV - Input is a BST + Given a Binary Search Tree and a target number, return true if there exist two + elements in the BST such that their sum is equal to the given target. + + Example 1: + Input: + 5 + / \ + 3 6 + / \ \ + 2 4 7 + + Target = 9 + + Output: True + * @param root + * @param k + * @return + */ + + //time : O(n), space : O(n) + public boolean findTarget(TreeNode root, int k) { + if (root == null) return false; + HashSet set = new HashSet<>(); + return helper(root, k, set); + } + + public boolean helper(TreeNode root, int k, HashSet set) { + if (root == null) return false; + if (set.contains(k - root.val)) { + return true; + } + set.add(root.val); + return helper(root.left, k, set) || helper(root.right, k, set); + } + + //time : O(nlogn) space : O(h) h : logn ~ n + + public boolean findTarget2(TreeNode root, int k) { + return firstDfs(root, root, k); + } + + public boolean firstDfs(TreeNode first, TreeNode second, int k) { + if (first == null) return false; + return secondDfs(first, second, k - first.val) + || firstDfs(first.left, second, k) + || firstDfs(first.right, second, k); + } + + public boolean secondDfs(TreeNode first, TreeNode second, int k) { + if (second == null) return false; + return (second.val == k) && (first != second) + || (second.val > k) && secondDfs(first, second.left, k) + || (second.val < k) && secondDfs(first, second.right, k); + } + +} diff --git a/UTF8Validation.java b/UTF8Validation.java new file mode 100644 index 0000000..cdb04cd --- /dev/null +++ b/UTF8Validation.java @@ -0,0 +1,96 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : UTF8Validation + * Creator : Edward + * Date : Jan, 2018 + * Description : 393. UTF-8 Validation + */ +public class UTF8Validation { + /** + * A character in UTF8 can be from 1 to 4 bytes long, subjected to the following rules: + + For 1-byte character, the first bit is a 0, followed by its unicode code. + For n-bytes character, the first n-bits are all one's, the n+1 bit is 0, followed by n-1 bytes with most significant 2 bits being 10. + This is how the UTF-8 encoding would work: + + Char. number range | UTF-8 octet sequence + (hexadecimal) | (binary) + --------------------+--------------------------------------------- + 0000 0000-0000 007F | 0xxxxxxx + 0000 0080-0000 07FF | 110xxxxx 10xxxxxx + 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx + 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + Given an array of integers representing the data, return whether it is a valid utf-8 encoding. + + Note: + The input is an array of integers. Only the least significant 8 bits of each integer is used to store the data. This means each integer represents only 1 byte of data. + + Example 1: + + data = [197, 130, 1], which represents the octet sequence: 11000101 10000010 00000001. + + Return true. + It is a valid utf-8 encoding for a 2-bytes character followed by a 1-byte character. + Example 2: + + data = [235, 140, 4], which represented the octet sequence: 11101011 10001100 00000100. + + Return false. + The first 3 bits are all one's and the 4th bit is 0 means it is a 3-bytes character. + The next byte is a continuation byte which starts with 10 and that's correct. + But the second continuation byte does not start with 10, so it is invalid. + + 10xxxxxx + 11000000 + + 10000000 + + + if((data[i] & 128) == 0) { // 0xxxxxxx, 1 byte, 128(10000000) + numberOfBytes = 1; + } else if((data[i] & 224) == 192) { // 110xxxxx, 2 bytes, 224(11100000), 192(11000000) + numberOfBytes = 2; + } else if((data[i] & 240) == 224) { // 1110xxxx, 3 bytes, 240(11110000), 224(11100000) + numberOfBytes = 3; + } else if((data[i] & 248) == 240) { // 11110xxx, 4 bytes, 248(11111000), 240(11110000) + numberOfBytes = 4; + } else { + return false; + } + if((data[i+j] & 192) != 128) return false; // 192(11000000), 128(10000000) + + time : O(n) + space : O(1) + + * @param data + * @return + */ + public boolean validUtf8(int[] data) { + if (data == null || data.length == 0) return false; + boolean isValid = true; + for (int i = 0; i < data.length; i++) { + if (data[i] > 255) return false; + int numberOfBytes = 0; + if((data[i] & 128) == 0) { // 0xxxxxxx, 1 byte, 128(10000000) + numberOfBytes = 1; + } else if((data[i] & 224) == 192) { // 110xxxxx, 2 bytes, 224(11100000), 192(11000000) + numberOfBytes = 2; + } else if((data[i] & 240) == 224) { // 1110xxxx, 3 bytes, 240(11110000), 224(11100000) + numberOfBytes = 3; + } else if((data[i] & 248) == 240) { // 11110xxx, 4 bytes, 248(11111000), 240(11110000) + numberOfBytes = 4; + } else { + return false; + } + for (int j = 1; j < numberOfBytes; j++) { + if (i + j >= data.length) return false; + if((data[i+j] & 192) != 128) return false; // 192(11000000), 128(10000000) + } + i = i + numberOfBytes - 1; + } + return isValid; + } +} diff --git a/UglyNumber.java b/UglyNumber.java new file mode 100644 index 0000000..a7a7f67 --- /dev/null +++ b/UglyNumber.java @@ -0,0 +1,42 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : UglyNumber + * Creator : Edward + * Date : Oct, 2017 + * Description : 263. Ugly Number + */ +public class UglyNumber { + /** + * Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. + * For example, 6, 8 are ugly while 14 is not ugly since it includes another prime factor 7. + + Note that 1 is typically treated as an ugly number. + + time : O(n) + space : O(1) + + * @param num + * @return + */ + + public boolean isUgly(int num) { + if (num == 1) return true; + if (num == 0) return false; + while (num % 2 == 0) num /= 2; + while (num % 3 == 0) num /= 3; + while (num % 5 == 0) num /= 5; + return num == 1; + } + + public boolean isUgly2(int num) { + for (int i = 2; i < 6 && num > 0; i++) { + while (num % i == 0) { + num /= i; + } + } + return num == 1; + } +} diff --git a/UglyNumberII.java b/UglyNumberII.java new file mode 100644 index 0000000..9c85727 --- /dev/null +++ b/UglyNumberII.java @@ -0,0 +1,32 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : UglyNumberII + * Creator : Edward + * Date : Oct, 2017 + * Description : 264. Ugly Number II + */ +public class UglyNumberII { + /** + * + * time : O(n) + * space : O(n) + * + * @param n + * @return + */ + public int nthUglyNumber(int n) { + int[] nums = new int[n]; + int index2 = 0, index3 = 0, index5 = 0; + nums[0] = 1; + for (int i = 1; i < nums.length; i++) { + nums[i] = Math.min(nums[index2] * 2, Math.min(nums[index3] * 3, nums[index5] * 5)); + if (nums[i] == nums[index2] * 2) index2++; + if (nums[i] == nums[index3] * 3) index3++; + if (nums[i] == nums[index5] * 5) index5++; + } + return nums[n - 1]; + } +} diff --git a/UndirectedGraphNode.java b/UndirectedGraphNode.java new file mode 100644 index 0000000..207e6ca --- /dev/null +++ b/UndirectedGraphNode.java @@ -0,0 +1,23 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : UndirectedGraphNode + * Creator : Edward + * Date : Oct, 2017 + * Description : TODO + */ +public class UndirectedGraphNode { + + int label; + List neighbors; + + UndirectedGraphNode(int x) { + label = x; + neighbors = new ArrayList(); + } +} diff --git a/UniqueBinarySearchTrees.java b/UniqueBinarySearchTrees.java new file mode 100644 index 0000000..d1200c1 --- /dev/null +++ b/UniqueBinarySearchTrees.java @@ -0,0 +1,48 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : UniqueBinarySearchTrees + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class UniqueBinarySearchTrees { + /** + * 96. Unique Binary Search Trees + * Given n, how many structurally unique BST's (binary search trees) that store values 1...n? + + For example, + Given n = 3, there are a total of 5 unique BST's. + + 1 3 3 2 1 + \ / / / \ \ + 3 2 1 1 3 2 + / / \ \ + 2 1 2 3 + + n = 3 + root : 1 left : 0 right : 2 f(0) * f(2); + root : 2 left : 1 right : 1 f(1) * f(1); + root : 3 left : 2 right : 0 f(2) * f(0); + + f(n) = f(0)*f(n-1) + f(1)*f(n-2) + ... + f(n-2)*f(1) + f(n-1)*f(0) + + time : O(n); + space : O(n); + * @param n + * @return + */ + + public int numTrees(int n) { + int[] res = new int[n + 1]; + res[0] = 1; + for (int i = 1; i <= n; i++) { + for (int j = 0; j < i; j++) { + res[i] += res[j] * res[i - j - 1]; + } + } + return res[n]; + } +} diff --git a/UniqueBinarySearchTreesII.java b/UniqueBinarySearchTreesII.java new file mode 100644 index 0000000..dc9e33b --- /dev/null +++ b/UniqueBinarySearchTreesII.java @@ -0,0 +1,87 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : UniqueBinarySearchTreesII + * Creator : Edward + * Date : Aug, 2017 + * Description : TODO + */ +public class UniqueBinarySearchTreesII { + /** + * 95. Unique Binary Search Trees II + * Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1...n. + + For example, + Given n = 3, your program should return all 5 unique BST's shown below. + + 1 3 3 2 1 + \ / / / \ \ + 3 2 1 1 3 2 + / / \ \ + 2 1 2 3 + + time : O(n^2); + space : O(n); + + * @param n + * @return + */ + public List generateTrees(int n) { + List[] res = new List[n + 1]; + res[0] = new ArrayList<>(); + if (n == 0) return res[0]; + res[0].add(null); + for (int i = 1; i <= n; i++) { + res[i] = new ArrayList<>(); + for (int j = 0; j < i; j++) { + for (TreeNode left : res[j]) { + for (TreeNode right : res[i - j - 1]) { + TreeNode root = new TreeNode(j + 1); + root.left = left; + root.right = clone(right, j + 1); + res[i].add(root); + } + } + } + } + return res[n]; + } + + public TreeNode clone(TreeNode root, int k) { + if (root == null) return root; + TreeNode cur = new TreeNode(root.val + k); + cur.left = clone(root.left, k); + cur.right = clone(root.right, k); + return cur; + } + + public List generateTrees2(int n) { + if (n == 0) return new ArrayList<>(); + return genTreeList(1, n); + } + + public List genTreeList(int start, int end) { + List list = new ArrayList<>(); + if (start > end) { + list.add(null); + } + for (int idx = start; idx <= end; idx++) { + List leftList = genTreeList(start, idx - 1); + List rightList = genTreeList(idx + 1, end); + for (TreeNode left : leftList) { + for (TreeNode right : rightList) { + TreeNode root = new TreeNode(idx); + root.left = left; + root.right = right; + list.add(root); + } + } + } + return list; + } +} diff --git a/UniquePaths.java b/UniquePaths.java new file mode 100644 index 0000000..aa97e78 --- /dev/null +++ b/UniquePaths.java @@ -0,0 +1,61 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : UniquePaths + * Creator : Edward + * Date : Nov, 2017 + * Description : 62. Unique Paths + */ +public class UniquePaths { + + // time : O(n * m) space : (n * m) + public int uniquePaths(int m, int n) { + int[][] res = new int[m][n]; + for (int i = 0; i < m; i++) { + res[i][0] = 1; + } + for (int i = 0; i < n; i++) { + res[0][i] = 1; + } + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + res[i][j] = res[i - 1][j] + res[i][j - 1]; + } + } + return res[m - 1][n - 1]; + } + + // time : O(n * m) space : O(n) + public int uniquePaths2(int m, int n) { + int[] res = new int[n]; + res[0] = 1; + for (int i = 0; i < m; i++) { + for (int j = 1; j < n; j++) { + res[j] = res[j] + res[j - 1]; + } + } + return res[n - 1]; + } + + /** + * Combination(Count, k) = count! / (k!*(count - k)!) + * C = (count - k + 1) * (count - k + 2) .../k! + * time : O(m) + * space : (1) + * @param m + * @param n + * @return + */ + + public int uniquePaths3(int m, int n) { + int count = m + n - 2; + int k = m - 1; + double res = 1; + for (int i = 1; i <= k; i++) { + res = res * (count - k + 1) / i; + } + return (int)res; + } +} diff --git a/UniquePathsII.java b/UniquePathsII.java new file mode 100644 index 0000000..77b709a --- /dev/null +++ b/UniquePathsII.java @@ -0,0 +1,51 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : UniquePathsII + * Creator : Edward + * Date : Nov, 2017 + * Description : 63. Unique Paths II + */ +public class UniquePathsII { + /** + * Follow up for "Unique Paths": + + Now consider if some obstacles are added to the grids. How many unique paths would there be? + + An obstacle and empty space is marked as 1 and 0 respectively in the grid. + + For example, + There is one obstacle in the middle of a 3x3 grid as illustrated below. + + [ + [0,0,0], + [0,1,0], + [0,0,0] + ] + The total number of unique paths is 2. + + time : O(m * n) + space : O(n) + + * @param obstacleGrid + * @return + */ + + public int uniquePathsWithObstacles(int[][] obstacleGrid) { + int length = obstacleGrid[0].length; + int[] res = new int[length]; + res[0] = 1; + for (int i = 0; i < obstacleGrid.length; i++) { + for (int j = 0; j < obstacleGrid[0].length; j++) { + if (obstacleGrid[i][j] == 1) { + res[j] = 0; + } else if (j > 0) { + res[j] += res[j - 1]; + } + } + } + return res[length - 1]; + } +} diff --git a/UniqueWordAbbreviation.java b/UniqueWordAbbreviation.java new file mode 100644 index 0000000..0edd857 --- /dev/null +++ b/UniqueWordAbbreviation.java @@ -0,0 +1,70 @@ +package leetcode; + +import java.util.HashMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : UniqueWordAbbreviation + * Creator : Edward + * Date : Dec, 2017 + * Description : 288. Unique Word Abbreviation + */ +public class UniqueWordAbbreviation { + /** + * An abbreviation of a word follows the form . + * Below are some examples of word abbreviations: + + a) it --> it (no abbreviation) + + 1 + b) d|o|g --> d1g + + 1 1 1 + 1---5----0----5--8 + c) i|nternationalizatio|n --> i18n + + 1 + 1---5----0 + d) l|ocalizatio|n --> l10n + Assume you have a dictionary and given a word, find whether its abbreviation is unique in the dictionary. + A word's abbreviation is unique if no other word from the dictionary has the same abbreviation. + + Example: + Given dictionary = [ "deer", "door", "cake", "card" ] "make" + + isUnique("dear") -> false + isUnique("cart") -> true + isUnique("cane") -> false + isUnique("make") -> true + + + * @param dictionary + */ + + HashMap map; + + // time : O(n) + public UniqueWordAbbreviation(String[] dictionary) { + map = new HashMap<>(); + for (String s : dictionary) { + String key = getKey(s); + if (map.containsKey(key)) { + if (!map.get(key).equals(s)) { + map.put(key, ""); + } + } else { + map.put(key, s); + } + } + } + + public boolean isUnique(String word) { + return !map.containsKey(getKey(word)) || map.get(getKey(word)).equals(word); + } + + private String getKey(String s) { + if (s.length() <= 2) return s; + return s.charAt(0) + Integer.toString(s.length() - 2) + s.charAt(s.length() - 1); + } +} diff --git a/ValidAnagram.java b/ValidAnagram.java new file mode 100644 index 0000000..e03ec80 --- /dev/null +++ b/ValidAnagram.java @@ -0,0 +1,52 @@ +package leetcode; + +import java.lang.reflect.Array; +import java.util.Arrays; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ValidAnagram + * Creator : Edward + * Date : Oct, 2017 + * Description : 242. Valid Anagram + */ +public class ValidAnagram { + /** + * For example, + s = "anagram", t = "nagaram", return true. + s = "rat", t = "car", return false. + + * @param s + * @param t + * @return + */ + + //time : O(nlogn) space : O(n) + public boolean isAnagram(String s, String t) { + if (s.length() != t.length()) { + return false; + } + char[] str1 = s.toCharArray(); + char[] str2 = t.toCharArray(); + Arrays.sort(str1); + Arrays.sort(str2); + return Arrays.equals(str1, str2); + } + + //time : O(n) space : O(1) + public boolean isAnagram2(String s, String t) { + if (s.length() != t.length()) { + return false; + } + int[] count = new int[26]; + for (int i = 0; i < s.length(); i++) { + count[s.charAt(i) - 'a']++; + count[t.charAt(i) - 'a']--; + } + for (int num : count) { + if (num != 0) return false; + } + return true; + } +} diff --git a/ValidNumber.java b/ValidNumber.java new file mode 100644 index 0000000..ecb734b --- /dev/null +++ b/ValidNumber.java @@ -0,0 +1,61 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ValidNumber + * Creator : Edward + * Date : Sep, 2017 + * Description : TODO + */ +public class ValidNumber { + + /** + * 65. Valid Number + * Validate if a given string is numeric. + + Some examples: + "0" => true + " 0.1 " => true + "abc" => false + "1 a" => false + "2e10" => true + + time : O(n); + space : O(1); + * @param s + * @return + */ + + public boolean isNumber(String s) { + s = s.trim(); + boolean numberSeen = false; + boolean pointSeen = false; + boolean eSeen = false; + boolean numberAfterE = true; + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) >= '0' && s.charAt(i) <= '9') { + numberSeen = true; + numberAfterE = true; + } else if (s.charAt(i) == '.') { + if (eSeen || pointSeen) { + return false; + } + pointSeen = true; + } else if (s.charAt(i) == 'e') { + if (eSeen || !numberSeen) { + return false; + } + eSeen = true; + numberAfterE = false; + } else if (s.charAt(i) == '+' || s.charAt(i) == '-') { + if (i != 0 && s.charAt(i - 1) != 'e') { + return false; + } + } else { + return false; + } + } + return numberSeen && numberAfterE; + } +} diff --git a/ValidPalindrome.java b/ValidPalindrome.java new file mode 100644 index 0000000..d12c248 --- /dev/null +++ b/ValidPalindrome.java @@ -0,0 +1,47 @@ +package leetcode; + +/** + * Created by Edward on 28/07/2017. + */ +public class ValidPalindrome { + /** + * 125. Valid Palindrome + * Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. + + For example, + "A man, a plan, a canal: Panama" is a palindrome. + "race a car" is not a palindrome. + + Note: + Have you consider that the string might be empty? This is a good question to ask during an interview. + + For the purpose of this problem, we define empty string as valid palindrome. + + case : "A man, a plan, a canal: Panama" + + time : O(n) + space : O(1); + + * @param s + * @return + */ + public static boolean isPalindrome(String s) { + if (s == null || s.length() == 0) return true; + int left = 0; + int right = s.length() - 1; + while (left < right) { + while (left < right && !Character.isLetterOrDigit(s.charAt(left))) { + left++; + } + while (left < right && !Character.isLetterOrDigit(s.charAt(right))) { + right--; + } + if (Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right))) { + return false; + } + left++; + right--; + } + return true; + } +} diff --git a/ValidParentheses.java b/ValidParentheses.java new file mode 100644 index 0000000..aa527b4 --- /dev/null +++ b/ValidParentheses.java @@ -0,0 +1,48 @@ +package leetcode; + +import java.util.Stack; + +/** + * Created by Edward on 27/07/2017. + */ +public class ValidParentheses { + /** + * 20. Valid Parentheses + * Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. + + The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not. + + case1 : ()[]{} + stack : + + case2 : ([)] + stack : + + case3 : } + stack : + + time : O(n); + space : O(n); + * @param s + * @return + */ + public static boolean isValid(String s) { + + if (s == null || s.length() == 0) return true; + Stack stack = new Stack<>(); + for (Character ch : s.toCharArray()) { + if (ch == '(') { + stack.push(')'); + } else if (ch == '[') { + stack.push(']'); + } else if (ch == '{') { + stack.push('}'); + } else { + if (stack.isEmpty() || stack.pop() != ch) { + return false; + } + } + } + return stack.isEmpty(); + } +} diff --git a/ValidPerfectSquare.java b/ValidPerfectSquare.java new file mode 100644 index 0000000..701c3ff --- /dev/null +++ b/ValidPerfectSquare.java @@ -0,0 +1,68 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ValidPerfectSquare + * Creator : Edward + * Date : Oct, 2017 + * Description : 367. Valid Perfect Square + */ +public class ValidPerfectSquare { + + // time : O(n) space : O(1) + public boolean isPerfectSquare(int num) { + if (num < 0) return false; + if (num == 1) return true; + for (int i = 1; i <= num / i; i++) { + if (i * i == num) return true; + } + return false; + } + + // time : O(logn) space : O(1) + public boolean isPerfectSquare2(int num) { + int low = 1; + int high = num; + while (low <= high) { + long mid = (high - low) / 2 + low; + if (mid * mid == num) { + return true; + } else if (mid * mid < num) { + low = (int) mid + 1; + } else { + high = (int) mid - 1; + } + } + return false; + } + + /** + * 1 = 1 + * 4 = 1 + 3 + * 9 = 1 + 3 + 5 + * 16 = 1 + 3 + 5 + 7 + * ... + * @param num + * @return + */ + + // time : O(n) space : O(1); + public boolean isPerfectSquare3(int num) { + int i = 1; + while (num > 0) { + num -= i; + i += 2; + } + return num == 0; + } + + // Newton Method time : 不知道 space : O(1); + public boolean isPerfectSquare4(int num) { + long x = num; + while (x * x > num) { + x = (x + num / x) / 2; + } + return x * x == num; + } +} diff --git a/ValidSudoku.java b/ValidSudoku.java new file mode 100644 index 0000000..2150150 --- /dev/null +++ b/ValidSudoku.java @@ -0,0 +1,63 @@ +package leetcode; + +import java.util.HashSet; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ValidSudoku + * Creator : Edward + * Date : Sep, 2017 + * Description : 36. Valid Sudoku + */ +public class ValidSudoku { + + + // time : O(n^2) space : O(n) + public boolean isValidSudoku1(char[][] board) { + for (int i = 0; i < board.length; i++) { + HashSet rows = new HashSet<>(); + HashSet cols = new HashSet<>(); + HashSet cube = new HashSet<>(); + for (int j = 0; j < board[0].length; j++) { + if (board[i][j] != '.' && !rows.add(board[i][j])) return false; + if (board[j][i] != '.' && !cols.add(board[j][i])) return false; + + int rowIndex = 3 * (i / 3); + int colIndex = 3 * (i % 3); + + if (board[rowIndex + j / 3][colIndex + j % 3] != '.' && !cube.add(board[rowIndex + j / 3][colIndex + j % 3])) + return false; + } + } + return true; + } + + public boolean isValidSudoku2(char[][] board) { + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + if (board[i][j] == '.') continue; + if (!valid(board, i, j)) return false; + } + } + return true; + } + + public boolean valid(char[][] board, int i, int j) { + for (int row = 0; row < board.length; row++) { + if (row == i) continue; + if (board[row][j] == board[i][j]) return false; + } + for (int col = 0; col < board[0].length; col++) { + if (col == i) continue; + if (board[i][col] == board[i][j]) return false; + } + for (int row = (i / 3) * 3; row < (i / 3 + 1) * 3; row++) { + for (int col = (j / 3) * 3; col < (j / 3 + 1) * 3; col++) { + if (row == i && col == j) continue; + if (board[row][col] == board[i][j]) return false; + } + } + return true; + } +} diff --git a/ValidateBinarySearchTree.java b/ValidateBinarySearchTree.java new file mode 100644 index 0000000..402e416 --- /dev/null +++ b/ValidateBinarySearchTree.java @@ -0,0 +1,38 @@ +package leetcode; + +/** + * Created by Edward on 24/07/2017. + */ +public class ValidateBinarySearchTree { + + /** + * 98. Validate Binary Search Tree + * Given a binary tree, determine if it is a valid binary search tree (BST). + + Assume a BST is defined as follows: + + The left subtree of a node contains only nodes with keys less than the node's key. + The right subtree of a node contains only nodes with keys greater than the node's key. + Both the left and right subtrees must also be binary search trees. + + time : O(n) + space : O(n) + * @param root + * @return + */ + + public static boolean isValidBST(TreeNode root) { + + if (root == null) return true; + return helper(root, null, null); + } + + public static boolean helper(TreeNode root, Integer min, Integer max) { + + if (root == null) return true; + if (min != null && root.val <= min) return false; + if (max != null && root.val >= max) return false; + + return helper(root.left, min, root.val) && helper(root.right, root.val, max); + } +} diff --git a/VerifyPreorderSequenceinBinarySearchTree.java b/VerifyPreorderSequenceinBinarySearchTree.java new file mode 100644 index 0000000..631dab1 --- /dev/null +++ b/VerifyPreorderSequenceinBinarySearchTree.java @@ -0,0 +1,51 @@ +package leetcode; + +import java.util.Iterator; +import java.util.Stack; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : VerifyPreorderSequenceinBinarySearchTree + * Creator : Edward + * Date : Nov, 2017 + * Description : 255. Verify Preorder Sequence in Binary Search Tree + */ +public class VerifyPreorderSequenceinBinarySearchTree { + /** + * 6 + / \ + 1 8 + / \ + 0 3 + / \ + 2 5 + + preorder : 6 1 0 3 2 5 8 + + num : 8 + min : 6 + stack : 8 + + time : O(n) + space : O(n) + + * @param preorder + * @return + */ + + public static boolean verifyPreorder(int[] preorder) { + Stack stack = new Stack<>(); + int min = Integer.MIN_VALUE; + for (int num : preorder) { + if (num < min) { + return false; + } + while (!stack.isEmpty() && num > stack.peek()) { + min = stack.pop(); + } + stack.push(num); + } + return true; + } +} diff --git a/VerifyPreorderSerializationofaBinaryTree.java b/VerifyPreorderSerializationofaBinaryTree.java new file mode 100644 index 0000000..98455f7 --- /dev/null +++ b/VerifyPreorderSerializationofaBinaryTree.java @@ -0,0 +1,66 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : VerifyPreorderSerializationofaBinaryTree + * Creator : Edward + * Date : Jan, 2018 + * Description : 331. Verify Preorder Serialization of a Binary Tree + */ +public class VerifyPreorderSerializationofaBinaryTree { + /** + * One way to serialize a binary tree is to use pre-order traversal. When we encounter a non-null node, we record the node's value. If it is a null node, we record using a sentinel value such as #. + + _9_ + / \ + 3 2 + / \ / \ + 4 1 # 6 + / \ / \ / \ + # # # # # # + + For example, the above binary tree can be serialized to the string "9,3,4,#,#,1,#,#,2,#,6,#,#", where # represents a null node. + + Given a string of comma separated values, verify whether it is a correct preorder traversal serialization of a binary tree. Find an algorithm without reconstructing the tree. + + Each comma separated value in the string must be either an integer or a character '#' representing null pointer. + + You may assume that the input format is always valid, for example it could never contain two consecutive commas such as "1,,3". + + Example 1: + "9,3,4,#,#,1,#,#,2,#,6,#,#" + Return true + + Example 2: + "1,#" + Return false + + Example 3: + "9,#,#,1" + Return false + + all non-null node provides 2 outdegree and 1 indegree (2 children and 1 parent), except root + all null node provides 0 outdegree and 1 indegree (0 child and 1 parent). + + diff = outdegree - indegree + + time : O(n) + space : O(n) + + * @param preorder + * @return + */ + + public boolean isValidSerialization(String preorder) { + String[] nodes = preorder.split(","); + int diff = 1; + for (String node : nodes) { + if (--diff < 0) return false; + if (!node.equals("#")) { + diff += 2; + } + } + return diff == 0; + } +} diff --git a/WallsandGates.java b/WallsandGates.java new file mode 100644 index 0000000..8eda24d --- /dev/null +++ b/WallsandGates.java @@ -0,0 +1,93 @@ +package leetcode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : WallsandGates + * Creator : Edward + * Date : Dec, 2017 + * Description : 286. Walls and Gates + */ +public class WallsandGates { + /** + * You are given a m x n 2D grid initialized with these three possible values. + + -1 - A wall or an obstacle. + 0 - A gate. + INF - Infinity means an empty room. We use the value 231 - 1 = 2147483647 to represent INF as you may assume + that the distance to a gate is less than 2147483647. + Fill each empty room with the distance to its nearest gate. If it is impossible to reach a gate, + it should be filled with INF. + + For example, given the 2D grid: + INF -1 0 INF + INF INF INF -1 + INF -1 INF -1 + 0 -1 INF INF + + After running your function, the 2D grid should be: + 3 -1 0 1 + 2 2 1 -1 + 1 -1 2 -1 + 0 -1 3 4 + + time : O(m * n) + space : O(m * n) + + * @param rooms + */ + + // space : O(n) + public void wallsAndGates(int[][] rooms) { + for (int i = 0; i < rooms.length; i++) { + for (int j = 0; j < rooms[0].length; j++) { + if (rooms[i][j] == 0) { + dfs(rooms, i, j, 0); + } + } + } + } + + private void dfs(int[][] rooms, int i, int j, int dis) { + if (i < 0 || i >= rooms.length || j < 0 || j >= rooms[0].length || rooms[i][j] < dis) return; + rooms[i][j] = dis; + dfs(rooms, i - 1, j, dis + 1); + dfs(rooms, i + 1, j, dis + 1); + dfs(rooms, i, j + 1, dis + 1); + dfs(rooms, i, j - 1, dis + 1); + } + + public void wallsAndGates2(int[][] rooms) { + Queue queue = new LinkedList<>(); + for (int i = 0; i < rooms.length; i++) { + for (int j = 0; j < rooms[0].length; j++) { + if (rooms[i][j] == 0) { + queue.add(new int[]{i, j}); + } + } + } + while (!queue.isEmpty()) { + int[] top = queue.remove(); + int row = top[0], col = top[1]; + if (row > 0 && rooms[row - 1][col] == Integer.MAX_VALUE) { + rooms[row - 1][col] = rooms[row][col] + 1; + queue.add(new int[]{row - 1, col}); + } + if (row < rooms.length - 1 && rooms[row + 1][col] == Integer.MAX_VALUE) { + rooms[row + 1][col] = rooms[row][col] + 1; + queue.add(new int[]{row + 1, col}); + } + if (col > 0 && rooms[row][col - 1] == Integer.MAX_VALUE) { + rooms[row][col - 1] = rooms[row][col] + 1; + queue.add(new int[]{row, col - 1}); + } + if (col < rooms[0].length - 1 && rooms[row][col + 1] == Integer.MAX_VALUE) { + rooms[row][col + 1] = rooms[row][col] + 1; + queue.add(new int[]{row, col + 1}); + } + } + } +} diff --git a/WaterandJugProblem.java b/WaterandJugProblem.java new file mode 100644 index 0000000..48f0265 --- /dev/null +++ b/WaterandJugProblem.java @@ -0,0 +1,71 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : WaterandJugProblem + * Creator : Edward + * Date : Jan, 2018 + * Description : 365. Water and Jug Problem + */ +public class WaterandJugProblem { + /** + * You are given two jugs with capacities x and y litres. There is an infinite amount of water supply available. + * You need to determine whether it is possible to measure exactly z litres using these two jugs. + + If z liters of water is measurable, you must have z liters of water contained within one or both buckets by the end. + + Operations allowed: + + Fill any of the jugs completely with water. + Empty any of the jugs. + Pour water from one jug into another till the other jug is completely full or the first jug itself is empty. + Example 1: (From the famous "Die Hard" example) + + Input: x = 3, y = 5, z = 4 + Output: True + Example 2: + + Input: x = 2, y = 6, z = 5 + Output: False + + x * m + y * n = z + 3 * -2 + 5 * 2 = 4 + + : 装水 + - : 倒水 + + x * m + y * n = z + 贝祖定理: z = gcd(x,y) * i z % gcd(x,y) = 0 + + GCD : 求最大公约数(a,b) + + a / b = c ... d + d = 0 : b + : b / d = f ... e + e = 0 : d + + a = 3 b = 6 + 6 3 + 3 0 + + 1 2 4 + + time : < O(n) O(1) + space : (n) + + * @param x + * @param y + * @param z + * @return + */ + public boolean canMeasureWater(int x, int y, int z) { + if (x + y < z) return false; + if (x == z || y == z || x + y == 2) return true; + return z % gcd(x, y) == 0; + } + + private int gcd(int a, int b) { + if (b == 0) return a; + return gcd(b, a % b); + } +} diff --git a/WiggleSort.java b/WiggleSort.java new file mode 100644 index 0000000..d85ef78 --- /dev/null +++ b/WiggleSort.java @@ -0,0 +1,32 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : WiggleSort + * Creator : Edward + * Date : Dec, 2017 + * Description : 280. Wiggle Sort + */ +public class WiggleSort { + /** + * Given an unsorted array nums, reorder it in-place such that nums[0] <= nums[1] >= nums[2] <= nums[3].... + + For example, given nums = [3, 5, 2, 1, 6, 4], one possible answer is [1, 6, 2, 5, 3, 4]. + + time : O(n) + space : O(1) + + + * @param nums + */ + public void wiggleSort(int[] nums) { + for (int i = 1; i < nums.length; i++) { + if ((i % 2 == 1 && nums[i] < nums[i - 1]) || (i % 2 == 0 && nums[i] > nums[i - 1])) { + int temp = nums[i - 1]; + nums[i - 1] = nums[i]; + nums[i] = temp; + } + } + } +} diff --git a/WiggleSortII.java b/WiggleSortII.java new file mode 100644 index 0000000..ab5c7a0 --- /dev/null +++ b/WiggleSortII.java @@ -0,0 +1,126 @@ +package leetcode; + +import java.util.Arrays; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : WiggleSortII + * Creator : Edward + * Date : Jan, 2018 + * Description : 324. Wiggle Sort II + */ +public class WiggleSortII { + /** + * Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3].... + + Example: + (1) Given nums = [1, 5, 1, 1, 6, 4], one possible answer is [1, 4, 1, 5, 1, 6]. + (2) Given nums = [1, 3, 2, 2, 3, 1], one possible answer is [2, 3, 1, 3, 1, 2]. + + Note: + You may assume all input has valid answer. + + Follow Up: + Can you do it in O(n) time and/or in-place with O(1) extra space? + + time : O(nlogn) + space : O(n) + + * @param nums + */ + public void wiggleSort(int[] nums) { + Arrays.sort(nums); + int n = nums.length; + int mid = (n - 1) / 2; + int index = 0; + int[] temp = new int[n]; + for (int i = 0; i <= mid; i++) { + temp[index] = nums[mid - i]; + if (index + 1 < n) { + temp[index + 1] = nums[n - 1 - i]; + } + index += 2; + } + System.arraycopy(temp, 0, nums, 0, n); + } + + /** + Original idx: 0 1 2 3 4 5 + Mapped idx: 1 3 5 0 2 4 + Array: 13 6 4 5 2 5 + 5 6 4 13 2 5 + r + i + l + median = 5 + + nums[] = 5 + + 大于中位数,左 - 右,奇 + 小于中位数,右 - 左,偶 + + time : O(n) + space : O(1) + + + * @param nums + */ + + public void wiggleSort2(int[] nums) { + int median = findKthLargest(nums, (nums.length + 1) / 2); + int n = nums.length; + int left = 0, right = n - 1; + int index = 0; + while (index <= right) { + if (nums[newIndex(index, n)] > median) { + swap(nums, newIndex(left++, n), newIndex(index++, n)); + } else if (nums[newIndex(index, n)] < median) { + swap(nums, newIndex(right--, n), newIndex(index, n)); + } else { + index++; + } + } + } + + private int newIndex(int index, int n) { + return (1 + 2 * index) % (n | 1); + } + + public int findKthLargest(int[] nums, int k) { + if (nums == null || nums.length == 0) return 0; + int left = 0; + int right = nums.length - 1; + while (true) { + int pos = partition(nums, left, right); + if (pos + 1 == k) { + return nums[pos]; + } else if (pos + 1 > k) { + right = pos - 1; + } else { + left = pos + 1; + } + } + } + + private int partition(int[] nums, int left, int right) { + int pivot = nums[left]; + int l = left + 1; + int r = right; + while (l <= r) { + if (nums[l] < pivot && nums[r] > pivot) { + swap(nums, l++, r--); + } + if (nums[l] >= pivot) l++; + if (nums[r] <= pivot) r--; + } + swap(nums, left, r); + return r; + } + + private void swap(int[] nums, int i, int j) { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } +} diff --git a/WiggleSubsequence.java b/WiggleSubsequence.java new file mode 100644 index 0000000..3595347 --- /dev/null +++ b/WiggleSubsequence.java @@ -0,0 +1,75 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : WiggleSubsequence + * Creator : Edward + * Date : Jan, 2018 + * Description : 376. Wiggle Subsequence + */ +public class WiggleSubsequence { + + /** + * Examples: + Input: [1,7,4,9,2,5] + Output: 6 + The entire sequence is a wiggle sequence. + + Input: [1,17,5,10,13,15,10,5,16,8] + Output: 7 + There are several subsequences that achieve this length. One is [1,17,10,13,10,16,8]. + + Input: [1,2,3,4,5,6,7,8,9] + Output: 2 + + dp up[] down[] + + Input: [1,7,4,9,2,5] + + up[1,2,2] + down[1,1,3] + + time : O(n) + space : O(n) / O(1) + + * @param nums + * @return + */ + + public int wiggleMaxLength(int[] nums) { + if (nums.length == 0) return 0; + int[] up = new int[nums.length]; + int[] down = new int[nums.length]; + + up[0] = 1; + down[0] = 1; + + for (int i = 1; i < nums.length; i++) { + if (nums[i] > nums[i - 1]) { + up[i] = down[i - 1] + 1; + down[i] = down[i - 1]; + } else if (nums[i] < nums[ i - 1]) { + down[i] = up[i - 1] + 1; + up[i] = up[i - 1]; + } else { + down[i] = down[i - 1]; + up[i] = up[i - 1]; + } + } + return Math.max(down[nums.length - 1], up[nums.length - 1]); + } + + public int wiggleMaxLength2(int[] nums) { + if (nums.length == 0) return 0; + int up = 1, down = 1; + for (int i = 1; i < nums.length; i++) { + if (nums[i] > nums[i - 1]) { + up = down + 1; + } else if (nums[i] < nums[i - 1]) { + down = up + 1; + } + } + return Math.max(up, down); + } +} diff --git a/WildcardMatching.java b/WildcardMatching.java new file mode 100644 index 0000000..1832838 --- /dev/null +++ b/WildcardMatching.java @@ -0,0 +1,66 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : WildcardMatching + * Creator : Edward + * Date : Nov, 2017 + * Description : 44. Wildcard Matching + */ +public class WildcardMatching { + /** + * Implement wildcard pattern matching with support for '?' and '*'. + + '?' Matches any single character. + '*' Matches any sequence of characters (including the empty sequence). + + The matching should cover the entire input string (not partial). + + The function prototype should be: + bool isMatch(const char *s, const char *p) + + Some examples: + isMatch("aa","a") → false + isMatch("aa","aa") → true + isMatch("aaa","aa") → false + isMatch("aa", "*") → true + isMatch("aa", "a*") → true + isMatch("ab", "?*") → true + isMatch("aab", "c*a*b") → false + + "bbarc" match = 3 sp = 3 + "*c" star = 0 pp = 1 + + time : O(n) + space : O(1) + + * @param s + * @param p + * @return + */ + public boolean isMatch(String s, String p) { + int sp = 0; + int pp = 0; + int match = 0; + int star = -1; + while (sp < s.length()) { + if (pp < p.length() && (s.charAt(sp) == p.charAt(pp) || p.charAt(pp) == '?')) { + sp++; + pp++; + } else if (pp < p.length() && p.charAt(pp) == '*') { + star = pp; + match = sp; + pp++; + } else if (star != -1) { + pp = star + 1; + match++; + sp = match; + } else return false; + } + while (pp < p.length() && p.charAt(pp) == '*') { + pp++; + } + return pp == p.length(); + } +} diff --git a/WordBreak.java b/WordBreak.java new file mode 100644 index 0000000..62d5ba0 --- /dev/null +++ b/WordBreak.java @@ -0,0 +1,51 @@ +package leetcode; + +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : WordBreak + * Creator : Edward + * Date : Sep, 2017 + * Description : 139. Word Break + */ +public class WordBreak { + + /** + * Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, + * determine if s can be segmented into a space-separated sequence of one or more dictionary words. + * You may assume the dictionary does not contain duplicate words. + + For example, given + s = "leetcode", + dict = ["leet", "code"]. + + Return true because "leetcode" can be segmented as "leet code". + + time : O(n^2); + space : O(n); + + s = "leetcode", + dict = ["leet", "code"] + + + * @param s + * @param wordDict + * @return + */ + + public boolean wordBreak(String s, List wordDict) { + boolean[] dp = new boolean[s.length() + 1]; + dp[0] = true; + for (int i = 1; i <= s.length(); i++) { + for (int j = 0; j < i; j++) { + if (dp[j] && wordDict.contains(s.substring(j, i))) { + dp[i] = true; + break; + } + } + } + return dp[s.length()]; + } +} diff --git a/WordBreakII.java b/WordBreakII.java new file mode 100644 index 0000000..cea1171 --- /dev/null +++ b/WordBreakII.java @@ -0,0 +1,57 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : WordBreakII + * Creator : Edward + * Date : Oct, 2017 + * Description : 140. Word Break II + */ +public class WordBreakII { + /** + * For example, given + s = "catsanddog", + dict = ["cat", "cats", "and", "sand", "dog"]. + + A solution is ["cats and dog", "cat sand dog"]. + + time : O(n^3) + space : O(n^3) + + * @param s + * @param wordDict + * @return + */ + + HashMap> map = new HashMap<>(); + + // DFS + public List wordBreak(String s, List wordDict) { + return dfs(s, wordDict, 0); + } + + public List dfs(String s, List wordDict, int start) { + if (map.containsKey(start)) { + return map.get(start); + } + List res = new ArrayList<>(); + if (start == s.length()) { + res.add(""); + } + for (int end = start + 1; end <= s.length(); end++) { + if (wordDict.contains(s.substring(start, end))) { + List list = dfs(s, wordDict, end); + for (String temp : list) { + res.add(s.substring(start, end) + (temp.equals("") ? "" : " ") + temp); + } + } + } + map.put(start, res); + return res; + } +} diff --git a/WordLadder.java b/WordLadder.java new file mode 100644 index 0000000..301bb3b --- /dev/null +++ b/WordLadder.java @@ -0,0 +1,105 @@ +package leetcode; + +import java.util.*; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : WordLadder + * Creator : Edward + * Date : Oct, 2017 + * Description : 127. Word Ladder + */ +public class WordLadder { + /** + * For example, + + Given: + beginWord = "hit" + endWord = "cog" + wordList = ["hot","dot","dog","lot","log","cog"] + As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", + return its length 5. + + + beginWord = "hit" + endWord = "cog" + wordList = ["hot","dot","dog","lot","log","cog"] + As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", + + time : O(n) + time : O(n) + + * @param beginWord + * @param endWord + * @param wordList + * @return + */ + public int ladderLength1(String beginWord, String endWord, List wordList) { + HashSet set = new HashSet<>(wordList); + if (set.contains(beginWord)) { + set.remove(beginWord); + } + Queue queue = new LinkedList<>(); + int level = 1; + int curNum = 1; + int nextNum = 0; + queue.offer(beginWord); + while (!queue.isEmpty()) { + String word = queue.poll(); + curNum--; + for (int i = 0; i < word.length(); i++) { + char[] wordUnit = word.toCharArray(); + for (char j = 'a'; j <= 'z'; j++) { + wordUnit[i] = j; + String temp = new String(wordUnit); + if (set.contains(temp)) { + if (temp.equals(endWord)) { + return level + 1; + } + nextNum++; + queue.offer(temp); + set.remove(temp); + } + } + } + if (curNum == 0) { + curNum = nextNum; + nextNum = 0; + level++; + } + } + return 0; + } + + public int ladderLength2(String beginWord, String endWord, List wordList) { + HashSet set = new HashSet<>(wordList); + if (set.contains(beginWord)) { + set.remove(beginWord); + } + Queue queue = new LinkedList<>(); + HashMap map = new HashMap<>(); + map.put(beginWord, 1); + queue.offer(beginWord); + while (!queue.isEmpty()) { + String word = queue.poll(); + int curLevel = map.get(word); + for (int i = 0; i < word.length(); i++) { + char[] wordUnit = word.toCharArray(); + for (char j = 'a'; j <= 'z'; j++) { + wordUnit[i] = j; + String temp = new String(wordUnit); + if (set.contains(temp)) { + if (temp.equals(endWord)) { + return curLevel + 1; + } + map.put(temp, curLevel + 1); + queue.offer(temp); + set.remove(temp); + } + } + } + } + return 0; + } +} diff --git a/WordLadderII.java b/WordLadderII.java new file mode 100644 index 0000000..5f1c615 --- /dev/null +++ b/WordLadderII.java @@ -0,0 +1,127 @@ +package leetcode; + +import java.util.*; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : WordLadderII + * Creator : Edward + * Date : Dec, 2017 + * Description : 126. Word Ladder II + */ +public class WordLadderII { + /** + * Given two words (beginWord and endWord), and a dictionary's word list, + * find all shortest transformation sequence(s) from beginWord to endWord, such that: + + Only one letter can be changed at a time + Each transformed word must exist in the word list. Note that beginWord is not a transformed word. + For example, + + Given: + beginWord = "hit" + endWord = "cog" + wordList = ["hot","dot","dog","lot","log","cog"] + + Return + [ + ["hit","hot","dot","dog","cog"], + ["hit","hot","lot","log","cog"] + ] + + BFS + DFS + + 无向图 -> BFS -> 树 -> DFS -> 结果 + + hit -> hot -> dot -> dog - cog + -> lot -> log - cog + + map : hot (hit) + dot (hot) + lot (hot) + dog (dot) + log (lot) + cog (dog,log) + + time : O(V + E) * wordList(max(length)) 不确定 + O(n ^ 2) + space : O(n) + + * @param beginWord + * @param endWord + * @param wordList + * @return + */ + + + public List> findLadders(String beginWord, String endWord, List wordList) { + List> res = new ArrayList<>(); + if (wordList.size() == 0) return res; + + int curNum = 1; + int nextNum = 0; + boolean found = false; + + Queue queue = new LinkedList<>(); + HashSet unvisited = new HashSet<>(wordList); + HashSet visited = new HashSet<>(); + + HashMap> map = new HashMap<>(); + + queue.offer(beginWord); + while (!queue.isEmpty()) { + String word = queue.poll(); + curNum--; + for (int i = 0; i < word.length(); i++) { + StringBuilder builder = new StringBuilder(word); + for (char ch = 'a'; ch <= 'z'; ch++) { + builder.setCharAt(i, ch); + String newWord = builder.toString(); + if (unvisited.contains(newWord)) { + if (visited.add(newWord)) { + nextNum++; + queue.offer(newWord); + } + if (map.containsKey(newWord)) { + map.get(newWord).add(word); + } else { + List list = new ArrayList<>(); + list.add(word); + map.put(newWord, list); + } + if (newWord.equals(endWord)) { + found = true; + } + } + } + } + if (curNum == 0) { + if (found) break; + curNum = nextNum; + nextNum = 0; + unvisited.removeAll(visited); + visited.clear(); + } + } + dfs(res, new ArrayList<>(), map, endWord, beginWord); + return res; + } + + private void dfs(List> res, List list, HashMap> map, String word, String start) { + if (word.equals(start)) { + list.add(0, start); + res.add(new ArrayList<>(list)); + // list.remove(list.size - 1) + list.remove(0); + return; + } + list.add(0, word); + if (map.get(word) != null) { + for (String s : map.get(word)) { + dfs(res, list, map, s, start); + } + } + list.remove(0); + } +} diff --git a/WordPattern.java b/WordPattern.java new file mode 100644 index 0000000..d88ff7d --- /dev/null +++ b/WordPattern.java @@ -0,0 +1,52 @@ +package leetcode; + +import java.util.HashMap; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : WordPattern + * Creator : Edward + * Date : Nov, 2017 + * Description : 290. Word Pattern + */ +public class WordPattern { + /** + * Given a pattern and a string str, find if str follows the same pattern. + + Here follow means a full match, such that there is a bijection between a letter in pattern and a non-empty word in str. + + Examples: + pattern = "abba", str = "dog cat cat dog" should return true. + pattern = "abba", str = "dog cat cat fish" should return false. + pattern = "aaaa", str = "dog cat cat dog" should return false. + pattern = "abba", str = "dog dog dog dog" should return false. + + time : O(n) space : O(n) + + * @param pattern + * @param str + * @return + */ + public boolean wordPattern(String pattern, String str) { + String[] arr = str.split(" "); + if (arr.length != pattern.length()) { + return false; + } + HashMap map = new HashMap<>(); + for (int i = 0; i < arr.length; i++) { + char c = pattern.charAt(i); + if (map.containsKey(c)) { + if (!map.get(c).equals(arr[i])) { + return false; + } else { + if (map.containsValue(arr[i])) { + return false; + } + map.put(c, arr[i]); + } + } + } + return true; + } +} diff --git a/WordPatternII.java b/WordPatternII.java new file mode 100644 index 0000000..a5c6654 --- /dev/null +++ b/WordPatternII.java @@ -0,0 +1,71 @@ +package leetcode; + +import java.util.HashMap; +import java.util.HashSet; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : WordPatternII + * Creator : Edward + * Date : Nov, 2017 + * Description : 291. Word Pattern II + */ +public class WordPatternII { + /** + * Given a pattern and a string str, find if str follows the same pattern. + + Here follow means a full match, such that there is a bijection + between a letter in pattern and a non-empty substring in str. + + Examples: + pattern = "abab", str = "redblueredblue" should return true. + pattern = "aaaa", str = "asdasdasdasd" should return true. + pattern = "aabb", str = "xyzabcxzyabc" should return false. + + + pattern = "abab", str = "redblueredblue" "redres + + + time : O(2^n) 不确定 + space : O(n) + + * @param pattern + * @param str + * @return + */ + public boolean wordPatternMatch(String pattern, String str) { + HashMap map = new HashMap<>(); + HashSet set = new HashSet<>(); + return isMatch(str, 0, pattern, 0, map, set); + } + + private boolean isMatch(String str, int i, String pat, int j, HashMap map, HashSet set) { + if (i == str.length() && j == pat.length()) return true; + if (i == str.length() || j == pat.length()) return false; + + char c = pat.charAt(j); + if (map.containsKey(c)) { + String s = map.get(c); + if (!str.startsWith(s, i)) { + return false; + } + return isMatch(str, i + s.length(), pat, j + 1, map, set); + } + + for (int k = i; k < str.length(); k++) { + String p = str.substring(i, k + 1); + if (set.contains(p)) { + continue; + } + map.put(c, p); + set.add(p); + if (isMatch(str, k + 1, pat, j + 1, map, set)) { + return true; + } + map.remove(c); + set.remove(p); + } + return false; + } +} diff --git a/WordSearch.java b/WordSearch.java new file mode 100644 index 0000000..2b21333 --- /dev/null +++ b/WordSearch.java @@ -0,0 +1,58 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : WordSearch + * Creator : Edward + * Date : Oct, 2017 + * Description : 79. Word Search + */ +public class WordSearch { + /** + * For example, + Given board = + + [ + ['A','B','C','E'], + ['S','F','C','S'], + ['A','D','E','E'] + ] + word = "ABCCED", -> returns true, + word = "SEE", -> returns true, + word = "ABCB", -> returns false. + + + time : 不知道 + space : 不知道 + + * @param board + * @param word + * @return + */ + public boolean exist(char[][] board, String word) { + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + if (exist(board, i, j, word, 0)) { + return true; + } + } + } + return false; + } + private boolean exist(char[][] board, int i, int j, String word, int start) { + if (start >= word.length()) return true; + if (i < 0 || i >= board.length || j < 0 || j >= board[0].length) return false; + if (board[i][j] == word.charAt(start++)) { + char c = board[i][j]; + board[i][j] = '#'; + boolean res = exist(board, i + 1, j, word, start) || + exist(board, i - 1, j, word, start) || + exist(board, i, j + 1, word, start) || + exist(board, i, j - 1, word, start); + board[i][j] = c; + return res; + } + return false; + } +} diff --git a/WordSearchII.java b/WordSearchII.java new file mode 100644 index 0000000..a9d6a35 --- /dev/null +++ b/WordSearchII.java @@ -0,0 +1,87 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : WordSearchII + * Creator : Edward + * Date : Dec, 2017 + * Description : 212. Word Search II + */ +public class WordSearchII { + /** + * Given a 2D board and a list of words from the dictionary, find all words in the board. + + Each word must be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word. + + For example, + Given words = ["oath","pea","eat","rain"] and board = + + [ + ['o','a','a','n'], + ['e','t','a','e'], + ['i','h','k','r'], + ['i','f','l','v'] + ] + Return ["eat","oath"]. + + time : O(m * n * TrieNode) + space : TrieNode + + * @param board + * @param words + * @return + */ + + public List findWords(char[][] board, String[] words) { + List res = new ArrayList<>(); + TrieNode root = buildTrie(words); + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[0].length; j++) { + dfs(board, i, j, root, res); + } + } + return res; + } + + public void dfs(char[][] board, int i, int j, TrieNode p, List res) { + if (i < 0 || i >= board.length || j < 0 || j >= board[0].length) return; + char c = board[i][j]; + if (c == '#' || p.next[c - 'a'] == null) return; + p = p.next[c - 'a']; + if (p.word != null) { + res.add(p.word); + p.word = null; + } + board[i][j] = '#'; + dfs(board, i - 1, j, p, res); + dfs(board, i + 1, j, p, res); + dfs(board, i, j + 1, p, res); + dfs(board, i, j - 1, p, res); + board[i][j] = c; + } + + public TrieNode buildTrie(String[] words) { + TrieNode root = new TrieNode(); + for (String word : words) { + TrieNode p = root; + for (char c : word.toCharArray()) { + int i = c - 'a'; + if (p.next[i] == null) { + p.next[i] = new TrieNode(); + } + p = p.next[i]; + } + p.word = word; + } + return root; + } + + class TrieNode { + TrieNode[] next = new TrieNode[26]; + String word; + } +} diff --git a/ZigZagConversion.java b/ZigZagConversion.java new file mode 100644 index 0000000..9a67555 --- /dev/null +++ b/ZigZagConversion.java @@ -0,0 +1,49 @@ +package leetcode; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ZigZagConversion + * Creator : Edward + * Date : Oct, 2017 + * Description : 6. ZigZag Conversion + */ +public class ZigZagConversion { + /** + * The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: + * (you may want to display this pattern in a fixed font for better legibility) + + P A H N + A P L S I I G + Y I R + + And then read line by line: "PAHNAPLSIIGYIR" + Write the code that will take a string and make this conversion given a number of rows: + + string convert(string text, int nRows); + convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR". + + time : O(n); + space : O(n); + + * @param s + * @param numRows + * @return + */ + public String convert(String s, int numRows) { + if (numRows <= 1) return s; + StringBuilder[] sb = new StringBuilder[numRows]; + for (int i = 0; i < sb.length; i++) { + sb[i] = new StringBuilder(""); + } + for (int i = 0; i < s.length(); i++) { + int index = i % (2 * numRows - 2); + index = index < numRows ? index : 2 * numRows - 2 - index; + sb[index].append(s.charAt(i)); + } + for (int i = 1; i < sb.length; i++) { + sb[0].append(sb[i]); + } + return sb[0].toString(); + } +} diff --git a/ZigzagIterator.java b/ZigzagIterator.java new file mode 100644 index 0000000..54c40a4 --- /dev/null +++ b/ZigzagIterator.java @@ -0,0 +1,86 @@ +package leetcode; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +/** + * Project Name : Leetcode + * Package Name : leetcode + * File Name : ZigzagIterator + * Creator : Edward + * Date : Oct, 2017 + * Description : 281. Zigzag Iterator + */ +public class ZigzagIterator { + /** + *For example, given two 1d vectors: + + v1 = [1, 2] + v2 = [3, 4, 5, 6] + + output : 1 3 2 4 5 6 + + [1,2,3] + [4,5,6,7] + [8,9] + It should return [1,4,8,2,5,9,3,6,7]. + + time : O(n) + space : O(1) + + * @param v1 + * @param v2 + */ + + private Iterator i, j, temp; + + + public ZigzagIterator(List v1, List v2) { + i = v2.iterator(); + j = v1.iterator(); + } + + public int next() { + if (j.hasNext()) { + temp = j; + j = i; + i = temp; + } + return i.next(); + } + + public boolean hasNext() { + return i.hasNext() || j.hasNext(); + } + + /** + * v1 = [1, 2] + v2 = [3, 4, 5, 6] + + time : O(n) + space : O(2) + */ + + LinkedList list; + + public void ZigzagIterator2(List v1, List v2) { + list = new LinkedList<>(); + if (!v1.isEmpty()) list.add(v1.iterator()); + if (!v2.isEmpty()) list.add(v2.iterator()); + } + + public int next2() { + Iterator poll = list.remove(); + int result = (Integer) poll.next(); + if (poll.hasNext()) { + list.add(poll); + } + return result; + } + + public boolean hasNext2() { + return !list.isEmpty(); + } +}