diff --git a/.gitignore b/.gitignore index 4042776d..c432b382 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,6 @@ leetcode.ipr leetcode.iws out/ problems/src.iml -.idea/codeStyles/ -.idea/copyright/ -.idea/markdown-navigator/ +.idea +.gradle/ +.DS_Store diff --git a/.idea/google-java-format.xml b/.idea/google-java-format.xml deleted file mode 100644 index 8b57f452..00000000 --- a/.idea/google-java-format.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index 0ca37c94..00000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_3_0_2.xml b/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_3_0_2.xml deleted file mode 100644 index 122552e3..00000000 --- a/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_3_0_2.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_errorprone_error_prone_annotations_2_2_0.xml b/.idea/libraries/Gradle__com_google_errorprone_error_prone_annotations_2_2_0.xml deleted file mode 100644 index 9b2f9076..00000000 --- a/.idea/libraries/Gradle__com_google_errorprone_error_prone_annotations_2_2_0.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_errorprone_javac_shaded_9_181_r4173_1.xml b/.idea/libraries/Gradle__com_google_errorprone_javac_shaded_9_181_r4173_1.xml deleted file mode 100644 index 52ed4de9..00000000 --- a/.idea/libraries/Gradle__com_google_errorprone_javac_shaded_9_181_r4173_1.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_googlejavaformat_google_java_format_1_7.xml b/.idea/libraries/Gradle__com_google_googlejavaformat_google_java_format_1_7.xml deleted file mode 100644 index 374a1a85..00000000 --- a/.idea/libraries/Gradle__com_google_googlejavaformat_google_java_format_1_7.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_guava_failureaccess_1_0_1.xml b/.idea/libraries/Gradle__com_google_guava_failureaccess_1_0_1.xml deleted file mode 100644 index 8ba66b57..00000000 --- a/.idea/libraries/Gradle__com_google_guava_failureaccess_1_0_1.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_guava_guava_27_0_1_jre.xml b/.idea/libraries/Gradle__com_google_guava_guava_27_0_1_jre.xml deleted file mode 100644 index d2f31086..00000000 --- a/.idea/libraries/Gradle__com_google_guava_guava_27_0_1_jre.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_guava_listenablefuture_9999_0_empty_to_avoid_conflict_with_guava.xml b/.idea/libraries/Gradle__com_google_guava_listenablefuture_9999_0_empty_to_avoid_conflict_with_guava.xml deleted file mode 100644 index 11f8cce0..00000000 --- a/.idea/libraries/Gradle__com_google_guava_listenablefuture_9999_0_empty_to_avoid_conflict_with_guava.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__com_google_j2objc_j2objc_annotations_1_1.xml b/.idea/libraries/Gradle__com_google_j2objc_j2objc_annotations_1_1.xml deleted file mode 100644 index ab45264c..00000000 --- a/.idea/libraries/Gradle__com_google_j2objc_j2objc_annotations_1_1.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_checkerframework_checker_qual_2_5_2.xml b/.idea/libraries/Gradle__org_checkerframework_checker_qual_2_5_2.xml deleted file mode 100644 index e629e112..00000000 --- a/.idea/libraries/Gradle__org_checkerframework_checker_qual_2_5_2.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/libraries/Gradle__org_codehaus_mojo_animal_sniffer_annotations_1_17.xml b/.idea/libraries/Gradle__org_codehaus_mojo_animal_sniffer_annotations_1_17.xml deleted file mode 100644 index cbfbdf1d..00000000 --- a/.idea/libraries/Gradle__org_codehaus_mojo_animal_sniffer_annotations_1_17.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/leetcode_main.iml b/.idea/modules/leetcode_main.iml deleted file mode 100644 index 784fcd71..00000000 --- a/.idea/modules/leetcode_main.iml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/modules/leetcode_test.iml b/.idea/modules/leetcode_test.iml deleted file mode 100644 index 7ac9b410..00000000 --- a/.idea/modules/leetcode_test.iml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/README.md b/README.md index 6070d906..50b25b37 100644 --- a/README.md +++ b/README.md @@ -1,386 +1,515 @@ # Leetcode solutions in Java -My accepted leetcode solutions to some of the common interview problems. - -#### [Array](problems/src/array) - -- [Pascals Traiangle II](problems/src/array/PascalsTriangle.java) (Easy) -- [Product Of Array Except Self](problems/src/array/ProductOfArrayExceptSelf.java) (Medium) -- [Rotate Matrix](problems/src/array/RotateMatrix.java) (Medium) -- [Set Matrix Zeroes](problems/src/array/SetMatrixZeroes.java) (Medium) -- [Third Maximum Number](problems/src/array/ThirdMaximumNumber.java) (Easy) -- [Two Sum](problems/src/array/TwoSum.java) (Easy) -- [TwoSum II](problems/src/array/TwoSumII.java) (Easy) -- [Can Place Flowers](problems/src/array/CanPlaceFlowers.java) (Easy) -- [Merge Intervals](problems/src/array/MergeIntervals.java) (Medium) -- [First Missing Positive](problems/src/array/FirstMissingPositive.java) (Hard) -- [Fruit Into Baskets](problems/src/array/FruitIntoBaskets.java) (Medium) -- [MaxProduct Of Three Numbers](problems/src/array/MaxProductOfThreeNumbers.java) (Easy) -- [Missing Number](problems/src/array/MissingNumber.java) (Easy) -- [Merge Sorted Array](problems/src/array/MergeSortedArray.java) (Easy) -- [Rotate Array](problems/src/array/RotateArray.java) (Easy) -- [Sort Colors](problems/src/array/SortColors.java) (Medium) -- [Battleships in a Board](problems/src/array/BattleshipsInABoard.java) (Medium) -- [Find the Celebrity](problems/src/array/FindTheCelebrity.java) (Medium) -- [Meeting Rooms](problems/src/array/MeetingRooms.java) (Easy) -- [Longest Continuous Increasing Subsequence](problems/src/array/LongestIncreasingSubsequence.java) (Easy) -- [Sparse Matrix Multiplication](problems/src/array/SparseMatrixMultiplication.java) (Medium) -- [Read N Characters Given Read4](problems/src/array/ReadNCharacters.java) (Easy) -- [Maximum Swap](problems/src/array/MaximumSwap.java) (Medium) -- [H-Index](problems/src/array/HIndex.java) (Medium) -- [Insert Interval](problems/src/array/InsertInterval.java) (Hard) -- [Increasing Triplet Subsequence](problems/src/array/IncreasingTripletSubsequence.java) (Medium) -- [K Empty Slots](problems/src/array/KEmptySlots.java) (Hard) -- [Subarray Sum Equals K](problems/src/array/SubarraySumEqualsK.java) (Medium) -- [Pour Water](problems/src/array/PourWater.java) (Medium) -- [Relative Ranks](problems/src/array/RelativeRanks.java) (Easy) -- [Next Greater Element I](problems/src/array/NextGreaterElementI.java) (Easy) -- [Largest Number At Least Twice of Others](problems/src/array/LargestNumberAtLeastTwice.java) (Easy) -- [Minimum Moves to Equal Array Elements II](problems/src/array/MinimumMovesToEqualArray.java) (Median) -- [Image Smoother](problems/src/array/ImageSmoother.java) (Easy) -- [Minimum Index Sum of Two Lists](problems/src/array/MinimumIndexSumOfTwoLists.java) (Easy) -- [Card Flipping Game](problems/src/array/CardFilipGame.java) (Medium) -- [Employee Free Time](problems/src/array/EmployeeFreeTime.java) (Hard) -- [Best Meeting Point](problems/src/array/BestMeetingPoint.java) (Hard) -- [My Calendar III](problems/src/array/MyCalendarThree.java) (Hard) -- [Champagne Tower](problems/src/array/ChampagneTower.java) (Medium) -- [Valid Tic-Tac-Toe State](problems/src/array/ValidTicTacToeState.java) (Medium) -- [Number of Subarrays with Bounded Maximum](problems/src/array/SubArraysWithBoundedMaximum.java) (Medium) -- [Surface Area of 3D Shapes](problems/src/array/SurfaceAreaOfThreeDShapes.java) (Easy) - -#### [Backtracking](problems/src/backtracking) - -- [Combinations](problems/src/backtracking/Combinations.java) (Medium) -- [Combinations Sum](problems/src/backtracking/CombinationSum.java) (Medium) -- [Combinations Sum II](problems/src/backtracking/CombinationSumII.java) (Medium) -- [Letter Phone Number](problems/src/backtracking/LetterPhoneNumber.java) (Medium) -- [Paliandrome Partitioning](problems/src/backtracking/PalindromePartitioning.java) (Medium) -- [Permutations](problems/src/backtracking/Permutations.java) (Medium) -- [Permutations II](problems/src/backtracking/PermutationsII.java) (Medium) -- [SubSets](problems/src/backtracking/Subsets.java) (Medium) -- [SubSet II](problems/src/backtracking/SubsetsII.java) (Medium) -- [Word Search](problems/src/backtracking/WordSearch.java) (Medium) -- [Word Search II](problems/src/backtracking/WordSearchII.java) (Hard) -- [Generate Parentheses](problems/src/backtracking/GenerateParentheses.java) (Medium) -- [Remove Invalid Parentheses](problems/src/backtracking/RemoveInvalidParentheses.java) (Hard) -- [Regular Expression Matching](problems/src/backtracking/RegularExpressionMatching.java) (Hard) -- [Expression Add Operators](problems/src/backtracking/ExpressionAddOperators.java) (Hard) -- [Wildcard Matching](problems/src/backtracking/WildcardMatching.java) (Hard) -- [Letter Case Permutation](problems/src/backtracking/LetterCasePermutation.java) (Easy) - - -#### [Binary Search](problems/src/binary_search) - -- [Minimum Sorted Rotated Array](problems/src/binary_search/MinSortedRotatedArray.java) (Medium) -- [Search in a Rotated Sorted Array](problems/src/binary_search/SearchRotatedSortedArray.java) (Medium) -- [Search for a Range](problems/src/binary_search/SearchForARange.java) (Medium) -- [Sqrt(x)](problems/src/binary_search/SqrtX.java) (Easy) -- [Search Insert Position](problems/src/binary_search/SearchInsertPosition.java) (Easy) -- [Median of Two Sorted Arrays](problems/src/binary_search/MedianOfTwoSortedArrays.java) (Hard) -- [Pow(x, n)](problems/src/binary_search/PowXN.java) (Medium) -- [Find Peak Element](problems/src/binary_search/FindPeakElement.java) (Medium) -- [Target Sum](problems/src/binary_search/TargetSum.java) (Medium) -- [H-Index II](problems/src/binary_search/HIndexII.java) (Medium) -- [Swim in Rising Water](problems/src/binary_search/SwimInRisingWater.java) (Hard) - -#### [Bit Manipulation](problems/src/bit_manipulation) - -- [Gray Code](problems/src/bit_manipulation/GrayCode.java) (Medium) -- [Hamming Distance](problems/src/bit_manipulation/HammingDistance.java) (Easy) -- [Total Hamming Distance](problems/src/bit_manipulation/TotalHammingDistance.java) (Medium) -- [Divide Two Integers](problems/src/bit_manipulation/DivideTwoIntegers.java) (Medium) - -#### [Breadth First Search](problems/src/breadth_first_search) - -- [Binaray Tree Level Order Traversal](problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java) (Medium) -- [Word Ladder](problems/src/breadth_first_search/WordLadder.java) (Medium) -- [Word Ladder II](problems/src/breadth_first_search/WordLadderII.java) (Hard) -- [Walls and Gates](problems/src/breadth_first_search/WallsAndGates.java) (Medium) -- [Open the lock](problems/src/breadth_first_search/OpenTheLock.java) (Medium) -- [Cut Off Trees for Golf Event](problems/src/breadth_first_search/CutOffTreesForGolfEvent.java) (Hard) -- [Race Car](problems/src/breadth_first_search/RaceCar.java) (Hard) -- [Bus Routes](problems/src/breadth_first_search/BusRoutes.java) (Hard) -- [Sliding Puzzle](problems/src/breadth_first_search/SlidingPuzzle.java) (Hard) -- [Matrix](problems/src/breadth_first_search/Matrix.java) (Medium) - -#### [Depth First Search](problems/src/depth_first_search) - -- [Minesweeper](problems/src/depth_first_search/Minesweeper.java) (Medium) -- [Movie Recommend](problems/src/depth_first_search/MovieRecommend.java) (Medium) -- [Number Of Islands](problems/src/depth_first_search/NumberOfIslands.java) (Medium) -- [Course Schedule](problems/src/depth_first_search/CourseSchedule.java) (Medium) -- [Course Schedule II](problems/src/depth_first_search/CourseScheduleII.java) (Medium) -- [Alien Dictionary](problems/src/depth_first_search/AlienDictionary.java) (Hard) -- [Graph Valid Tree](problems/src/depth_first_search/GraphValidTree.java) (Medium) -- [Longest Consecutive Sequence](problems/src/depth_first_search/LongestConsecutiveSequence.java) (Hard) -- [Accounts Merge](problems/src/depth_first_search/AccountsMerge.java) (Medium) -- [CloneGraph](problems/src/depth_first_search/CloneGraph.java) (Medium) -- [Island Perimeter](problems/src/depth_first_search/IslandPerimeter.java) (Easy) -- [Number of Distinct Islands](problems/src/depth_first_search/NumberOfDistinctIslands.java) (Medium) -- [Number of Distinct Islands II](problems/src/depth_first_search/NumberOfDistinctIslandsII.java) (Hard) -- [Smallest Rectangle Enclosing Black Pixels](problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java) (Hard) -- [Bricks Falling When Hit](problems/src/depth_first_search/BricksFallingWhenHit.java) (Hard) -- [Robot Room Cleaner](problems/src/depth_first_search/RobotRoomCleaner.java) (Hard) -- [Cracking the Safe](problems/src/depth_first_search/CrackingTheSafe.java) (Hard) -- [All Paths From Source to Target](problems/src/depth_first_search/AllPathsFromSourceToTarget.java) (Medium) - -#### [Design](problems/src/design) - -- [Copy List With Random Pointer](problems/src/design/CopyListWithRandomPointer.java) (Medium) -- [Encode and Decode Tiny URL](problems/src/design/EncodeAndDecodeTinyURL.java) (Medium) -- [LFU Cache](problems/src/design/LFUCache.java) (Hard) -- [LRU Cache](problems/src/design/LRUCache.java) (Hard) -- [Insert Delete Get Random](problems/src/design/RandomizedSet.java) (Medium) -- [Serialize Deserialize Binary Tree](problems/src/design/SerializeDeserializeBinaryTree.java) (Hard) -- [Design Twitter](problems/src/design/Twitter.java) (Medium) -- [Tic-Tac-Toe](problems/src/design/TicTacToe.java) (Medium) -- [Implement Trie (Prefix Tree)](problems/src/design/Trie.java) (Medium) -- [Binary Search Tree Iterator](problems/src/design/BSTIterator.java) (Medium) -- [Design Search Autocomplete System](problems/src/design/AutocompleteSystem.java) (Hard) -- [Design Excel Sum Formula](problems/src/design/Excel.java) (Hard) -- [Flatten Nested List Iterator](problems/src/design/NestedIterator.java) (Medium) -- [Add and Search Word - Data structure design](problems/src/design/WordDictionary.java) (Medium) -- [Prefix and Suffix Search](problems/src/design/WordFilter.java) (Hard) -- [Insert Delete GetRandom O(1) - Duplicates allowed](problems/src/design/RandomizedCollection.java) (Hard) - -#### [Divide and Conquer](problems/src/divide_and_conquer) - -- [Kth Largest Element In a Array](problems/src/divide_and_conquer/KthLargestElementInAnArray.java) (Medium) -- [Reverse Pairs](problems/src/divide_and_conquer/ReversePairs.java) (Hard) -- [Search in a 2D Matrix](problems/src/divide_and_conquer/SearchA2DMatrix.java) (Medium) - -#### [Dynamic Programming](problems/src/dynamic_programming) - -- [Best Time To Buy and Sell Stocks](problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java) (Easy) -- [Best Time to Buy and Sell Stock III](problems/src/dynamic_programming/BestTimeToBuyAndSellStockIII.java) (Hard) -- [Best Time to Buy and Sell Stock with Transaction Fee](problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java) (Medium) -- [Climbing Stairs](problems/src/dynamic_programming/ClimbingStairs.java) (Easy) -- [Coin Change](problems/src/dynamic_programming/CoinChange.java) (Medium) -- [Coin Change 2](problems/src/dynamic_programming/CoinChange2.java) (Medium) -- [Decode Ways](problems/src/dynamic_programming/DecodeWays.java) (Medium) -- [House Robber](problems/src/dynamic_programming/HouseRobber.java) (Easy) -- [House Robber II](problems/src/dynamic_programming/HouseRobberII.java) (Medium) -- [Longest Increasing Subsequence](problems/src/dynamic_programming/LongestIncreasingSubsequence.java) (Medium) -- [Longest Paliandromic Substring](problems/src/dynamic_programming/LongestPaliandromicSubstring.java) (Medium) -- [Longest Palindromic Subsequence](problems/src/dynamic_programming/LongestPalindromicSubsequence.java) (Medium) -- [Maximum Product Subarray](problems/src/dynamic_programming/MaximumProductSubarray.java) (Medium) -- [Min Cost Climbing Stairs](problems/src/dynamic_programming/MinCostClimbingStairs.java) (Easy) -- [Palindrome Partitioning II](problems/src/dynamic_programming/PalindromePartitioningII.java) (Hard) -- [UniqueBinary Search Trees](problems/src/dynamic_programming/UniqueBinarySearchTrees.java) (Medium) -- [Unique Binary Search Trees II](problems/src/dynamic_programming/UniqueBinarySearchTreesII.java) (Medium) -- [WordBreak](problems/src/dynamic_programming/WordBreak.java) (Medium) -- [WordBreak II](problems/src/dynamic_programming/WordBreakII.java) (Hard) -- [Concatenated Words](problems/src/dynamic_programming/ConcatenatedWords.java) (Hard) -- [Can I Win](problems/src/dynamic_programming/CanIWin.java) (Medium) -- [Maximum Subarray](problems/src/dynamic_programming/MaximumSubarray.java) (Easy) -- [Dungeon Game](problems/src/dynamic_programming/DungeonGame.java) (Hard) -- [2 Keys Keyboard](problems/src/dynamic_programming/TwoKeysKeyboard.java) (Medium) -- [Maximum Sum of 3 Non-Overlapping Subarrays](problems/src/dynamic_programming/MaxSum3SubArray.java) (Hard) -- [Maximal Square](problems/src/dynamic_programming/MaximalSquare.java) (Medium) -- [Continuous Subarray Sum](problems/src/dynamic_programming/ContinuousSubarraySum.java) (Medium) -- [Decode Ways II](problems/src/dynamic_programming/DecodeWaysII.java) (Hard) -- [Palindromic Substrings](problems/src/dynamic_programming/PalindromicSubstrings.java) (Medium) -- [Number of Longest Increasing Subsequence](problems/src/dynamic_programming/NumberOfLIS.java) (Medium) -- [Combination Sum IV](problems/src/dynamic_programming/CombinationSumIV.java) (Medium) -- [Paint House II](problems/src/dynamic_programming/PaintHouseII.java) (Hard) -- [Split Array Largest Sum](problems/src/dynamic_programming/SplitArrayLargestSum.java) (Hard) -- [Number Of Corner Rectangles](problems/src/dynamic_programming/CornerRectangles.java) (Medium) -- [Burst Balloons](problems/src/dynamic_programming/BurstBalloons.java) (Hard) -- [Largest Plus Sign](problems/src/dynamic_programming/LargestPlusSign.java) (Medium) -- [Palindrome Pairs](problems/src/dynamic_programming/PalindromePairs.java) (Hard) -- [Cherry Pickup](problems/src/dynamic_programming/CherryPickup.java) (Hard) -- [Knight Probability in Chessboard](problems/src/dynamic_programming/KnightProbabilityInChessboard.java) (Medium) -- [Largest Sum of Averages](problems/src/dynamic_programming/LargestSumOfAverages.java) (Medium) -- [Minimum Number of Refueling Stops](problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java) (Hard) -- [Cat and Mouse](problems/src/dynamic_programming/CatAndMouse.java) (Hard) -- [Stone Game](problems/src/dynamic_programming/StoneGame.java) (Medium) -- [Odd Even Jump](problems/src/dynamic_programming/OddEvenJump.java) (Hard) -- [Profitable Schemes](problems/src/dynamic_programming/ProfitableSchemes.java) (Hard) -- [Maximum Vacation Days](problems/src/dynamic_programming/MaximumVacationDays.java) (Hard) - -#### [Greedy](problems/src/greedy) - -- [Jump Game](problems/src/greedy/JumpGame.java) (Medium) -- [Jump Game II](problems/src/greedy/JumpGameII.java) (Hard) -- [Course Schedule III](problems/src/greedy/CourseScheduleIII.java) (Medium) -- [GasStation](problems/src/greedy/GasStation.java) (Medium) -- [Non-Overlapping Intervals](problems/src/greedy/NonOverlappingIntervals.java) (Medium) -- [Minimum Number of Arrows to Burst Balloons](problems/src/greedy/BurstBalloons.java) (Medium) -- [Queue Reconstruction By Height](problems/src/greedy/QueueReconstructionByHeight.java) (Medium) -- [Task Scheduler](problems/src/greedy/TaskScheduler.java) (Medium) -- [Maximum Length of Pair Chain](problems/src/greedy/MaximumLengthOfPairChain.java) (Medium) -- [Lemonade Change](problems/src/greedy/LemonadeChange.java) (Easy) -- [Score After Flipping Matrix](problems/src/greedy/ScoreAfterFlippingMatrix.java) (Medium) -- [IPO](problems/src/greedy/IPO.java) (Hard) - -#### [Hashing](problems/src/hashing) - -- [Anagrams](problems/src/hashing/Anagrams.java) (Medium) -- [Group Anagrams](problems/src/hashing/GroupAnagrams.java) (Medium) -- [Kdiff Pairs In a Array](problems/src/hashing/KdiffPairsInanArray.java) (Easy) -- [Sort Character by Frequency](problems/src/hashing/SortCharByFrequency.java) (Medium) -- [Two Sum](problems/src/hashing/TwoSum.java) (Easy) -- [Valid Anagram](problems/src/hashing/ValidAnagram.java) (Easy) -- [Maximum Size Subarray Sum Equals k](problems/src/hashing/MaximumSizeSubarraySumEqualsk.java) (Medium) -- [Contiguous Array](problems/src/hashing/ContiguousArray.java) (Medium) -- [Brick Wall](problems/src/hashing/BrickWall.java) (Medium) -- [Partition Labels](problems/src/hashing/PartitionLabels.java) (Medium) -- [Custom Sort String](problems/src/hashing/CustomSortString.java) (Medium) -- [Short Encoding of Words](problems/src/hashing/ShortEncodingOfWords.java) (Medium) -- [Substring with Concatenation of All Words](problems/src/hashing/SubstringConcatenationOfWords.java) (Hard) -- [Distribute Candies](problems/src/hashing/DistributeCandies.java) (Easy) -- [Groups of Special-Equivalent Strings](problems/src/hashing/GroupsOfSpecialEquivalentStrings.java) (Easy) - -#### [Heap](problems/src/heap) - -- [Sliding Window Maximum](problems/src/heap/SlidingWindowMaximum.java) (Hard) -- [The Skyline Problem](problems/src/heap/TheSkylineProblem.java) (Hard) -- [Meeting Rooms II](problems/src/heap/MeetingRoomsII.java) (Medium) -- [Top K Frequent Words](problems/src/heap/TopKFrequentWords.java) (Medium) -- [Candy](problems/src/heap/Candy.java) (Hard) -- [Smallest Rotation with Highest Score](problems/src/heap/SmallestRotationWithHighestScore.java) (Hard) -- [Maximum Frequency Stack](problems/src/heap/FreqStack.java) (Hard) - -#### [Linked List](problems/src/linked_list) - -- [Intersection of two Linked-Lists](problems/src/linked_list/IntersectionOfTwoLists.java) (Easy) -- [Linked List Cycle](problems/src/linked_list/LinkedListCycle.java) (Easy) -- [Merge K Sorted Lists](problems/src/linked_list/MergeKSortedLists.java) (Hard) -- [Merge Two Sorted List](problems/src/linked_list/MergeTwoSortedList.java) (Easy) -- [Paliandrome List](problems/src/linked_list/PaliandromeList.java) (Easy) -- [Reverse Linked List](problems/src/linked_list/ReverseLinkedList.java) (Easy) -- [Delete Node in a Linked List](problems/src/linked_list/DeleteNode.java) (Easy) -- [Reverse Nodes in k-Group](problems/src/linked_list/ReverseNodesKGroup.java) (Hard) -- [Swap Nodes in Pairs](problems/src/linked_list/SwapNodesInPairs.java) (Medium) -- [Middle of Linked List](problems/src/linked_list/MiddleOfLinkedList.java) (Easy) - -#### [Math](problems/src/math) - -- [Add Two Numbers](problems/src/math/AddTwoNumbers.java) (Medium) -- [Count Primes](problems/src/math/CountPrimes.java) (Easy) -- [Rotate Function](problems/src/math/RotateFunction.java) (Medium) -- [Water and Jug Problem](problems/src/math/WaterAndJugProblem.java) (Medium) -- [Add Digits](problems/src/math/AddDigits.java) (Easy) -- [Excel Sheet Column Title](problems/src/math/ExcelSheetColumnTitle.java) (Easy) -- [Roman to Integer](problems/src/math/RomanToInteger.java) (Easy) -- [Bulb Switcher II](problems/src/math/BulbSwitcherII.java) (Medium) -- [Global and Local Inversions](problems/src/math/GlobalAndLocalInversions.java) (Medium) -- [Solve the Equation](problems/src/math/SolveTheEquation.java) (Medium) -- [Couples Holding Hands](problems/src/math/CouplesHoldingHands.java) (Hard) -- [Reaching Points](problems/src/math/ReachingPoints.java) (Hard) -- [Nth Magical Number](problems/src/math/NthMagicalNumber.java) (Hard) -- [Squirrel Simulation](problems/src/math/SquirrelSimulation.java) (Medium) - -#### [Reservoir Sampling](problems/src/reservoir_sampling) - -- [Random Pick Index](problems/src/reservoir_sampling/RandomPickIndex.java) (Medium) - -#### [Stack](problems/src/stack) - -- [Min Stack](problems/src/stack/MinStack.java) (Easy) -- [Valid Parentheses](problems/src/stack/ValidParentheses.java) (Easy) -- [Largest Rectangle In Histogram](problems/src/stack/LargestRectangleInHistogram.java) (Hard) -- [Implement Queue using Stacks](problems/src/stack/MyQueue.java) (Easy) -- [Maximal Rectangle](problems/src/stack/MaximalRectangle.java) (Hard) -- [Exclusive Time of Functions](problems/src/stack/ExclusiveTimeOfFunctions.java) (Medium) -- [Basic Calculator](problems/src/stack/BasicCalculator.java) (Hard) -- [Decode String](problems/src/stack/DecodeString.java) (Medium) -- [Longest Valid Parentheses](problems/src/stack/LongestValidParentheses.java) (Hard) - - -#### [String](problems/src/string) - -- [First Unique Character In a String](problems/src/string/FirstUniqueCharacterInAString.java) (Easy) -- [Repeated Substring Pattern](problems/src/string/RepeatedSubstringPattern.java) (Easy) -- [Reverse Words In a String](problems/src/string/ReverseWordsInAString.java) (Medium) -- [ReverseWords II](problems/src/string/ReverseWordsII.java) (Medium) -- [String to Integer](problems/src/string/StringToInteger.java) (Medium) -- [Text Justification](problems/src/string/TextJustification.java) (Hard) -- [ZigZag Conversion](problems/src/string/ZigZagConversion.java) (Medium) -- [Implement StrStr](problems/src/string/ImplementStrStr.java) (Easy) -- [Excel Sheet Column Number](problems/src/string/ExcelSheetColumnNumber.java) (Easy) -- [Compare Version Numbers](problems/src/string/CompareVersionNumbers.java) (Easy) -- [Valid Palindrome](problems/src/string/ValidPalindrome.java) (Easy) -- [Simplify Path](problems/src/string/SimplifyPath.java) (Medium) -- [Permutation in String](problems/src/string/PermutationInString.java) (Medium) -- [Add Binary](problems/src/string/AddBinary.java) (Easy) -- [Valid Palindrome II](problems/src/string/ValidPalindromeII.java) (Easy) -- [One Edit Distance](problems/src/string/OneEditDistance.java) (Medium) -- [Count and Say](problems/src/string/CountAndSay.java) (Easy) -- [Multiply Strings](problems/src/string/MultiplyStrings.java) (Medium) -- [Longest Word in Dictionary through Deleting](problems/src/string/LongestWordInDictonary.java) (Medium) -- [Isomorphic Strings](problems/src/string/IsomorphicStrings.java) (Easy) -- [String Compression](problems/src/string/StringCompression.java) (Easy) -- [Longest Common Prefix](problems/src/string/LongestCommonPrefix.java) (Easy) -- [Find the Closest Palindrome](problems/src/string/FindTheClosestPalindrome.java) (Hard) -- [Monotone Increasing Digits](problems/src/string/MonotoneIncreasingDigits.java) (Medium) -- [Shortest Palindrome](problems/src/string/ShortestPalindrome.java) (Hard) -- [Valid Word Abbreviation](problems/src/string/ValidWordAbbreviation.java) (Easy) -- [Longest Palindrome](problems/src/string/LongestPalindrome.java) (Easy) -- [Replace Words](problems/src/string/ReplaceWords.java) (Medium) -- [Rotate String](problems/src/string/RotateString.java) (Easy) -- [Keyboard Row](problems/src/string/KeyboardRow.java) (Easy) - -#### [Tree](problems/src/tree) - -- [Binaray Tree Right Side View](problems/src/tree/BinarayTreeRightSideView.java) (Medium) -- [Binary Tree Maximum Path Sum](problems/src/tree/BinaryTreeMaximumPathSum.java) (Hard) -- [Boundary of Binary Tree](problems/src/tree/BoundaryOfBinaryTree.java) (Medium) -- [Convert sorted array to BST](problems/src/tree/ConvertSortedArrayToBST.java) (Medium) -- [Lowest Common Ancestor of a Binary Tree](problems/src/tree/LCA.java) (Medium) -- [Lowest Common Ancestor of a BST](problems/src/tree/LowestCommonAncestorBST.java) (Easy) -- [Most Frequent Subtree Sum](problems/src/tree/MostFrequentSubtreeSum.java) (Medium) -- [Path Sum III](problems/src/tree/PathSumIII.java) (Easy) -- [Convert Postorder and Inorder traversal to Binary Tree](problems/src/tree/PostorderToBT.java) (Medium) -- [Convert Preorder and Inorder traversal to Binary Tree](problems/src/tree/PreorderToBT.java) (Medium) -- [Sorted Array to BST](problems/src/tree/SortedArrayToBST.java) (Medium) -- [Valid Binary Search Tree](problems/src/tree/ValidBinarySearchTree.java) (Medium) -- [Largest BST Subtree](problems/src/tree/LargestBSTSubtree.java) (Medium) -- [Closest Binary Search Tree Value](problems/src/tree/ClosestBinarySearchTreeValue.java) (Easy) -- [Inorder Successor in BST](problems/src/tree/InorderSuccessorInBST.java) (Medium) -- [Construct String From Binary Tree](problems/src/tree/ConstructStringFromBinaryTree.java) (Easy) -- [Flatten Binary Tree to Linked List](problems/src/tree/FlattenBinaryTree.java) (Medium) -- [Populating Next Right Pointers in Each Node](problems/src/tree/NextRightPointer.java) (Medium) -- [Populating Next Right Pointers in Each Node II](problems/src/tree/NextRightPointerII.java) (Medium) -- [Subtree of Another Tree](problems/src/tree/SubtreeOfAnotherTree.java) (Easy) -- [Binary Tree Zigzag Level Order Traversal](problems/src/tree/ZigZagTraversal.java) (Medium) -- [Binary Tree Inorder Traversal](problems/src/tree/BinaryTreeInorderTraversal.java) (Medium) -- [Symmetric Tree](problems/src/tree/SymmetricTree.java) (Easy) -- [Maximum Binary Tree](problems/src/tree/MaximumBinaryTree.java) (Medium) -- [Find Bottom Left Tree Value](problems/src/tree/FindBottomLeftTreeValue.java) (Medium) -- [Diameter of Binary Tree](problems/src/tree/DiameterOfBinaryTree.java) (Easy) -- [Binary Tree Paths](problems/src/tree/BinaryTreePaths.java) (Easy) -- [Sum of Left Leaves](problems/src/tree/SumofLeftLeaves.java) (Easy) -- [Two Sum IV - Input is a BST](problems/src/tree/TwoSumIV.java) (Easy) -- [Average of Levels in Binary Tree](problems/src/tree/AverageOfLevelsInBinaryTree.java) (Easy) -- [Convert Binary Search Tree to Sorted Doubly Linked List](problems/src/tree/BSTtoDoublyLinkedList.java) (Easy) -- [Same Tree](problems/src/tree/SameTree.java) (Easy) -- [Binary Tree Longest Consecutive Sequence II](problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java) (Medium) -- [Minimum Absolute Difference in BST](problems/src/tree/MinimumAbsoluteDifferenceInBST.java) (Medium) -- [Equal Tree Partition](problems/src/tree/EqualTreePartition.java) (Medium) -- [Split BST](problems/src/tree/SplitBST.java) (Medium) -- [Closest Leaf in a Binary Tree](problems/src/tree/ClosestLeafInABinaryTree.java) (Medium) -- [Maximum Width of Binary Tree](problems/src/tree/MaximumWidthOfBinaryTree.java) (Medium) -- [Recover Binary Search Tree](problems/src/tree/RecoverBinarySearchTree.java) (Hard) -- [Binary Tree Postorder Traversal](problems/src/tree/BinaryTreePostorderTraversal.java) (Hard) -- [Serialize and Deserialize N-ary Tree](problems/src/tree/SerializeAndDeserializeNAryTree.java) (Hard) -- [Convert BST to Greater Tree](problems/src/tree/ConvertBSTToGreaterTree.java) (Easy) -- [All Nodes Distance K in Binary Tree](problems/src/tree/AllNodesDistanceKInBinaryTree.java) (Medium) -- [All Possible Full Binary Trees](problems/src/tree/AllPossibleFullBinaryTrees.java) (Medium) - -#### [Two Pointers](problems/src/two_pointers) - -- [Four Sum](problems/src/two_pointers/FourSum.java) (Medium) -- [Longest Substring Witout Repeats](problems/src/two_pointers/LongestSubstringWitoutRepeats.java) (Medium) -- [Three Sum](problems/src/two_pointers/ThreeSum.java) (Medium) -- [Trapping Rain Water](problems/src/two_pointers/TrappingRainWater.java) (Hard) -- [3Sum Closest](problems/src/two_pointers/ThreeSumClosest.java) (Medium) -- [Move Zeroes](problems/src/two_pointers/MoveZeroes.java) (Easy) -- [Remove Duplicates](problems/src/two_pointers/RemoveDuplicates.java) (Easy) -- [Remove Duplicates II](problems/src/two_pointers/RemoveDuplicatesII.java) (Medium) -- [Minimum Size Subarray Sum](problems/src/two_pointers/MinimumSizeSubarraySum.java) (Medium) -- [Minimum Window Substring](problems/src/two_pointers/MinimumWindowSubstring.java) (Hard) -- [Smallest Range](problems/src/two_pointers/SmallestRange.java) (Hard) -- [Subarray Product Less Than K](problems/src/two_pointers/SubarrayProductLessThanK.java) (Medium) -- [Number of Matching Subsequences](problems/src/two_pointers/NumberOfMatchingSubsequences.java) (Medium) +My accepted leetcode solutions to some of the common interview problems. +Also, some solutions have youtube video link. + +[Youtube channel](https://www.youtube.com/@codernaut) + + +#### [Array](src/main/java/array) + +- [Pascals Traiangle II](src/main/java/array/PascalsTriangle.java) (Easy) +- [Product Of Array Except Self](src/main/java/array/ProductOfArrayExceptSelf.java) (Medium) +- [Rotate Matrix](src/main/java/array/RotateMatrix.java) (Medium) +- [Set Matrix Zeroes](src/main/java/array/SetMatrixZeroes.java) (Medium) +- [Third Maximum Number](src/main/java/array/ThirdMaximumNumber.java) (Easy) +- [Two Sum](src/main/java/array/TwoSum.java) (Easy) +- [TwoSum II](src/main/java/array/TwoSumII.java) (Easy) +- [Can Place Flowers](src/main/java/array/CanPlaceFlowers.java) (Easy) +- [Merge Intervals](src/main/java/array/MergeIntervals.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [First Missing Positive](src/main/java/array/FirstMissingPositive.java) (Hard) +- [Fruit Into Baskets](src/main/java/array/FruitIntoBaskets.java) (Medium) +- [MaxProduct Of Three Numbers](src/main/java/array/MaxProductOfThreeNumbers.java) (Easy) +- [Missing Number](src/main/java/array/MissingNumber.java) (Easy) +- [Merge Sorted Array](src/main/java/array/MergeSortedArray.java) (Easy) +- [Rotate Array](src/main/java/array/RotateArray.java) (Easy) +- [Sort Colors](src/main/java/array/SortColors.java) (Medium) +- [Battleships in a Board](src/main/java/array/BattleshipsInABoard.java) (Medium) +- [Find the Celebrity](src/main/java/array/FindTheCelebrity.java) (Medium) +- [Meeting Rooms](src/main/java/array/MeetingRooms.java) (Easy) +- [Longest Continuous Increasing Subsequence](src/main/java/array/LongestIncreasingSubsequence.java) (Easy) +- [Sparse Matrix Multiplication](src/main/java/array/SparseMatrixMultiplication.java) (Medium) +- [Read N Characters Given Read4](src/main/java/array/ReadNCharacters.java) (Easy) +- [Maximum Swap](src/main/java/array/MaximumSwap.java) (Medium) +- [H-Index](src/main/java/array/HIndex.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Insert Interval](src/main/java/array/InsertInterval.java) (Hard) +- [Increasing Triplet Subsequence](src/main/java/array/IncreasingTripletSubsequence.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [K Empty Slots](src/main/java/array/KEmptySlots.java) (Hard) +- [Subarray Sum Equals K](src/main/java/array/SubarraySumEqualsK.java) (Medium) +- [Pour Water](src/main/java/array/PourWater.java) (Medium) +- [Relative Ranks](src/main/java/array/RelativeRanks.java) (Easy) +- [Next Greater Element I](src/main/java/array/NextGreaterElementI.java) (Easy) +- [Largest Number At Least Twice of Others](src/main/java/array/LargestNumberAtLeastTwice.java) (Easy) +- [Minimum Moves to Equal Array Elements II](src/main/java/array/MinimumMovesToEqualArray.java) (Median) +- [Image Smoother](src/main/java/array/ImageSmoother.java) (Easy) +- [Minimum Index Sum of Two Lists](src/main/java/array/MinimumIndexSumOfTwoLists.java) (Easy) +- [Card Flipping Game](src/main/java/array/CardFilipGame.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Employee Free Time](src/main/java/array/EmployeeFreeTime.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Best Meeting Point](src/main/java/array/BestMeetingPoint.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [My Calendar III](src/main/java/array/MyCalendarThree.java) (Hard) +- [Champagne Tower](src/main/java/array/ChampagneTower.java) (Medium) +- [Valid Tic-Tac-Toe State](src/main/java/array/ValidTicTacToeState.java) (Medium) +- [Number of Subarrays with Bounded Maximum](src/main/java/array/SubArraysWithBoundedMaximum.java) (Medium) +- [Surface Area of 3D Shapes](src/main/java/array/SurfaceAreaOfThreeDShapes.java) (Easy) +- [Max Consecutive Ones](src/main/java/array/MaxConsecutiveOnes.java) (Easy) +- [Max Consecutive Ones II](src/main/java/array/MaxConsecutiveOnesII.java) (Medium) +- [Add to Array-Form of Integer](src/main/java/array/AddToArrayFormOfInteger.java) (Easy) +- [Find Pivot Index](src/main/java/array/FindPivotIndex.java) (Easy) +- [Largest Time for Given Digits](src/main/java/array/LargestTimeForGivenDigits.java) (Easy) +- [Minimum Time Difference](src/main/java/array/MinimumTimeDifference.java) (Medium) +- [Reveal Cards In Increasing Order](src/main/java/array/RevealCardsInIncreasingOrder.java) (Medium) +- [Sort Array By Parity II](src/main/java/array/SortArrayByParityII.java) (Easy) +- [Matrix Cells in Distance Order](src/main/java/array/MatrixCellsinDistanceOrder.java) (Easy) +- [Maximum Sum of Two Non-Overlapping Subarrays](src/main/java/array/MaximumSumofTwoNonOverlappingSubarrays.java) (Medium) +- [Longest Line of Consecutive One in Matrix](src/main/java/array/LongestLineofConsecutiveOneinMatrix.java) (Medium) +- [Array Partition I](src/main/java/array/ArrayPartitionI.java) (Easy) +- [Relative Sort Array](src/main/java/array/RelativeSortArray.java) (Easy) +- [Meeting Scheduler](src/main/java/array/MeetingScheduler.java) (Medium) +- [Minimum Swaps to Group All 1's Together](src/main/java/array/MinimumSwapsToGroupAll1Together.java) (Medium) +- [Array Nesting](src/main/java/array/ArrayNesting.java) (Medium) + +#### [Backtracking](src/main/java/backtracking) + +- [Combinations](src/main/java/backtracking/Combinations.java) (Medium) +- [Combinations Sum](src/main/java/backtracking/CombinationSum.java) (Medium) +- [Combinations Sum II](src/main/java/backtracking/CombinationSumII.java) (Medium) +- [Letter Phone Number](src/main/java/backtracking/LetterPhoneNumber.java) (Medium) +- [Paliandrome Partitioning](src/main/java/backtracking/PalindromePartitioning.java) (Medium) +- [Permutations](src/main/java/backtracking/Permutations.java) (Medium) +- [Permutations II](src/main/java/backtracking/PermutationsII.java) (Medium) +- [SubSets](src/main/java/backtracking/Subsets.java) (Medium) +- [SubSet II](src/main/java/backtracking/SubsetsII.java) (Medium) +- [Word Search](src/main/java/backtracking/WordSearch.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Word Search II](src/main/java/backtracking/WordSearchII.java) (Hard) +- [Generate Parentheses](src/main/java/backtracking/GenerateParentheses.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Remove Invalid Parentheses](src/main/java/backtracking/RemoveInvalidParentheses.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Regular Expression Matching](src/main/java/backtracking/RegularExpressionMatching.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Expression Add Operators](src/main/java/backtracking/ExpressionAddOperators.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Wildcard Matching](src/main/java/backtracking/WildcardMatching.java) (Hard) +- [Letter Case Permutation](src/main/java/backtracking/LetterCasePermutation.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Zuma Game](src/main/java/backtracking/ZumaGame.java) (Hard) +- [Matchsticks to Square](src/main/java/backtracking/MatchsticksToSquare.java) (Medium) + +#### [Binary Search](src/main/java/binary_search) + +- [Minimum Sorted Rotated Array](src/main/java/binary_search/MinSortedRotatedArray.java) (Medium) +- [Search in a Rotated Sorted Array](src/main/java/binary_search/SearchRotatedSortedArray.java) (Medium) +- [Search for a Range](src/main/java/binary_search/SearchForARange.java) (Medium) +- [Sqrt(x)](src/main/java/binary_search/SqrtX.java) (Easy) +- [Search Insert Position](src/main/java/binary_search/SearchInsertPosition.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Median of Two Sorted Arrays](src/main/java/binary_search/MedianOfTwoSortedArrays.java) (Hard) +- [Pow(x, n)](src/main/java/binary_search/PowXN.java) (Medium) +- [Find Peak Element](src/main/java/binary_search/FindPeakElement.java) (Medium) +- [Target Sum](src/main/java/binary_search/TargetSum.java) (Medium) +- [H-Index II](src/main/java/binary_search/HIndexII.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Swim in Rising Water](src/main/java/binary_search/SwimInRisingWater.java) (Hard) +- [Time Based Key-Value Store](src/main/java/binary_search/TimeBasedKeyValuePair.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Window Subsequence](src/main/java/binary_search/MinimumWindowSubsequence.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Koko Eating Bananas](src/main/java/binary_search/KokoEatingBananas.java) (Hard) +- [Single Element in a Sorted Array](src/main/java/binary_search/SingleElementInASortedArray.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimize the Maximum Adjacent Element Difference](src/main/java/binary_search/MinimizeTheMaximumAdjacentElementDifference.java) (Hard) + - [Youtube video explanation](https://www.youtube.com/watch?v=2fCtjA_eitU) + +#### [Bit Manipulation](src/main/java/bit_manipulation) + +- [Gray Code](src/main/java/bit_manipulation/GrayCode.java) (Medium) +- [Hamming Distance](src/main/java/bit_manipulation/HammingDistance.java) (Easy) +- [Total Hamming Distance](src/main/java/bit_manipulation/TotalHammingDistance.java) (Medium) +- [Divide Two Integers](src/main/java/bit_manipulation/DivideTwoIntegers.java) (Medium) +- [Binary Number with Alternating Bits](src/main/java/bit_manipulation/BinaryNumberWithAlternatingBits.java) (Easy) +- [Binary Watch](src/main/java/bit_manipulation/BinaryWatch.java) (Easy) + +#### [Breadth First Search](src/main/java/breadth_first_search) + +- [Binaray Tree Level Order Traversal](src/main/java/breadth_first_search/BinarayTreeLevelOrderTraversal.java) (Medium) +- [Word Ladder](src/main/java/breadth_first_search/WordLadder.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Word Ladder II](src/main/java/breadth_first_search/WordLadderII.java) (Hard) +- [Walls and Gates](src/main/java/breadth_first_search/WallsAndGates.java) (Medium) +- [Open the lock](src/main/java/breadth_first_search/OpenTheLock.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Cut Off Trees for Golf Event](src/main/java/breadth_first_search/CutOffTreesForGolfEvent.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Race Car](src/main/java/breadth_first_search/RaceCar.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Bus Routes](src/main/java/breadth_first_search/BusRoutes.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Sliding Puzzle](src/main/java/breadth_first_search/SlidingPuzzle.java) (Hard) +- [Matrix](src/main/java/breadth_first_search/Matrix.java) (Medium) +- [Rotting Oranges](src/main/java/breadth_first_search/RottingOranges.java) (Medium) + +#### [Depth First Search](src/main/java/depth_first_search) + +- [Minesweeper](src/main/java/depth_first_search/Minesweeper.java) (Medium) +- [Movie Recommend](src/main/java/depth_first_search/MovieRecommend.java) (Medium) +- [Number Of Islands](src/main/java/depth_first_search/NumberOfIslands.java) (Medium) +- [Course Schedule](src/main/java/depth_first_search/CourseSchedule.java) (Medium) +- [Course Schedule II](src/main/java/depth_first_search/CourseScheduleII.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Alien Dictionary](src/main/java/depth_first_search/AlienDictionary.java) (Hard) +- [Graph Valid Tree](src/main/java/depth_first_search/GraphValidTree.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Longest Consecutive Sequence](src/main/java/depth_first_search/LongestConsecutiveSequence.java) (Hard) +- [Accounts Merge](src/main/java/depth_first_search/AccountsMerge.java) (Medium) +- [CloneGraph](src/main/java/depth_first_search/CloneGraph.java) (Medium) +- [Island Perimeter](src/main/java/depth_first_search/IslandPerimeter.java) (Easy) +- [Number of Distinct Islands](src/main/java/depth_first_search/NumberOfDistinctIslands.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Distinct Islands II](src/main/java/depth_first_search/NumberOfDistinctIslandsII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Smallest Rectangle Enclosing Black Pixels](src/main/java/depth_first_search/SmallestRectangleEnclosingBlackPixels.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Bricks Falling When Hit](src/main/java/depth_first_search/BricksFallingWhenHit.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Robot Room Cleaner](src/main/java/depth_first_search/RobotRoomCleaner.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Cracking the Safe](src/main/java/depth_first_search/CrackingTheSafe.java) (Hard) +- [All Paths From Source to Target](src/main/java/depth_first_search/AllPathsFromSourceToTarget.java) (Medium) +- [Max Area of Island](src/main/java/depth_first_search/MaxAreaOfIsland.java) (Medium) +- [Satisfiability of Equality Equations](src/main/java/depth_first_search/SatisfiabilityOfEquations.java) (Medium) +- [Number of Enclaves](src/main/java/depth_first_search/NumberOfEnclaves.java) (Medium) +- [As Far from Land as Possible](src/main/java/depth_first_search/AsFarfromLandAsPossible.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimize Malware Spread](src/main/java/depth_first_search/MinimizeMalwareSpread.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Parallel Courses](src/main/java/depth_first_search/ParallelCourses.java) (Hard) +- [Connecting Cities With Minimum Cost](src/main/java/depth_first_search/ConnectingCitiesWithMinimumCost.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Critical Connections in a Network](src/main/java/depth_first_search/CriticalConnection.java) (Hard) + +#### [Design](src/main/java/design) + +- [Copy List With Random Pointer](src/main/java/design/CopyListWithRandomPointer.java) (Medium) +- [Encode and Decode Tiny URL](src/main/java/design/EncodeAndDecodeTinyURL.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [LFU Cache](src/main/java/design/LFUCache.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [LRU Cache](src/main/java/design/LRUCache.java) (Hard) +- [Insert Delete Get Random](src/main/java/design/RandomizedSet.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Serialize Deserialize Binary Tree](src/main/java/design/SerializeDeserializeBinaryTree.java) (Hard) +- [Design Twitter](src/main/java/design/Twitter.java) (Medium) +- [Tic-Tac-Toe](src/main/java/design/TicTacToe.java) (Medium) +- [Implement Trie (Prefix Tree)](src/main/java/design/Trie.java) (Medium) +- [Binary Search Tree Iterator](src/main/java/design/BSTIterator.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Design Search Autocomplete System](src/main/java/design/AutocompleteSystem.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Design Excel Sum Formula](src/main/java/design/Excel.java) (Hard) +- [Flatten Nested List Iterator](src/main/java/design/NestedIterator.java) (Medium) +- [Add and Search Word - Data structure design](src/main/java/design/WordDictionary.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Prefix and Suffix Search](src/main/java/design/WordFilter.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Insert Delete GetRandom O(1) - Duplicates allowed](src/main/java/design/RandomizedCollection.java) (Hard) + +#### [Divide and Conquer](src/main/java/divide_and_conquer) + +- [Kth Largest Element In a Array](src/main/java/divide_and_conquer/KthLargestElementInAnArray.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reverse Pairs](src/main/java/divide_and_conquer/ReversePairs.java) (Hard) +- [Search in a 2D Matrix](src/main/java/divide_and_conquer/SearchA2DMatrix.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [24 Game](src/main/java/divide_and_conquer/TwentyFourGame.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reverse Pairs II](src/main/java/divide_and_conquer/ReversePairsII.java) (Hard) +- [My Calendar II](src/main/java/divide_and_conquer/MyCalendarII.java) (Medium) + +#### [Dynamic Programming](src/main/java/dynamic_programming) + +- [Best Time To Buy and Sell Stocks](src/main/java/dynamic_programming/BestTimeToBuyAndSellStocks.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Best Time to Buy and Sell Stock III](src/main/java/dynamic_programming/BestTimeToBuyAndSellStockIII.java) (Hard) +- [Best Time to Buy and Sell Stock with Transaction Fee](src/main/java/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java) (Medium) +- [Climbing Stairs](src/main/java/dynamic_programming/ClimbingStairs.java) (Easy) +- [Coin Change](src/main/java/dynamic_programming/CoinChange.java) (Medium) +- [Coin Change 2](src/main/java/dynamic_programming/CoinChange2.java) (Medium) +- [Decode Ways](src/main/java/dynamic_programming/DecodeWays.java) (Medium) +- [House Robber](src/main/java/dynamic_programming/HouseRobber.java) (Easy) +- [House Robber II](src/main/java/dynamic_programming/HouseRobberII.java) (Medium) +- [Longest Increasing Subsequence](src/main/java/dynamic_programming/LongestIncreasingSubsequence.java) (Medium) +- [Longest Paliandromic Substring](src/main/java/dynamic_programming/LongestPaliandromicSubstring.java) (Medium) +- [Longest Palindromic Subsequence](src/main/java/dynamic_programming/LongestPalindromicSubsequence.java) (Medium) +- [Maximum Product Subarray](src/main/java/dynamic_programming/MaximumProductSubarray.java) (Medium) +- [Min Cost Climbing Stairs](src/main/java/dynamic_programming/MinCostClimbingStairs.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Palindrome Partitioning II](src/main/java/dynamic_programming/PalindromePartitioningII.java) (Hard) +- [UniqueBinary Search Trees](src/main/java/dynamic_programming/UniqueBinarySearchTrees.java) (Medium) +- [Unique Binary Search Trees II](src/main/java/dynamic_programming/UniqueBinarySearchTreesII.java) (Medium) +- [WordBreak](src/main/java/dynamic_programming/WordBreak.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [WordBreak II](src/main/java/dynamic_programming/WordBreakII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Concatenated Words](src/main/java/dynamic_programming/ConcatenatedWords.java) (Hard) +- [Can I Win](src/main/java/dynamic_programming/CanIWin.java) (Medium) +- [Maximum Subarray](src/main/java/dynamic_programming/MaximumSubarray.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Dungeon Game](src/main/java/dynamic_programming/DungeonGame.java) (Hard) +- [2 Keys Keyboard](src/main/java/dynamic_programming/TwoKeysKeyboard.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Maximum Sum of 3 Non-Overlapping Subarrays](src/main/java/dynamic_programming/MaxSum3SubArray.java) (Hard) +- [Maximal Square](src/main/java/dynamic_programming/MaximalSquare.java) (Medium) +- [Continuous Subarray Sum](src/main/java/dynamic_programming/ContinuousSubarraySum.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Decode Ways II](src/main/java/dynamic_programming/DecodeWaysII.java) (Hard) +- [Palindromic Substrings](src/main/java/dynamic_programming/PalindromicSubstrings.java) (Medium) +- [Number of Longest Increasing Subsequence](src/main/java/dynamic_programming/NumberOfLIS.java) (Medium) +- [Combination Sum IV](src/main/java/dynamic_programming/CombinationSumIV.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Paint House II](src/main/java/dynamic_programming/PaintHouseII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Split Array Largest Sum](src/main/java/dynamic_programming/SplitArrayLargestSum.java) (Hard) +- [Number Of Corner Rectangles](src/main/java/dynamic_programming/CornerRectangles.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Burst Balloons](src/main/java/dynamic_programming/BurstBalloons.java) (Hard) +- [Largest Plus Sign](src/main/java/dynamic_programming/LargestPlusSign.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Palindrome Pairs](src/main/java/dynamic_programming/PalindromePairs.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Cherry Pickup](src/main/java/dynamic_programming/CherryPickup.java) (Hard) +- [Knight Probability in Chessboard](src/main/java/dynamic_programming/KnightProbabilityInChessboard.java) (Medium) +- [Largest Sum of Averages](src/main/java/dynamic_programming/LargestSumOfAverages.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Number of Refueling Stops](src/main/java/dynamic_programming/MinimumNumberOfRefuelingStops.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Cat and Mouse](src/main/java/dynamic_programming/CatAndMouse.java) (Hard) +- [Stone Game](src/main/java/dynamic_programming/StoneGame.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Odd Even Jump](src/main/java/dynamic_programming/OddEvenJump.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Profitable Schemes](src/main/java/dynamic_programming/ProfitableSchemes.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Maximum Vacation Days](src/main/java/dynamic_programming/MaximumVacationDays.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Russian Doll Envelopes](src/main/java/dynamic_programming/RussianDollEnvelopes.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Student Attendance Record II](src/main/java/dynamic_programming/StudentAttendanceRecordII.java) (Hard) +- [Out of Boundary Paths](src/main/java/dynamic_programming/OutOfBoundaryPaths.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Remove Boxes](src/main/java/dynamic_programming/RemoveBoxes.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Stickers to Spell Word](src/main/java/dynamic_programming/StickersToSpellWord.java) (Hard) +- [Ones and Zeroes](src/main/java/dynamic_programming/OnesAndZeroes.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Encode String with Shortest Length](src/main/java/dynamic_programming/EncodeStringWithShortestLength.java) (Hard) +- [Length of Longest Fibonacci Subsequence](src/main/java/dynamic_programming/LengthofLongestFibonacciSubsequence.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Make Array Strictly Increasing](src/main/java/dynamic_programming/MakeArrayStrictlyIncreasing.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Number of Taps to Open to Water a Garden](src/main/java/dynamic_programming/MinimumNumberOfTaps.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Delete Columns to Make Sorted III](src/main/java/dynamic_programming/DeleteColumnsToMakeSortedIII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Handshakes That Don't Cross](src/main/java/dynamic_programming/HandshakesThatDontCross.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Difficulty of a Job Schedule](src/main/java/dynamic_programming/MinimumDifficultyOfAJobSchedule.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Jump Game V](src/main/java/dynamic_programming/JumpGameV.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Freedom Trail](src/main/java/dynamic_programming/FreedomTrail.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Strange Printer](src/main/java/dynamic_programming/StrangePrinter.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Cost to Merge Stones](src/main/java/dynamic_programming/MinimumCostToMergeStones.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Interleaving String](src/main/java/dynamic_programming/InterleavingString.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Count Vowels Permutation](src/main/java/dynamic_programming/CountVowelsPermutation.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Non-negative Integers without Consecutive Ones](src/main/java/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java) (Hard) +- [Bomb Enemy](src/main/java/dynamic_programming/BombEnemy.java) (Medium) +- [Number of Dice Rolls With Target Sum](src/main/java/dynamic_programming/NumberOfDiceRollsWithTargetSum.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Distinct Subsequences](src/main/java/dynamic_programming/DistinctSubsequences.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Distinct Subsequences II](src/main/java/dynamic_programming/DistinctSubsequencesII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Distance to Type a Word Using Two Fingers](src/main/java/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Valid Palindrome III](src/main/java/dynamic_programming/ValidPalindromeIII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Palindrome Partitioning III](src/main/java/dynamic_programming/PalindromePartitioningIII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Tiling a Rectangle with the Fewest Squares](src/main/java/dynamic_programming/TilingARectangle.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Longest Chunked Palindrome Decomposition](src/main/java/dynamic_programming/LongestChunkedPalindromeDecomposition.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Stone Game III](src/main/java/dynamic_programming/StoneGameIII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Ways to Stay in the Same Place After Some Steps](src/main/java/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java) (Hard) +- [Toss Strange Coins](src/main/java/dynamic_programming/TossStrangeCoins.java) (Medium) +- [Knight Dialer](src/main/java/dynamic_programming/KnightDialer.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Palindrome Removal](src/main/java/dynamic_programming/PalindromeRemoval.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Restore The Array](src/main/java/dynamic_programming/RestoreTheArray.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Cherry Pickup II](src/main/java/dynamic_programming/CherryPickupII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Constrained Subsequence Sum](src/main/java/dynamic_programming/ConstrainedSubsequenceSum.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Largest Multiple of Three](src/main/java/dynamic_programming/LargestMultipleOfThree.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Largest Multiple of Three](src/main/java/dynamic_programming/MaximumProfitInJobScheduling.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Music Playlists](src/main/java/dynamic_programming/NumberOfMusicPlaylists.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Paint House III](src/main/java/dynamic_programming/PaintHouseIII.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Shortest Path Visiting All Nodes](src/main/java/dynamic_programming/ShortestPathVisitingAllNodes.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Smallest Sufficient Team](src/main/java/dynamic_programming/SmallestSufficientTeam.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Stone Game IV](src/main/java/dynamic_programming/StoneGameIV.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Tallest Billboard](src/main/java/dynamic_programming/TallestBillboard.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Count Different Palindromic Subsequences](src/main/java/dynamic_programming/CountDifferentPalindromicSubsequences.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Paths with Max Score](src/main/java/dynamic_programming/NumberOfPathsWithMaxScore.java) (Hard) + + +#### [Greedy](src/main/java/greedy) + +- [Jump Game](src/main/java/greedy/JumpGame.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Jump Game II](src/main/java/greedy/JumpGameII.java) (Hard) +- [Course Schedule III](src/main/java/greedy/CourseScheduleIII.java) (Medium) +- [GasStation](src/main/java/greedy/GasStation.java) (Medium) +- [Non-Overlapping Intervals](src/main/java/greedy/NonOverlappingIntervals.java) (Medium) +- [Minimum Number of Arrows to Burst Balloons](src/main/java/greedy/BurstBalloons.java) (Medium) +- [Queue Reconstruction By Height](src/main/java/greedy/QueueReconstructionByHeight.java) (Medium) +- [Task Scheduler](src/main/java/greedy/TaskScheduler.java) (Medium) +- [Maximum Length of Pair Chain](src/main/java/greedy/MaximumLengthOfPairChain.java) (Medium) +- [Lemonade Change](src/main/java/greedy/LemonadeChange.java) (Easy) +- [Score After Flipping Matrix](src/main/java/greedy/ScoreAfterFlippingMatrix.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [IPO](src/main/java/greedy/IPO.java) (Hard) +- [String Without AAA or BBB](src/main/java/greedy/StringWithout3A3B.java) (Medium) +- [Boats to Save People](src/main/java/greedy/BoatsToSavePeople.java) (Medium) +- [Broken Calculator](src/main/java/greedy/BrokenCalculator.java) (Medium) +- [Two City Scheduling](src/main/java/greedy/TwoCityScheduling.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Time to Build Blocks](src/main/java/greedy/MinimumTimeToBuildBlocks.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reducing Dishes](src/main/java/greedy/ReducingDishes.java) (Hard) + +#### [Hashing](src/main/java/hashing) + +- [Anagrams](src/main/java/hashing/Anagrams.java) (Medium) +- [Group Anagrams](src/main/java/hashing/GroupAnagrams.java) (Medium) +- [Kdiff Pairs In a Array](src/main/java/hashing/KdiffPairsInanArray.java) (Easy) +- [Sort Character by Frequency](src/main/java/hashing/SortCharByFrequency.java) (Medium) +- [Two Sum](src/main/java/hashing/TwoSum.java) (Easy) +- [Valid Anagram](src/main/java/hashing/ValidAnagram.java) (Easy) +- [Maximum Size Subarray Sum Equals k](src/main/java/hashing/MaximumSizeSubarraySumEqualsk.java) (Medium) +- [Contiguous Array](src/main/java/hashing/ContiguousArray.java) (Medium) +- [Brick Wall](src/main/java/hashing/BrickWall.java) (Medium) +- [Partition Labels](src/main/java/hashing/PartitionLabels.java) (Medium) +- [Custom Sort String](src/main/java/hashing/CustomSortString.java) (Medium) +- [Short Encoding of Words](src/main/java/hashing/ShortEncodingOfWords.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Substring with Concatenation of All Words](src/main/java/hashing/SubstringConcatenationOfWords.java) (Hard) +- [Distribute Candies](src/main/java/hashing/DistributeCandies.java) (Easy) +- [Groups of Special-Equivalent Strings](src/main/java/hashing/GroupsOfSpecialEquivalentStrings.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Number of Atoms](src/main/java/hashing/NumberOfAtoms.java) (Hard) +- [Analyze User Website Visit Pattern](src/main/java/hashing/AnalyzeUserWebsiteVisitPattern.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [String Transforms Into Another String](src/main/java/hashing/StringTransformsIntoAnotherString.java) (Hard) + +#### [Heap](src/main/java/heap) + +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Sliding Window Maximum](src/main/java/heap/SlidingWindowMaximum.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [The Skyline Problem](src/main/java/heap/TheSkylineProblem.java) (Hard) +- [Meeting Rooms II](src/main/java/heap/MeetingRoomsII.java) (Medium) +- [Top K Frequent Words](src/main/java/heap/TopKFrequentWords.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Candy](src/main/java/heap/Candy.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Smallest Rotation with Highest Score](src/main/java/heap/SmallestRotationWithHighestScore.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Maximum Frequency Stack](src/main/java/heap/FreqStack.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reachable Nodes In Subdivided Graph](src/main/java/heap/ReachableNodesInSubdividedGraph.java) (Hard) +- [K Closest Points to Origin](src/main/java/heap/KClosestPointsToOrigin.java) (Medium) +- [Distant Barcodes](src/main/java/heap/DistantBarcodes.java) (Medium) + +#### [Linked List](src/main/java/linked_list) + +- [Intersection of two Linked-Lists](src/main/java/linked_list/IntersectionOfTwoLists.java) (Easy) +- [Linked List Cycle](src/main/java/linked_list/LinkedListCycle.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Merge K Sorted Lists](src/main/java/linked_list/MergeKSortedLists.java) (Hard) +- [Merge Two Sorted List](src/main/java/linked_list/MergeTwoSortedList.java) (Easy) +- [Paliandrome List](src/main/java/linked_list/PaliandromeList.java) (Easy) +- [Reverse Linked List](src/main/java/linked_list/ReverseLinkedList.java) (Easy) +- [Delete Node in a Linked List](src/main/java/linked_list/DeleteNode.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reverse Nodes in k-Group](src/main/java/linked_list/ReverseNodesKGroup.java) (Hard) +- [Swap Nodes in Pairs](src/main/java/linked_list/SwapNodesInPairs.java) (Medium) +- [Middle of Linked List](src/main/java/linked_list/MiddleOfLinkedList.java) (Easy) +- [Split Linked List in Parts](src/main/java/linked_list/SplitLinkedListInParts.java) (Medium) +- [Next Greater Node In Linked List](src/main/java/linked_list/NextGreaterNodeInLinkedList.java) (Medium) + +#### [Math](src/main/java/math) + +- [Add Two Numbers](src/main/java/math/AddTwoNumbers.java) (Medium) +- [Count Primes](src/main/java/math/CountPrimes.java) (Easy) +- [Rotate Function](src/main/java/math/RotateFunction.java) (Medium) +- [Water and Jug Problem](src/main/java/math/WaterAndJugProblem.java) (Medium) +- [Add Digits](src/main/java/math/AddDigits.java) (Easy) +- [Excel Sheet Column Title](src/main/java/math/ExcelSheetColumnTitle.java) (Easy) +- [Roman to Integer](src/main/java/math/RomanToInteger.java) (Easy) +- [Bulb Switcher II](src/main/java/math/BulbSwitcherII.java) (Medium) +- [Global and Local Inversions](src/main/java/math/GlobalAndLocalInversions.java) (Medium) +- [Solve the Equation](src/main/java/math/SolveTheEquation.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Couples Holding Hands](src/main/java/math/CouplesHoldingHands.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Reaching Points](src/main/java/math/ReachingPoints.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Nth Magical Number](src/main/java/math/NthMagicalNumber.java) (Hard) +- [Squirrel Simulation](src/main/java/math/SquirrelSimulation.java) (Medium) +- [Projection Area of 3D Shapes](src/main/java/math/ProjectionAreaOf3DShapes.java) (Easy) +- [Decoded String at Index](src/main/java/math/DecodedStringAtIndex.java) (Medium) +- [Base 7](src/main/java/math/Base7.java) (Easy) +- [Smallest Range I](src/main/java/math/SmallestRangeI.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Largest Component Size by Common Factor](src/main/java/math/LargestComponentSizebyCommonFactor.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Super Washing Machines](src/main/java/math/SuperWashingMachines.java) (Hard) +- [Rectangle Overlap](src/main/java/math/RectangleOverlap.java) (Easy) +- [Nth Digit](src/main/java/math/NthDigit.java) (Easy) + +#### [Reservoir Sampling](src/main/java/reservoir_sampling) + +- [Random Pick Index](src/main/java/reservoir_sampling/RandomPickIndex.java) (Medium) + +#### [Stack](src/main/java/stack) + +- [Min Stack](src/main/java/stack/MinStack.java) (Easy) +- [Valid Parentheses](src/main/java/stack/ValidParentheses.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Largest Rectangle In Histogram](src/main/java/stack/LargestRectangleInHistogram.java) (Hard) +- [Implement Queue using Stacks](src/main/java/stack/MyQueue.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Maximal Rectangle](src/main/java/stack/MaximalRectangle.java) (Hard) +- [Exclusive Time of Functions](src/main/java/stack/ExclusiveTimeOfFunctions.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Basic Calculator](src/main/java/stack/BasicCalculator.java) (Hard) +- [Decode String](src/main/java/stack/DecodeString.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Longest Valid Parentheses](src/main/java/stack/LongestValidParentheses.java) (Hard) + + +#### [String](src/main/java/string) + +- [First Unique Character In a String](src/main/java/string/FirstUniqueCharacterInAString.java) (Easy) +- [Repeated Substring Pattern](src/main/java/string/RepeatedSubstringPattern.java) (Easy) +- [Reverse Words In a String](src/main/java/string/ReverseWordsInAString.java) (Medium) +- [ReverseWords II](src/main/java/string/ReverseWordsII.java) (Medium) +- [String to Integer](src/main/java/string/StringToInteger.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Text Justification](src/main/java/string/TextJustification.java) (Hard) +- [ZigZag Conversion](src/main/java/string/ZigZagConversion.java) (Medium) +- [Implement StrStr](src/main/java/string/ImplementStrStr.java) (Easy) +- [Excel Sheet Column Number](src/main/java/string/ExcelSheetColumnNumber.java) (Easy) +- [Compare Version Numbers](src/main/java/string/CompareVersionNumbers.java) (Easy) +- [Valid Palindrome](src/main/java/string/ValidPalindrome.java) (Easy) +- [Simplify Path](src/main/java/string/SimplifyPath.java) (Medium) +- [Permutation in String](src/main/java/string/PermutationInString.java) (Medium) +- [Add Binary](src/main/java/string/AddBinary.java) (Easy) +- [Valid Palindrome II](src/main/java/string/ValidPalindromeII.java) (Easy) +- [One Edit Distance](src/main/java/string/OneEditDistance.java) (Medium) +- [Count and Say](src/main/java/string/CountAndSay.java) (Easy) +- [Multiply Strings](src/main/java/string/MultiplyStrings.java) (Medium) +- [Longest Word in Dictionary through Deleting](src/main/java/string/LongestWordInDictonary.java) (Medium) +- [Isomorphic Strings](src/main/java/string/IsomorphicStrings.java) (Easy) +- [String Compression](src/main/java/string/StringCompression.java) (Easy) +- [Longest Common Prefix](src/main/java/string/LongestCommonPrefix.java) (Easy) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Find the Closest Palindrome](src/main/java/string/FindTheClosestPalindrome.java) (Hard) +- [Monotone Increasing Digits](src/main/java/string/MonotoneIncreasingDigits.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Shortest Palindrome](src/main/java/string/ShortestPalindrome.java) (Hard) +- [Valid Word Abbreviation](src/main/java/string/ValidWordAbbreviation.java) (Easy) +- [Longest Palindrome](src/main/java/string/LongestPalindrome.java) (Easy) +- [Replace Words](src/main/java/string/ReplaceWords.java) (Medium) +- [Rotate String](src/main/java/string/RotateString.java) (Easy) +- [Keyboard Row](src/main/java/string/KeyboardRow.java) (Easy) +- [Student Attendance Record I](src/main/java/string/StudentAttendanceRecordI.java) (Easy) +- [Split Concatenated Strings](src/main/java/string/SplitConcatenatedStrings.java) (Medium) +- [Valid Word Square](src/main/java/string/ValidWordSquare.java) (Easy) +- [Reconstruct Original Digits from English](src/main/java/string/ReconstructOriginalDigitsFromEnglish.java) (Medium) +- [Push Dominoes](src/main/java/string/PushDominoes.java) (Medium) +- [Validate IP Address](src/main/java/string/ValidateIPAddress.java) (Medium) +- [Reverse String II](src/main/java/string/ReverseStringII.java) (Easy) +- [Find Words That Can Be Formed by Characters](src/main/java/string/FindWordsThatCanBeFormedbyCharacters.java) (Easy) +- [Minimum Add to Make Parentheses Valid](src/main/java/string/MinimumAddtoMakeParenthesesValid.java) (Medium) + +#### [Tree](src/main/java/tree) + +- [Binaray Tree Right Side View](src/main/java/tree/BinarayTreeRightSideView.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Binary Tree Maximum Path Sum](src/main/java/tree/BinaryTreeMaximumPathSum.java) (Hard) +- [Boundary of Binary Tree](src/main/java/tree/BoundaryOfBinaryTree.java) (Medium) +- [Convert sorted array to BST](src/main/java/tree/ConvertSortedArrayToBST.java) (Medium) +- [Lowest Common Ancestor of a Binary Tree](src/main/java/tree/LCA.java) (Medium) +- [Lowest Common Ancestor of a BST](src/main/java/tree/LowestCommonAncestorBST.java) (Easy) +- [Most Frequent Subtree Sum](src/main/java/tree/MostFrequentSubtreeSum.java) (Medium) +- [Path Sum III](src/main/java/tree/PathSumIII.java) (Easy) +- [Convert Postorder and Inorder traversal to Binary Tree](src/main/java/tree/PostorderToBT.java) (Medium) +- [Convert Preorder and Inorder traversal to Binary Tree](src/main/java/tree/PreorderToBT.java) (Medium) +- [Sorted Array to BST](src/main/java/tree/SortedArrayToBST.java) (Medium) +- [Valid Binary Search Tree](src/main/java/tree/ValidBinarySearchTree.java) (Medium) +- [Largest BST Subtree](src/main/java/tree/LargestBSTSubtree.java) (Medium) +- [Closest Binary Search Tree Value](src/main/java/tree/ClosestBinarySearchTreeValue.java) (Easy) +- [Inorder Successor in BST](src/main/java/tree/InorderSuccessorInBST.java) (Medium) +- [Construct String From Binary Tree](src/main/java/tree/ConstructStringFromBinaryTree.java) (Easy) +- [Flatten Binary Tree to Linked List](src/main/java/tree/FlattenBinaryTree.java) (Medium) +- [Populating Next Right Pointers in Each Node](src/main/java/tree/NextRightPointer.java) (Medium) +- [Populating Next Right Pointers in Each Node II](src/main/java/tree/NextRightPointerII.java) (Medium) +- [Subtree of Another Tree](src/main/java/tree/SubtreeOfAnotherTree.java) (Easy) +- [Binary Tree Zigzag Level Order Traversal](src/main/java/tree/ZigZagTraversal.java) (Medium) +- [Binary Tree Inorder Traversal](src/main/java/tree/BinaryTreeInorderTraversal.java) (Medium) +- [Symmetric Tree](src/main/java/tree/SymmetricTree.java) (Easy) +- [Maximum Binary Tree](src/main/java/tree/MaximumBinaryTree.java) (Medium) +- [Find Bottom Left Tree Value](src/main/java/tree/FindBottomLeftTreeValue.java) (Medium) +- [Diameter of Binary Tree](src/main/java/tree/DiameterOfBinaryTree.java) (Easy) +- [Binary Tree Paths](src/main/java/tree/BinaryTreePaths.java) (Easy) +- [Sum of Left Leaves](src/main/java/tree/SumofLeftLeaves.java) (Easy) +- [Two Sum IV - Input is a BST](src/main/java/tree/TwoSumIV.java) (Easy) +- [Average of Levels in Binary Tree](src/main/java/tree/AverageOfLevelsInBinaryTree.java) (Easy) +- [Convert Binary Search Tree to Sorted Doubly Linked List](src/main/java/tree/BSTtoDoublyLinkedList.java) (Easy) +- [Same Tree](src/main/java/tree/SameTree.java) (Easy) +- [Binary Tree Longest Consecutive SequencefindMinDifference II](src/main/java/tree/BinaryTreeLongestConsecutiveSequenceII.java) (Medium) +- [Minimum Absolute Difference in BST](src/main/java/tree/MinimumAbsoluteDifferenceInBST.java) (Medium) +- [Equal Tree Partition](src/main/java/tree/EqualTreePartition.java) (Medium) +- [Split BST](src/main/java/tree/SplitBST.java) (Medium) +- [Closest Leaf in a Binary Tree](src/main/java/tree/ClosestLeafInABinaryTree.java) (Medium) +- [Maximum Width of Binary Tree](src/main/java/tree/MaximumWidthOfBinaryTree.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Recover Binary Search Tree](src/main/java/tree/RecoverBinarySearchTree.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Binary Tree Postorder Traversal](src/main/java/tree/BinaryTreePostorderTraversal.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Serialize and Deserialize N-ary Tree](src/main/java/tree/SerializeAndDeserializeNAryTree.java) (Hard) +- [Convert BST to Greater Tree](src/main/java/tree/ConvertBSTToGreaterTree.java) (Easy) +- [All Nodes Distance K in Binary Tree](src/main/java/tree/AllNodesDistanceKInBinaryTree.java) (Medium) +- [All Possible Full Binary Trees](src/main/java/tree/AllPossibleFullBinaryTrees.java) (Medium) +- [Flip Equivalent Binary Trees](src/main/java/tree/FlipEquivalentBinaryTrees.java) (Medium) +- [Construct Binary Tree from String](src/main/java/tree/ConstructBinaryTreefromString.java) (Medium) +- [Find Largest Value in Each Tree Row](src/main/java/tree/FindLargestValueInEachTreeRow.java) (Medium) +- [Find Bottom Left Tree Value](src/main/java/tree/FindBottomLeftTreeValue.java) (Medium) +- [Maximum Level Sum of a Binary Tree](src/main/java/tree/MaximumLevelSumofABinaryTree.java) (Medium) +- [Leaf-Similar Trees](src/main/java/tree/LeafSimilarTrees.java) (Easy) +- [Binary Tree Tilt](src/main/java/tree/BinaryTreeTilt.java) (Easy) + +#### [Two Pointers](src/main/java/two_pointers) + +- [Four Sum](src/main/java/two_pointers/FourSum.java) (Medium) +- [Longest Substring Witout Repeats](src/main/java/two_pointers/LongestSubstringWitoutRepeats.java) (Medium) +- [Three Sum](src/main/java/two_pointers/ThreeSum.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Trapping Rain Water](src/main/java/two_pointers/TrappingRainWater.java) (Hard) +- [3Sum Closest](src/main/java/two_pointers/ThreeSumClosest.java) (Medium) +- [Move Zeroes](src/main/java/two_pointers/MoveZeroes.java) (Easy) +- [Remove Duplicates](src/main/java/two_pointers/RemoveDuplicates.java) (Easy) +- [Remove Duplicates II](src/main/java/two_pointers/RemoveDuplicatesII.java) (Medium) +- [Minimum Size Subarray Sum](src/main/java/two_pointers/MinimumSizeSubarraySum.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Minimum Window Substring](src/main/java/two_pointers/MinimumWindowSubstring.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Smallest Range](src/main/java/two_pointers/SmallestRange.java) (Hard) +- [Subarray Product Less Than K](src/main/java/two_pointers/SubarrayProductLessThanK.java) (Medium) +- [Number of Matching Subsequences](src/main/java/two_pointers/NumberOfMatchingSubsequences.java) (Medium) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Subarrays with K Different Integers](src/main/java/two_pointers/SubarraysWithKDifferentIntegers.java) (Hard) +- ![#f03c15](https://placehold.it/15/f03c15/000000?text=+) [Last Substring in Lexicographical Order](src/main/java/two_pointers/LastSubstringInLexicographicalOrder.java) (Hard) diff --git a/build.gradle b/build.gradle index 2a27034e..9f9314b2 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,31 @@ plugins { id 'java' - id 'com.github.sherter.google-java-format' version '0.8' + id 'com.diffplug.spotless' version '7.0.0.BETA4' } -dependencies { - compile 'com.google.googlejavaformat:google-java-format:1.7' +java { + toolchain { + languageVersion = JavaLanguageVersion.of(23) // Replace with your desired version + } +} + +spotless { + java { + // Use the default import order configuration + importOrder('java', 'javax', 'com.acme', '', '#com.acme', '#') + + // Remove unused imports + removeUnusedImports() + + // Apply formatting to annotations + formatAnnotations() + } +} + +tasks.withType(JavaCompile).configureEach { + options.release = 23 // Match the desired version } repositories { - jcenter() // or mavenCentral() -} \ No newline at end of file + mavenCentral() +} diff --git a/src/main/java/array/AddToArrayFormOfInteger.java b/src/main/java/array/AddToArrayFormOfInteger.java new file mode 100644 index 00000000..8b8e7eef --- /dev/null +++ b/src/main/java/array/AddToArrayFormOfInteger.java @@ -0,0 +1,51 @@ +/* (C) 2024 YourCompanyName */ +package array; + +import java.math.BigInteger; +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 25/07/2019 + * + *

For a non-negative integer X, the array-form of X is an array of its digits in left to right + * order. For example, if X = 1231, then the array form is [1,2,3,1]. + * + *

Given the array-form A of a non-negative integer X, return the array-form of the integer X+K. + * + *

Example 1: + * + *

Input: A = [1,2,0,0], K = 34 Output: [1,2,3,4] Explanation: 1200 + 34 = 1234 Example 2: + * + *

Input: A = [2,7,4], K = 181 Output: [4,5,5] Explanation: 274 + 181 = 455 Example 3: + * + *

Input: A = [2,1,5], K = 806 Output: [1,0,2,1] Explanation: 215 + 806 = 1021 Example 4: + * + *

Input: A = [9,9,9,9,9,9,9,9,9,9], K = 1 Output: [1,0,0,0,0,0,0,0,0,0,0] Explanation: + * 9999999999 + 1 = 10000000000 + * + *

Note: + * + *

1 <= A.length <= 10000 0 <= A[i] <= 9 0 <= K <= 10000 If A.length > 1, then A[0] != 0 + * + *

Solution: O(N) use BigInteger to add long numbers + */ +public class AddToArrayFormOfInteger { + public static void main(String[] args) { + // + } + + public List addToArrayForm(int[] A, int K) { + StringBuilder sb = new StringBuilder(); + for (int a : A) { + sb.append(a); + } + BigInteger big = new BigInteger(sb.toString()); + BigInteger result = big.add(BigInteger.valueOf(K)); + String resultStr = result.toString(); + List list = new ArrayList<>(); + for (char a : resultStr.toCharArray()) { + list.add(Integer.parseInt(String.valueOf(a))); + } + return list; + } +} diff --git a/src/main/java/array/ArrayNesting.java b/src/main/java/array/ArrayNesting.java new file mode 100644 index 00000000..05686dc3 --- /dev/null +++ b/src/main/java/array/ArrayNesting.java @@ -0,0 +1,57 @@ +/* (C) 2024 YourCompanyName */ +package array; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 09/10/2019 A zero-indexed array A of length N contains all + * integers from 0 to N-1. Find and return the longest length of set S, where S[i] = {A[i], A[A[i]], + * A[A[A[i]]], ... } subjected to the rule below. + * + *

Suppose the first element in S starts with the selection of element A[i] of index = i, the + * next element in S should be A[A[i]], and then A[A[A[i]]]… By that analogy, we stop adding right + * before a duplicate element occurs in S. + * + *

Example 1: + * + *

Input: A = [5,4,0,3,1,6,2] Output: 4 Explanation: A[0] = 5, A[1] = 4, A[2] = 0, A[3] = 3, A[4] + * = 1, A[5] = 6, A[6] = 2. + * + *

One of the longest S[K]: S[0] = {A[0], A[5], A[6], A[2]} = {5, 6, 2, 0} + * + *

Note: + * + *

N is an integer within the range [1, 20,000]. The elements of A are all distinct. Each element + * of A is an integer within the range [0, N-1]. + */ +public class ArrayNesting { + public static void main(String[] args) { + int[] A = {5, 4, 0, 3, 1, 6, 2}; + System.out.println(new ArrayNesting().arrayNesting(A)); + } + + Set done; + int count; + + public int arrayNesting(int[] nums) { + done = new HashSet<>(); + int max = 0; + for (int i = 0; i < nums.length; i++) { + if (!done.contains(i)) { + count = 0; + dfs(i, nums); + max = Math.max(max, count); + } + } + return max; + } + + private void dfs(int i, int[] nums) { + done.add(i); + count++; + int n = nums[i]; + if (!done.contains(n)) { + dfs(n, nums); + } + } +} diff --git a/src/main/java/array/ArrayPartitionI.java b/src/main/java/array/ArrayPartitionI.java new file mode 100644 index 00000000..c0ac8770 --- /dev/null +++ b/src/main/java/array/ArrayPartitionI.java @@ -0,0 +1,34 @@ +/* (C) 2024 YourCompanyName */ +package array; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 14/08/2019 Given an array of 2n integers, your task is to group + * these integers into n pairs of integer, say (a1, b1), (a2, b2), ..., (an, bn) which makes sum of + * min(ai, bi) for all i from 1 to n as large as possible. + * + *

Example 1: Input: [1,4,3,2] + * + *

Output: 4 Explanation: n is 2, and the maximum sum of pairs is 4 = min(1, 2) + min(3, 4). + * Note: n is a positive integer, which is in the range of [1, 10000]. All the integers in the array + * will be in the range of [-10000, 10000]. + * + *

Solution: O(n log n) General idea is to pair the smallest with the next smallest value inorder + * to get the max sum of minimum. + */ +public class ArrayPartitionI { + public static void main(String[] args) { + int[] A = {1, 2, 3, 4}; + System.out.println(new ArrayPartitionI().arrayPairSum(A)); + } + + public int arrayPairSum(int[] nums) { + Arrays.sort(nums); + int sum = 0; + for (int i = 1; i < nums.length; i += 2) { + sum += Math.min(nums[i - 1], nums[i]); + } + return sum; + } +} diff --git a/problems/src/array/BattleshipsInABoard.java b/src/main/java/array/BattleshipsInABoard.java similarity index 98% rename from problems/src/array/BattleshipsInABoard.java rename to src/main/java/array/BattleshipsInABoard.java index 566221fe..f714ea45 100644 --- a/problems/src/array/BattleshipsInABoard.java +++ b/src/main/java/array/BattleshipsInABoard.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/BestMeetingPoint.java b/src/main/java/array/BestMeetingPoint.java similarity index 98% rename from problems/src/array/BestMeetingPoint.java rename to src/main/java/array/BestMeetingPoint.java index 46c04225..6252d428 100644 --- a/problems/src/array/BestMeetingPoint.java +++ b/src/main/java/array/BestMeetingPoint.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/CanPlaceFlowers.java b/src/main/java/array/CanPlaceFlowers.java similarity index 98% rename from problems/src/array/CanPlaceFlowers.java rename to src/main/java/array/CanPlaceFlowers.java index d811e108..8936f37d 100644 --- a/problems/src/array/CanPlaceFlowers.java +++ b/src/main/java/array/CanPlaceFlowers.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/CardFilipGame.java b/src/main/java/array/CardFilipGame.java similarity index 98% rename from problems/src/array/CardFilipGame.java rename to src/main/java/array/CardFilipGame.java index 5a8e1e90..1b145691 100644 --- a/problems/src/array/CardFilipGame.java +++ b/src/main/java/array/CardFilipGame.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.ArrayList; diff --git a/problems/src/array/ChampagneTower.java b/src/main/java/array/ChampagneTower.java similarity index 98% rename from problems/src/array/ChampagneTower.java rename to src/main/java/array/ChampagneTower.java index 6296214d..2cfec24d 100644 --- a/problems/src/array/ChampagneTower.java +++ b/src/main/java/array/ChampagneTower.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/EmployeeFreeTime.java b/src/main/java/array/EmployeeFreeTime.java similarity index 99% rename from problems/src/array/EmployeeFreeTime.java rename to src/main/java/array/EmployeeFreeTime.java index f6aff8dc..4eb584c1 100644 --- a/problems/src/array/EmployeeFreeTime.java +++ b/src/main/java/array/EmployeeFreeTime.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.ArrayList; diff --git a/src/main/java/array/FindPivotIndex.java b/src/main/java/array/FindPivotIndex.java new file mode 100644 index 00000000..7bb8aeda --- /dev/null +++ b/src/main/java/array/FindPivotIndex.java @@ -0,0 +1,67 @@ +/* (C) 2024 YourCompanyName */ +package array; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 06/08/2019 Given an array of integers nums, write a method that + * returns the "pivot" index of this array. + * + *

We define the pivot index as the index where the sum of the numbers to the left of the index + * is equal to the sum of the numbers to the right of the index. + * + *

If no such index exists, we should return -1. If there are multiple pivot indexes, you should + * return the left-most pivot index. + * + *

Example 1: + * + *

Input: nums = [1, 7, 3, 6, 5, 6] Output: 3 Explanation: The sum of the numbers to the left of + * index 3 (nums[3] = 6) is equal to the sum of numbers to the right of index 3. Also, 3 is the + * first index where this occurs. + * + *

Example 2: + * + *

Input: nums = [1, 2, 3] Output: -1 Explanation: There is no index that satisfies the + * conditions in the problem statement. + * + *

Note: + * + *

The length of nums will be in the range [0, 10000]. Each element nums[i] will be an integer in + * the range [-1000, 1000]. + * + *

Solution: O(N) maintain a prefix and posfix sum array and then use this to arrive at the + * answer. + */ +public class FindPivotIndex { + public static void main(String[] args) {} + + public int pivotIndex(int[] nums) { + if (nums.length == 1) return 0; + int[] left = new int[nums.length]; + int[] right = new int[nums.length]; + left[0] = nums[0]; + for (int i = 1; i < nums.length; i++) { + left[i] = left[i - 1] + nums[i]; + } + right[nums.length - 1] = nums[nums.length - 1]; + for (int i = nums.length - 2; i >= 0; i--) { + right[i] = right[i + 1] + nums[i]; + } + for (int i = 0; i < nums.length; i++) { + int l, r; + if (i == 0) { + l = 0; + } else { + l = left[i - 1]; + } + + if (i == nums.length - 1) { + r = 0; + } else { + r = right[i + 1]; + } + if (l == r) return i; + } + return -1; + } +} diff --git a/problems/src/array/FindTheCelebrity.java b/src/main/java/array/FindTheCelebrity.java similarity index 98% rename from problems/src/array/FindTheCelebrity.java rename to src/main/java/array/FindTheCelebrity.java index c18bf6c1..c4b4b5ca 100644 --- a/problems/src/array/FindTheCelebrity.java +++ b/src/main/java/array/FindTheCelebrity.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.HashMap; diff --git a/problems/src/array/FirstMissingPositive.java b/src/main/java/array/FirstMissingPositive.java similarity index 97% rename from problems/src/array/FirstMissingPositive.java rename to src/main/java/array/FirstMissingPositive.java index 1e704581..b589eb20 100644 --- a/problems/src/array/FirstMissingPositive.java +++ b/src/main/java/array/FirstMissingPositive.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/FruitIntoBaskets.java b/src/main/java/array/FruitIntoBaskets.java similarity index 98% rename from problems/src/array/FruitIntoBaskets.java rename to src/main/java/array/FruitIntoBaskets.java index 5a6404e8..10a3d9be 100644 --- a/problems/src/array/FruitIntoBaskets.java +++ b/src/main/java/array/FruitIntoBaskets.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.Stack; diff --git a/problems/src/array/HIndex.java b/src/main/java/array/HIndex.java similarity index 98% rename from problems/src/array/HIndex.java rename to src/main/java/array/HIndex.java index 2cc1dad3..5360b375 100644 --- a/problems/src/array/HIndex.java +++ b/src/main/java/array/HIndex.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/ImageSmoother.java b/src/main/java/array/ImageSmoother.java similarity index 98% rename from problems/src/array/ImageSmoother.java rename to src/main/java/array/ImageSmoother.java index 5c8894f1..af1d4903 100644 --- a/problems/src/array/ImageSmoother.java +++ b/src/main/java/array/ImageSmoother.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** * Created by gouthamvidyapradhan on 17/02/2018. * Given a 2D integer matrix M representing the gray diff --git a/problems/src/array/IncreasingTripletSubsequence.java b/src/main/java/array/IncreasingTripletSubsequence.java similarity index 97% rename from problems/src/array/IncreasingTripletSubsequence.java rename to src/main/java/array/IncreasingTripletSubsequence.java index 23f258c1..02fe1d96 100644 --- a/problems/src/array/IncreasingTripletSubsequence.java +++ b/src/main/java/array/IncreasingTripletSubsequence.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.Arrays; diff --git a/problems/src/array/InsertInterval.java b/src/main/java/array/InsertInterval.java similarity index 98% rename from problems/src/array/InsertInterval.java rename to src/main/java/array/InsertInterval.java index 5202ade0..8216e270 100644 --- a/problems/src/array/InsertInterval.java +++ b/src/main/java/array/InsertInterval.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.ArrayList; diff --git a/problems/src/array/KEmptySlots.java b/src/main/java/array/KEmptySlots.java similarity index 98% rename from problems/src/array/KEmptySlots.java rename to src/main/java/array/KEmptySlots.java index 2055612f..f83dc515 100644 --- a/problems/src/array/KEmptySlots.java +++ b/src/main/java/array/KEmptySlots.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.TreeSet; diff --git a/problems/src/array/LargestNumberAtLeastTwice.java b/src/main/java/array/LargestNumberAtLeastTwice.java similarity index 97% rename from problems/src/array/LargestNumberAtLeastTwice.java rename to src/main/java/array/LargestNumberAtLeastTwice.java index 664ace41..03905711 100644 --- a/problems/src/array/LargestNumberAtLeastTwice.java +++ b/src/main/java/array/LargestNumberAtLeastTwice.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/LargestTimeForGivenDigits.java b/src/main/java/array/LargestTimeForGivenDigits.java new file mode 100644 index 00000000..d934f6f9 --- /dev/null +++ b/src/main/java/array/LargestTimeForGivenDigits.java @@ -0,0 +1,55 @@ +/* (C) 2024 YourCompanyName */ +package array; + +/** + * Created by gouthamvidyapradhan on 06/08/2019 Given an array of 4 digits, return the largest 24 + * hour time that can be made. + * + *

The smallest 24 hour time is 00:00, and the largest is 23:59. Starting from 00:00, a time is + * larger if more time has elapsed since midnight. + * + *

Return the answer as a string of length 5. If no valid time can be made, return an empty + * string. + * + *

Example 1: + * + *

Input: [1,2,3,4] Output: "23:41" Example 2: + * + *

Input: [5,5,5,5] Output: "" + * + *

Note: + * + *

A.length == 4 0 <= A[i] <= 9 Solution O(N ^ 4) Check all combinations of time possible and + * return the maximum possible as the answer. + */ +public class LargestTimeForGivenDigits { + public static void main(String[] args) { + int[] A = {2, 0, 6, 6}; + System.out.println(new LargestTimeForGivenDigits().largestTimeFromDigits(A)); + } + + public String largestTimeFromDigits(int[] A) { + int max = -1; + String result = ""; + for (int i = 0; i < A.length; i++) { + if (A[i] > 2) continue; + for (int j = 0; j < A.length; j++) { + if (j == i) continue; + if (A[i] == 2 && A[j] > 3) continue; + for (int k = 0; k < A.length; k++) { + if (k == i || k == j) continue; + if (A[k] > 5) continue; + for (int l = 0; l < A.length; l++) { + if (l == i || l == j || l == k) continue; + int value = ((A[i] * 10 + A[j]) * 60) + A[k] * 10 + A[l]; + if (value > max) { + max = value; + result = A[i] + "" + A[j] + ":" + A[k] + "" + A[l]; + } + } + } + } + } + return result; + } +} diff --git a/problems/src/array/LongestIncreasingSubsequence.java b/src/main/java/array/LongestIncreasingSubsequence.java similarity index 97% rename from problems/src/array/LongestIncreasingSubsequence.java rename to src/main/java/array/LongestIncreasingSubsequence.java index 9f7a7e2f..5d009116 100644 --- a/problems/src/array/LongestIncreasingSubsequence.java +++ b/src/main/java/array/LongestIncreasingSubsequence.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/src/main/java/array/LongestLineofConsecutiveOneinMatrix.java b/src/main/java/array/LongestLineofConsecutiveOneinMatrix.java new file mode 100644 index 00000000..4e03d461 --- /dev/null +++ b/src/main/java/array/LongestLineofConsecutiveOneinMatrix.java @@ -0,0 +1,118 @@ +/* (C) 2024 YourCompanyName */ +package array; + +/** + * Created by gouthamvidyapradhan on 14/08/2019 Given a 01 matrix M, find the longest line of + * consecutive one in the matrix. The line could be horizontal, vertical, diagonal or anti-diagonal. + * Example: Input: [[0,1,1,0], [0,1,1,0], [0,0,0,1]] Output: 3 Hint: The number of elements in the + * given matrix will not exceed 10,000. + * + *

Solution O(N x M) for each cell keep track of maximum value possible horizontally, vertically + * and diagonally. Start iterating from left-right and top-bottom and repeat the same from + * right-left and top to bottom to get max for anti-diagonal and return the max value. + */ +public class LongestLineofConsecutiveOneinMatrix { + final int[] R = {0, 0, -1, 1}; + final int[] C = {1, -1, 0, 0}; + + public static void main(String[] args) { + int[][] M = { + {1, 1, 0, 0, 1, 0, 0, 1, 1, 0}, + {1, 0, 0, 1, 0, 1, 1, 1, 1, 1}, + {1, 1, 1, 0, 0, 1, 1, 1, 1, 0}, + {0, 1, 1, 1, 0, 1, 1, 1, 1, 1}, + {0, 0, 1, 1, 1, 1, 1, 1, 1, 0}, + {1, 1, 1, 1, 1, 1, 0, 1, 1, 1}, + {0, 1, 1, 1, 1, 1, 1, 0, 0, 1}, + {1, 1, 1, 1, 1, 0, 0, 1, 1, 1}, + {0, 1, 0, 1, 1, 0, 1, 1, 1, 1}, + {1, 1, 1, 0, 1, 0, 1, 1, 1, 1} + }; + System.out.println(new LongestLineofConsecutiveOneinMatrix().longestLine(M)); + } + + class Cell { + int h, v, d; + + Cell(int h, int v, int d) { + this.h = h; + this.v = v; + this.d = d; + } + } + + public int longestLine(int[][] M) { + if (M.length == 0) return 0; + int max = 0; + Cell[][] cells = new Cell[M.length][M[0].length]; + for (int i = 0; i < M.length; i++) { + for (int j = 0; j < M[0].length; j++) { + int h = 0, v = 0, d = 0; + if (M[i][j] == 1) { + h = 1; + v = 1; + d = 1; + max = Math.max(max, 1); + if (j - 1 >= 0) { + Cell left = cells[i][j - 1]; + if (left.h > 0) { + h += left.h; + max = Math.max(max, h); + } + } + if (i - 1 >= 0) { + Cell top = cells[i - 1][j]; + if (top.v > 0) { + v += top.v; + max = Math.max(max, v); + } + } + if (i - 1 >= 0 && j - 1 >= 0) { + Cell diagonal = cells[i - 1][j - 1]; + if (diagonal.d > 0) { + d += diagonal.d; + max = Math.max(max, d); + } + } + } + cells[i][j] = new Cell(h, v, d); + } + } + + for (int i = 0; i < M.length; i++) { + for (int j = M[0].length - 1; j >= 0; j--) { + int h = 0, v = 0, d = 0; + if (M[i][j] == 1) { + h = 1; + v = 1; + d = 1; + max = Math.max(max, 1); + if (j + 1 < M[0].length) { + Cell left = cells[i][j + 1]; + if (left.h > 0) { + h += left.h; + max = Math.max(max, h); + } + } + if (i - 1 >= 0) { + Cell top = cells[i - 1][j]; + if (top.v > 0) { + v += top.v; + max = Math.max(max, v); + } + } + if (i - 1 >= 0 && j + 1 < M[0].length) { + Cell diagonal = cells[i - 1][j + 1]; + if (diagonal.d > 0) { + d += diagonal.d; + max = Math.max(max, d); + } + } + } + cells[i][j] = new Cell(h, v, d); + } + } + + return max; + } +} diff --git a/src/main/java/array/MatrixCellsinDistanceOrder.java b/src/main/java/array/MatrixCellsinDistanceOrder.java new file mode 100644 index 00000000..2efe7f7a --- /dev/null +++ b/src/main/java/array/MatrixCellsinDistanceOrder.java @@ -0,0 +1,68 @@ +/* (C) 2024 YourCompanyName */ +package array; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 15/08/2019 We are given a matrix with R rows and C columns has + * cells with integer coordinates (r, c), where 0 <= r < R and 0 <= c < C. + * + *

Additionally, we are given a cell in that matrix with coordinates (r0, c0). + * + *

Return the coordinates of all cells in the matrix, sorted by their distance from (r0, c0) from + * smallest distance to largest distance. Here, the distance between two cells (r1, c1) and (r2, c2) + * is the Manhattan distance, |r1 - r2| + |c1 - c2|. (You may return the answer in any order that + * satisfies this condition.) + * + *

Example 1: + * + *

Input: R = 1, C = 2, r0 = 0, c0 = 0 Output: [[0,0],[0,1]] Explanation: The distances from (r0, + * c0) to other cells are: [0,1] Example 2: + * + *

Input: R = 2, C = 2, r0 = 0, c0 = 1 Output: [[0,1],[0,0],[1,1],[1,0]] Explanation: The + * distances from (r0, c0) to other cells are: [0,1,1,2] The answer [[0,1],[1,1],[0,0],[1,0]] would + * also be accepted as correct. Example 3: + * + *

Input: R = 2, C = 3, r0 = 1, c0 = 2 Output: [[1,2],[0,2],[1,1],[0,1],[1,0],[0,0]] Explanation: + * The distances from (r0, c0) to other cells are: [0,1,1,2,2,3] There are other answers that would + * also be accepted as correct, such as [[1,2],[1,1],[0,2],[1,0],[0,1],[0,0]]. + * + *

Note: + * + *

1 <= R <= 100 1 <= C <= 100 0 <= r0 < R 0 <= c0 < C + * + *

Solution: O (log (R x C)) Straight forward solution, find the Manhattan distance from the + * given cell to all the cells in the grid and sort by min distance and return their coordinates. + */ +public class MatrixCellsinDistanceOrder { + public static void main(String[] args) { + // + } + + class Cell { + int max, i, j; + + Cell(int max, int i, int j) { + this.max = max; + this.i = i; + this.j = j; + } + } + + public int[][] allCellsDistOrder(int R, int C, int r0, int c0) { + List list = new ArrayList<>(); + for (int i = 0; i < R; i++) { + for (int j = 0; j < C; j++) { + int sum = Math.abs(r0 - i) + Math.abs(c0 - j); + list.add(new Cell(sum, i, j)); + } + } + list.sort(Comparator.comparingInt(o -> o.max)); + int[][] A = new int[list.size()][2]; + for (int i = 0; i < A.length; i++) { + A[i][0] = list.get(i).i; + A[i][1] = list.get(i).j; + } + return A; + } +} diff --git a/src/main/java/array/MaxConsecutiveOnes.java b/src/main/java/array/MaxConsecutiveOnes.java new file mode 100644 index 00000000..95b3f749 --- /dev/null +++ b/src/main/java/array/MaxConsecutiveOnes.java @@ -0,0 +1,37 @@ +/* (C) 2024 YourCompanyName */ +package array; + +/** + * Created by gouthamvidyapradhan on 08/05/2019 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. Note: + * + *

The input array will only contain 0 and 1. The length of input array is a positive integer and + * will not exceed 10,000 + */ +public class MaxConsecutiveOnes { + public static void main(String[] args) { + // + } + + public int findMaxConsecutiveOnes(int[] nums) { + int max = 0; + boolean flag = false; + int count = 0; + for (int i = 0; i < nums.length; i++) { + if (nums[i] == 1) { + if (!flag) { + flag = true; + } + count++; + max = Math.max(max, count); + } else { + count = 0; + flag = false; + } + } + return max; + } +} diff --git a/src/main/java/array/MaxConsecutiveOnesII.java b/src/main/java/array/MaxConsecutiveOnesII.java new file mode 100644 index 00000000..f42b0ab3 --- /dev/null +++ b/src/main/java/array/MaxConsecutiveOnesII.java @@ -0,0 +1,72 @@ +/* (C) 2024 YourCompanyName */ +package array; + +/** + * Created by gouthamvidyapradhan on 08/05/2019 Given a binary array, find the maximum number of + * consecutive 1s in this array if you can flip at most one 0. + * + *

Example 1: Input: [1,0,1,1,0] Output: 4 Explanation: Flip the first zero will get the the + * maximum number of consecutive 1s. After flipping, the maximum number of consecutive 1s is 4. + * Note: + * + *

The input array will only contain 0 and 1. The length of input array is a positive integer and + * will not exceed 10,000 Follow up: What if the input numbers come in one by one as an infinite + * stream? In other words, you can't store all numbers coming from the stream as it's too large to + * hold in memory. Could you solve it efficiently? + * + *

Solution: O(N) Maintain a left and right auxiliary array with counts of contagious 1's from + * both directions. Now, iterate through the array and flip a 0 to 1 and sum up left and right + * contagious sum of 1's and return the max sum as the answer + */ +public class MaxConsecutiveOnesII { + public static void main(String[] args) { + // + } + + public int findMaxConsecutiveOnes(int[] nums) { + int[] L = new int[nums.length]; + int[] R = new int[nums.length]; + boolean flag = false; + int count = 0; + int max = 0; + for (int j = 0; j < nums.length; j++) { + if (nums[j] == 1) { + if (!flag) { + flag = true; + } + count++; + L[j] = count; + } else { + count = 0; + flag = false; + L[j] = count; + } + max = Math.max(max, count); + } + + flag = false; + count = 0; + for (int j = nums.length - 1; j >= 0; j--) { + if (nums[j] == 1) { + if (!flag) { + flag = true; + } + count++; + R[j] = count; + } else { + count = 0; + flag = false; + R[j] = count; + } + } + + for (int i = 0; i < nums.length; i++) { + if (nums[i] == 0) { + int l = i == 0 ? 0 : L[i - 1]; + int r = i == nums.length - 1 ? 0 : R[i + 1]; + max = Math.max(max, l + r + 1); + } + } + return max; + } +} diff --git a/problems/src/array/MaxProductOfThreeNumbers.java b/src/main/java/array/MaxProductOfThreeNumbers.java similarity index 96% rename from problems/src/array/MaxProductOfThreeNumbers.java rename to src/main/java/array/MaxProductOfThreeNumbers.java index 0658073c..eb3972d0 100644 --- a/problems/src/array/MaxProductOfThreeNumbers.java +++ b/src/main/java/array/MaxProductOfThreeNumbers.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.Arrays; diff --git a/src/main/java/array/MaximumSumofTwoNonOverlappingSubarrays.java b/src/main/java/array/MaximumSumofTwoNonOverlappingSubarrays.java new file mode 100644 index 00000000..bf2b7fdc --- /dev/null +++ b/src/main/java/array/MaximumSumofTwoNonOverlappingSubarrays.java @@ -0,0 +1,81 @@ +/* (C) 2024 YourCompanyName */ +package array; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 15/08/2019 Given an array A of non-negative integers, return + * the maximum sum of elements in two non-overlapping (contiguous) subarrays, which have lengths L + * and M. (For clarification, the L-length subarray could occur before or after the M-length + * subarray.) + * + *

Formally, return the largest V for which V = (A[i] + A[i+1] + ... + A[i+L-1]) + (A[j] + A[j+1] + * + ... + A[j+M-1]) and either: + * + *

0 <= i < i + L - 1 < j < j + M - 1 < A.length, or 0 <= j < j + M - 1 < i < i + L - 1 < + * A.length. + * + *

Example 1: + * + *

Input: A = [0,6,5,2,2,5,1,9,4], L = 1, M = 2 Output: 20 Explanation: One choice of subarrays + * is [9] with length 1, and [6,5] with length 2. Example 2: + * + *

Input: A = [3,8,1,3,2,1,8,9,0], L = 3, M = 2 Output: 29 Explanation: One choice of subarrays + * is [3,8,1] with length 3, and [8,9] with length 2. Example 3: + * + *

Input: A = [2,1,5,6,0,9,5,0,3,8], L = 4, M = 3 Output: 31 Explanation: One choice of subarrays + * is [5,6,0,9] with length 4, and [3,8] with length 3. + * + *

Note: + * + *

L >= 1 M >= 1 L + M <= A.length <= 1000 0 <= A[i] <= 1000 Solution O(N ^ 2) Find prefix sum of + * array of length L and array of length M and keep track of their begin and end indices. Now, + * brute-force compare pairs of prefix array sum where their indices don't overlap and return the + * max possible answer. + */ +public class MaximumSumofTwoNonOverlappingSubarrays { + public static void main(String[] args) { + int[] A = {2, 1, 5, 6, 0, 9, 5, 0, 3, 8}; + System.out.println(new MaximumSumofTwoNonOverlappingSubarrays().maxSumTwoNoOverlap(A, 4, 3)); + } + + class MaxWithIndex { + int max, i, j; + + MaxWithIndex(int max, int i, int j) { + this.max = max; + this.i = i; + this.j = j; + } + } + + public int maxSumTwoNoOverlap(int[] A, int L, int M) { + List first = getMax(A, L); + List second = getMax(A, M); + int max = 0; + for (MaxWithIndex f : first) { + for (MaxWithIndex s : second) { + if (f.j < s.i || s.j < f.i) { + max = Math.max(max, f.max + s.max); + } + } + } + return max; + } + + private List getMax(int[] A, int L) { + List list = new ArrayList<>(); + int i = 0, j = L; + int sum = 0; + for (; i < L; i++) { + sum += A[i]; + } + list.add(new MaxWithIndex(sum, 0, j - 1)); + for (i = 1; j < A.length; i++, j++) { + sum -= A[i - 1]; + sum += A[j]; + list.add(new MaxWithIndex(sum, i, j)); + } + return list; + } +} diff --git a/problems/src/array/MaximumSwap.java b/src/main/java/array/MaximumSwap.java similarity index 97% rename from problems/src/array/MaximumSwap.java rename to src/main/java/array/MaximumSwap.java index df8df20e..8093da65 100644 --- a/problems/src/array/MaximumSwap.java +++ b/src/main/java/array/MaximumSwap.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/MeetingRooms.java b/src/main/java/array/MeetingRooms.java similarity index 97% rename from problems/src/array/MeetingRooms.java rename to src/main/java/array/MeetingRooms.java index ee7d2dd8..b5626f4a 100644 --- a/problems/src/array/MeetingRooms.java +++ b/src/main/java/array/MeetingRooms.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.Arrays; diff --git a/src/main/java/array/MeetingScheduler.java b/src/main/java/array/MeetingScheduler.java new file mode 100644 index 00000000..1039599c --- /dev/null +++ b/src/main/java/array/MeetingScheduler.java @@ -0,0 +1,87 @@ +/* (C) 2024 YourCompanyName */ +package array; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 19/11/2019 Given the availability time slots arrays slots1 and + * slots2 of two people and a meeting duration duration, return the earliest time slot that works + * for both of them and is of duration duration. + * + *

If there is no common time slot that satisfies the requirements, return an empty array. + * + *

The format of a time slot is an array of two elements [start, end] representing an inclusive + * time range from start to end. + * + *

It is guaranteed that no two availability slots of the same person intersect with each other. + * That is, for any two time slots [start1, end1] and [start2, end2] of the same person, either + * start1 > end2 or start2 > end1. + * + *

Example 1: + * + *

Input: slots1 = [[10,50],[60,120],[140,210]], slots2 = [[0,15],[60,70]], duration = 8 Output: + * [60,68] Example 2: + * + *

Input: slots1 = [[10,50],[60,120],[140,210]], slots2 = [[0,15],[60,70]], duration = 12 Output: + * [] + * + *

Constraints: + * + *

1 <= slots1.length, slots2.length <= 10^4 slots1[i].length, slots2[i].length == 2 slots1[i][0] + * < slots1[i][1] slots2[i][0] < slots2[i][1] 0 <= slots1[i][j], slots2[i][j] <= 10^9 1 <= duration + * <= 10^6 + */ +public class MeetingScheduler { + public static void main(String[] args) { + int[][] slots1 = {{10, 50}, {60, 120}, {140, 210}}; + int[][] slots2 = {{0, 15}, {60, 70}}; + List result = new MeetingScheduler().minAvailableDuration(slots1, slots2, 12); + System.out.println(); + } + + private class Node { + int s, e, type; + + Node(int s, int e, int type) { + this.s = s; + this.e = e; + this.type = type; + } + } + + public List minAvailableDuration(int[][] slots1, int[][] slots2, int duration) { + PriorityQueue pq = + new PriorityQueue<>( + (o1, o2) -> { + int r = Integer.compare(o1.s, o2.s); + if (r == 0) { + return Integer.compare(o1.e, o2.e); + } else return r; + }); + for (int[] s : slots1) { + pq.offer(new Node(s[0], s[1], 1)); + } + for (int[] s : slots2) { + pq.offer(new Node(s[0], s[1], 2)); + } + Node prev = null; + while (!pq.isEmpty()) { + Node node = pq.poll(); + if (prev == null) { + prev = node; + } else { + if (prev.type != node.type) { + int s = Math.max(prev.s, node.s); + int e = Math.min(prev.e, node.e); + if ((e - s) >= duration) { + return Arrays.asList(s, s + duration); + } + } + if (node.e > prev.e) { + prev = node; + } + } + } + return new ArrayList<>(); + } +} diff --git a/problems/src/array/MergeIntervals.java b/src/main/java/array/MergeIntervals.java similarity index 98% rename from problems/src/array/MergeIntervals.java rename to src/main/java/array/MergeIntervals.java index c8638b32..d3657670 100644 --- a/problems/src/array/MergeIntervals.java +++ b/src/main/java/array/MergeIntervals.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.ArrayList; diff --git a/problems/src/array/MergeSortedArray.java b/src/main/java/array/MergeSortedArray.java similarity index 96% rename from problems/src/array/MergeSortedArray.java rename to src/main/java/array/MergeSortedArray.java index 6121ed33..472fb9e2 100644 --- a/problems/src/array/MergeSortedArray.java +++ b/src/main/java/array/MergeSortedArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/MinimumIndexSumOfTwoLists.java b/src/main/java/array/MinimumIndexSumOfTwoLists.java similarity index 98% rename from problems/src/array/MinimumIndexSumOfTwoLists.java rename to src/main/java/array/MinimumIndexSumOfTwoLists.java index 771a1db3..a550910b 100644 --- a/problems/src/array/MinimumIndexSumOfTwoLists.java +++ b/src/main/java/array/MinimumIndexSumOfTwoLists.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.ArrayList; diff --git a/problems/src/array/MinimumMovesToEqualArray.java b/src/main/java/array/MinimumMovesToEqualArray.java similarity index 98% rename from problems/src/array/MinimumMovesToEqualArray.java rename to src/main/java/array/MinimumMovesToEqualArray.java index a431b840..c65394d6 100644 --- a/problems/src/array/MinimumMovesToEqualArray.java +++ b/src/main/java/array/MinimumMovesToEqualArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.Arrays; diff --git a/src/main/java/array/MinimumSwapsToGroupAll1Together.java b/src/main/java/array/MinimumSwapsToGroupAll1Together.java new file mode 100644 index 00000000..c1d699e6 --- /dev/null +++ b/src/main/java/array/MinimumSwapsToGroupAll1Together.java @@ -0,0 +1,62 @@ +/* (C) 2024 YourCompanyName */ +package array; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 23/10/2019 Given a binary array data, return the minimum number + * of swaps required to group all 1’s present in the array together in any place in the array. + * + *

Example 1: + * + *

Input: [1,0,1,0,1] Output: 1 Explanation: There are 3 ways to group all 1's together: + * [1,1,1,0,0] using 1 swap. [0,1,1,1,0] using 2 swaps. [0,0,1,1,1] using 1 swap. The minimum is 1. + * Example 2: + * + *

Input: [0,0,0,1,0] Output: 0 Explanation: Since there is only one 1 in the array, no swaps + * needed. Example 3: + * + *

Input: [1,0,1,0,1,0,0,1,1,0,1] Output: 3 Explanation: One possible solution that uses 3 swaps + * is [0,0,0,0,0,1,1,1,1,1,1]. Solution: O(N) All the 1s to be grouped together would mean that all + * 1s should occupy a small window in a array, this window could be in any part of the array - a + * window with minimum number of 0s is the minimum number of swap required. + */ +public class MinimumSwapsToGroupAll1Together { + public static void main(String[] args) { + // + } + + public int minSwaps(int[] data) { + int one = 0; + int zero = 0; + for (int i = 0; i < data.length; i++) { + if (data[i] == 1) { + one++; + } else zero++; + } + if (one == 0) return 0; + int window = one; + one = 0; + zero = 0; + int i = 0, j = window - 1; + for (int k = i; k <= j; k++) { + if (data[k] == 1) { + one++; + } else zero++; + } + i++; + j++; + int min = zero; + for (; j < data.length; i++, j++) { + if (data[j] == 0) { + zero++; + } else one++; + + if (data[i - 1] == 0) { + zero--; + } else one--; + min = Math.min(min, zero); + } + return min; + } +} diff --git a/src/main/java/array/MinimumTimeDifference.java b/src/main/java/array/MinimumTimeDifference.java new file mode 100644 index 00000000..92acfd51 --- /dev/null +++ b/src/main/java/array/MinimumTimeDifference.java @@ -0,0 +1,48 @@ +/* (C) 2024 YourCompanyName */ +package array; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * Created by gouthamvidyapradhan on 30/07/2019 Given a list of 24-hour clock time points in + * "Hour:Minutes" format, find the minimum minutes difference between any two time points in the + * list. Example 1: Input: ["23:59","00:00"] Output: 1 Note: The number of time points in the given + * list is at least 2 and won't exceed 20000. The input time is legal and ranges from 00:00 to + * 23:59. + * + *

Solution: O(N log N) convert each time value of the form hh:mm to minutes and sort the array. + * For every pair (i, j) where j = i + 1 (also for the case where i = 0 and j = N - 1) check the + * minute difference and return the minimum time difference as the answer. + */ +public class MinimumTimeDifference { + public static void main(String[] args) { + List list = Arrays.asList("23:59", "00:00"); + System.out.println(new MinimumTimeDifference().findMinDifference(list)); + } + + public int findMinDifference(List timePoints) { + List timeInMinutes = + timePoints + .stream() + .map( + t -> { + String[] strings = t.split(":"); + return Integer.parseInt(strings[0]) * 60 + Integer.parseInt(strings[1]); + }) + .sorted(Integer::compareTo) + .collect(Collectors.toList()); + int min = Integer.MAX_VALUE; + for (int i = 1, l = timeInMinutes.size(); i < l; i++) { + int prev = timeInMinutes.get(i - 1); + int curr = timeInMinutes.get(i); + min = Math.min(min, curr - prev); + min = Math.min(min, ((24 * 60) - curr) + prev); + } + int prev = timeInMinutes.get(0); + int curr = timeInMinutes.get(timeInMinutes.size() - 1); + min = Math.min(min, curr - prev); + min = Math.min(min, ((24 * 60) - curr) + prev); + return min; + } +} diff --git a/problems/src/array/MissingNumber.java b/src/main/java/array/MissingNumber.java similarity index 96% rename from problems/src/array/MissingNumber.java rename to src/main/java/array/MissingNumber.java index 3be7a426..9532902b 100644 --- a/problems/src/array/MissingNumber.java +++ b/src/main/java/array/MissingNumber.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/MyCalendarThree.java b/src/main/java/array/MyCalendarThree.java similarity index 98% rename from problems/src/array/MyCalendarThree.java rename to src/main/java/array/MyCalendarThree.java index 335341c3..267eb8ea 100644 --- a/problems/src/array/MyCalendarThree.java +++ b/src/main/java/array/MyCalendarThree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.*; diff --git a/problems/src/array/NextGreaterElementI.java b/src/main/java/array/NextGreaterElementI.java similarity index 98% rename from problems/src/array/NextGreaterElementI.java rename to src/main/java/array/NextGreaterElementI.java index 9021407c..33c7f426 100644 --- a/problems/src/array/NextGreaterElementI.java +++ b/src/main/java/array/NextGreaterElementI.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/PascalsTriangle.java b/src/main/java/array/PascalsTriangle.java similarity index 97% rename from problems/src/array/PascalsTriangle.java rename to src/main/java/array/PascalsTriangle.java index be60ed1d..32c8ada8 100644 --- a/problems/src/array/PascalsTriangle.java +++ b/src/main/java/array/PascalsTriangle.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.ArrayList; diff --git a/problems/src/array/PourWater.java b/src/main/java/array/PourWater.java similarity index 99% rename from problems/src/array/PourWater.java rename to src/main/java/array/PourWater.java index aa377d8b..e0c5ed20 100644 --- a/problems/src/array/PourWater.java +++ b/src/main/java/array/PourWater.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/ProductOfArrayExceptSelf.java b/src/main/java/array/ProductOfArrayExceptSelf.java similarity index 97% rename from problems/src/array/ProductOfArrayExceptSelf.java rename to src/main/java/array/ProductOfArrayExceptSelf.java index d9ebac09..e905ce2f 100644 --- a/problems/src/array/ProductOfArrayExceptSelf.java +++ b/src/main/java/array/ProductOfArrayExceptSelf.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/ReadNCharacters.java b/src/main/java/array/ReadNCharacters.java similarity index 97% rename from problems/src/array/ReadNCharacters.java rename to src/main/java/array/ReadNCharacters.java index fc58afae..75017539 100644 --- a/problems/src/array/ReadNCharacters.java +++ b/src/main/java/array/ReadNCharacters.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/RelativeRanks.java b/src/main/java/array/RelativeRanks.java similarity index 98% rename from problems/src/array/RelativeRanks.java rename to src/main/java/array/RelativeRanks.java index 9423baa7..adfbf31f 100644 --- a/problems/src/array/RelativeRanks.java +++ b/src/main/java/array/RelativeRanks.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.ArrayList; diff --git a/src/main/java/array/RelativeSortArray.java b/src/main/java/array/RelativeSortArray.java new file mode 100644 index 00000000..8244f7c0 --- /dev/null +++ b/src/main/java/array/RelativeSortArray.java @@ -0,0 +1,61 @@ +/* (C) 2024 YourCompanyName */ +package array; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 05/12/2019 Given two arrays arr1 and arr2, the elements of arr2 + * are distinct, and all elements in arr2 are also in arr1. + * + *

Sort the elements of arr1 such that the relative ordering of items in arr1 are the same as in + * arr2. Elements that don't appear in arr2 should be placed at the end of arr1 in ascending order. + * + *

Example 1: + * + *

Input: arr1 = [2,3,1,3,2,4,6,7,9,2,19], arr2 = [2,1,4,3,9,6] Output: [2,2,2,1,4,3,3,9,6,7,19] + * + *

Constraints: + * + *

arr1.length, arr2.length <= 1000 0 <= arr1[i], arr2[i] <= 1000 Each arr2[i] is distinct. Each + * arr2[i] is in arr1. + */ +public class RelativeSortArray { + public static void main(String[] args) { + // + } + + public int[] relativeSortArray(int[] arr1, int[] arr2) { + List notPresent = new ArrayList<>(); + Map map = new HashMap<>(); + Set set = new HashSet<>(); + for (int i : arr2) { + set.add(i); + } + for (int i : arr1) { + map.putIfAbsent(i, 0); + map.put(i, map.get(i) + 1); + } + List result = new ArrayList<>(); + for (int i : arr2) { + int count = map.get(i); + for (int j = 0; j < count; j++) { + result.add(i); + } + } + for (int k : map.keySet()) { + if (!set.contains(k)) { + int count = map.get(k); + for (int i = 0; i < count; i++) { + notPresent.add(k); + } + } + } + notPresent.sort(Comparator.comparingInt(o -> o)); + result.addAll(notPresent); + int[] resA = new int[result.size()]; + for (int i = 0; i < result.size(); i++) { + resA[i] = result.get(i); + } + return resA; + } +} diff --git a/src/main/java/array/RevealCardsInIncreasingOrder.java b/src/main/java/array/RevealCardsInIncreasingOrder.java new file mode 100644 index 00000000..dea70a6d --- /dev/null +++ b/src/main/java/array/RevealCardsInIncreasingOrder.java @@ -0,0 +1,63 @@ +/* (C) 2024 YourCompanyName */ +package array; + +import java.util.ArrayDeque; +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 12/08/2019 In a deck of cards, every card has a unique integer. + * You can order the deck in any order you want. + * + *

Initially, all the cards start face down (unrevealed) in one deck. + * + *

Now, you do the following steps repeatedly, until all cards are revealed: + * + *

Take the top card of the deck, reveal it, and take it out of the deck. If there are still + * cards in the deck, put the next top card of the deck at the bottom of the deck. If there are + * still unrevealed cards, go back to step 1. Otherwise, stop. Return an ordering of the deck that + * would reveal the cards in increasing order. + * + *

The first entry in the answer is considered to be the top of the deck. + * + *

Example 1: + * + *

Input: [17,13,11,2,3,5,7] Output: [2,13,3,11,5,17,7] Explanation: We get the deck in the order + * [17,13,11,2,3,5,7] (this order doesn't matter), and reorder it. After reordering, the deck starts + * as [2,13,3,11,5,17,7], where 2 is the top of the deck. We reveal 2, and move 13 to the bottom. + * The deck is now [3,11,5,17,7,13]. We reveal 3, and move 11 to the bottom. The deck is now + * [5,17,7,13,11]. We reveal 5, and move 17 to the bottom. The deck is now [7,13,11,17]. We reveal + * 7, and move 13 to the bottom. The deck is now [11,17,13]. We reveal 11, and move 17 to the + * bottom. The deck is now [13,17]. We reveal 13, and move 17 to the bottom. The deck is now [17]. + * We reveal 17. Since all the cards revealed are in increasing order, the answer is correct. + * + *

Note: + * + *

1 <= A.length <= 1000 1 <= A[i] <= 10^6 A[i] != A[j] for all i != j + * + *

Solution: O(N) General idea is to start from the last element and build the array of element + * in the backwards order. Use a doubly-ended queue which allows you to poll from either end of a + * queue. + */ +public class RevealCardsInIncreasingOrder { + public static void main(String[] args) { + int[] A = {17, 13, 11, 2, 3, 5, 7}; + int[] R = new RevealCardsInIncreasingOrder().deckRevealedIncreasing(A); + } + + public int[] deckRevealedIncreasing(int[] deck) { + Arrays.sort(deck); + ArrayDeque queue = new ArrayDeque<>(); + for (int i = deck.length - 1; i >= 0; i--) { + queue.offer(deck[i]); + if (i == 0) break; + int temp = queue.pollFirst(); + queue.offer(temp); + } + int[] answer = new int[deck.length]; + int i = 0; + while (!queue.isEmpty()) { + answer[i++] = queue.pollLast(); + } + return answer; + } +} diff --git a/problems/src/array/RotateArray.java b/src/main/java/array/RotateArray.java similarity index 97% rename from problems/src/array/RotateArray.java rename to src/main/java/array/RotateArray.java index 4b809291..863c60f1 100644 --- a/problems/src/array/RotateArray.java +++ b/src/main/java/array/RotateArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/RotateMatrix.java b/src/main/java/array/RotateMatrix.java similarity index 97% rename from problems/src/array/RotateMatrix.java rename to src/main/java/array/RotateMatrix.java index 367e9c1c..42251de7 100644 --- a/problems/src/array/RotateMatrix.java +++ b/src/main/java/array/RotateMatrix.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/SetMatrixZeroes.java b/src/main/java/array/SetMatrixZeroes.java similarity index 97% rename from problems/src/array/SetMatrixZeroes.java rename to src/main/java/array/SetMatrixZeroes.java index 4a80b448..c30b919e 100644 --- a/problems/src/array/SetMatrixZeroes.java +++ b/src/main/java/array/SetMatrixZeroes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.HashSet; diff --git a/src/main/java/array/SortArrayByParityII.java b/src/main/java/array/SortArrayByParityII.java new file mode 100644 index 00000000..b3fea546 --- /dev/null +++ b/src/main/java/array/SortArrayByParityII.java @@ -0,0 +1,44 @@ +/* (C) 2024 YourCompanyName */ +package array; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 20/08/2019 Given an array A of non-negative integers, half of + * the integers in A are odd, and half of the integers are even. + * + *

Sort the array so that whenever A[i] is odd, i is odd; and whenever A[i] is even, i is even. + * + *

You may return any answer array that satisfies this condition. + * + *

Example 1: + * + *

Input: [4,2,5,7] Output: [4,5,2,7] Explanation: [4,7,2,5], [2,5,4,7], [2,7,4,5] would also + * have been accepted. + * + *

Note: + * + *

2 <= A.length <= 20000 A.length % 2 == 0 0 <= A[i] <= 1000 Solution: O(N) straight forward + * linear solution, keep track of odd and even indices and increment by 2 every time a value is + * added at the index. + */ +public class SortArrayByParityII { + public static void main(String[] args) { + // + } + + public int[] sortArrayByParityII(int[] A) { + int[] R = new int[A.length]; + int i = 0, j = 1; + for (int a : A) { + if (a % 2 == 0) { + R[i] = a; + i += 2; + } else { + R[j] = a; + j += 2; + } + } + return R; + } +} diff --git a/problems/src/array/SortColors.java b/src/main/java/array/SortColors.java similarity index 98% rename from problems/src/array/SortColors.java rename to src/main/java/array/SortColors.java index dc9c7e39..14d563c2 100644 --- a/problems/src/array/SortColors.java +++ b/src/main/java/array/SortColors.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/SparseMatrixMultiplication.java b/src/main/java/array/SparseMatrixMultiplication.java similarity index 98% rename from problems/src/array/SparseMatrixMultiplication.java rename to src/main/java/array/SparseMatrixMultiplication.java index 04f6c8ed..c8d2f669 100644 --- a/problems/src/array/SparseMatrixMultiplication.java +++ b/src/main/java/array/SparseMatrixMultiplication.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/SubArraysWithBoundedMaximum.java b/src/main/java/array/SubArraysWithBoundedMaximum.java similarity index 98% rename from problems/src/array/SubArraysWithBoundedMaximum.java rename to src/main/java/array/SubArraysWithBoundedMaximum.java index 5ed30588..05baf09a 100644 --- a/problems/src/array/SubArraysWithBoundedMaximum.java +++ b/src/main/java/array/SubArraysWithBoundedMaximum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/SubarraySumEqualsK.java b/src/main/java/array/SubarraySumEqualsK.java similarity index 98% rename from problems/src/array/SubarraySumEqualsK.java rename to src/main/java/array/SubarraySumEqualsK.java index 282c1f80..3cd9ca34 100644 --- a/problems/src/array/SubarraySumEqualsK.java +++ b/src/main/java/array/SubarraySumEqualsK.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.HashMap; diff --git a/problems/src/array/SurfaceAreaOfThreeDShapes.java b/src/main/java/array/SurfaceAreaOfThreeDShapes.java similarity index 98% rename from problems/src/array/SurfaceAreaOfThreeDShapes.java rename to src/main/java/array/SurfaceAreaOfThreeDShapes.java index 2f35ef3d..9c646c68 100644 --- a/problems/src/array/SurfaceAreaOfThreeDShapes.java +++ b/src/main/java/array/SurfaceAreaOfThreeDShapes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/ThirdMaximumNumber.java b/src/main/java/array/ThirdMaximumNumber.java similarity index 98% rename from problems/src/array/ThirdMaximumNumber.java rename to src/main/java/array/ThirdMaximumNumber.java index 59259b33..ba0e42c4 100644 --- a/problems/src/array/ThirdMaximumNumber.java +++ b/src/main/java/array/ThirdMaximumNumber.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/TwoSum.java b/src/main/java/array/TwoSum.java similarity index 98% rename from problems/src/array/TwoSum.java rename to src/main/java/array/TwoSum.java index 546b04ff..3b45668e 100644 --- a/problems/src/array/TwoSum.java +++ b/src/main/java/array/TwoSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; import java.util.ArrayList; diff --git a/problems/src/array/TwoSumII.java b/src/main/java/array/TwoSumII.java similarity index 97% rename from problems/src/array/TwoSumII.java rename to src/main/java/array/TwoSumII.java index b7a3fe3c..837dba97 100644 --- a/problems/src/array/TwoSumII.java +++ b/src/main/java/array/TwoSumII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/array/ValidTicTacToeState.java b/src/main/java/array/ValidTicTacToeState.java similarity index 98% rename from problems/src/array/ValidTicTacToeState.java rename to src/main/java/array/ValidTicTacToeState.java index 6d2fa83c..22bc822b 100644 --- a/problems/src/array/ValidTicTacToeState.java +++ b/src/main/java/array/ValidTicTacToeState.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package array; /** diff --git a/problems/src/backtracking/CombinationSum.java b/src/main/java/backtracking/CombinationSum.java similarity index 98% rename from problems/src/backtracking/CombinationSum.java rename to src/main/java/backtracking/CombinationSum.java index 0ec28dc3..281dda21 100644 --- a/problems/src/backtracking/CombinationSum.java +++ b/src/main/java/backtracking/CombinationSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/problems/src/backtracking/CombinationSumII.java b/src/main/java/backtracking/CombinationSumII.java similarity index 98% rename from problems/src/backtracking/CombinationSumII.java rename to src/main/java/backtracking/CombinationSumII.java index 30fd2d20..4fa9f73d 100644 --- a/problems/src/backtracking/CombinationSumII.java +++ b/src/main/java/backtracking/CombinationSumII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/problems/src/backtracking/Combinations.java b/src/main/java/backtracking/Combinations.java similarity index 97% rename from problems/src/backtracking/Combinations.java rename to src/main/java/backtracking/Combinations.java index 625ed94e..613c832e 100644 --- a/problems/src/backtracking/Combinations.java +++ b/src/main/java/backtracking/Combinations.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/problems/src/backtracking/ExpressionAddOperators.java b/src/main/java/backtracking/ExpressionAddOperators.java similarity index 98% rename from problems/src/backtracking/ExpressionAddOperators.java rename to src/main/java/backtracking/ExpressionAddOperators.java index 1a61b49e..33d74351 100644 --- a/problems/src/backtracking/ExpressionAddOperators.java +++ b/src/main/java/backtracking/ExpressionAddOperators.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/problems/src/backtracking/GenerateParentheses.java b/src/main/java/backtracking/GenerateParentheses.java similarity index 97% rename from problems/src/backtracking/GenerateParentheses.java rename to src/main/java/backtracking/GenerateParentheses.java index 9d61c2a3..6de5d66f 100644 --- a/problems/src/backtracking/GenerateParentheses.java +++ b/src/main/java/backtracking/GenerateParentheses.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/problems/src/backtracking/LetterCasePermutation.java b/src/main/java/backtracking/LetterCasePermutation.java similarity index 98% rename from problems/src/backtracking/LetterCasePermutation.java rename to src/main/java/backtracking/LetterCasePermutation.java index b5b09c56..935e27eb 100644 --- a/problems/src/backtracking/LetterCasePermutation.java +++ b/src/main/java/backtracking/LetterCasePermutation.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/problems/src/backtracking/LetterPhoneNumber.java b/src/main/java/backtracking/LetterPhoneNumber.java similarity index 98% rename from problems/src/backtracking/LetterPhoneNumber.java rename to src/main/java/backtracking/LetterPhoneNumber.java index b32a09eb..e63a38fa 100644 --- a/problems/src/backtracking/LetterPhoneNumber.java +++ b/src/main/java/backtracking/LetterPhoneNumber.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/src/main/java/backtracking/MatchsticksToSquare.java b/src/main/java/backtracking/MatchsticksToSquare.java new file mode 100644 index 00000000..4e79a9ba --- /dev/null +++ b/src/main/java/backtracking/MatchsticksToSquare.java @@ -0,0 +1,117 @@ +/* (C) 2024 YourCompanyName */ +package backtracking; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 25/05/2019 Remember the story of Little Match Girl? By now, you + * know exactly what matchsticks the little match girl has, please find out a way you can make one + * square by using up all those matchsticks. You should not break any stick, but you can link them + * up, and each matchstick must be used exactly one time. + * + *

Your input will be several matchsticks the girl has, represented with their stick length. Your + * output will either be true or false, to represent whether you could make one square using all the + * matchsticks the little match girl has. + * + *

Example 1: Input: [1,1,2,2,2] Output: true + * + *

Explanation: You can form a square with length 2, one side of the square came two sticks with + * length 1. Example 2: Input: [3,3,3,3,4] Output: false + * + *

Explanation: You cannot find a way to form a square with all the matchsticks. Note: The length + * sum of the given matchsticks is in the range of 0 to 10^9. The length of the given matchstick + * array will not exceed 15. + * + *

Solution: O(2 ^ N): Generate a power set of all combination of numbers for the given array + * which sum up to the length of a side of square. Now, to check if a square can be made using all + * the sides sticks of different length, generate a hash for for each of the combination which was + * generated in the previous step. The hash function should be such that it uses unique indexes of + * each match stick. If 4 different hash values are formed using unique and all indices then a + * square is possible. + */ +public class MatchsticksToSquare { + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[] A = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 6, 10, 10}; + System.out.println(new MatchsticksToSquare().makesquare(A)); + } + + class Pair { + int value, i; + + Pair(int value, int i) { + this.value = value; + this.i = i; + } + } + + public boolean makesquare(int[] nums) { + if (nums.length == 0) return false; + int sum = 0; + for (int n : nums) { + sum += n; + } + int side = sum / 4; + if ((sum % 4) != 0) return false; + List> list = powerSet(nums, side); + Set hashIndex = new HashSet<>(); + int cons = 0; + for (int i = 0; i < nums.length; i++) { + cons |= (1 << i); + } + for (int i = 0; i < list.size(); i++) { + for (int j = i + 1; j < list.size(); j++) { + Set indexList = new HashSet<>(); + List list1 = list.get(i); + List list2 = list.get(j); + int hash = 0; + for (Pair l1 : list1) { + indexList.add(l1.i); + hash |= (1 << l1.i); + } + boolean allUnique = true; + for (Pair l2 : list2) { + if (indexList.contains(l2.i)) { + allUnique = false; + break; + } + indexList.add(l2.i); + hash |= (1 << l2.i); + } + if (allUnique) { + hashIndex.add(hash); + int complement = ((~hash) & cons); + if (hashIndex.contains(complement)) return true; + } + } + } + return false; + } + + private List> powerSet(int[] nums, int expectedSum) { + List> result = new ArrayList<>(); + generate(0, nums, new ArrayList<>(), result, 0, expectedSum); + return result; + } + + private void generate( + int i, int[] nums, List subList, List> result, int sum, int expected) { + if (i >= nums.length) { + if (sum == expected) { + List pairs = new ArrayList<>(subList); + result.add(pairs); + } + } else { + if (sum + nums[i] <= expected) { + subList.add(new Pair(nums[i], i)); + generate(i + 1, nums, subList, result, sum + nums[i], expected); + subList.remove(subList.size() - 1); + } + generate(i + 1, nums, subList, result, sum, expected); + } + } +} diff --git a/problems/src/backtracking/PalindromePartitioning.java b/src/main/java/backtracking/PalindromePartitioning.java similarity index 97% rename from problems/src/backtracking/PalindromePartitioning.java rename to src/main/java/backtracking/PalindromePartitioning.java index b3718570..f1aeb823 100644 --- a/problems/src/backtracking/PalindromePartitioning.java +++ b/src/main/java/backtracking/PalindromePartitioning.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/problems/src/backtracking/Permutations.java b/src/main/java/backtracking/Permutations.java similarity index 97% rename from problems/src/backtracking/Permutations.java rename to src/main/java/backtracking/Permutations.java index 5509d3d1..13a26e37 100644 --- a/problems/src/backtracking/Permutations.java +++ b/src/main/java/backtracking/Permutations.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/problems/src/backtracking/PermutationsII.java b/src/main/java/backtracking/PermutationsII.java similarity index 97% rename from problems/src/backtracking/PermutationsII.java rename to src/main/java/backtracking/PermutationsII.java index 27f55f8e..56a9f5ca 100644 --- a/problems/src/backtracking/PermutationsII.java +++ b/src/main/java/backtracking/PermutationsII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/problems/src/backtracking/RegularExpressionMatching.java b/src/main/java/backtracking/RegularExpressionMatching.java similarity index 98% rename from problems/src/backtracking/RegularExpressionMatching.java rename to src/main/java/backtracking/RegularExpressionMatching.java index 0db4538b..c31929f7 100644 --- a/problems/src/backtracking/RegularExpressionMatching.java +++ b/src/main/java/backtracking/RegularExpressionMatching.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; /** diff --git a/problems/src/backtracking/RemoveInvalidParentheses.java b/src/main/java/backtracking/RemoveInvalidParentheses.java similarity index 98% rename from problems/src/backtracking/RemoveInvalidParentheses.java rename to src/main/java/backtracking/RemoveInvalidParentheses.java index 2ab68beb..145dee39 100644 --- a/problems/src/backtracking/RemoveInvalidParentheses.java +++ b/src/main/java/backtracking/RemoveInvalidParentheses.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/problems/src/backtracking/Subsets.java b/src/main/java/backtracking/Subsets.java similarity index 97% rename from problems/src/backtracking/Subsets.java rename to src/main/java/backtracking/Subsets.java index 03956e3e..3251446a 100644 --- a/problems/src/backtracking/Subsets.java +++ b/src/main/java/backtracking/Subsets.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/problems/src/backtracking/SubsetsII.java b/src/main/java/backtracking/SubsetsII.java similarity index 97% rename from problems/src/backtracking/SubsetsII.java rename to src/main/java/backtracking/SubsetsII.java index daa83bf9..76d4e7b2 100644 --- a/problems/src/backtracking/SubsetsII.java +++ b/src/main/java/backtracking/SubsetsII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.ArrayList; diff --git a/problems/src/backtracking/TargetSum.java b/src/main/java/backtracking/TargetSum.java similarity index 97% rename from problems/src/backtracking/TargetSum.java rename to src/main/java/backtracking/TargetSum.java index dce00652..e586d33a 100644 --- a/problems/src/backtracking/TargetSum.java +++ b/src/main/java/backtracking/TargetSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; /** diff --git a/problems/src/backtracking/WildcardMatching.java b/src/main/java/backtracking/WildcardMatching.java similarity index 98% rename from problems/src/backtracking/WildcardMatching.java rename to src/main/java/backtracking/WildcardMatching.java index 90b383bd..811aee77 100644 --- a/problems/src/backtracking/WildcardMatching.java +++ b/src/main/java/backtracking/WildcardMatching.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; /** diff --git a/problems/src/backtracking/WordSearch.java b/src/main/java/backtracking/WordSearch.java similarity index 98% rename from problems/src/backtracking/WordSearch.java rename to src/main/java/backtracking/WordSearch.java index 5fa5df91..c6c2abdd 100644 --- a/problems/src/backtracking/WordSearch.java +++ b/src/main/java/backtracking/WordSearch.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; /** diff --git a/problems/src/backtracking/WordSearchII.java b/src/main/java/backtracking/WordSearchII.java similarity index 99% rename from problems/src/backtracking/WordSearchII.java rename to src/main/java/backtracking/WordSearchII.java index 07377143..4cf67e8b 100644 --- a/problems/src/backtracking/WordSearchII.java +++ b/src/main/java/backtracking/WordSearchII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package backtracking; import java.util.*; diff --git a/src/main/java/backtracking/ZumaGame.java b/src/main/java/backtracking/ZumaGame.java new file mode 100644 index 00000000..5d905143 --- /dev/null +++ b/src/main/java/backtracking/ZumaGame.java @@ -0,0 +1,94 @@ +/* (C) 2024 YourCompanyName */ +package backtracking; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 14/05/2019 Think about Zuma Game. You have a row of balls on + * the table, colored red(R), yellow(Y), blue(B), green(G), and white(W). You also have several + * balls in your hand. + * + *

Each time, you may choose a ball in your hand, and insert it into the row (including the + * leftmost place and rightmost place). Then, if there is a group of 3 or more balls in the same + * color touching, remove these balls. Keep doing this until no more balls can be removed. + * + *

Find the minimal balls you have to insert to remove all the balls on the table. If you cannot + * remove all the balls, output -1. + * + *

Examples: + * + *

Input: "WRRBBW", "RB" Output: -1 Explanation: WRRBBW -> WRR[R]BBW -> WBBW -> WBB[B]W -> WW + * + *

Input: "WWRRBBWW", "WRBRW" Output: 2 Explanation: WWRRBBWW -> WWRR[R]BBWW -> WWBBWW -> + * WWBB[B]WW -> WWWW -> empty + * + *

Input:"G", "GGGGG" Output: 2 Explanation: G -> G[G] -> GG[G] -> empty + * + *

Input: "RBYYBBRRB", "YRBGB" Output: 3 Explanation: RBYYBBRRB -> RBYY[Y]BBRRB -> RBBBRRB -> + * RRRB -> B -> B[B] -> BB[B] -> empty + * + *

Note: You may assume that the initial row of balls on the table won’t have any 3 or more + * consecutive balls with the same color. The number of balls on the table won't exceed 20, and the + * string represents these balls is called "board" in the input. The number of balls in your hand + * won't exceed 5, and the string represents these balls is called "hand" in the input. Both input + * strings will be non-empty and only contain characters 'R','Y','B','G','W'. + * + *

Solution: Maintain a count of each colored balls. Reduce the string to a new string by + * removing the contiguous same coloured balls which exceeds the count of 3 starting from index i = + * 0. Each new string formed (by adding a new ball to a position i) makes a new state. Backtrack and + * traverse the search space and keep track of count of balls used. Maintain a minimum count + * variable and return that as the answer. + */ +public class ZumaGame { + public static void main(String[] args) { + System.out.println(new ZumaGame().findMinStep("BBWWRRYYRRWWBB", "Y")); + } + + Map map; + int min = Integer.MAX_VALUE; + + public int findMinStep(String board, String hand) { + map = new HashMap<>(); + for (char c : hand.toCharArray()) { + map.putIfAbsent(c, 0); + map.put(c, map.get(c) + 1); + } + backtrack(board, 0); + return min == Integer.MAX_VALUE ? -1 : min; + } + + private void backtrack(String board, int total) { + if (board.isEmpty()) { + min = Math.min(min, total); + } else { + int i = 0, j = 0; + for (int l = board.length(); i < l; ) { + if (j < l && board.charAt(j) == board.charAt(i)) { + j++; + } else { + if (j - i > 2) { + backtrack(board.substring(0, i) + ((j < l) ? board.substring(j) : ""), total); + } else { + int a = j - i; + char c = board.charAt(i); + if (map.containsKey(c)) { + int count = map.get(c); + if (count >= (3 - a)) { + if ((count - (3 - a)) == 0) { + map.remove(c); + } else { + map.put(c, count - (3 - a)); + } + backtrack( + board.substring(0, i) + ((j < l) ? board.substring(j) : ""), total + (3 - a)); + map.put(c, count); + } + } + } + i = j; + j++; + } + } + } + } +} diff --git a/src/main/java/binary_search/ArmstrongNumber.java b/src/main/java/binary_search/ArmstrongNumber.java new file mode 100644 index 00000000..c3c13c8d --- /dev/null +++ b/src/main/java/binary_search/ArmstrongNumber.java @@ -0,0 +1,46 @@ +/* (C) 2024 YourCompanyName */ +package binary_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 26/11/2019 The k-digit number N is an Armstrong number if and + * only if the k-th power of each digit sums to N. + * + *

Given a positive integer N, return true if and only if it is an Armstrong number. + * + *

Example 1: + * + *

Input: 153 Output: true Explanation: 153 is a 3-digit number, and 153 = 1^3 + 5^3 + 3^3. + * Example 2: + * + *

Input: 123 Output: false Explanation: 123 is a 3-digit number, and 123 != 1^3 + 2^3 + 3^3 = + * 36. + * + *

Note: + * + *

1 <= N <= 10^8 + */ +public class ArmstrongNumber { + public static void main(String[] args) { + // + } + + public boolean isArmstrong(int N) { + int s = String.valueOf(N).length(); + long sum = 0; + for (char c : String.valueOf(N).toCharArray()) { + int i = Integer.parseInt(String.valueOf(c)); + sum += power(i, s); + } + return (sum == N); + } + + private long power(int n, int p) { + long res = 1L; + for (int i = 0; i < p; i++) { + res *= n; + } + return res; + } +} diff --git a/problems/src/binary_search/FindPeakElement.java b/src/main/java/binary_search/FindPeakElement.java similarity index 98% rename from problems/src/binary_search/FindPeakElement.java rename to src/main/java/binary_search/FindPeakElement.java index 8904353f..8c5b9d5e 100644 --- a/problems/src/binary_search/FindPeakElement.java +++ b/src/main/java/binary_search/FindPeakElement.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/problems/src/binary_search/FirstBadVersion.java b/src/main/java/binary_search/FirstBadVersion.java similarity index 97% rename from problems/src/binary_search/FirstBadVersion.java rename to src/main/java/binary_search/FirstBadVersion.java index b4dbb393..0e1c0a89 100644 --- a/problems/src/binary_search/FirstBadVersion.java +++ b/src/main/java/binary_search/FirstBadVersion.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/problems/src/binary_search/HIndexII.java b/src/main/java/binary_search/HIndexII.java similarity index 96% rename from problems/src/binary_search/HIndexII.java rename to src/main/java/binary_search/HIndexII.java index 9a9733ee..5450d3b3 100644 --- a/problems/src/binary_search/HIndexII.java +++ b/src/main/java/binary_search/HIndexII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/src/main/java/binary_search/KokoEatingBananas.java b/src/main/java/binary_search/KokoEatingBananas.java new file mode 100644 index 00000000..bd5c3400 --- /dev/null +++ b/src/main/java/binary_search/KokoEatingBananas.java @@ -0,0 +1,76 @@ +/* (C) 2024 YourCompanyName */ +package binary_search; + +/** + * Created by gouthamvidyapradhan on 23/08/2019 Koko loves to eat bananas. There are N piles of + * bananas, the i-th pile has piles[i] bananas. The guards have gone and will come back in H hours. + * + *

Koko can decide her bananas-per-hour eating speed of K. Each hour, she chooses some pile of + * bananas, and eats K bananas from that pile. If the pile has less than K bananas, she eats all of + * them instead, and won't eat any more bananas during this hour. + * + *

Koko likes to eat slowly, but still wants to finish eating all the bananas before the guards + * come back. + * + *

Return the minimum integer K such that she can eat all the bananas within H hours. + * + *

Example 1: + * + *

Input: piles = [3,6,7,11], H = 8 Output: 4 Example 2: + * + *

Input: piles = [30,11,23,4,20], H = 5 Output: 30 Example 3: + * + *

Input: piles = [30,11,23,4,20], H = 6 Output: 23 + * + *

Note: + * + *

1 <= piles.length <= 10^4 piles.length <= H <= 10^9 1 <= piles[i] <= 10^9 + * + *

Solution: O(N x log Max(piles[i])) Binary search for the minimum possible value between (1 and + * max(piles[i])) + */ +public class KokoEatingBananas { + public static void main(String[] args) { + int[] A = {312884470}; + System.out.println(new KokoEatingBananas().minEatingSpeed(A, 968709470)); + } + + public int minEatingSpeed(int[] piles, int H) { + int max = 0; + for (int i = 0; i < piles.length; i++) { + max = Math.max(max, piles[i]); + } + if (H == piles.length) return max; + int h = max, l = 1; + int answer = H; + while (l <= h) { + int m = l + (h - l) / 2; + boolean status = check(piles, H, m); + if (status) { + answer = m; + h = m - 1; + } else { + l = m + 1; + } + } + return answer; + } + + private boolean check(int[] piles, int H, int k) { + for (int p : piles) { + if (p <= k) { + H--; + } else { + int q = p / k; + if ((p % k) > 0) { + q++; + } + H -= q; + } + if (H < 0) { + return false; + } + } + return true; + } +} diff --git a/problems/src/binary_search/MedianOfTwoSortedArrays.java b/src/main/java/binary_search/MedianOfTwoSortedArrays.java similarity index 98% rename from problems/src/binary_search/MedianOfTwoSortedArrays.java rename to src/main/java/binary_search/MedianOfTwoSortedArrays.java index d908e664..221a1228 100644 --- a/problems/src/binary_search/MedianOfTwoSortedArrays.java +++ b/src/main/java/binary_search/MedianOfTwoSortedArrays.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; import java.util.ArrayList; diff --git a/problems/src/binary_search/MinSortedRotatedArray.java b/src/main/java/binary_search/MinSortedRotatedArray.java similarity index 97% rename from problems/src/binary_search/MinSortedRotatedArray.java rename to src/main/java/binary_search/MinSortedRotatedArray.java index ee5e151f..3a3d7f3c 100644 --- a/problems/src/binary_search/MinSortedRotatedArray.java +++ b/src/main/java/binary_search/MinSortedRotatedArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/src/main/java/binary_search/MinimizeTheMaximumAdjacentElementDifference.java b/src/main/java/binary_search/MinimizeTheMaximumAdjacentElementDifference.java new file mode 100644 index 00000000..260cc55d --- /dev/null +++ b/src/main/java/binary_search/MinimizeTheMaximumAdjacentElementDifference.java @@ -0,0 +1,108 @@ +/* (C) 2024 YourCompanyName */ +package binary_search; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class MinimizeTheMaximumAdjacentElementDifference { + record Interval(int s, int e, boolean hasMoreThanOne){ + static boolean check(int a, int mid, int b, int range){ + return Math.abs(mid - a) <= range && Math.abs(mid - b) <= range; + } + static boolean check(int a, int mid1, int mid2, int b, int range){ + return Math.abs(mid1 - a) <= range && Math.abs(mid1 - mid2) <= range && Math.abs(mid2 - b) <= range; + } + } + + public static void main(String[] args) { + int[] nums = new int[]{-1,10,-1,8}; + int res = new MinimizeTheMaximumAdjacentElementDifference().minDifference(nums); + System.out.println(res); + } + + public int minDifference(int[] nums) { + boolean noPositiveNum = Arrays.stream(nums).filter(i -> i != -1).findAny().isEmpty(); + if(noPositiveNum){ + return 0; + } + int currentMax = getCurrentMax(nums); + List intervals = buildIntervals(nums); + int minStart = Integer.MAX_VALUE, maxEnd = Integer.MIN_VALUE; + for (Interval interval : intervals) { + minStart = Math.min(minStart, Math.min(interval.e, interval.s)); + maxEnd = Math.max(maxEnd, Math.max(interval.e, interval.s)); + } + int l = 0, h = maxEnd, m; + int ans = -1; + while(l <= h){ + m = l + (h - l) / 2; + boolean result = checkIfThisNumberSatisfiesAllIntervals(intervals, minStart + m, maxEnd - m, m); + if(result){ + ans = m; + h = m - 1; + } else { + l = m + 1; + } + } + return Math.max(ans, currentMax); + } + + private int getCurrentMax(int[] nums){ + int currMax = Integer.MIN_VALUE; + int previous = nums[0]; + for(int i = 1; i < nums.length; i ++){ + if(nums[i] != -1){ + if(previous != -1){ + currMax = Math.max(currMax, Math.abs(previous - nums[i])); + } + previous = nums[i]; + } else { + previous = -1; + } + } + return currMax; + } + + private List buildIntervals(int[] nums) { + int previous = -1; + int minusOneCount = 0; + List intervals = new ArrayList<>(); + for (int num : nums) { + if (num == -1) { + minusOneCount ++; + } else { + if (minusOneCount > 0) { + intervals.add(new Interval(previous != -1 ? previous : num, num, minusOneCount > 1)); + minusOneCount = 0; + } + previous = num; + } + } + if(nums[nums.length - 1] == -1){ + intervals.add(new Interval(previous, previous, minusOneCount > 1)); + } + return intervals; + } + + boolean checkIfThisNumberSatisfiesAllIntervals(List intervals, int minStart, int maxEnd, int maxDiff){ + for (Interval interval : intervals) { + if (interval.hasMoreThanOne) { + boolean res1 = Interval.check(interval.s, minStart, minStart, interval.e, maxDiff); + boolean res2 = Interval.check(interval.s, minStart, maxEnd, interval.e, maxDiff); + boolean res3 = Interval.check(interval.s, maxEnd, minStart, interval.e, maxDiff); + boolean res4 = Interval.check(interval.s, maxEnd, maxEnd, interval.e, maxDiff); + if (!res1 && !res2 && !res3 && !res4) { + return false; + } + } else { + boolean res1 = Interval.check(interval.s, minStart, interval.e, maxDiff); + boolean res2 = Interval.check(interval.s, maxEnd, interval.e, maxDiff); + if (!res1 && !res2) { + return false; + } + } + } + return true; + } +} diff --git a/src/main/java/binary_search/MinimumWindowSubsequence.java b/src/main/java/binary_search/MinimumWindowSubsequence.java new file mode 100644 index 00000000..0d92648f --- /dev/null +++ b/src/main/java/binary_search/MinimumWindowSubsequence.java @@ -0,0 +1,84 @@ +/* (C) 2024 YourCompanyName */ +package binary_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 06/08/2019 Given strings S and T, find the minimum (contiguous) + * substring W of S, so that T is a subsequence of W. + * + *

If there is no such window in S that covers all characters in T, return the empty string "". + * If there are multiple such minimum-length windows, return the one with the left-most starting + * index. + * + *

Example 1: + * + *

Input: S = "abcdebdde", T = "bde" Output: "bcde" Explanation: "bcde" is the answer because it + * occurs before "bdde" which has the same length. "deb" is not a smaller window because the + * elements of T in the window must occur in order. + * + *

Note: + * + *

All the strings in the input will only contain lowercase letters. The length of S will be in + * the range [1, 20000]. The length of T will be in the range [1, 100]. + * + *

Solution O(S x T x log S) General idea is to first find the left-most left (l) and right (r) + * index where r - l is minimum and the minimum window contains the sub-sequence and iteratively + * check the next left-most indices and continue for the entire string S. A naive implementation + * would result in O(S ^ 2) therefore to speed up we have to maintain a hashtable of character as + * key and all its index of occurrence in a sorted list. Now, since this list is sorted we can + * easily find the next left-most by binarySearch or even better by using a TreeSet higher or ceil + * function. + */ +public class MinimumWindowSubsequence { + public static void main(String[] args) { + System.out.println(new MinimumWindowSubsequence().minWindow("abcdebdde", "x")); + } + + public String minWindow(String S, String T) { + if (T.isEmpty() || S.isEmpty()) return ""; + Map> charMap = new HashMap<>(); + for (int i = 0, l = S.length(); i < l; i++) { + char c = S.charAt(i); + charMap.putIfAbsent(c, new TreeSet<>()); + charMap.get(c).add(i); + } + int min = Integer.MAX_VALUE; + int start = -1, end; + int ansStart = -1, ansEnd = -1; + boolean finished = false; + while (true) { + int index = start; + end = -1; + for (int i = 0, l = T.length(); i < l; i++) { + char c = T.charAt(i); + if (!charMap.containsKey(c)) { + return ""; + } else { + TreeSet indicies = charMap.get(c); + Integer found = indicies.higher(index); + if (found == null) { + finished = true; + break; + } else { + index = found; + if (i == 0) { + start = index; + } + if (i == l - 1) { + end = index; + } + } + } + } + if (start != -1 && end != -1) { + if ((end - start) < min) { + min = end - start; + ansStart = start; + ansEnd = end; + } + } + if (finished) return ansStart == -1 ? "" : S.substring(ansStart, ansEnd + 1); + } + } +} diff --git a/problems/src/binary_search/PowXN.java b/src/main/java/binary_search/PowXN.java similarity index 95% rename from problems/src/binary_search/PowXN.java rename to src/main/java/binary_search/PowXN.java index 05c3eef4..e45def72 100644 --- a/problems/src/binary_search/PowXN.java +++ b/src/main/java/binary_search/PowXN.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/problems/src/binary_search/SearchForARange.java b/src/main/java/binary_search/SearchForARange.java similarity index 98% rename from problems/src/binary_search/SearchForARange.java rename to src/main/java/binary_search/SearchForARange.java index 8da19dfe..a53816e6 100644 --- a/problems/src/binary_search/SearchForARange.java +++ b/src/main/java/binary_search/SearchForARange.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/problems/src/binary_search/SearchInsertPosition.java b/src/main/java/binary_search/SearchInsertPosition.java similarity index 96% rename from problems/src/binary_search/SearchInsertPosition.java rename to src/main/java/binary_search/SearchInsertPosition.java index 4b9e9fac..78312a18 100644 --- a/problems/src/binary_search/SearchInsertPosition.java +++ b/src/main/java/binary_search/SearchInsertPosition.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/problems/src/binary_search/SearchRotatedSortedArray.java b/src/main/java/binary_search/SearchRotatedSortedArray.java similarity index 97% rename from problems/src/binary_search/SearchRotatedSortedArray.java rename to src/main/java/binary_search/SearchRotatedSortedArray.java index a4380b01..e6edcc7c 100644 --- a/problems/src/binary_search/SearchRotatedSortedArray.java +++ b/src/main/java/binary_search/SearchRotatedSortedArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/src/main/java/binary_search/SingleElementInASortedArray.java b/src/main/java/binary_search/SingleElementInASortedArray.java new file mode 100644 index 00000000..29d5a503 --- /dev/null +++ b/src/main/java/binary_search/SingleElementInASortedArray.java @@ -0,0 +1,57 @@ +/* (C) 2024 YourCompanyName */ +package binary_search; + +/** + * Created by gouthamvidyapradhan on 30/01/2020 You are given a sorted array consisting of only + * integers where every element appears exactly twice, except for one element which appears exactly + * once. Find this single element that appears only once. + * + *

Example 1: + * + *

Input: [1,1,2,3,3,4,4,8,8] Output: 2 Example 2: + * + *

Input: [3,3,7,7,10,11,11] Output: 10 + * + *

Note: Your solution should run in O(log n) time and O(1) space. + */ +public class SingleElementInASortedArray { + public static void main(String[] args) { + int[] A = {3, 3, 7, 7, 10, 11, 11}; + System.out.println(new SingleElementInASortedArray().singleNonDuplicate(A)); + } + + public int singleNonDuplicate(int[] nums) { + if (nums.length == 1) return nums[0]; + int l = 0, h = nums.length - 1; + while (l <= h) { + int m = l + ((h - l) / 2); + int N = nums[m]; + if (m + 1 >= nums.length) { + if (nums[m - 1] != N) { + return N; + } + h = m - 1; + } else if (m - 1 < 0) { + if (nums[m + 1] != N) { + return N; + } + l = m + 1; + } else { + if (m % 2 == 0) { + if (nums[m + 1] != N && nums[m - 1] != N) { + return N; + } else if (nums[m + 1] != N) { + h = m - 1; + } else l = m + 1; + } else { + if (nums[m + 1] != N && nums[m - 1] != N) { + return N; + } else if (nums[m - 1] != N) { + h = m - 1; + } else l = m + 1; + } + } + } + return -1; + } +} diff --git a/problems/src/binary_search/SqrtX.java b/src/main/java/binary_search/SqrtX.java similarity index 94% rename from problems/src/binary_search/SqrtX.java rename to src/main/java/binary_search/SqrtX.java index 1cb3462e..e3cb34a3 100644 --- a/problems/src/binary_search/SqrtX.java +++ b/src/main/java/binary_search/SqrtX.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; /** diff --git a/problems/src/binary_search/SwimInRisingWater.java b/src/main/java/binary_search/SwimInRisingWater.java similarity index 99% rename from problems/src/binary_search/SwimInRisingWater.java rename to src/main/java/binary_search/SwimInRisingWater.java index 3d8febc8..5f13d9a1 100644 --- a/problems/src/binary_search/SwimInRisingWater.java +++ b/src/main/java/binary_search/SwimInRisingWater.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package binary_search; import java.util.HashSet; diff --git a/src/main/java/binary_search/TimeBasedKeyValuePair.java b/src/main/java/binary_search/TimeBasedKeyValuePair.java new file mode 100644 index 00000000..c94ff317 --- /dev/null +++ b/src/main/java/binary_search/TimeBasedKeyValuePair.java @@ -0,0 +1,85 @@ +/* (C) 2024 YourCompanyName */ +package binary_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 07/05/2019 Create a timebased key-value store class TimeMap, + * that supports two operations. + * + *

1. set(string key, string value, int timestamp) + * + *

Stores the key and value, along with the given timestamp. 2. get(string key, int timestamp) + * + *

Returns a value such that set(key, value, timestamp_prev) was called previously, with + * timestamp_prev <= timestamp. If there are multiple such values, it returns the one with the + * largest timestamp_prev. If there are no values, it returns the empty string (""). + * + *

Example 1: + * + *

Input: inputs = ["TimeMap","set","get","get","set","get","get"], inputs = + * [[],["foo","bar",1],["foo",1],["foo",3],["foo","bar2",4],["foo",4],["foo",5]] Output: + * [null,null,"bar","bar",null,"bar2","bar2"] Explanation: TimeMap kv; kv.set("foo", "bar", 1); // + * store the key "foo" and value "bar" along with timestamp = 1 kv.get("foo", 1); // output "bar" + * kv.get("foo", 3); // output "bar" since there is no value corresponding to foo at timestamp 3 and + * timestamp 2, then the only value is at timestamp 1 ie "bar" kv.set("foo", "bar2", 4); + * kv.get("foo", 4); // output "bar2" kv.get("foo", 5); //output "bar2" + * + *

Example 2: + * + *

Input: inputs = ["TimeMap","set","set","get","get","get","get","get"], inputs = + * [[],["love","high",10],["love","low",20],["love",5],["love",10],["love",15],["love",20],["love",25]] + * Output: [null,null,null,"","high","high","low","low"] + * + *

Note: + * + *

All key/value strings are lowercase. All key/value strings have length in the range [1, 100] + * The timestamps for all TimeMap.set operations are strictly increasing. 1 <= timestamp <= 10^7 + * TimeMap.set and TimeMap.get functions will be called a total of 120000 times (combined) per test + * case. + * + *

Solution O(log N) where N is the number of values for the same key (but different timestamp) + * Idea is to use the HashMap to store the unique key and a TreeMap as value containing all + * different timestamps and value. Use the floor function in treemap to get the value for a given + * timestamp. + */ +public class TimeBasedKeyValuePair { + + private Map> map; + + public TimeBasedKeyValuePair() { + map = new HashMap<>(); + } + + public void set(String key, String value, int timestamp) { + map.putIfAbsent(key, new TreeMap<>()); + TreeMap treeMap = map.get(key); + treeMap.put(timestamp, value); + } + + public String get(String key, int timestamp) { + if (!map.containsKey(key)) { + return ""; + } else { + TreeMap treeMap = map.get(key); + Map.Entry entry = treeMap.floorEntry(timestamp); + if (entry == null) { + return ""; + } else { + return entry.getValue(); + } + } + } + + public static void main(String[] args) { + TimeBasedKeyValuePair task = new TimeBasedKeyValuePair(); + task.set("foo", "bar", 1); + System.out.println(task.get("foo", 1)); + System.out.println(task.get("foo", 3)); + System.out.println(task.get("foo", 0)); + task.set("foo", "bar2", 4); + System.out.println(task.get("foo", 3)); + System.out.println(task.get("foo", 4)); + System.out.println(task.get("foo", 5)); + } +} diff --git a/src/main/java/bit_manipulation/BinaryNumberWithAlternatingBits.java b/src/main/java/bit_manipulation/BinaryNumberWithAlternatingBits.java new file mode 100644 index 00000000..bced945e --- /dev/null +++ b/src/main/java/bit_manipulation/BinaryNumberWithAlternatingBits.java @@ -0,0 +1,33 @@ +/* (C) 2024 YourCompanyName */ +package bit_manipulation; +/** + * Created by gouthamvidyapradhan on 28/05/2019\ Given a positive integer, check whether it has + * alternating bits: namely, if two adjacent bits will always have different values. + * + *

Example 1: Input: 5 Output: True Explanation: The binary representation of 5 is: 101 Example + * 2: Input: 7 Output: False Explanation: The binary representation of 7 is: 111. Example 3: Input: + * 11 Output: False Explanation: The binary representation of 11 is: 1011. Example 4: Input: 10 + * Output: True Explanation: The binary representation of 10 is: 1010. + */ +public class BinaryNumberWithAlternatingBits { + public static void main(String[] args) { + System.out.println(new BinaryNumberWithAlternatingBits().hasAlternatingBits(18)); + } + + public boolean hasAlternatingBits(int n) { + int curr = n & 1; + int pos = 0; + for (int i = 0; i < 32; i++) { + if ((n & (1 << i)) > 0) { + pos = i; + } + } + + for (int i = 1; i <= pos; i++) { + int temp = (1 << i) & n; + if ((temp > 0 && curr > 0) || (temp == 0 && curr == 0)) return false; + curr = temp; + } + return true; + } +} diff --git a/src/main/java/bit_manipulation/BinaryWatch.java b/src/main/java/bit_manipulation/BinaryWatch.java new file mode 100644 index 00000000..34fa3f48 --- /dev/null +++ b/src/main/java/bit_manipulation/BinaryWatch.java @@ -0,0 +1,56 @@ +/* (C) 2024 YourCompanyName */ +package bit_manipulation; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 05/11/2019 A binary watch has 4 LEDs on the top which represent + * the hours (0-11), and the 6 LEDs on the bottom represent the minutes (0-59). + * + *

Each LED represents a zero or one, with the least significant bit on the right. + * + *

For example, the above binary watch reads "3:25". + * + *

Given a non-negative integer n which represents the number of LEDs that are currently on, + * return all possible times the watch could represent. + * + *

Example: + * + *

Input: n = 1 Return: ["1:00", "2:00", "4:00", "8:00", "0:01", "0:02", "0:04", "0:08", "0:16", + * "0:32"] Note: The order of output does not matter. The hour must not contain a leading zero, for + * example "01:00" is not valid, it should be "1:00". The minute must be consist of two digits and + * may contain a leading zero, for example "10:2" is not valid, it should be "10:02". + */ +public class BinaryWatch { + public static void main(String[] args) { + System.out.println(new BinaryWatch().readBinaryWatch(1)); + } + + public List readBinaryWatch(int num) { + int H = 11, M = 59; + List result = new ArrayList<>(); + if (num == 0) { + result.add("0:00"); + return result; + } + for (int i = 0; i <= H; i++) { + for (int j = 0; j <= M; j++) { + int count = 0; + for (int k = 0; k < 4; k++) { + if (((1 << k) & i) > 0) { + count++; + } + } + for (int k = 0; k < 6; k++) { + if (((1 << k) & j) > 0) { + count++; + } + } + if (count == num) { + result.add(i + ":" + ((String.valueOf(j).length() == 1) ? ("0" + j) : j)); + } + } + } + return result; + } +} diff --git a/problems/src/bit_manipulation/DivideTwoIntegers.java b/src/main/java/bit_manipulation/DivideTwoIntegers.java similarity index 97% rename from problems/src/bit_manipulation/DivideTwoIntegers.java rename to src/main/java/bit_manipulation/DivideTwoIntegers.java index 7bdeab67..0929dfc6 100644 --- a/problems/src/bit_manipulation/DivideTwoIntegers.java +++ b/src/main/java/bit_manipulation/DivideTwoIntegers.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package bit_manipulation; /** diff --git a/problems/src/bit_manipulation/GrayCode.java b/src/main/java/bit_manipulation/GrayCode.java similarity index 97% rename from problems/src/bit_manipulation/GrayCode.java rename to src/main/java/bit_manipulation/GrayCode.java index 9c74430d..d08695fa 100644 --- a/problems/src/bit_manipulation/GrayCode.java +++ b/src/main/java/bit_manipulation/GrayCode.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package bit_manipulation; import java.util.ArrayList; diff --git a/problems/src/bit_manipulation/HammingDistance.java b/src/main/java/bit_manipulation/HammingDistance.java similarity index 96% rename from problems/src/bit_manipulation/HammingDistance.java rename to src/main/java/bit_manipulation/HammingDistance.java index 63fb1fd5..d800eda0 100644 --- a/problems/src/bit_manipulation/HammingDistance.java +++ b/src/main/java/bit_manipulation/HammingDistance.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package bit_manipulation; /** diff --git a/problems/src/bit_manipulation/TotalHammingDistance.java b/src/main/java/bit_manipulation/TotalHammingDistance.java similarity index 97% rename from problems/src/bit_manipulation/TotalHammingDistance.java rename to src/main/java/bit_manipulation/TotalHammingDistance.java index e0e89307..b685dced 100644 --- a/problems/src/bit_manipulation/TotalHammingDistance.java +++ b/src/main/java/bit_manipulation/TotalHammingDistance.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package bit_manipulation; /** diff --git a/problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java b/src/main/java/breadth_first_search/BinarayTreeLevelOrderTraversal.java similarity index 98% rename from problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java rename to src/main/java/breadth_first_search/BinarayTreeLevelOrderTraversal.java index 92462939..8e8bd36a 100644 --- a/problems/src/breadth_first_search/BinarayTreeLevelOrderTraversal.java +++ b/src/main/java/breadth_first_search/BinarayTreeLevelOrderTraversal.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.ArrayDeque; diff --git a/problems/src/breadth_first_search/BusRoutes.java b/src/main/java/breadth_first_search/BusRoutes.java similarity index 99% rename from problems/src/breadth_first_search/BusRoutes.java rename to src/main/java/breadth_first_search/BusRoutes.java index 4b975dc2..dbb3e892 100644 --- a/problems/src/breadth_first_search/BusRoutes.java +++ b/src/main/java/breadth_first_search/BusRoutes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.*; diff --git a/problems/src/breadth_first_search/CutOffTreesForGolfEvent.java b/src/main/java/breadth_first_search/CutOffTreesForGolfEvent.java similarity index 99% rename from problems/src/breadth_first_search/CutOffTreesForGolfEvent.java rename to src/main/java/breadth_first_search/CutOffTreesForGolfEvent.java index 72e2057b..1bc7df05 100644 --- a/problems/src/breadth_first_search/CutOffTreesForGolfEvent.java +++ b/src/main/java/breadth_first_search/CutOffTreesForGolfEvent.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.*; diff --git a/problems/src/breadth_first_search/Matrix.java b/src/main/java/breadth_first_search/Matrix.java similarity index 98% rename from problems/src/breadth_first_search/Matrix.java rename to src/main/java/breadth_first_search/Matrix.java index 1c6eb9da..c2c63988 100644 --- a/problems/src/breadth_first_search/Matrix.java +++ b/src/main/java/breadth_first_search/Matrix.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.*; diff --git a/problems/src/breadth_first_search/OpenTheLock.java b/src/main/java/breadth_first_search/OpenTheLock.java similarity index 99% rename from problems/src/breadth_first_search/OpenTheLock.java rename to src/main/java/breadth_first_search/OpenTheLock.java index 49bcde56..3ad720a9 100644 --- a/problems/src/breadth_first_search/OpenTheLock.java +++ b/src/main/java/breadth_first_search/OpenTheLock.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.*; diff --git a/problems/src/breadth_first_search/RaceCar.java b/src/main/java/breadth_first_search/RaceCar.java similarity index 98% rename from problems/src/breadth_first_search/RaceCar.java rename to src/main/java/breadth_first_search/RaceCar.java index 21c8705a..6cda24fc 100644 --- a/problems/src/breadth_first_search/RaceCar.java +++ b/src/main/java/breadth_first_search/RaceCar.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.*; diff --git a/src/main/java/breadth_first_search/RottingOranges.java b/src/main/java/breadth_first_search/RottingOranges.java new file mode 100644 index 00000000..0d84292a --- /dev/null +++ b/src/main/java/breadth_first_search/RottingOranges.java @@ -0,0 +1,85 @@ +/* (C) 2024 YourCompanyName */ +package breadth_first_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 04/12/2019 In a given grid, each cell can have one of three + * values: + * + *

the value 0 representing an empty cell; the value 1 representing a fresh orange; the value 2 + * representing a rotten orange. Every minute, any fresh orange that is adjacent (4-directionally) + * to a rotten orange becomes rotten. + * + *

Return the minimum number of minutes that must elapse until no cell has a fresh orange. If + * this is impossible, return -1 instead. + * + *

Example 1: + * + *

Input: [[2,1,1],[1,1,0],[0,1,1]] Output: 4 Example 2: + * + *

Input: [[2,1,1],[0,1,1],[1,0,1]] Output: -1 Explanation: The orange in the bottom left corner + * (row 2, column 0) is never rotten, because rotting only happens 4-directionally. Example 3: + * + *

Input: [[0,2]] Output: 0 Explanation: Since there are already no fresh oranges at minute 0, + * the answer is just 0. + * + *

Note: + * + *

1 <= grid.length <= 10 1 <= grid[0].length <= 10 grid[i][j] is only 0, 1, or 2. + */ +public class RottingOranges { + final int[] R = {1, -1, 0, 0}; + final int[] C = {0, 0, 1, -1}; + + public static void main(String[] args) { + int[][] A = {{2, 1, 1}, {1, 1, 0}, {0, 1, 1}}; + System.out.println(new RottingOranges().orangesRotting(A)); + } + + private class Node { + int r, c, v; + + Node(int r, int c, int v) { + this.r = r; + this.c = c; + this.v = v; + } + } + + public int orangesRotting(int[][] grid) { + Queue queue = new ArrayDeque<>(); + boolean[][] done = new boolean[grid.length][grid[0].length]; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 2) { + queue.offer(new Node(i, j, 0)); + done[i][j] = true; + } + } + } + int max = 0; + while (!queue.isEmpty()) { + Node curr = queue.poll(); + for (int i = 0; i < 4; i++) { + int newR = curr.r + R[i]; + int newC = curr.c + C[i]; + if (newR >= 0 && newR < grid.length && newC >= 0 && newC < grid[0].length) { + if (!done[newR][newC] && grid[newR][newC] != 0) { + done[newR][newC] = true; + max = Math.max(max, curr.v + 1); + queue.offer(new Node(newR, newC, curr.v + 1)); + } + } + } + } + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 1 && !done[i][j]) { + return -1; + } + } + } + return max; + } +} diff --git a/problems/src/breadth_first_search/SlidingPuzzle.java b/src/main/java/breadth_first_search/SlidingPuzzle.java similarity index 99% rename from problems/src/breadth_first_search/SlidingPuzzle.java rename to src/main/java/breadth_first_search/SlidingPuzzle.java index 4fa7723a..73a96103 100644 --- a/problems/src/breadth_first_search/SlidingPuzzle.java +++ b/src/main/java/breadth_first_search/SlidingPuzzle.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.*; diff --git a/problems/src/breadth_first_search/WallsAndGates.java b/src/main/java/breadth_first_search/WallsAndGates.java similarity index 98% rename from problems/src/breadth_first_search/WallsAndGates.java rename to src/main/java/breadth_first_search/WallsAndGates.java index 29c027ec..84136ba3 100644 --- a/problems/src/breadth_first_search/WallsAndGates.java +++ b/src/main/java/breadth_first_search/WallsAndGates.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.ArrayDeque; diff --git a/problems/src/breadth_first_search/WordLadder.java b/src/main/java/breadth_first_search/WordLadder.java similarity index 98% rename from problems/src/breadth_first_search/WordLadder.java rename to src/main/java/breadth_first_search/WordLadder.java index 6a71f9d1..1054b222 100644 --- a/problems/src/breadth_first_search/WordLadder.java +++ b/src/main/java/breadth_first_search/WordLadder.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.*; diff --git a/problems/src/breadth_first_search/WordLadderII.java b/src/main/java/breadth_first_search/WordLadderII.java similarity index 99% rename from problems/src/breadth_first_search/WordLadderII.java rename to src/main/java/breadth_first_search/WordLadderII.java index 686dd9cf..d5374242 100644 --- a/problems/src/breadth_first_search/WordLadderII.java +++ b/src/main/java/breadth_first_search/WordLadderII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package breadth_first_search; import java.util.*; diff --git a/problems/src/depth_first_search/AccountsMerge.java b/src/main/java/depth_first_search/AccountsMerge.java similarity index 99% rename from problems/src/depth_first_search/AccountsMerge.java rename to src/main/java/depth_first_search/AccountsMerge.java index de15f02a..ab049aad 100644 --- a/problems/src/depth_first_search/AccountsMerge.java +++ b/src/main/java/depth_first_search/AccountsMerge.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/problems/src/depth_first_search/AlienDictionary.java b/src/main/java/depth_first_search/AlienDictionary.java similarity index 99% rename from problems/src/depth_first_search/AlienDictionary.java rename to src/main/java/depth_first_search/AlienDictionary.java index f5dae3b9..6de53887 100644 --- a/problems/src/depth_first_search/AlienDictionary.java +++ b/src/main/java/depth_first_search/AlienDictionary.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/problems/src/depth_first_search/AllPathsFromSourceToTarget.java b/src/main/java/depth_first_search/AllPathsFromSourceToTarget.java similarity index 98% rename from problems/src/depth_first_search/AllPathsFromSourceToTarget.java rename to src/main/java/depth_first_search/AllPathsFromSourceToTarget.java index fa03bba1..72f9f479 100644 --- a/problems/src/depth_first_search/AllPathsFromSourceToTarget.java +++ b/src/main/java/depth_first_search/AllPathsFromSourceToTarget.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/src/main/java/depth_first_search/AsFarfromLandAsPossible.java b/src/main/java/depth_first_search/AsFarfromLandAsPossible.java new file mode 100644 index 00000000..2a7a4efc --- /dev/null +++ b/src/main/java/depth_first_search/AsFarfromLandAsPossible.java @@ -0,0 +1,87 @@ +/* (C) 2024 YourCompanyName */ +package depth_first_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 28/08/2019 Given an N x N grid containing only values 0 and 1, + * where 0 represents water and 1 represents land, find a water cell such that its distance to the + * nearest land cell is maximized and return the distance. + * + *

The distance used in this problem is the Manhattan distance: the distance between two cells + * (x0, y0) and (x1, y1) is |x0 - x1| + |y0 - y1|. + * + *

If no land or water exists in the grid, return -1. + * + *

Example 1: + * + *

Input: [[1,0,1],[0,0,0],[1,0,1]] Output: 2 Explanation: The cell (1, 1) is as far as possible + * from all the land with distance 2. Example 2: + * + *

Input: [[1,0,0],[0,0,0],[0,0,0]] Output: 4 Explanation: The cell (2, 2) is as far as possible + * from all the land with distance 4. + * + *

Note: + * + *

1 <= grid.length == grid[0].length <= 100 grid[i][j] is 0 or 1 + * + *

Solution: O(N x N) Do a multi-sources BFS starting from each of the water cell and end as soon + * as a land cell is found. Record the maximum distance to the land cell and return the value. + */ +public class AsFarfromLandAsPossible { + final int[] R = {1, -1, 0, 0}; + final int[] C = {0, 0, -1, 1}; + + public static void main(String[] args) { + int[][] G = {{1, 0, 1}, {0, 0, 0}, {1, 0, 1}}; + System.out.println(new AsFarfromLandAsPossible().maxDistance(G)); + } + + private class Node { + int r, c, d; + + Node(int r, int c, int d) { + this.r = r; + this.c = c; + this.d = d; + } + } + + public int maxDistance(int[][] grid) { + int[][] D = new int[grid.length][grid[0].length]; + Queue queue = new ArrayDeque<>(); + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 1) { + queue.offer(new Node(i, j, 0)); + } else { + D[i][j] = -1; + } + } + } + if (queue.isEmpty()) return -1; + while (!queue.isEmpty()) { + Node current = queue.poll(); + for (int i = 0; i < 4; i++) { + int newR = current.r + R[i]; + int newC = current.c + C[i]; + if (newR >= 0 && newC >= 0 && newR < grid.length && newC < grid[0].length) { + if (D[newR][newC] < 0) { + D[newR][newC] = current.d + 1; + Node child = new Node(newR, newC, current.d + 1); + queue.offer(child); + } + } + } + } + int max = 0; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 0) { + max = Math.max(max, D[i][j]); + } + } + } + return max == 0 ? -1 : max; + } +} diff --git a/problems/src/depth_first_search/BricksFallingWhenHit.java b/src/main/java/depth_first_search/BricksFallingWhenHit.java similarity index 99% rename from problems/src/depth_first_search/BricksFallingWhenHit.java rename to src/main/java/depth_first_search/BricksFallingWhenHit.java index 466bcc36..9b4baefb 100644 --- a/problems/src/depth_first_search/BricksFallingWhenHit.java +++ b/src/main/java/depth_first_search/BricksFallingWhenHit.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.ArrayList; diff --git a/problems/src/depth_first_search/CloneGraph.java b/src/main/java/depth_first_search/CloneGraph.java similarity index 98% rename from problems/src/depth_first_search/CloneGraph.java rename to src/main/java/depth_first_search/CloneGraph.java index 42232959..2ef7caed 100644 --- a/problems/src/depth_first_search/CloneGraph.java +++ b/src/main/java/depth_first_search/CloneGraph.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.ArrayList; diff --git a/src/main/java/depth_first_search/ConnectingCitiesWithMinimumCost.java b/src/main/java/depth_first_search/ConnectingCitiesWithMinimumCost.java new file mode 100644 index 00000000..788c7336 --- /dev/null +++ b/src/main/java/depth_first_search/ConnectingCitiesWithMinimumCost.java @@ -0,0 +1,118 @@ +/* (C) 2024 YourCompanyName */ +package depth_first_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 26/11/2019 There are N cities numbered from 1 to N. + * + *

You are given connections, where each connections[i] = [city1, city2, cost] represents the + * cost to connect city1 and city2 together. (A connection is bidirectional: connecting city1 and + * city2 is the same as connecting city2 and city1.) + * + *

Return the minimum cost so that for every pair of cities, there exists a path of connections + * (possibly of length 1) that connects those two cities together. The cost is the sum of the + * connection costs used. If the task is impossible, return -1. + * + *

Example 1: + * + *

Input: N = 3, connections = [[1,2,5],[1,3,6],[2,3,1]] Output: 6 Explanation: Choosing any 2 + * edges will connect all cities so we choose the minimum 2. Example 2: + * + *

Input: N = 4, connections = [[1,2,3],[3,4,4]] Output: -1 Explanation: There is no way to + * connect all cities even if all edges are used. + * + *

Note: + * + *

1 <= N <= 10000 1 <= connections.length <= 10000 1 <= connections[i][0], connections[i][1] <= + * N 0 <= connections[i][2] <= 10^5 connections[i][0] != connections[i][1] + */ +public class ConnectingCitiesWithMinimumCost { + + /** @author gouthamvidyapradhan Class to represent UnionFind Disjoint Set */ + private class UnionFind { + private int[] p; + private int[] rank; + private int numOfDisjoinSet; + + UnionFind(int s) { + this.p = new int[s]; + this.rank = new int[s]; + this.numOfDisjoinSet = s - 1; + init(); + } + + /** Initialize with its same index as its parent */ + public void init() { + for (int i = 0; i < p.length; i++) p[i] = i; + } + /** + * Find the representative vertex + * + * @param i + * @return + */ + private int findSet(int i) { + if (p[i] != i) p[i] = findSet(p[i]); + return p[i]; + } + /** + * Perform union of two vertex + * + * @param i + * @param j + * @return true if union is performed successfully, false otherwise + */ + public boolean union(int i, int j) { + int x = findSet(i); + int y = findSet(j); + if (x != y) { + if (rank[x] > rank[y]) p[y] = p[x]; + else { + p[x] = p[y]; + if (rank[x] == rank[y]) rank[y]++; // increment the rank + } + numOfDisjoinSet--; + return true; + } + return false; + } + } + + private class Edge { + int v1; + int v2; + int distance; + + Edge(int v1, int v2, int distance) { + this.v1 = v1; + this.v2 = v2; + this.distance = distance; + } + } + + private List edges = new ArrayList<>(); + int min = 0; + + public static void main(String[] args) { + int[][] A = {{1, 2, 3}, {3, 4, 4}}; + System.out.println(new ConnectingCitiesWithMinimumCost().minimumCost(4, A)); + } + + public int minimumCost(int N, int[][] connections) { + UnionFind uF = new UnionFind(N + 1); + for (int i = 0; i < connections.length; i++) { + edges.add(new Edge(connections[i][0], connections[i][1], connections[i][2])); + } + edges.sort(Comparator.comparingInt(o -> o.distance)); + for (Edge e : edges) { + if (uF.union(e.v1, e.v2)) { + min += e.distance; + } + if (uF.numOfDisjoinSet == 1) { + return min; + } + } + return -1; + } +} diff --git a/problems/src/depth_first_search/CourseSchedule.java b/src/main/java/depth_first_search/CourseSchedule.java similarity index 98% rename from problems/src/depth_first_search/CourseSchedule.java rename to src/main/java/depth_first_search/CourseSchedule.java index 1e96e567..93383963 100644 --- a/problems/src/depth_first_search/CourseSchedule.java +++ b/src/main/java/depth_first_search/CourseSchedule.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/problems/src/depth_first_search/CourseScheduleII.java b/src/main/java/depth_first_search/CourseScheduleII.java similarity index 99% rename from problems/src/depth_first_search/CourseScheduleII.java rename to src/main/java/depth_first_search/CourseScheduleII.java index 77b12023..cba31a4a 100644 --- a/problems/src/depth_first_search/CourseScheduleII.java +++ b/src/main/java/depth_first_search/CourseScheduleII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/problems/src/depth_first_search/CrackingTheSafe.java b/src/main/java/depth_first_search/CrackingTheSafe.java similarity index 98% rename from problems/src/depth_first_search/CrackingTheSafe.java rename to src/main/java/depth_first_search/CrackingTheSafe.java index ffa5f443..359dc597 100644 --- a/problems/src/depth_first_search/CrackingTheSafe.java +++ b/src/main/java/depth_first_search/CrackingTheSafe.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.HashSet; diff --git a/src/main/java/depth_first_search/CriticalConnection.java b/src/main/java/depth_first_search/CriticalConnection.java new file mode 100644 index 00000000..57fd6f9f --- /dev/null +++ b/src/main/java/depth_first_search/CriticalConnection.java @@ -0,0 +1,80 @@ +/* (C) 2024 YourCompanyName */ +package depth_first_search; + +import java.util.*; + +/** Created by gouthamvidyapradhan on 05/12/2019 */ +public class CriticalConnection { + public static void main(String[] args) { + CriticalConnection task = new CriticalConnection(); + List c = new ArrayList<>(); + c.add(0); + c.add(1); + + List c1 = new ArrayList<>(); + c1.add(1); + c1.add(2); + + List c2 = new ArrayList<>(); + c2.add(2); + c2.add(0); + + List c3 = new ArrayList<>(); + c3.add(1); + c3.add(3); + + List> connections = new ArrayList<>(); + connections.add(c); + connections.add(c1); + connections.add(c2); + connections.add(c3); + List> result = task.criticalConnections(4, connections); + System.out.println(); + } + + private int[] dLow; + private int[] dNum; + private int num = 0; + + public List> criticalConnections(int n, List> connections) { + dLow = new int[n]; + dNum = new int[n]; + Map> graph = new HashMap<>(); + Arrays.fill(dLow, -1); + Arrays.fill(dNum, -1); + for (List connection : connections) { + graph.putIfAbsent(connection.get(0), new ArrayList<>()); + graph.putIfAbsent(connection.get(1), new ArrayList<>()); + graph.get(connection.get(0)).add(connection.get(1)); + graph.get(connection.get(1)).add(connection.get(0)); + } + dfs(-1, 0, graph); + List> result = new ArrayList<>(); + for (List connection : connections) { + if (dLow[connection.get(1)] > dNum[connection.get(0)] + || dLow[connection.get(0)] > dNum[connection.get(1)]) { + result.add(connection); + } + } + return result; + } + + private int dfs(int u, int v, Map> graph) { + int n = num++; + dNum[v] = n; + dLow[v] = n; + List children = graph.get(v); + if (children != null) { + for (int c : children) { + if (c != u) { + if (dNum[c] == -1) { + dLow[v] = Math.min(dLow[v], dfs(v, c, graph)); + } else { + dLow[v] = Math.min(dLow[c], dLow[v]); + } + } + } + } + return dLow[v]; + } +} diff --git a/src/main/java/depth_first_search/FloodFill.java b/src/main/java/depth_first_search/FloodFill.java new file mode 100644 index 00000000..834a7286 --- /dev/null +++ b/src/main/java/depth_first_search/FloodFill.java @@ -0,0 +1,45 @@ +/* (C) 2024 YourCompanyName */ +package depth_first_search; + +import java.util.*; + +/** Created by gouthamvidyapradhan on 29/01/2020 */ +public class FloodFill { + final int[] R = {1, -1, 0, 0}; + final int[] C = {0, 0, -1, 1}; + + public static void main(String[] args) { + // + } + + boolean done[][]; + + public int[][] floodFill(int[][] image, int sr, int sc, int newColor) { + done = new boolean[image.length][image[0].length]; + int[][] copy = new int[image.length][image[0].length]; + for (int i = 0; i < image.length; i++) { + for (int j = 0; j < image[0].length; j++) { + copy[i][j] = image[i][j]; + } + } + dfs(copy, sr, sc, image[sr][sc], newColor); + return copy; + } + + private void dfs(int[][] image, int r, int c, int c1, int c2) { + done[r][c] = true; + image[r][c] = c2; + for (int i = 0; i < 4; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR >= 0 + && newC >= 0 + && newR < image.length + && newC < image[0].length + && image[newR][newC] == c1 + && !done[newR][newC]) { + dfs(image, newR, newC, c1, c2); + } + } + } +} diff --git a/problems/src/depth_first_search/GraphValidTree.java b/src/main/java/depth_first_search/GraphValidTree.java similarity index 98% rename from problems/src/depth_first_search/GraphValidTree.java rename to src/main/java/depth_first_search/GraphValidTree.java index 43543bc3..2b69ec1f 100644 --- a/problems/src/depth_first_search/GraphValidTree.java +++ b/src/main/java/depth_first_search/GraphValidTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.ArrayList; diff --git a/problems/src/depth_first_search/IslandPerimeter.java b/src/main/java/depth_first_search/IslandPerimeter.java similarity index 98% rename from problems/src/depth_first_search/IslandPerimeter.java rename to src/main/java/depth_first_search/IslandPerimeter.java index 0cc67fa1..3a020f91 100644 --- a/problems/src/depth_first_search/IslandPerimeter.java +++ b/src/main/java/depth_first_search/IslandPerimeter.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; /** diff --git a/problems/src/depth_first_search/LongestConsecutiveSequence.java b/src/main/java/depth_first_search/LongestConsecutiveSequence.java similarity index 98% rename from problems/src/depth_first_search/LongestConsecutiveSequence.java rename to src/main/java/depth_first_search/LongestConsecutiveSequence.java index 1d4cd980..053cacbe 100644 --- a/problems/src/depth_first_search/LongestConsecutiveSequence.java +++ b/src/main/java/depth_first_search/LongestConsecutiveSequence.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/src/main/java/depth_first_search/MaxAreaOfIsland.java b/src/main/java/depth_first_search/MaxAreaOfIsland.java new file mode 100644 index 00000000..c4001310 --- /dev/null +++ b/src/main/java/depth_first_search/MaxAreaOfIsland.java @@ -0,0 +1,77 @@ +/* (C) 2024 YourCompanyName */ +package depth_first_search; + +/** + * Created by gouthamvidyapradhan on 28/05/2019 Given a non-empty 2D array grid of 0's and 1's, an + * island is a group of 1's (representing land) connected 4-directionally (horizontal or vertical.) + * You may assume all four edges of the grid are surrounded by water. + * + *

Find the maximum area of an island in the given 2D array. (If there is no island, the maximum + * area is 0.) + * + *

Example 1: + * + *

[[0,0,1,0,0,0,0,1,0,0,0,0,0], [0,0,0,0,0,0,0,1,1,1,0,0,0], [0,1,1,0,1,0,0,0,0,0,0,0,0], + * [0,1,0,0,1,1,0,0,1,0,1,0,0], [0,1,0,0,1,1,0,0,1,1,1,0,0], [0,0,0,0,0,0,0,0,0,0,1,0,0], + * [0,0,0,0,0,0,0,1,1,1,0,0,0], [0,0,0,0,0,0,0,1,1,0,0,0,0]] Given the above grid, return 6. Note + * the answer is not 11, because the island must be connected 4-directionally. Example 2: + * + *

[[0,0,0,0,0,0,0,0]] Given the above grid, return 0. Note: The length of each dimension in the + * given grid does not exceed 50. + * + *

Solution: O(N x M) Do a dfs and keep track of max connected 1's + */ +public class MaxAreaOfIsland { + final int[] R = {0, 0, -1, 1}; + final int[] C = {1, -1, 0, 0}; + + int count = 0; + int max = 0; + boolean[][] done; + + public static void main(String[] args) { + int[][] grid = { + {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0}, + {0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0}, + {0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0} + }; + + System.out.println(new MaxAreaOfIsland().maxAreaOfIsland(grid)); + } + + public int maxAreaOfIsland(int[][] grid) { + done = new boolean[grid.length][grid[0].length]; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 1 && !done[i][j]) { + count = 0; + dfs(grid, i, j); + max = Math.max(max, count); + } + } + } + return max; + } + + private void dfs(int[][] grid, int r, int c) { + done[r][c] = true; + count++; + for (int i = 0; i < 4; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR >= 0 + && newC >= 0 + && newR < grid.length + && newC < grid[0].length + && !done[newR][newC] + && grid[newR][newC] == 1) { + dfs(grid, newR, newC); + } + } + } +} diff --git a/problems/src/depth_first_search/Minesweeper.java b/src/main/java/depth_first_search/Minesweeper.java similarity index 99% rename from problems/src/depth_first_search/Minesweeper.java rename to src/main/java/depth_first_search/Minesweeper.java index eb71da36..b2243211 100644 --- a/problems/src/depth_first_search/Minesweeper.java +++ b/src/main/java/depth_first_search/Minesweeper.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; /** diff --git a/src/main/java/depth_first_search/MinimizeMalwareSpread.java b/src/main/java/depth_first_search/MinimizeMalwareSpread.java new file mode 100644 index 00000000..4731f44d --- /dev/null +++ b/src/main/java/depth_first_search/MinimizeMalwareSpread.java @@ -0,0 +1,137 @@ +/* (C) 2024 YourCompanyName */ +package depth_first_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 20/08/2019 In a network of nodes, each node i is directly + * connected to another node j if and only if graph[i][j] = 1. + * + *

Some nodes initial are initially infected by malware. Whenever two nodes are directly + * connected and at least one of those two nodes is infected by malware, both nodes will be infected + * by malware. This spread of malware will continue until no more nodes can be infected in this + * manner. + * + *

Suppose M(initial) is the final number of nodes infected with malware in the entire network, + * after the spread of malware stops. + * + *

We will remove one node from the initial list. Return the node that if removed, would minimize + * M(initial). If multiple nodes could be removed to minimize M(initial), return such a node with + * the smallest index. + * + *

Note that if a node was removed from the initial list of infected nodes, it may still be + * infected later as a result of the malware spread. + * + *

Example 1: + * + *

Input: graph = [[1,1,0],[1,1,0],[0,0,1]], initial = [0,1] Output: 0 Example 2: + * + *

Input: graph = [[1,0,0],[0,1,0],[0,0,1]], initial = [0,2] Output: 0 Example 3: + * + *

Input: graph = [[1,1,1],[1,1,1],[1,1,1]], initial = [1,2] Output: 1 + * + *

Note: + * + *

1 < graph.length = graph[0].length <= 300 0 <= graph[i][j] == graph[j][i] <= 1 graph[i][i] = 1 + * 1 <= initial.length < graph.length 0 <= initial[i] < graph.length + * + *

Solution: O(N x M x I) + O(I ^ 2) where N x M is number of nodes and I is the size of the + * initial Do a dfs from each of the initial nodes and color the reachable nodes with color i (color + * of initial node) and keep track of count of nodes reachable by this node - do not re-visit the + * already visited nodes. Check the list of initial nodes which have unique color which no other + * initial nodes have and mark this as eligible candidate. Sort the eligible candidates by pick the + * candidate which has maximum count of nodes reachable from it. + */ +public class MinimizeMalwareSpread { + public static void main(String[] args) { + int[][] graph = { + {1, 0, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0}, + {0, 0, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 0}, + {0, 0, 0, 1, 1, 0}, + {0, 0, 0, 0, 0, 1} + }; + int[] i = {5, 0}; + new MinimizeMalwareSpread().minMalwareSpread(graph, i); + } + + Map> graphMap; + Map size; + Set done; + Map color; + int count = 0; + + public int minMalwareSpread(int[][] graph, int[] initial) { + graphMap = new HashMap<>(); + done = new HashSet<>(); + color = new HashMap<>(); + size = new HashMap<>(); + for (int i = 0; i < graph.length; i++) { + for (int j = 0; j < graph[0].length; j++) { + if (graph[i][j] == 1) { + graphMap.putIfAbsent(i, new ArrayList<>()); + graphMap.get(i).add(j); + graphMap.putIfAbsent(j, new ArrayList<>()); + graphMap.get(j).add(i); + } + } + } + for (int i : initial) { + if (!done.contains(i)) { + count = 0; + dfs(i, i); + size.put(i, count); + } + } + List eligible = new ArrayList<>(); + boolean candidate; + for (int i = 0; i < initial.length; i++) { + int iColor = color.get(initial[i]); + candidate = true; + for (int j = 0; j < initial.length; j++) { + if (j != i) { + if (color.get(initial[j]) == iColor) { + candidate = false; + break; + } + } + } + if (candidate) { + eligible.add(initial[i]); + } + } + Arrays.sort(initial); + eligible.sort(Comparator.comparingInt(o -> o)); + if (eligible.isEmpty()) { + return initial[0]; + } else { + int answer = initial[0]; + int max = 0; + for (int i = 0, l = eligible.size(); i < l; i++) { + int node = eligible.get(i); + if (size.containsKey(node)) { + if (size.get(node) > max) { + max = size.get(node); + answer = node; + } + } + } + return answer; + } + } + + private void dfs(int i, int col) { + done.add(i); + color.put(i, col); + count++; + List children = graphMap.get(i); + if (children != null && !children.isEmpty()) { + for (int c : children) { + if (!done.contains(c)) { + dfs(c, col); + } + } + } + } +} diff --git a/problems/src/depth_first_search/MovieRecommend.java b/src/main/java/depth_first_search/MovieRecommend.java similarity index 97% rename from problems/src/depth_first_search/MovieRecommend.java rename to src/main/java/depth_first_search/MovieRecommend.java index 1acb16b2..df6cf76b 100644 --- a/problems/src/depth_first_search/MovieRecommend.java +++ b/src/main/java/depth_first_search/MovieRecommend.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/problems/src/depth_first_search/NumberOfDistinctIslands.java b/src/main/java/depth_first_search/NumberOfDistinctIslands.java similarity index 98% rename from problems/src/depth_first_search/NumberOfDistinctIslands.java rename to src/main/java/depth_first_search/NumberOfDistinctIslands.java index e20e8960..e774fb17 100644 --- a/problems/src/depth_first_search/NumberOfDistinctIslands.java +++ b/src/main/java/depth_first_search/NumberOfDistinctIslands.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.HashSet; diff --git a/problems/src/depth_first_search/NumberOfDistinctIslandsII.java b/src/main/java/depth_first_search/NumberOfDistinctIslandsII.java similarity index 99% rename from problems/src/depth_first_search/NumberOfDistinctIslandsII.java rename to src/main/java/depth_first_search/NumberOfDistinctIslandsII.java index ae4af067..84f30333 100644 --- a/problems/src/depth_first_search/NumberOfDistinctIslandsII.java +++ b/src/main/java/depth_first_search/NumberOfDistinctIslandsII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.*; diff --git a/src/main/java/depth_first_search/NumberOfEnclaves.java b/src/main/java/depth_first_search/NumberOfEnclaves.java new file mode 100644 index 00000000..a5b65dc6 --- /dev/null +++ b/src/main/java/depth_first_search/NumberOfEnclaves.java @@ -0,0 +1,76 @@ +/* (C) 2024 YourCompanyName */ +package depth_first_search; + +/** + * Created by gouthamvidyapradhan on 31/07/2019 Given a 2D array A, each cell is 0 (representing + * sea) or 1 (representing land) + * + *

A move consists of walking from one land square 4-directionally to another land square, or off + * the boundary of the grid. + * + *

Return the number of land squares in the grid for which we cannot walk off the boundary of the + * grid in any number of moves. + * + *

Example 1: + * + *

Input: [[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]] Output: 3 Explanation: There are three 1s + * that are enclosed by 0s, and one 1 that isn't enclosed because its on the boundary. Example 2: + * + *

Input: [[0,1,1,0],[0,0,1,0],[0,0,1,0],[0,0,0,0]] Output: 0 Explanation: All 1s are either on + * the boundary or can reach the boundary. + * + *

Note: + * + *

1 <= A.length <= 500 1 <= A[i].length <= 500 0 <= A[i][j] <= 1 All rows have the same size. + * Solution O(N x M) Do a dfs to count number of enclaves - in each dfs check if it violates the + * condition to be considered a enclave. + */ +public class NumberOfEnclaves { + + final int[] R = {0, 0, -1, 1}; + final int[] C = {1, -1, 0, 0}; + + boolean[][] done; + int count = 0; + int answer = 0; + boolean possible = true; + + public static void main(String[] args) { + int[][] A = {{0, 1, 1, 0}, {0, 0, 1, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}}; + System.out.println(new NumberOfEnclaves().numEnclaves(A)); + } + + public int numEnclaves(int[][] A) { + done = new boolean[A.length][A[0].length]; + for (int i = 0; i < A.length; i++) { + for (int j = 0; j < A[0].length; j++) { + if (!done[i][j] && A[i][j] == 1) { + count = 0; + possible = true; + dfs(A, i, j); + if (possible) { + answer += count; + } + } + } + } + return answer; + } + + private void dfs(int[][] A, int r, int c) { + done[r][c] = true; + if (r == 0 || c == 0 || r == A.length - 1 || c == A[0].length - 1) { + possible = false; + } + count++; + for (int i = 0; i < 4; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR < A.length && newC < A[0].length && newR >= 0 && newC >= 0 && !done[newR][newC]) { + if (A[newR][newC] == 1) { + dfs(A, newR, newC); + } + } + } + } +} diff --git a/problems/src/depth_first_search/NumberOfIslands.java b/src/main/java/depth_first_search/NumberOfIslands.java similarity index 97% rename from problems/src/depth_first_search/NumberOfIslands.java rename to src/main/java/depth_first_search/NumberOfIslands.java index a4745b05..1d6925dd 100644 --- a/problems/src/depth_first_search/NumberOfIslands.java +++ b/src/main/java/depth_first_search/NumberOfIslands.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; /** diff --git a/src/main/java/depth_first_search/ParallelCourses.java b/src/main/java/depth_first_search/ParallelCourses.java new file mode 100644 index 00000000..010ca8dc --- /dev/null +++ b/src/main/java/depth_first_search/ParallelCourses.java @@ -0,0 +1,91 @@ +/* (C) 2024 YourCompanyName */ +package depth_first_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 26/11/2019 There are N courses, labelled from 1 to N. + * + *

We are given relations[i] = [X, Y], representing a prerequisite relationship between course X + * and course Y: course X has to be studied before course Y. + * + *

In one semester you can study any number of courses as long as you have studied all the + * prerequisites for the course you are studying. + * + *

Return the minimum number of semesters needed to study all courses. If there is no way to + * study all the courses, return -1. + * + *

Example 1: + * + *

Input: N = 3, relations = [[1,3],[2,3]] Output: 2 Explanation: In the first semester, courses + * 1 and 2 are studied. In the second semester, course 3 is studied. Example 2: + * + *

Input: N = 3, relations = [[1,2],[2,3],[3,1]] Output: -1 Explanation: No course can be studied + * because they depend on each other. + * + *

Note: + * + *

1 <= N <= 5000 1 <= relations.length <= 5000 relations[i][0] != relations[i][1] There are no + * repeated relations in the input. + */ +public class ParallelCourses { + public static void main(String[] args) { + int[][] A = {{1, 3}, {2, 3}}; + System.out.println(new ParallelCourses().minimumSemesters(3, A)); + } + + Map> graph; + Set done; + Set visited; + + public int minimumSemesters(int N, int[][] relations) { + graph = new HashMap<>(); + for (int[] E : relations) { + graph.putIfAbsent(E[0], new ArrayList<>()); + graph.get(E[0]).add(E[1]); + } + done = new HashSet<>(); + visited = new HashSet<>(); + Stack stack = new Stack<>(); + for (int v : graph.keySet()) { + if (!done.contains(v)) { + boolean status = dfs(v, stack); // toposort and return false if a cycle is found + if (!status) return -1; + } + } + int[] DP = new int[N + 1]; + int max = 0; + while (!stack.isEmpty()) { + int v = stack.pop(); + List children = graph.get(v); + if (children != null) { + for (int c : children) { + DP[c] = Math.max(DP[c], DP[v] + 1); + max = Math.max(max, DP[c]); + } + } + } + return max + 1; + } + + private boolean dfs(int v, Stack stack) { + done.add(v); + visited.add(v); + List children = graph.get(v); + if (children != null) { + for (int c : children) { + if (!visited.contains(c)) { + if (!done.contains(c)) { + boolean status = dfs(c, stack); + if (!status) return false; + } + } else { + return false; + } + } + } + visited.remove(v); + stack.push(v); + return true; + } +} diff --git a/problems/src/depth_first_search/RobotRoomCleaner.java b/src/main/java/depth_first_search/RobotRoomCleaner.java similarity index 99% rename from problems/src/depth_first_search/RobotRoomCleaner.java rename to src/main/java/depth_first_search/RobotRoomCleaner.java index 189a6478..9da6a0f5 100644 --- a/problems/src/depth_first_search/RobotRoomCleaner.java +++ b/src/main/java/depth_first_search/RobotRoomCleaner.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; import java.util.HashSet; diff --git a/src/main/java/depth_first_search/SatisfiabilityOfEquations.java b/src/main/java/depth_first_search/SatisfiabilityOfEquations.java new file mode 100644 index 00000000..034f7247 --- /dev/null +++ b/src/main/java/depth_first_search/SatisfiabilityOfEquations.java @@ -0,0 +1,103 @@ +/* (C) 2024 YourCompanyName */ +package depth_first_search; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 25/07/2019 Given an array equations of strings that represent + * relationships between variables, each string equations[i] has length 4 and takes one of two + * different forms: "a==b" or "a!=b". Here, a and b are lowercase letters (not necessarily + * different) that represent one-letter variable names. + * + *

Return true if and only if it is possible to assign integers to variable names so as to + * satisfy all the given equations. + * + *

Example 1: + * + *

Input: ["a==b","b!=a"] Output: false Explanation: If we assign say, a = 1 and b = 1, then the + * first equation is satisfied, but not the second. There is no way to assign the variables to + * satisfy both equations. Example 2: + * + *

Input: ["b==a","a==b"] Output: true Explanation: We could assign a = 1 and b = 1 to satisfy + * both equations. Example 3: + * + *

Input: ["a==b","b==c","a==c"] Output: true Example 4: + * + *

Input: ["a==b","b!=c","c==a"] Output: false Example 5: + * + *

Input: ["c==c","b==d","x!=z"] Output: true + * + *

Note: + * + *

1 <= equations.length <= 500 equations[i].length == 4 equations[i][0] and equations[i][3] are + * lowercase letters equations[i][1] is either '=' or '!' equations[i][2] is '=' + * + *

Solution: O(N) For all the equations which are of the form 'a==b' form a graph of connected + * components. Start assigning values to each of the connected components. All the nodes in the + * connected components should have the same value assigned - If any of the connected components + * fails this criteria then return false. + */ +public class SatisfiabilityOfEquations { + public static void main(String[] args) { + String[] input = {"c==c", "f!=a", "f==b", "b==c"}; + System.out.println(new SatisfiabilityOfEquations().equationsPossible(input)); + } + + private Set done; + private Map valueMap; + private int count = 0; + + public boolean equationsPossible(String[] equations) { + Map> graph = new HashMap<>(); + done = new HashSet<>(); + valueMap = new HashMap<>(); + for (String eq : equations) { + if (eq.charAt(1) == '=') { + graph.putIfAbsent(eq.charAt(0), new ArrayList<>()); + graph.get(eq.charAt(0)).add(eq.charAt(3)); + graph.putIfAbsent(eq.charAt(3), new ArrayList<>()); + graph.get(eq.charAt(3)).add(eq.charAt(0)); + } + } + for (char c : graph.keySet()) { + if (!done.contains(c)) { + dfs(c, graph, ++count); + } + } + + for (String eq : equations) { + if (eq.charAt(1) == '!') { + char a = eq.charAt(0); + char b = eq.charAt(3); + if (a == b) return false; + if (valueMap.containsKey(a) && valueMap.containsKey(b)) { + if (valueMap.get(a).intValue() == valueMap.get(b).intValue()) { + return false; + } + } + } + } + return true; + } + + private boolean dfs(char node, Map> graph, int value) { + done.add(node); + valueMap.put(node, value); + List children = graph.get(node); + if (!children.isEmpty()) { + for (char c : children) { + if (!done.contains(c)) { + boolean status = dfs(c, graph, value); + if (!status) { + return status; + } + } else { + if (valueMap.get(c) != value) { + return false; + } + } + } + } + return true; + } +} diff --git a/problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java b/src/main/java/depth_first_search/SmallestRectangleEnclosingBlackPixels.java similarity index 98% rename from problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java rename to src/main/java/depth_first_search/SmallestRectangleEnclosingBlackPixels.java index b82ed190..055f6026 100644 --- a/problems/src/depth_first_search/SmallestRectangleEnclosingBlackPixels.java +++ b/src/main/java/depth_first_search/SmallestRectangleEnclosingBlackPixels.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package depth_first_search; /** diff --git a/problems/src/design/AutocompleteSystem.java b/src/main/java/design/AutocompleteSystem.java similarity index 99% rename from problems/src/design/AutocompleteSystem.java rename to src/main/java/design/AutocompleteSystem.java index ebe9deb2..105100d4 100644 --- a/problems/src/design/AutocompleteSystem.java +++ b/src/main/java/design/AutocompleteSystem.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.*; diff --git a/problems/src/design/BSTIterator.java b/src/main/java/design/BSTIterator.java similarity index 98% rename from problems/src/design/BSTIterator.java rename to src/main/java/design/BSTIterator.java index 743eae61..107d86ba 100644 --- a/problems/src/design/BSTIterator.java +++ b/src/main/java/design/BSTIterator.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.Stack; diff --git a/problems/src/design/CopyListWithRandomPointer.java b/src/main/java/design/CopyListWithRandomPointer.java similarity index 98% rename from problems/src/design/CopyListWithRandomPointer.java rename to src/main/java/design/CopyListWithRandomPointer.java index dbcb225c..2c1c5eb6 100644 --- a/problems/src/design/CopyListWithRandomPointer.java +++ b/src/main/java/design/CopyListWithRandomPointer.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; /** diff --git a/problems/src/design/EncodeAndDecodeTinyURL.java b/src/main/java/design/EncodeAndDecodeTinyURL.java similarity index 97% rename from problems/src/design/EncodeAndDecodeTinyURL.java rename to src/main/java/design/EncodeAndDecodeTinyURL.java index 94ca34f8..859a0684 100644 --- a/problems/src/design/EncodeAndDecodeTinyURL.java +++ b/src/main/java/design/EncodeAndDecodeTinyURL.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.ArrayList; diff --git a/problems/src/design/Excel.java b/src/main/java/design/Excel.java similarity index 99% rename from problems/src/design/Excel.java rename to src/main/java/design/Excel.java index c00bd33a..240acab5 100644 --- a/problems/src/design/Excel.java +++ b/src/main/java/design/Excel.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.*; diff --git a/problems/src/design/LFUCache.java b/src/main/java/design/LFUCache.java similarity index 99% rename from problems/src/design/LFUCache.java rename to src/main/java/design/LFUCache.java index 371054bf..3f5d2143 100644 --- a/problems/src/design/LFUCache.java +++ b/src/main/java/design/LFUCache.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.HashMap; diff --git a/problems/src/design/LRUCache.java b/src/main/java/design/LRUCache.java similarity index 99% rename from problems/src/design/LRUCache.java rename to src/main/java/design/LRUCache.java index 2d12a86e..9f02b5c1 100644 --- a/problems/src/design/LRUCache.java +++ b/src/main/java/design/LRUCache.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.HashMap; diff --git a/problems/src/design/NestedIterator.java b/src/main/java/design/NestedIterator.java similarity index 98% rename from problems/src/design/NestedIterator.java rename to src/main/java/design/NestedIterator.java index b7d1fc09..54ffa9c0 100644 --- a/problems/src/design/NestedIterator.java +++ b/src/main/java/design/NestedIterator.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.ArrayList; diff --git a/problems/src/design/RandomizedCollection.java b/src/main/java/design/RandomizedCollection.java similarity index 99% rename from problems/src/design/RandomizedCollection.java rename to src/main/java/design/RandomizedCollection.java index 466178c4..9d3abb76 100644 --- a/problems/src/design/RandomizedCollection.java +++ b/src/main/java/design/RandomizedCollection.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.*; diff --git a/problems/src/design/RandomizedSet.java b/src/main/java/design/RandomizedSet.java similarity index 99% rename from problems/src/design/RandomizedSet.java rename to src/main/java/design/RandomizedSet.java index 42babec3..5d52197e 100644 --- a/problems/src/design/RandomizedSet.java +++ b/src/main/java/design/RandomizedSet.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.*; diff --git a/problems/src/design/SerializeDeserializeBinaryTree.java b/src/main/java/design/SerializeDeserializeBinaryTree.java similarity index 99% rename from problems/src/design/SerializeDeserializeBinaryTree.java rename to src/main/java/design/SerializeDeserializeBinaryTree.java index 2313ad53..cdb5a640 100644 --- a/problems/src/design/SerializeDeserializeBinaryTree.java +++ b/src/main/java/design/SerializeDeserializeBinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.*; diff --git a/problems/src/design/TicTacToe.java b/src/main/java/design/TicTacToe.java similarity index 99% rename from problems/src/design/TicTacToe.java rename to src/main/java/design/TicTacToe.java index 1e0728b8..2f356a77 100644 --- a/problems/src/design/TicTacToe.java +++ b/src/main/java/design/TicTacToe.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; /** diff --git a/problems/src/design/Trie.java b/src/main/java/design/Trie.java similarity index 98% rename from problems/src/design/Trie.java rename to src/main/java/design/Trie.java index f49eeccf..e896bb0a 100644 --- a/problems/src/design/Trie.java +++ b/src/main/java/design/Trie.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.HashMap; diff --git a/problems/src/design/Twitter.java b/src/main/java/design/Twitter.java similarity index 99% rename from problems/src/design/Twitter.java rename to src/main/java/design/Twitter.java index 8c58506a..f5c0e622 100644 --- a/problems/src/design/Twitter.java +++ b/src/main/java/design/Twitter.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.*; diff --git a/problems/src/design/WordDictionary.java b/src/main/java/design/WordDictionary.java similarity index 99% rename from problems/src/design/WordDictionary.java rename to src/main/java/design/WordDictionary.java index af1c8e58..b24468ca 100644 --- a/problems/src/design/WordDictionary.java +++ b/src/main/java/design/WordDictionary.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.HashMap; diff --git a/problems/src/design/WordFilter.java b/src/main/java/design/WordFilter.java similarity index 99% rename from problems/src/design/WordFilter.java rename to src/main/java/design/WordFilter.java index 566f5999..23e21b71 100644 --- a/problems/src/design/WordFilter.java +++ b/src/main/java/design/WordFilter.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package design; import java.util.HashMap; diff --git a/problems/src/divide_and_conquer/KthLargestElementInAnArray.java b/src/main/java/divide_and_conquer/KthLargestElementInAnArray.java similarity index 97% rename from problems/src/divide_and_conquer/KthLargestElementInAnArray.java rename to src/main/java/divide_and_conquer/KthLargestElementInAnArray.java index d1666fb3..d87be858 100644 --- a/problems/src/divide_and_conquer/KthLargestElementInAnArray.java +++ b/src/main/java/divide_and_conquer/KthLargestElementInAnArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package divide_and_conquer; /** diff --git a/src/main/java/divide_and_conquer/MyCalendarII.java b/src/main/java/divide_and_conquer/MyCalendarII.java new file mode 100644 index 00000000..45462d50 --- /dev/null +++ b/src/main/java/divide_and_conquer/MyCalendarII.java @@ -0,0 +1,99 @@ +/* (C) 2024 YourCompanyName */ +package divide_and_conquer; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 02/11/2019 Implement a MyCalendarTwo class to store your + * events. A new event can be added if adding the event will not cause a triple booking. + * + *

Your class will have one method, book(int start, int end). Formally, this represents a booking + * on the half open interval [start, end), the range of real numbers x such that start <= x < end. + * + *

A triple booking happens when three events have some non-empty intersection (ie., there is + * some time that is common to all 3 events.) + * + *

For each call to the method MyCalendar.book, return true if the event can be added to the + * calendar successfully without causing a triple booking. Otherwise, return false and do not add + * the event to the calendar. + * + *

Your class will be called like this: MyCalendar cal = new MyCalendar(); MyCalendar.book(start, + * end) Example 1: + * + *

MyCalendar(); MyCalendar.book(10, 20); // returns true MyCalendar.book(50, 60); // returns + * true MyCalendar.book(10, 40); // returns true MyCalendar.book(5, 15); // returns false + * MyCalendar.book(5, 10); // returns true MyCalendar.book(25, 55); // returns true Explanation: The + * first two events can be booked. The third event can be double booked. The fourth event (5, 15) + * can't be booked, because it would result in a triple booking. The fifth event (5, 10) can be + * booked, as it does not use time 10 which is already double booked. The sixth event (25, 55) can + * be booked, as the time in [25, 40) will be double booked with the third event; the time [40, 50) + * will be single booked, and the time [50, 55) will be double booked with the second event. + * + *

Note: + * + *

The number of calls to MyCalendar.book per test case will be at most 1000. In calls to + * MyCalendar.book(start, end), start and end are integers in the range [0, 10^9]. + */ +public class MyCalendarII { + public static void main(String[] args) { + MyCalendarII t = new MyCalendarII(); + System.out.println(t.book(20, 27)); + System.out.println(t.book(27, 36)); + System.out.println(t.book(27, 36)); + System.out.println(t.book(24, 33)); + } + + private class Pair { + int a, b, index; + + Pair(int a, int b, int index) { + this.a = a; + this.b = b; + this.index = index; + } + } + + TreeSet treeSet; + int count; + + public MyCalendarII() { + count = 0; + treeSet = + new TreeSet<>( + (o1, o2) -> { + int r = Integer.compare(o1.a, o2.a); + if (r == 0) { + int r2 = Integer.compare(o1.b, o2.b); + if (r2 == 0) { + return Integer.compare(o1.index, o2.index); + } else return r2; + } + return r; + }); + } + + public boolean book(int start, int end) { + Pair range = new Pair(start, end, count++); + Iterator ascending = treeSet.iterator(); + Pair prev = null; + while (ascending.hasNext()) { + Pair cur = ascending.next(); + if (prev != null) { + if ((range.a >= prev.a && range.a < prev.b) && (range.a >= cur.a && range.a < cur.b)) { + return false; + } else if ((prev.a >= range.a && prev.a < range.b) + && (cur.a >= prev.a && cur.a < Math.min(prev.b, range.b))) { + return false; + } else if ((range.a >= prev.a && range.a < range.b) + && (cur.a >= range.a && cur.a < Math.min(prev.b, range.b))) { + return false; + } + } + if ((range.a >= cur.a && range.a < cur.b) || (cur.a >= range.a && cur.a < range.b)) { + prev = cur; + } + } + treeSet.add(range); + return true; + } +} diff --git a/problems/src/divide_and_conquer/ReversePairs.java b/src/main/java/divide_and_conquer/ReversePairs.java similarity index 99% rename from problems/src/divide_and_conquer/ReversePairs.java rename to src/main/java/divide_and_conquer/ReversePairs.java index a919a4ef..0706ccf8 100644 --- a/problems/src/divide_and_conquer/ReversePairs.java +++ b/src/main/java/divide_and_conquer/ReversePairs.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package divide_and_conquer; import java.util.*; diff --git a/src/main/java/divide_and_conquer/ReversePairsII.java b/src/main/java/divide_and_conquer/ReversePairsII.java new file mode 100644 index 00000000..fb79020b --- /dev/null +++ b/src/main/java/divide_and_conquer/ReversePairsII.java @@ -0,0 +1,87 @@ +/* (C) 2024 YourCompanyName */ +package divide_and_conquer; + +/** + * Created by gouthamvidyapradhan on 01/08/2019 Given an array nums, we call (i, j) an important + * reverse pair if i < j and nums[i] > 2*nums[j]. + * + *

You need to return the number of important reverse pairs in the given array. + * + *

Example1: + * + *

Input: [1,3,2,3,1] Output: 2 Example2: + * + *

Input: [2,4,3,5,1] Output: 3 Note: The length of the given array will not exceed 50,000. All + * the numbers in the input array are in the range of 32-bit integer. + * + *

Solution: O(N log N) Given two sorted arrays A[] and B[] it is quite easy to see for every + * element i in A, how many elements in A have a value > 2 * B[j] using binary search (also possible + * using two pointers) - using this idea we can implement standard merge sort algorithm and for + * every sorted pairs A[] and B[] before we merge we can total number of elements in A which are > 2 + * x B[i] + */ +public class ReversePairsII { + public static void main(String[] args) { + int[] A = {2, 4, 3, 5, 1}; + System.out.println(new ReversePairsII().reversePairs(A)); + } + + int answer = 0; + + public int reversePairs(int[] nums) { + mergeSort(nums, 0, nums.length - 1); + return answer; + } + + private int[] mergeSort(int[] num, int l, int h) { + if (l < h) { + int m = l + (h - l) / 2; + int[] left = mergeSort(num, l, m); + int[] right = mergeSort(num, m + 1, h); + return merge(left, right); + } else if (l == h) { + return new int[] {num[l]}; + } else { + return new int[] {}; + } + } + + private int[] merge(int[] A, int[] B) { + for (int i = 0; i < B.length; i++) { + int num = B[i]; + int l = 0, h = A.length; + int index = -1; + while (l < h) { + int m = l + (h - l) / 2; + if ((long) A[m] > (2 * (long) num)) { + index = m; + h = m; + } else { + l = m + 1; + } + } + if (index > -1) { + answer += ((A.length - index)); + } + } + int[] C = new int[A.length + B.length]; + int k = 0; + int i = 0, j = 0; + for (; i < A.length && j < B.length; ) { + if (A[i] < B[j]) { + C[k++] = A[i]; + i++; + } else { + C[k++] = B[j]; + j++; + } + } + while (i < A.length) { + C[k++] = A[i++]; + } + while (j < B.length) { + C[k++] = B[j++]; + } + return C; + } +} diff --git a/problems/src/divide_and_conquer/SearchA2DMatrix.java b/src/main/java/divide_and_conquer/SearchA2DMatrix.java similarity index 97% rename from problems/src/divide_and_conquer/SearchA2DMatrix.java rename to src/main/java/divide_and_conquer/SearchA2DMatrix.java index e6941fb0..5234afae 100644 --- a/problems/src/divide_and_conquer/SearchA2DMatrix.java +++ b/src/main/java/divide_and_conquer/SearchA2DMatrix.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package divide_and_conquer; /** diff --git a/src/main/java/divide_and_conquer/TwentyFourGame.java b/src/main/java/divide_and_conquer/TwentyFourGame.java new file mode 100644 index 00000000..a9c5535a --- /dev/null +++ b/src/main/java/divide_and_conquer/TwentyFourGame.java @@ -0,0 +1,113 @@ +/* (C) 2024 YourCompanyName */ +package divide_and_conquer; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 18/05/2019 You have 4 cards each containing a number from 1 to + * 9. You need to judge whether they could operated through *, /, +, -, (, ) to get the value of 24. + * + *

Example 1: Input: [4, 1, 8, 7] Output: True Explanation: (8-4) * (7-1) = 24 Example 2: Input: + * [1, 2, 1, 2] Output: False Note: The division operator / represents real division, not integer + * division. For example, 4 / (1 - 2/3) = 12. Every operation done is between two numbers. In + * particular, we cannot use - as a unary operator. For example, with [1, 1, 1, 1] as input, the + * expression -1 - 1 - 1 - 1 is not allowed. You cannot concatenate numbers together. For example, + * if the input is [1, 2, 1, 2], we cannot write this as 12 + 12. + * + *

Solution O(1) Generate all permutation of a given 4 digit number and for each permutation + * split the number into two parts with left and right (at various possible split points). Now + * perform all possible operations(+, -, * and /) for each left and right and check if any of the + * operation results in 24 + */ +public class TwentyFourGame { + + public static void main(String[] args) { + int[] A = {4, 7, 7, 7}; + System.out.println(new TwentyFourGame().judgePoint24(A)); + } + + class Fraction { + int n, d; + + Fraction(int n, int d) { + this.n = n; + this.d = d; + } + } + + public boolean judgePoint24(int[] nums) { + List result = new ArrayList<>(); + permute(0, nums, result); + for (int[] A : result) { + List list = generate(0, 3, A); + for (Fraction f : list) { + if ((f.d != 0) && (f.n / f.d) == 24 && (f.n % f.d) == 0) return true; + } + } + return false; + } + + private void permute(int i, int[] nums, List result) { + if (i >= nums.length) { + result.add(Arrays.copyOf(nums, 4)); + } else { + for (int j = i; j < nums.length; j++) { + swap(i, j, nums); + permute(i + 1, nums, result); + swap(i, j, nums); + } + } + } + + private void swap(int i, int j, int[] nums) { + int temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } + + private List generate(int l, int r, int[] nums) { + if (l > r) { + return new ArrayList<>(); + } else if (l == r) { + return Arrays.asList(new Fraction(nums[l], 1)); + } else { + List result = new ArrayList<>(); + for (int i = l; i < r; i++) { + for (int j = l; j <= i; j++) { + List left = generate(l, j, nums); + List right = generate(j + 1, r, nums); + if (right.isEmpty()) { + result.addAll(left); + } else if (left.isEmpty()) { + result.addAll(right); + } else { + for (Fraction lF : left) { + for (Fraction rF : right) { + int n = (lF.n * rF.d + rF.n * lF.d); + int d = (lF.d * rF.d); + Fraction sum = new Fraction(n, d); + + n = (lF.n * rF.d - (rF.n * lF.d)); + d = (lF.d * rF.d); + Fraction diff = new Fraction(n, d); + + n = (lF.n * rF.n); + d = (lF.d * rF.d); + Fraction prod = new Fraction(n, d); + + n = (lF.n * rF.d); + d = (lF.d * rF.n); + Fraction div = new Fraction(n, d); + result.add(sum); + result.add(diff); + result.add(prod); + result.add(div); + } + } + } + } + } + return result; + } + } +} diff --git a/problems/src/dynamic_programming/BestTimeToBuyAndSellStockIII.java b/src/main/java/dynamic_programming/BestTimeToBuyAndSellStockIII.java similarity index 98% rename from problems/src/dynamic_programming/BestTimeToBuyAndSellStockIII.java rename to src/main/java/dynamic_programming/BestTimeToBuyAndSellStockIII.java index 01bffcb1..9e03a07e 100644 --- a/problems/src/dynamic_programming/BestTimeToBuyAndSellStockIII.java +++ b/src/main/java/dynamic_programming/BestTimeToBuyAndSellStockIII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java b/src/main/java/dynamic_programming/BestTimeToBuyAndSellStocks.java similarity index 97% rename from problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java rename to src/main/java/dynamic_programming/BestTimeToBuyAndSellStocks.java index acb6eb14..5945831f 100644 --- a/problems/src/dynamic_programming/BestTimeToBuyAndSellStocks.java +++ b/src/main/java/dynamic_programming/BestTimeToBuyAndSellStocks.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java b/src/main/java/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java similarity index 98% rename from problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java rename to src/main/java/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java index 7154a204..ba4b3100 100644 --- a/problems/src/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java +++ b/src/main/java/dynamic_programming/BestTimeToBuyAndSellStocksWithFee.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/BombEnemy.java b/src/main/java/dynamic_programming/BombEnemy.java new file mode 100644 index 00000000..ece7d3d1 --- /dev/null +++ b/src/main/java/dynamic_programming/BombEnemy.java @@ -0,0 +1,73 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 25/01/2020 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: You can only put the bomb at an + * empty cell. + * + *

Example: + * + *

Input: [["0","E","0","0"],["E","0","W","E"],["0","E","0","0"]] Output: 3 Explanation: For the + * given grid, + * + *

0 E 0 0 E 0 W E 0 E 0 0 + * + *

Placing a bomb at (1,1) kills 3 enemies. + */ +public class BombEnemy { + public static void main(String[] args) { + char[][] grid = {{'0', 'E', '0', '0'}, {'E', '0', 'W', 'E'}, {'0', 'E', '0', '0'}}; + System.out.println(new BombEnemy().maxKilledEnemies(grid)); + } + + public int maxKilledEnemies(char[][] grid) { + int[][] DP1 = new int[grid.length][grid[0].length]; + int[][] DP2 = new int[grid.length][grid[0].length]; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 'E') { + DP1[i][j] = 1; + } + if (grid[i][j] != 'W') { + if (j - 1 >= 0) { + DP1[i][j] += DP1[i][j - 1]; + } + if (i - 1 >= 0) { + DP1[i][j] += DP1[i - 1][j]; + } + } + } + } + + for (int i = grid.length - 1; i >= 0; i--) { + for (int j = grid[0].length - 1; j >= 0; j--) { + if (grid[i][j] == 'E') { + DP2[i][j] = 1; + } + if (grid[i][j] != 'W') { + if (j + 1 < grid[0].length) { + DP2[i][j] += DP2[i][j + 1]; + } + if (i + 1 < grid.length) { + DP2[i][j] += DP2[i + 1][j]; + } + } + } + } + + int max = 0; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == '0') { + max = Math.max(max, DP1[i][j] + DP2[i][j]); + } + } + } + return max; + } +} diff --git a/problems/src/dynamic_programming/BurstBalloons.java b/src/main/java/dynamic_programming/BurstBalloons.java similarity index 79% rename from problems/src/dynamic_programming/BurstBalloons.java rename to src/main/java/dynamic_programming/BurstBalloons.java index 0379ebad..7a7db0f3 100644 --- a/problems/src/dynamic_programming/BurstBalloons.java +++ b/src/main/java/dynamic_programming/BurstBalloons.java @@ -1,7 +1,6 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; -import java.util.Arrays; - /** * Created by gouthamvidyapradhan on 02/01/2018. 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 @@ -52,11 +51,28 @@ public int maxCoins(int[] nums) { for (int i = 0; i < nums.length; i++) { N[i + 1] = nums[i]; } + int[][] DP = new int[N.length][N.length]; + for (int r = 2; r < N.length; r++) { + for (int i = 0; i < N.length; i++) { + int j = i + r; + if (j < N.length) { + int max = Integer.MIN_VALUE; + for (int t = i + 1; t < j; t++) { + max = Math.max(max, N[t] * N[i] * N[j] + DP[t][j] + DP[i][t]); + } + DP[i][j] = max; + } + } + } + return DP[0][N.length - 1]; + /* for (int i = 0; i < nums.length; i++) { + N[i + 1] = nums[i]; + } dp = new int[N.length][N.length]; for (int[] aDp : dp) { Arrays.fill(aDp, -1); - } - return dp(0, N.length - 1); + }*/ + // return dp(0, N.length - 1); } private int dp(int l, int r) { diff --git a/problems/src/dynamic_programming/CanIWin.java b/src/main/java/dynamic_programming/CanIWin.java similarity index 98% rename from problems/src/dynamic_programming/CanIWin.java rename to src/main/java/dynamic_programming/CanIWin.java index f68e925d..183b85aa 100644 --- a/problems/src/dynamic_programming/CanIWin.java +++ b/src/main/java/dynamic_programming/CanIWin.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.HashMap; diff --git a/problems/src/dynamic_programming/CatAndMouse.java b/src/main/java/dynamic_programming/CatAndMouse.java similarity index 99% rename from problems/src/dynamic_programming/CatAndMouse.java rename to src/main/java/dynamic_programming/CatAndMouse.java index b0dbbdb0..7d8e847d 100644 --- a/problems/src/dynamic_programming/CatAndMouse.java +++ b/src/main/java/dynamic_programming/CatAndMouse.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/problems/src/dynamic_programming/CherryPickup.java b/src/main/java/dynamic_programming/CherryPickup.java similarity index 99% rename from problems/src/dynamic_programming/CherryPickup.java rename to src/main/java/dynamic_programming/CherryPickup.java index 348c11d0..082c03a6 100644 --- a/problems/src/dynamic_programming/CherryPickup.java +++ b/src/main/java/dynamic_programming/CherryPickup.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/CherryPickupII.java b/src/main/java/dynamic_programming/CherryPickupII.java new file mode 100644 index 00000000..0118620b --- /dev/null +++ b/src/main/java/dynamic_programming/CherryPickupII.java @@ -0,0 +1,90 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 28/07/2020 Given a rows x cols matrix grid representing a field + * of cherries. Each cell in grid represents the number of cherries that you can collect. + * + *

You have two robots that can collect cherries for you, Robot #1 is located at the top-left + * corner (0,0) , and Robot #2 is located at the top-right corner (0, cols-1) of the grid. + * + *

Return the maximum number of cherries collection using both robots by following the rules + * below: + * + *

From a cell (i,j), robots can move to cell (i+1, j-1) , (i+1, j) or (i+1, j+1). When any robot + * is passing through a cell, It picks it up all cherries, and the cell becomes an empty cell (0). + * When both robots stay on the same cell, only one of them takes the cherries. Both robots cannot + * move outside of the grid at any moment. Both robots should reach the bottom row in the grid. + * + *

Example 1: + * + *

Input: grid = [[3,1,1],[2,5,1],[1,5,5],[2,1,1]] Output: 24 Explanation: Path of robot #1 and + * #2 are described in color green and blue respectively. Cherries taken by Robot #1, (3 + 2 + 5 + + * 2) = 12. Cherries taken by Robot #2, (1 + 5 + 5 + 1) = 12. Total of cherries: 12 + 12 = 24. + * Example 2: + * + *

Input: grid = + * [[1,0,0,0,0,0,1],[2,0,0,0,0,3,0],[2,0,9,0,0,0,0],[0,3,0,5,4,0,0],[1,0,2,3,0,0,6]] Output: 28 + * Explanation: Path of robot #1 and #2 are described in color green and blue respectively. Cherries + * taken by Robot #1, (1 + 9 + 5 + 2) = 17. Cherries taken by Robot #2, (1 + 3 + 4 + 3) = 11. Total + * of cherries: 17 + 11 = 28. Example 3: + * + *

Input: grid = [[1,0,0,3],[0,0,0,3],[0,0,3,3],[9,0,3,3]] Output: 22 Example 4: + * + *

Input: grid = [[1,1],[1,1]] Output: 4 + * + *

Constraints: + * + *

rows == grid.length cols == grid[i].length 2 <= rows, cols <= 70 0 <= grid[i][j] <= 100 + */ +public class CherryPickupII { + private final int[] R = {1, 1, 1}; + private final int[] C = {0, -1, 1}; + + public static void main(String[] args) { + int[][] A = { + {1, 0, 0, 3}, + {2, 0, 0, 0, 0, 3, 0}, + {2, 0, 9, 0, 0, 0, 0}, + {0, 3, 0, 5, 4, 0, 0}, + {1, 0, 2, 3, 0, 0, 6} + }; + System.out.println(new CherryPickupII().cherryPickup(A)); + } + + int[][][] DP; + + public int cherryPickup(int[][] grid) { + DP = new int[grid.length][grid[0].length][grid[0].length]; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + Arrays.fill(DP[i][j], -1); + } + } + return dp(0, 0, grid[0].length - 1, grid); + } + + private int dp(int r, int c1, int c2, int[][] grid) { + if (DP[r][c1][c2] != -1) return DP[r][c1][c2]; + else { + int count = (c1 == c2) ? grid[r][c1] : (grid[r][c1] + grid[r][c2]); + int max = count; + for (int i = 0; i < 3; i++) { + int newR = r + R[i]; + int newC1 = c1 + C[i]; + if (newR >= 0 && newR < grid.length && newC1 >= 0 && newC1 < grid[0].length) { + for (int j = 0; j < 3; j++) { + int newC2 = c2 + C[j]; + if (newC2 >= 0 && newC2 < grid[0].length) { + max = Math.max(max, count + dp(newR, newC1, newC2, grid)); + } + } + } + } + DP[r][c1][c2] = max; + return max; + } + } +} diff --git a/problems/src/dynamic_programming/ClimbingStairs.java b/src/main/java/dynamic_programming/ClimbingStairs.java similarity index 95% rename from problems/src/dynamic_programming/ClimbingStairs.java rename to src/main/java/dynamic_programming/ClimbingStairs.java index 531687ac..6d283ed8 100644 --- a/problems/src/dynamic_programming/ClimbingStairs.java +++ b/src/main/java/dynamic_programming/ClimbingStairs.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/problems/src/dynamic_programming/CoinChange.java b/src/main/java/dynamic_programming/CoinChange.java similarity index 98% rename from problems/src/dynamic_programming/CoinChange.java rename to src/main/java/dynamic_programming/CoinChange.java index fedb648c..1233b457 100644 --- a/problems/src/dynamic_programming/CoinChange.java +++ b/src/main/java/dynamic_programming/CoinChange.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/problems/src/dynamic_programming/CoinChange2.java b/src/main/java/dynamic_programming/CoinChange2.java similarity index 98% rename from problems/src/dynamic_programming/CoinChange2.java rename to src/main/java/dynamic_programming/CoinChange2.java index fe5e84e6..86c5ff2f 100644 --- a/problems/src/dynamic_programming/CoinChange2.java +++ b/src/main/java/dynamic_programming/CoinChange2.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/problems/src/dynamic_programming/CombinationSumIV.java b/src/main/java/dynamic_programming/CombinationSumIV.java similarity index 97% rename from problems/src/dynamic_programming/CombinationSumIV.java rename to src/main/java/dynamic_programming/CombinationSumIV.java index 33a6634a..f0d2e714 100644 --- a/problems/src/dynamic_programming/CombinationSumIV.java +++ b/src/main/java/dynamic_programming/CombinationSumIV.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/problems/src/dynamic_programming/ConcatenatedWords.java b/src/main/java/dynamic_programming/ConcatenatedWords.java similarity index 98% rename from problems/src/dynamic_programming/ConcatenatedWords.java rename to src/main/java/dynamic_programming/ConcatenatedWords.java index eae5112d..f462ac00 100644 --- a/problems/src/dynamic_programming/ConcatenatedWords.java +++ b/src/main/java/dynamic_programming/ConcatenatedWords.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.ArrayList; diff --git a/src/main/java/dynamic_programming/ConstrainedSubsequenceSum.java b/src/main/java/dynamic_programming/ConstrainedSubsequenceSum.java new file mode 100644 index 00000000..5b1dcc06 --- /dev/null +++ b/src/main/java/dynamic_programming/ConstrainedSubsequenceSum.java @@ -0,0 +1,53 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.*; + +/** Created by gouthamvidyapradhan on 14/05/2020 */ +public class ConstrainedSubsequenceSum { + + public static void main(String[] args) { + int[] A = {10, -2, -10, -5, 20}; + System.out.println(new ConstrainedSubsequenceSum().constrainedSubsetSum(A, 2)); + } + + class Node { + int v, i; + + public int getV() { + return v; + } + + public int getI() { + return i; + } + + Node(int v, int i) { + this.v = v; + this.i = i; + } + } + + public int constrainedSubsetSum(int[] nums, int k) { + Queue pQ = + new PriorityQueue<>(Comparator.comparing(Node::getV).thenComparing(Node::getI).reversed()); + int max = Integer.MIN_VALUE; + for (int i = 0; i < nums.length; i++) { + int value = nums[i]; + while (!pQ.isEmpty() && (i - pQ.peek().i > k)) { + pQ.poll(); + } + if (pQ.isEmpty()) { + pQ.offer(new Node(value, i)); + } else { + if (pQ.peek().v + value > value) { + pQ.offer(new Node(pQ.peek().v + value, i)); + } else { + pQ.offer(new Node(value, i)); + } + } + max = Math.max(max, pQ.peek().v); + } + return max; + } +} diff --git a/problems/src/dynamic_programming/ContinuousSubarraySum.java b/src/main/java/dynamic_programming/ContinuousSubarraySum.java similarity index 98% rename from problems/src/dynamic_programming/ContinuousSubarraySum.java rename to src/main/java/dynamic_programming/ContinuousSubarraySum.java index 53c17413..4cdeb35d 100644 --- a/problems/src/dynamic_programming/ContinuousSubarraySum.java +++ b/src/main/java/dynamic_programming/ContinuousSubarraySum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.HashMap; diff --git a/problems/src/dynamic_programming/CornerRectangles.java b/src/main/java/dynamic_programming/CornerRectangles.java similarity index 98% rename from problems/src/dynamic_programming/CornerRectangles.java rename to src/main/java/dynamic_programming/CornerRectangles.java index 2ee8ec0f..649278dc 100644 --- a/problems/src/dynamic_programming/CornerRectangles.java +++ b/src/main/java/dynamic_programming/CornerRectangles.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/CountDifferentPalindromicSubsequences.java b/src/main/java/dynamic_programming/CountDifferentPalindromicSubsequences.java new file mode 100644 index 00000000..6b0476d6 --- /dev/null +++ b/src/main/java/dynamic_programming/CountDifferentPalindromicSubsequences.java @@ -0,0 +1,84 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 10/04/2021 Given a string S, find the number of different + * non-empty palindromic subsequences in S, and return that number modulo 10^9 + 7. + * + *

A subsequence of a string S is obtained by deleting 0 or more characters from S. + * + *

A sequence is palindromic if it is equal to the sequence reversed. + * + *

Two sequences A_1, A_2, ... and B_1, B_2, ... are different if there is some i for which A_i + * != B_i. + * + *

Example 1: Input: S = 'bccb' Output: 6 Explanation: The 6 different non-empty palindromic + * subsequences are 'b', 'c', 'bb', 'cc', 'bcb', 'bccb'. Note that 'bcb' is counted only once, even + * though it occurs twice. Example 2: Input: S = + * 'abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba' Output: 104860361 Explanation: + * There are 3104860382 different non-empty palindromic subsequences, which is 104860361 modulo 10^9 + * + 7. Note: + * + *

The length of S will be in the range [1, 1000]. Each character S[i] will be in the set {'a', + * 'b', 'c', 'd'}. + * + *

Solution: O(N ^ 2) x 4 + */ +public class CountDifferentPalindromicSubsequences { + public static void main(String[] args) { + System.out.println( + new CountDifferentPalindromicSubsequences() + .countPalindromicSubsequences( + "abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba")); + } + + private long[][][] DP; + final char[] chars = {'a', 'b', 'c', 'd'}; + final int MOD = (int) 1e9 + 7; + + public int countPalindromicSubsequences(String S) { + DP = new long[S.length()][S.length()][4]; + for (int i = 0; i < S.length(); i++) { + for (int j = 0; j < S.length(); j++) { + Arrays.fill(DP[i][j], -1); + } + } + long result = 0L; + for (char c : chars) { + long r = dp(0, S.length() - 1, S, c); + result = ((result + r) % MOD); + } + return (int) result; + } + + private long dp(int i, int j, String s, char c) { + if (i > j) return 0; + else if (DP[i][j][c - 'a'] != -1) return DP[i][j][c - 'a']; + else if (s.charAt(i) == s.charAt(j) && s.charAt(i) == c) { + if (i == j) return 1; + else { + long sum = 0L; + for (char aChar : chars) { + long r = dp(i + 1, j - 1, s, aChar); + if (aChar == c) { + r = ((r + 2) % MOD); + } + sum = ((sum + r) % MOD); + } + DP[i][j][c - 'a'] = sum; + return DP[i][j][c - 'a']; + } + } else if (s.charAt(i) == c) { + DP[i][j][c - 'a'] = dp(i, j - 1, s, c); + return DP[i][j][c - 'a']; + } else if (s.charAt(j) == c) { + DP[i][j][c - 'a'] = dp(i + 1, j, s, c); + return DP[i][j][c - 'a']; + } else { + DP[i][j][c - 'a'] = dp(i + 1, j - 1, s, c); + return DP[i][j][c - 'a']; + } + } +} diff --git a/src/main/java/dynamic_programming/CountVowelsPermutation.java b/src/main/java/dynamic_programming/CountVowelsPermutation.java new file mode 100644 index 00000000..f0484020 --- /dev/null +++ b/src/main/java/dynamic_programming/CountVowelsPermutation.java @@ -0,0 +1,72 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 25/01/2020 Given an integer n, your task is to count how many + * strings of length n can be formed under the following rules: + * + *

Each character is a lower case vowel ('a', 'e', 'i', 'o', 'u') Each vowel 'a' may only be + * followed by an 'e'. Each vowel 'e' may only be followed by an 'a' or an 'i'. Each vowel 'i' may + * not be followed by another 'i'. Each vowel 'o' may only be followed by an 'i' or a 'u'. Each + * vowel 'u' may only be followed by an 'a'. Since the answer may be too large, return it modulo + * 10^9 + 7. + * + *

Example 1: + * + *

Input: n = 1 Output: 5 Explanation: All possible strings are: "a", "e", "i" , "o" and "u". + * Example 2: + * + *

Input: n = 2 Output: 10 Explanation: All possible strings are: "ae", "ea", "ei", "ia", "ie", + * "io", "iu", "oi", "ou" and "ua". Example 3: + * + *

Input: n = 5 Output: 68 + */ +public class CountVowelsPermutation { + public static void main(String[] args) {} + + public int countVowelPermutation(int n) { + if (n == 1) return 5; + Map> graph = new HashMap<>(); + List vowels = Arrays.asList('a', 'e', 'i', 'o', 'u'); + Map count = new HashMap<>(); + vowels.forEach(v -> graph.put(v, new ArrayList<>())); + graph.get('a').add('e'); + graph.get('e').add('a'); + graph.get('e').add('i'); + graph.get('i').add('a'); + graph.get('i').add('e'); + graph.get('i').add('o'); + graph.get('i').add('u'); + graph.get('u').add('a'); + graph.get('o').add('i'); + graph.get('o').add('u'); + count.put('a', 1); + count.put('e', 2); + count.put('i', 4); + count.put('o', 2); + count.put('u', 1); + int[] charCount = new int[5]; + for (int i = 2; i < n; i++) { + int j = 0; + Arrays.fill(charCount, 0); + for (char c : vowels) { + List children = graph.get(c); + for (char child : children) { + charCount[j] = ((charCount[j] + count.get(child)) % 1000000007); + } + j++; + } + j = 0; + for (char c : vowels) { + count.put(c, charCount[j++]); + } + } + int sum = 0; + for (char c : vowels) { + sum = ((sum + (count.get(c))) % 1000000007); + } + return sum; + } +} diff --git a/problems/src/dynamic_programming/DecodeWays.java b/src/main/java/dynamic_programming/DecodeWays.java similarity index 97% rename from problems/src/dynamic_programming/DecodeWays.java rename to src/main/java/dynamic_programming/DecodeWays.java index bfd708f5..fb82e92d 100644 --- a/problems/src/dynamic_programming/DecodeWays.java +++ b/src/main/java/dynamic_programming/DecodeWays.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/problems/src/dynamic_programming/DecodeWaysII.java b/src/main/java/dynamic_programming/DecodeWaysII.java similarity index 99% rename from problems/src/dynamic_programming/DecodeWaysII.java rename to src/main/java/dynamic_programming/DecodeWaysII.java index e17c441e..25cc3f2f 100644 --- a/problems/src/dynamic_programming/DecodeWaysII.java +++ b/src/main/java/dynamic_programming/DecodeWaysII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/DeleteColumnsToMakeSortedIII.java b/src/main/java/dynamic_programming/DeleteColumnsToMakeSortedIII.java new file mode 100644 index 00000000..6b4a31e1 --- /dev/null +++ b/src/main/java/dynamic_programming/DeleteColumnsToMakeSortedIII.java @@ -0,0 +1,75 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 21/02/2020 We are given an array A of N lowercase letter + * strings, all of the same length. + * + *

Now, we may choose any set of deletion indices, and for each string, we delete all the + * characters in those indices. + * + *

For example, if we have an array A = ["babca","bbazb"] and deletion indices {0, 1, 4}, then + * the final array after deletions is ["bc","az"]. + * + *

Suppose we chose a set of deletion indices D such that after deletions, the final array has + * every element (row) in lexicographic order. + * + *

For clarity, A[0] is in lexicographic order (ie. A[0][0] <= A[0][1] <= ... <= A[0][A[0].length + * - 1]), A[1] is in lexicographic order (ie. A[1][0] <= A[1][1] <= ... <= A[1][A[1].length - 1]), + * and so on. + * + *

Return the minimum possible value of D.length. + * + *

Example 1: + * + *

Input: ["babca","bbazb"] Output: 3 Explanation: After deleting columns 0, 1, and 4, the final + * array is A = ["bc", "az"]. Both these rows are individually in lexicographic order (ie. A[0][0] + * <= A[0][1] and A[1][0] <= A[1][1]). Note that A[0] > A[1] - the array A isn't necessarily in + * lexicographic order. Example 2: + * + *

Input: ["edcba"] Output: 4 Explanation: If we delete less than 4 columns, the only row won't + * be lexicographically sorted. Example 3: + * + *

Input: ["ghi","def","abc"] Output: 0 Explanation: All rows are already lexicographically + * sorted. + * + *

Note: + * + *

1 <= A.length <= 100 1 <= A[i].length <= 100 + */ +public class DeleteColumnsToMakeSortedIII { + public static void main(String[] args) { + String[] A = {"ghi", "def", "abc"}; + System.out.println(new DeleteColumnsToMakeSortedIII().minDeletionSize(A)); + } + + int[] DP; + + public int minDeletionSize(String[] A) { + DP = new int[A[0].length()]; + int max = 0; + for (int i = 0; i < A[0].length(); i++) { + max = Math.max(max, dp(A, i)); + } + return A[0].length() - max; + } + + private int dp(String[] A, int i) { + if (i >= A[0].length()) return 0; + else if (DP[i] != 0) return DP[i]; + DP[i] = 1; + for (int j = i + 1; j < A[0].length(); j++) { + boolean possible = true; + for (String str : A) { + if (str.charAt(j) < str.charAt(i)) { + possible = false; + break; + } + } + if (possible) { + DP[i] = Math.max(DP[i], dp(A, j) + 1); + } + } + return DP[i]; + } +} diff --git a/src/main/java/dynamic_programming/DistinctSubsequences.java b/src/main/java/dynamic_programming/DistinctSubsequences.java new file mode 100644 index 00000000..24a6ebaa --- /dev/null +++ b/src/main/java/dynamic_programming/DistinctSubsequences.java @@ -0,0 +1,56 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 08/05/2020 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). + * + *

It's guaranteed the answer fits on a 32-bit signed integer. + * + *

Example 1: + * + *

Input: S = "rabbbit", T = "rabbit" Output: 3 Explanation: As shown below, there are 3 ways you + * can generate "rabbit" from S. (The caret symbol ^ means the chosen letters) + * + *

rabbbit ^^^^ ^^ rabbbit ^^ ^^^^ rabbbit ^^^ ^^^ Example 2: + * + *

Input: S = "babgbag", T = "bag" Output: 5 Explanation: As shown below, there are 5 ways you + * can generate "bag" from S. (The caret symbol ^ means the chosen letters) + * + *

babgbag ^^ ^ babgbag ^^ ^ babgbag ^ ^^ babgbag ^ ^^ babgbag ^^^ + */ +public class DistinctSubsequences { + int[][] DP; + + public static void main(String[] args) { + System.out.println(new DistinctSubsequences().numDistinct("babgbag", "bag")); + } + + public int numDistinct(String s, String t) { + DP = new int[s.length()][t.length()]; + for (int i = 0; i < s.length(); i++) { + Arrays.fill(DP[i], -1); + } + return dp(0, 0, s, t); + } + + private int dp(int i, int j, String s, String t) { + if (j >= t.length()) return 1; + else if (i >= s.length()) return 0; + else if (DP[i][j] != -1) return DP[i][j]; + else { + if (s.charAt(i) != t.charAt(j)) { + DP[i][j] = dp(i + 1, j, s, t); + } else { + DP[i][j] = dp(i + 1, j + 1, s, t) + dp(i + 1, j, s, t); + } + return DP[i][j]; + } + } +} diff --git a/src/main/java/dynamic_programming/DistinctSubsequencesII.java b/src/main/java/dynamic_programming/DistinctSubsequencesII.java new file mode 100644 index 00000000..54499fc4 --- /dev/null +++ b/src/main/java/dynamic_programming/DistinctSubsequencesII.java @@ -0,0 +1,49 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; +/** + * Created by gouthamvidyapradhan on 08/05/2020 Given a string S, count the number of distinct, + * non-empty subsequences of S . + * + *

Since the result may be large, return the answer modulo 10^9 + 7. + * + *

Example 1: + * + *

Input: "abc" Output: 7 Explanation: The 7 distinct subsequences are "a", "b", "c", "ab", "ac", + * "bc", and "abc". Example 2: + * + *

Input: "aba" Output: 6 Explanation: The 6 distinct subsequences are "a", "b", "ab", "ba", "aa" + * and "aba". Example 3: + * + *

Input: "aaa" Output: 3 Explanation: The 3 distinct subsequences are "a", "aa" and "aaa". + * + *

Note: + * + *

S contains only lowercase letters. 1 <= S.length <= 2000 + */ +public class DistinctSubsequencesII { + public static void main(String[] args) { + System.out.println(new DistinctSubsequencesII().distinctSubseqII("abac")); + } + + final int MOD = (int) 1e9 + 7; + + public int distinctSubseqII(String S) { + int[] DP = new int[S.length() + 1]; + DP[S.length()] = 1; + for (int i = S.length() - 1; i >= 0; i--) { + int sum = 0; + for (int j = i + 1; j <= S.length(); j++) { + sum = ((sum + DP[j]) % MOD); + if (j < S.length() && S.charAt(j) == S.charAt(i)) { + break; + } + } + DP[i] = sum; + } + int ans = 0; + for (int i : DP) { + ans = ((ans + i) % MOD); + } + return ans - 1; + } +} diff --git a/problems/src/dynamic_programming/DungeonGame.java b/src/main/java/dynamic_programming/DungeonGame.java similarity index 98% rename from problems/src/dynamic_programming/DungeonGame.java rename to src/main/java/dynamic_programming/DungeonGame.java index e275dca5..80b669cd 100644 --- a/problems/src/dynamic_programming/DungeonGame.java +++ b/src/main/java/dynamic_programming/DungeonGame.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/EncodeStringWithShortestLength.java b/src/main/java/dynamic_programming/EncodeStringWithShortestLength.java new file mode 100644 index 00000000..2520dde5 --- /dev/null +++ b/src/main/java/dynamic_programming/EncodeStringWithShortestLength.java @@ -0,0 +1,90 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; +/** + * Created by gouthamvidyapradhan on 15/09/2019 Given a non-empty string, encode the string such + * that its encoded length is the shortest. + * + *

The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets + * is being repeated exactly k times. + * + *

Note: + * + *

k will be a positive integer and encoded string will not be empty or have extra space. You may + * assume that the input string contains only lowercase English letters. The string's length is at + * most 160. If an encoding process does not make the string shorter, then do not encode it. If + * there are several solutions, return any of them is fine. + * + *

Example 1: + * + *

Input: "aaa" Output: "aaa" Explanation: There is no way to encode it such that it is shorter + * than the input string, so we do not encode it. + * + *

Example 2: + * + *

Input: "aaaaa" Output: "5[a]" Explanation: "5[a]" is shorter than "aaaaa" by 1 character. + * + *

Example 3: + * + *

Input: "aaaaaaaaaa" Output: "10[a]" Explanation: "a9[a]" or "9[a]a" are also valid solutions, + * both of them have the same length = 5, which is the same as "10[a]". + * + *

Example 4: + * + *

Input: "aabcaabcd" Output: "2[aabc]d" Explanation: "aabc" occurs twice, so one answer can be + * "2[aabc]d". + * + *

Example 5: + * + *

Input: "abbbabbbcabbbabbbc" Output: "2[2[abbb]c]" Explanation: "abbbabbbc" occurs twice, but + * "abbbabbbc" can also be encoded to "2[abbb]c", so one answer can be "2[2[abbb]c]". + * + *

Solution: O(N ^ 4) Maintain a 2d String array of minimum substring and split each substring + * and combine the minimum substrings So, the answer could be either DP[i][j] = min(DP[i][k] + DP[k + * + 1][j]) or split (i, j) at every index k and check if a new minimum substring can be formed + * which is lesser than the current minimum. + */ +public class EncodeStringWithShortestLength { + + private String[][] DP; + + public static void main(String[] args) { + System.out.println( + new EncodeStringWithShortestLength() + .encode( + "xabcabcabcxxabcabcabcxxabcabcabcxxabcdabcabcxxabcabcabcxxabcabcabcxxabcabcabcxxabcabcabcx")); + } + + public String encode(String s) { + DP = new String[s.length()][s.length()]; + return encodeStr(s, 0, s.length() - 1); + } + + private String encodeStr(String s, int i, int j) { + if (i == j) { + DP[i][j] = String.valueOf(s.charAt(i)); + return DP[i][j]; + } else if (DP[i][j] != null) return DP[i][j]; + String currSubStr = s.substring(i, j + 1); + DP[i][j] = currSubStr; + for (int k = i + 1; k < j + 1; k++) { + String left = encodeStr(s, i, k - 1); + String right = encodeStr(s, k, j); + if (left.length() + right.length() < DP[i][j].length()) { + DP[i][j] = left + right; + } + } + for (int k = i + 1; k < j + 1; k++) { + if (currSubStr.length() % (k - i) == 0) { + String subStr = s.substring(i, k); + if (currSubStr.replaceAll(subStr, "").trim().isEmpty()) { + String candidate = + (currSubStr.length() / subStr.length()) + "[" + encodeStr(s, i, k - 1) + "]"; + if (candidate.length() < DP[i][j].length()) { + DP[i][j] = candidate; + } + } + } + } + return DP[i][j]; + } +} diff --git a/src/main/java/dynamic_programming/FreedomTrail.java b/src/main/java/dynamic_programming/FreedomTrail.java new file mode 100644 index 00000000..69cd9e1c --- /dev/null +++ b/src/main/java/dynamic_programming/FreedomTrail.java @@ -0,0 +1,67 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 15/02/2020 In the video game Fallout 4, the quest "Road to + * Freedom" requires players to reach a metal dial called the "Freedom Trail Ring", and use the dial + * to spell a specific keyword in order to open the door. + * + *

Given a string ring, which represents the code engraved on the outer ring and another string + * key, which represents the keyword needs to be spelled. You need to find the minimum number of + * steps in order to spell all the characters in the keyword. + * + *

Initially, the first character of the ring is aligned at 12:00 direction. You need to spell + * all the characters in the string key one by one by rotating the ring clockwise or anticlockwise + * to make each character of the string key aligned at 12:00 direction and then by pressing the + * center button. + * + *

At the stage of rotating the ring to spell the key character key[i]: + * + *

You can rotate the ring clockwise or anticlockwise one place, which counts as 1 step. The + * final purpose of the rotation is to align one of the string ring's characters at the 12:00 + * direction, where this character must equal to the character key[i]. If the character key[i] has + * been aligned at the 12:00 direction, you need to press the center button to spell, which also + * counts as 1 step. After the pressing, you could begin to spell the next character in the key + * (next stage), otherwise, you've finished all the spelling. Example: + * + *

Input: ring = "godding", key = "gd" Output: 4 Explanation: For the first key character 'g', + * since it is already in place, we just need 1 step to spell this character. For the second key + * character 'd', we need to rotate the ring "godding" anticlockwise by two steps to make it become + * "ddinggo". Also, we need 1 more step for spelling. So the final output is 4. Note: + * + *

Length of both ring and key will be in range 1 to 100. There are only lowercase letters in + * both strings and might be some duplcate characters in both strings. It's guaranteed that string + * key could always be spelled by rotating the string ring. + */ +public class FreedomTrail { + public static void main(String[] args) { + System.out.println(new FreedomTrail().findRotateSteps("godding", "gd")); + } + + int[][] DP; + + public int findRotateSteps(String ring, String key) { + DP = new int[ring.length()][key.length()]; + return dp(0, ring, key, 0) + key.length(); + } + + private int dp(int i, String ring, String key, int k) { + if (k == key.length()) return 0; + else { + if (DP[i][k] != 0) return DP[i][k]; + char c = key.charAt(k); + int min = Integer.MAX_VALUE; + for (int j = 0; j < ring.length(); j++) { + if (ring.charAt(j) == c) { + min = + Math.min( + min, + Math.min(Math.abs(i - j), ring.length() - Math.abs(i - j)) + + dp(j, ring, key, k + 1)); + } + } + DP[i][k] = min; + return min; + } + } +} diff --git a/src/main/java/dynamic_programming/HandshakesThatDontCross.java b/src/main/java/dynamic_programming/HandshakesThatDontCross.java new file mode 100644 index 00000000..1450b29e --- /dev/null +++ b/src/main/java/dynamic_programming/HandshakesThatDontCross.java @@ -0,0 +1,64 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 19/02/2020 You are given an even number of people num_people + * that stand around a circle and each person shakes hands with someone else, so that there are + * num_people / 2 handshakes total. + * + *

Return the number of ways these handshakes could occur such that none of the handshakes cross. + * + *

Since this number could be very big, return the answer mod 10^9 + 7 + * + *

Example 1: + * + *

Input: num_people = 2 Output: 1 Example 2: + * + *

Input: num_people = 4 Output: 2 Explanation: There are two ways to do it, the first way is + * [(1,2),(3,4)] and the second one is [(2,3),(4,1)]. Example 3: + * + *

Input: num_people = 6 Output: 5 Example 4: + * + *

Input: num_people = 8 Output: 14 + * + *

Constraints: + * + *

2 <= num_people <= 1000 num_people % 2 == 0 + */ +public class HandshakesThatDontCross { + public static void main(String[] args) { + System.out.println(new HandshakesThatDontCross().numberOfWays(20)); + } + + int[] DP; + final int MOD = 1000000007; + + public int numberOfWays(int N) { + // DP = new int[N + 1][N + 1]; + DP = new int[N + 1]; + Arrays.fill(DP, -1); + // + // for(int i = 0; i <= N; i ++){ + // Arrays.fill(DP[i], -1); + // } + return dp(0, N - 1); + } + + private int dp(int i, int j) { + if (i > j) return 1; + else if ((j - i + 1) % 2 != 0) return 0; + else if (DP[j - i + 1] != -1) return DP[j - i + 1]; + else { + int sum = 0; + for (int k = i; k <= j; k++) { + int left = (dp(i + 1, k - 1) % MOD); + int right = (dp(k + 1, j) % MOD); + sum = ((sum + ((left * right) % MOD)) % MOD); + } + DP[j - i + 1] = sum; + return sum; + } + } +} diff --git a/problems/src/dynamic_programming/HouseRobber.java b/src/main/java/dynamic_programming/HouseRobber.java similarity index 97% rename from problems/src/dynamic_programming/HouseRobber.java rename to src/main/java/dynamic_programming/HouseRobber.java index 3f363840..8d6c0762 100644 --- a/problems/src/dynamic_programming/HouseRobber.java +++ b/src/main/java/dynamic_programming/HouseRobber.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/problems/src/dynamic_programming/HouseRobberII.java b/src/main/java/dynamic_programming/HouseRobberII.java similarity index 98% rename from problems/src/dynamic_programming/HouseRobberII.java rename to src/main/java/dynamic_programming/HouseRobberII.java index bc469bea..23b67131 100644 --- a/problems/src/dynamic_programming/HouseRobberII.java +++ b/src/main/java/dynamic_programming/HouseRobberII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/InterleavingString.java b/src/main/java/dynamic_programming/InterleavingString.java new file mode 100644 index 00000000..defcddd3 --- /dev/null +++ b/src/main/java/dynamic_programming/InterleavingString.java @@ -0,0 +1,40 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; +/** + * Created by gouthamvidyapradhan on 30/01/2020 Given s1, s2, s3, find whether s3 is formed by the + * interleaving of s1 and s2. + * + *

Example 1: + * + *

Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac" Output: true Example 2: + * + *

Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc" Output: false + */ +public class InterleavingString { + public static void main(String[] args) { + System.out.println(new InterleavingString().isInterleave("aabcc", "aabcc", "aabcaabccc")); + } + + public boolean isInterleave(String s1, String s2, String s3) { + boolean[][] DP = new boolean[s1.length() + 1][s2.length() + 1]; + DP[0][0] = true; + if (s3.length() != (s2.length() + s1.length())) return false; + for (int i = 0; i <= s1.length(); i++) { + for (int j = 0; j <= s2.length(); j++) { + if (i == 0 && j == 0) continue; + int index = (i + j); + if (j > 0) { + if (s3.charAt(index - 1) == s2.charAt(j - 1) && DP[i][j - 1]) { + DP[i][j] = true; + } + } + if (i > 0) { + if (s3.charAt(index - 1) == s1.charAt(i - 1) && DP[i - 1][j]) { + DP[i][j] = true; + } + } + } + } + return DP[s1.length()][s2.length()]; + } +} diff --git a/src/main/java/dynamic_programming/JumpGameV.java b/src/main/java/dynamic_programming/JumpGameV.java new file mode 100644 index 00000000..142c49d2 --- /dev/null +++ b/src/main/java/dynamic_programming/JumpGameV.java @@ -0,0 +1,71 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 18/02/2020 Given an array of integers arr and an integer d. In + * one step you can jump from index i to index: + * + *

i + x where: i + x < arr.length and 0 < x <= d. i - x where: i - x >= 0 and 0 < x <= d. In + * addition, you can only jump from index i to index j if arr[i] > arr[j] and arr[i] > arr[k] for + * all indices k between i and j (More formally min(i, j) < k < max(i, j)). + * + *

You can choose any index of the array and start jumping. Return the maximum number of indices + * you can visit. + * + *

Notice that you can not jump outside of the array at any time. + * + *

Example 1: + * + *

Input: arr = [6,4,14,6,8,13,9,7,10,6,12], d = 2 Output: 4 Explanation: You can start at index + * 10. You can jump 10 --> 8 --> 6 --> 7 as shown. Note that if you start at index 6 you can only + * jump to index 7. You cannot jump to index 5 because 13 > 9. You cannot jump to index 4 because + * index 5 is between index 4 and 6 and 13 > 9. Similarly You cannot jump from index 3 to index 2 or + * index 1. Example 2: + * + *

Input: arr = [3,3,3,3,3], d = 3 Output: 1 Explanation: You can start at any index. You always + * cannot jump to any index. Example 3: + * + *

Input: arr = [7,6,5,4,3,2,1], d = 1 Output: 7 Explanation: Start at index 0. You can visit all + * the indicies. Example 4: + * + *

Input: arr = [7,1,7,1,7,1], d = 2 Output: 2 Example 5: + * + *

Input: arr = [66], d = 1 Output: 1 + * + *

Constraints: + * + *

1 <= arr.length <= 1000 1 <= arr[i] <= 10^5 1 <= d <= arr.length + */ +public class JumpGameV { + public static void main(String[] args) { + int[] A = {7, 1, 7, 1, 7, 1}; + System.out.println(new JumpGameV().maxJumps(A, 2)); + } + + int[] DP; + + public int maxJumps(int[] arr, int d) { + DP = new int[arr.length]; + // Arrays.fill(DP, -1); + int max = 0; + for (int i = 0; i < arr.length; i++) { + max = Math.max(max, dp(arr, d, i)); + } + return max; + } + + private int dp(int[] A, int d, int i) { + if (DP[i] != 0) return DP[i]; + int max = 1; + for (int j = i - 1; j >= (i - d); j--) { + if (j < 0 || A[j] >= A[i]) break; + max = Math.max(max, dp(A, d, j) + 1); + } + for (int j = i + 1; j <= (i + d); j++) { + if (j >= A.length || A[j] >= A[i]) break; + max = Math.max(max, dp(A, d, j) + 1); + } + DP[i] = max; + return max; + } +} diff --git a/src/main/java/dynamic_programming/KnightDialer.java b/src/main/java/dynamic_programming/KnightDialer.java new file mode 100644 index 00000000..0424ecc7 --- /dev/null +++ b/src/main/java/dynamic_programming/KnightDialer.java @@ -0,0 +1,82 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 24/09/2019 A chess knight can move as indicated in the chess + * diagram below: + * + *

. + * + *

This time, we place our chess knight on any numbered key of a phone pad (indicated above), and + * the knight makes N-1 hops. Each hop must be from one key to another numbered key. + * + *

Each time it lands on a key (including the initial placement of the knight), it presses the + * number of that key, pressing N digits total. + * + *

How many distinct numbers can you dial in this manner? + * + *

Since the answer may be large, output the answer modulo 10^9 + 7. + * + *

Example 1: + * + *

Input: 1 Output: 10 Example 2: + * + *

Input: 2 Output: 20 Example 3: + * + *

Input: 3 Output: 46 + * + *

Note: + * + *

1 <= N <= 5000 + * + *

Solution: O(N x 4 x 3) Visit all different possible states and sum up the total possible + * moves. Cache the states to avoid recalculating. + */ +public class KnightDialer { + + final int[] R = {-1, -1, -2, -2, 1, 1, 2, 2}; + final int[] C = {2, -2, -1, 1, 2, -2, 1, -1}; + + public static void main(String[] args) { + System.out.println(new KnightDialer().knightDialer(2)); + } + + int[][][] DP; + + public int knightDialer(int N) { + DP = new int[4][3][N + 1]; + int ans = 0; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + if ((i == 3 && j == 0) || (i == 3 && j == 2)) continue; + DP[i][j][0] = 1; + } + } + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + if ((i == 3 && j == 0) || (i == 3 && j == 2)) continue; + ans += (dp(N - 1, i, j) % 10e9 + 7); + ans %= 10e9 + 7; + } + } + return ans; + } + + private int dp(int N, int r, int c) { + if (N < 0) return 0; + if (r == 3 && c == 0) return 0; + if (r == 3 && c == 2) return 0; + if (DP[r][c][N] != 0) return DP[r][c][N]; + int sum = 0; + for (int i = 0; i < 8; i++) { + int newR = r + R[i]; + int newC = c + C[i]; + if (newR >= 0 && newC >= 0 && newR < 4 && newC < 3) { + sum += (dp(N - 1, newR, newC) % 10e9 + 7); + sum %= 10e9 + 7; + } + } + DP[r][c][N] = sum; + return sum; + } +} diff --git a/problems/src/dynamic_programming/KnightProbabilityInChessboard.java b/src/main/java/dynamic_programming/KnightProbabilityInChessboard.java similarity index 98% rename from problems/src/dynamic_programming/KnightProbabilityInChessboard.java rename to src/main/java/dynamic_programming/KnightProbabilityInChessboard.java index 34afbea9..5674e4cb 100644 --- a/problems/src/dynamic_programming/KnightProbabilityInChessboard.java +++ b/src/main/java/dynamic_programming/KnightProbabilityInChessboard.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/LargestMultipleOfThree.java b/src/main/java/dynamic_programming/LargestMultipleOfThree.java new file mode 100644 index 00000000..1042aca3 --- /dev/null +++ b/src/main/java/dynamic_programming/LargestMultipleOfThree.java @@ -0,0 +1,81 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 29/05/2020 Given an integer array of digits, return the largest + * multiple of three that can be formed by concatenating some of the given digits in any order. + * + *

Since the answer may not fit in an integer data type, return the answer as a string. + * + *

If there is no answer return an empty string. + * + *

Example 1: + * + *

Input: digits = [8,1,9] Output: "981" Example 2: + * + *

Input: digits = [8,6,7,1,0] Output: "8760" Example 3: + * + *

Input: digits = [1] Output: "" Example 4: + * + *

Input: digits = [0,0,0,0,0,0] Output: "0" + * + *

Constraints: + * + *

1 <= digits.length <= 10^4 0 <= digits[i] <= 9 The returning answer must not contain + * unnecessary leading zeros. + */ +public class LargestMultipleOfThree { + public static void main(String[] args) { + int[] A = {8, 4, 1, 7}; + System.out.println(new LargestMultipleOfThree().largestMultipleOfThree(A)); + } + + int[][][] DP; + + public String largestMultipleOfThree(int[] digits) { + Arrays.sort(digits); + for (int i = 0, j = digits.length - 1; i < j; i++, j--) { + int t = digits[i]; + digits[i] = digits[j]; + digits[j] = t; + } + DP = new int[digits.length][3][2]; + for (int i = 0; i < digits.length; i++) { + for (int j = 0; j < 3; j++) { + Arrays.fill(DP[i][j], -2); + } + } + dp(0, 0, digits); + StringBuilder sb = new StringBuilder(); + int r = 0; + for (int i = 0; i < digits.length; i++) { + if (DP[i][r][1] >= DP[i][r][0]) { + if (sb.length() != 1 || sb.charAt(0) != '0') { + sb.append(digits[i]); + } + r = (Integer.parseInt(String.valueOf(r + "" + digits[i])) % 3); + } + } + return sb.toString(); + } + + private int dp(int i, int r, int[] A) { + if (i == A.length) { + return r == 0 ? 0 : -1; + } else if (DP[i][r][0] != -2) { + return Math.max(DP[i][r][0], DP[i][r][1]); + } else { + int d = A[i]; + int newR = (Integer.parseInt(String.valueOf(r + "" + d)) % 3); + int result = dp(i + 1, newR, A); + if (result >= 0) { + result = result + 1; + } + DP[i][r][1] = result; + DP[i][r][0] = dp(i + 1, r, A); + return Math.max(DP[i][r][0], DP[i][r][1]); + } + } +} diff --git a/problems/src/dynamic_programming/LargestPlusSign.java b/src/main/java/dynamic_programming/LargestPlusSign.java similarity index 99% rename from problems/src/dynamic_programming/LargestPlusSign.java rename to src/main/java/dynamic_programming/LargestPlusSign.java index 11206209..19310d26 100644 --- a/problems/src/dynamic_programming/LargestPlusSign.java +++ b/src/main/java/dynamic_programming/LargestPlusSign.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/problems/src/dynamic_programming/LargestSumOfAverages.java b/src/main/java/dynamic_programming/LargestSumOfAverages.java similarity index 98% rename from problems/src/dynamic_programming/LargestSumOfAverages.java rename to src/main/java/dynamic_programming/LargestSumOfAverages.java index 2b63ef84..11377ce4 100644 --- a/problems/src/dynamic_programming/LargestSumOfAverages.java +++ b/src/main/java/dynamic_programming/LargestSumOfAverages.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** * Created by gouthamvidyapradhan on 04/05/2018. We partition a row of numbers A into at most K diff --git a/src/main/java/dynamic_programming/LengthofLongestFibonacciSubsequence.java b/src/main/java/dynamic_programming/LengthofLongestFibonacciSubsequence.java new file mode 100644 index 00000000..d7966bee --- /dev/null +++ b/src/main/java/dynamic_programming/LengthofLongestFibonacciSubsequence.java @@ -0,0 +1,63 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 23/08/2019 A sequence X_1, X_2, ..., X_n is fibonacci-like if: + * + *

n >= 3 X_i + X_{i+1} = X_{i+2} for all i + 2 <= n Given a strictly increasing array A of + * positive integers forming a sequence, find the length of the longest fibonacci-like subsequence + * of A. If one does not exist, return 0. + * + *

(Recall that a subsequence is derived from another sequence A by deleting any number of + * elements (including none) from A, without changing the order of the remaining elements. For + * example, [3, 5, 8] is a subsequence of [3, 4, 5, 6, 7, 8].) + * + *

Example 1: + * + *

Input: [1,2,3,4,5,6,7,8] Output: 5 Explanation: The longest subsequence that is + * fibonacci-like: [1,2,3,5,8]. Example 2: + * + *

Input: [1,3,7,11,12,14,18] Output: 3 Explanation: The longest subsequence that is + * fibonacci-like: [1,11,12], [3,11,14] or [7,11,18]. + * + *

Note: + * + *

3 <= A.length <= 1000 1 <= A[0] < A[1] < ... < A[A.length - 1] <= 10^9 (The time limit has + * been reduced by 50% for submissions in Java, C, and C++.) + * + *

Solution O(N ^ 2) For every value at index i sum up with every value at index j and check if + * this sum is already known if known then increment the sub-sequence length by 1, continue this + * process until max length is found. + */ +public class LengthofLongestFibonacciSubsequence { + public static void main(String[] args) { + int[] A = {1, 2, 4, 7, 12, 20}; + System.out.println(new LengthofLongestFibonacciSubsequence().lenLongestFibSubseq(A)); + } + + public int lenLongestFibSubseq(int[] A) { + if (A.length < 3) return 0; + Map> indexMap = new HashMap<>(); + int max = 0; + for (int i = A.length - 1; i >= 0; i--) { + Map subHashMap = new HashMap<>(); + for (int j = 0; j < i; j++) { + int sum = A[i] + A[j]; + if (indexMap.containsKey(sum)) { + if (indexMap.get(sum).containsKey(A[i])) { + int value = 1 + indexMap.get(sum).get(A[i]); + subHashMap.put(A[j], value); + max = Math.max(max, value); + } else { + subHashMap.put(A[j], 1); + max = Math.max(max, 1); + } + } + } + indexMap.put(A[i], subHashMap); + } + return max == 0 ? 0 : max + 2; + } +} diff --git a/src/main/java/dynamic_programming/LongestChunkedPalindromeDecomposition.java b/src/main/java/dynamic_programming/LongestChunkedPalindromeDecomposition.java new file mode 100644 index 00000000..2d2ed539 --- /dev/null +++ b/src/main/java/dynamic_programming/LongestChunkedPalindromeDecomposition.java @@ -0,0 +1,57 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 17/04/2020 Return the largest possible k such that there exists + * a_1, a_2, ..., a_k such that: + * + *

Each a_i is a non-empty string; Their concatenation a_1 + a_2 + ... + a_k is equal to text; + * For all 1 <= i <= k, a_i = a_{k+1 - i}. + * + *

Example 1: + * + *

Input: text = "ghiabcdefhelloadamhelloabcdefghi" Output: 7 Explanation: We can split the + * string on "(ghi)(abcdef)(hello)(adam)(hello)(abcdef)(ghi)". Example 2: + * + *

Input: text = "merchant" Output: 1 Explanation: We can split the string on "(merchant)". + * Example 3: + * + *

Input: text = "antaprezatepzapreanta" Output: 11 Explanation: We can split the string on + * "(a)(nt)(a)(pre)(za)(tpe)(za)(pre)(a)(nt)(a)". Example 4: + * + *

Input: text = "aaa" Output: 3 Explanation: We can split the string on "(a)(a)(a)". + * + *

Constraints: + * + *

text consists only of lowercase English characters. 1 <= text.length <= 1000 + */ +public class LongestChunkedPalindromeDecomposition { + public static void main(String[] args) { + System.out.println( + new LongestChunkedPalindromeDecomposition().longestDecomposition("merchant")); + } + + private int[] DP; + + public int longestDecomposition(String text) { + DP = new int[text.length()]; + return dp(0, text.length() - 1, text); + } + + private int dp(int i, int e, String text) { + if (i > e) return 0; + else if (i == e) return 1; + else if (DP[i] > 0) return DP[i]; + else { + for (int j = e; j > i; j--) { + if (text.charAt(j) == text.charAt(i)) { + if (text.substring(j, e + 1).equals(text.substring(i, i + (e - j + 1)))) { + DP[i] = Math.max(DP[i], dp(i + (e - j + 1), j - 1, text) + 2); + } + } + } + DP[i] = DP[i] == 0 ? 1 : DP[i]; + return DP[i]; + } + } +} diff --git a/problems/src/dynamic_programming/LongestIncreasingSubsequence.java b/src/main/java/dynamic_programming/LongestIncreasingSubsequence.java similarity index 97% rename from problems/src/dynamic_programming/LongestIncreasingSubsequence.java rename to src/main/java/dynamic_programming/LongestIncreasingSubsequence.java index e594a47e..1550be7d 100644 --- a/problems/src/dynamic_programming/LongestIncreasingSubsequence.java +++ b/src/main/java/dynamic_programming/LongestIncreasingSubsequence.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/problems/src/dynamic_programming/LongestPaliandromicSubstring.java b/src/main/java/dynamic_programming/LongestPaliandromicSubstring.java similarity index 97% rename from problems/src/dynamic_programming/LongestPaliandromicSubstring.java rename to src/main/java/dynamic_programming/LongestPaliandromicSubstring.java index da69442f..30b34e83 100644 --- a/problems/src/dynamic_programming/LongestPaliandromicSubstring.java +++ b/src/main/java/dynamic_programming/LongestPaliandromicSubstring.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/problems/src/dynamic_programming/LongestPalindromicSubsequence.java b/src/main/java/dynamic_programming/LongestPalindromicSubsequence.java similarity index 97% rename from problems/src/dynamic_programming/LongestPalindromicSubsequence.java rename to src/main/java/dynamic_programming/LongestPalindromicSubsequence.java index d49d6a1b..ce06e81a 100644 --- a/problems/src/dynamic_programming/LongestPalindromicSubsequence.java +++ b/src/main/java/dynamic_programming/LongestPalindromicSubsequence.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/MakeArrayStrictlyIncreasing.java b/src/main/java/dynamic_programming/MakeArrayStrictlyIncreasing.java new file mode 100644 index 00000000..1a403009 --- /dev/null +++ b/src/main/java/dynamic_programming/MakeArrayStrictlyIncreasing.java @@ -0,0 +1,82 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 28/02/2020 Given two integer arrays arr1 and arr2, return the + * minimum number of operations (possibly zero) needed to make arr1 strictly increasing. + * + *

In one operation, you can choose two indices 0 <= i < arr1.length and 0 <= j < arr2.length and + * do the assignment arr1[i] = arr2[j]. + * + *

If there is no way to make arr1 strictly increasing, return -1. + * + *

Example 1: + * + *

Input: arr1 = [1,5,3,6,7], arr2 = [1,3,2,4] Output: 1 Explanation: Replace 5 with 2, then arr1 + * = [1, 2, 3, 6, 7]. Example 2: + * + *

Input: arr1 = [1,5,3,6,7], arr2 = [4,3,1] Output: 2 Explanation: Replace 5 with 3 and then + * replace 3 with 4. arr1 = [1, 3, 4, 6, 7]. Example 3: + * + *

Input: arr1 = [1,5,3,6,7], arr2 = [1,6,3,3] Output: -1 Explanation: You can't make arr1 + * strictly increasing. + * + *

Constraints: + * + *

1 <= arr1.length, arr2.length <= 2000 0 <= arr1[i], arr2[i] <= 10^9 + */ +public class MakeArrayStrictlyIncreasing { + public static void main(String[] args) { + int[] A = {1, 5, 3, 6, 7}; + int[] B = {4, 3, 1}; + System.out.println(new MakeArrayStrictlyIncreasing().makeArrayIncreasing(A, B)); + } + + private int[][] DP; + + public int makeArrayIncreasing(int[] arr1, int[] arr2) { + DP = new int[arr1.length][arr2.length + 1]; + Arrays.sort(arr2); + for (int i = 0; i < arr1.length; i++) { + Arrays.fill(DP[i], -1); + } + int min = dp(1, 0, arr1, arr2); + for (int i = 0; i < arr2.length; i++) { + min = Math.min(min, dp(1, i + 1, arr1, arr2) + 1); + } + return min == 2000 ? -1 : min; + } + + private int dp(int i, int j, int[] arr1, int[] arr2) { + if (i >= arr1.length) return 0; + else if (DP[i][j] != -1) return DP[i][j]; + else { + int curr = (j == 0 ? arr1[i - 1] : arr2[j - 1]); + int min = 2000; + if (arr1[i] > curr) { + min = dp(i + 1, 0, arr1, arr2); + } + int k = binarySearch(arr2, curr); + if (k != -1) { + min = Math.min(min, dp(i + 1, k + 1, arr1, arr2) + 1); + } + DP[i][j] = min; + return min; + } + } + + private int binarySearch(int[] A, int k) { + int l = 0, h = A.length; + int ans = -1; + while (l < h) { + int m = l + (h - l) / 2; + if (A[m] > k) { + ans = m; + h = m; + } else l = m + 1; + } + return ans; + } +} diff --git a/problems/src/dynamic_programming/MaxSum3SubArray.java b/src/main/java/dynamic_programming/MaxSum3SubArray.java similarity index 99% rename from problems/src/dynamic_programming/MaxSum3SubArray.java rename to src/main/java/dynamic_programming/MaxSum3SubArray.java index b57f4ec1..ce9cfe6e 100644 --- a/problems/src/dynamic_programming/MaxSum3SubArray.java +++ b/src/main/java/dynamic_programming/MaxSum3SubArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** * Created by gouthamvidyapradhan on 22/11/2017. diff --git a/problems/src/dynamic_programming/MaximalSquare.java b/src/main/java/dynamic_programming/MaximalSquare.java similarity index 98% rename from problems/src/dynamic_programming/MaximalSquare.java rename to src/main/java/dynamic_programming/MaximalSquare.java index c87eb9da..c2ec8835 100644 --- a/problems/src/dynamic_programming/MaximalSquare.java +++ b/src/main/java/dynamic_programming/MaximalSquare.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/problems/src/dynamic_programming/MaximumProductSubarray.java b/src/main/java/dynamic_programming/MaximumProductSubarray.java similarity index 97% rename from problems/src/dynamic_programming/MaximumProductSubarray.java rename to src/main/java/dynamic_programming/MaximumProductSubarray.java index ae67a77c..b669a656 100644 --- a/problems/src/dynamic_programming/MaximumProductSubarray.java +++ b/src/main/java/dynamic_programming/MaximumProductSubarray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/MaximumProfitInJobScheduling.java b/src/main/java/dynamic_programming/MaximumProfitInJobScheduling.java new file mode 100644 index 00000000..3495aec1 --- /dev/null +++ b/src/main/java/dynamic_programming/MaximumProfitInJobScheduling.java @@ -0,0 +1,81 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 18/06/2020 We have n jobs, where every job is scheduled to be + * done from startTime[i] to endTime[i], obtaining a profit of profit[i]. + * + *

You're given the startTime, endTime and profit arrays, return the maximum profit you can take + * such that there are no two jobs in the subset with overlapping time range. + * + *

If you choose a job that ends at time X you will be able to start another job that starts at + * time X. + * + *

Example 1: + * + *

Input: startTime = [1,2,3,3], endTime = [3,4,5,6], profit = [50,10,40,70] Output: 120 + * Explanation: The subset chosen is the first and fourth job. Time range [1-3]+[3-6] , we get + * profit of 120 = 50 + 70. Example 2: + * + *

Input: startTime = [1,2,3,4,6], endTime = [3,5,10,6,9], profit = [20,20,100,70,60] Output: 150 + * Explanation: The subset chosen is the first, fourth and fifth job. Profit obtained 150 = 20 + 70 + * + 60. Example 3: + * + *

Input: startTime = [1,1,1], endTime = [2,3,4], profit = [5,6,4] Output: 6 + * + *

Constraints: + * + *

1 <= startTime.length == endTime.length == profit.length <= 5 * 104 1 <= startTime[i] < + * endTime[i] <= 109 1 <= profit[i] <= 104 + */ +public class MaximumProfitInJobScheduling { + private class Pair { + int a, b; + + Pair(int a, int b) { + this.a = a; + this.b = b; + } + } + + public static void main(String[] args) { + int[] st = {4, 2, 4, 8, 2}; + int[] et = {5, 5, 5, 10, 8}; + int[] p = {1, 2, 8, 10, 4}; + System.out.println(new MaximumProfitInJobScheduling().jobScheduling(st, et, p)); + } + + Map DP; + TreeMap> graph; + + public int jobScheduling(int[] startTime, int[] endTime, int[] profit) { + DP = new HashMap<>(); + graph = new TreeMap<>(); + int start = 0; + for (int i = 0; i < startTime.length; i++) { + List children = graph.getOrDefault(startTime[i], new ArrayList<>()); + children.add(new Pair(endTime[i], profit[i])); + graph.putIfAbsent(startTime[i], children); + start = Math.min(start, startTime[i]); + } + return dp(start); + } + + private int dp(int i) { + Integer current = graph.ceilingKey(i); + if (current == null) return 0; + else if (DP.containsKey(current)) return DP.get(current); + else { + List children = graph.get(current); + int profit = 0; + for (Pair c : children) { + profit = Math.max(profit, dp(c.a) + c.b); + } + profit = Math.max(profit, dp(current + 1)); + DP.put(current, profit); + return profit; + } + } +} diff --git a/problems/src/dynamic_programming/MaximumSubarray.java b/src/main/java/dynamic_programming/MaximumSubarray.java similarity index 96% rename from problems/src/dynamic_programming/MaximumSubarray.java rename to src/main/java/dynamic_programming/MaximumSubarray.java index c51abb4b..82ed2628 100644 --- a/problems/src/dynamic_programming/MaximumSubarray.java +++ b/src/main/java/dynamic_programming/MaximumSubarray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/problems/src/dynamic_programming/MaximumVacationDays.java b/src/main/java/dynamic_programming/MaximumVacationDays.java similarity index 99% rename from problems/src/dynamic_programming/MaximumVacationDays.java rename to src/main/java/dynamic_programming/MaximumVacationDays.java index 5f57de6a..a530a7a8 100644 --- a/problems/src/dynamic_programming/MaximumVacationDays.java +++ b/src/main/java/dynamic_programming/MaximumVacationDays.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/problems/src/dynamic_programming/MinCostClimbingStairs.java b/src/main/java/dynamic_programming/MinCostClimbingStairs.java similarity index 97% rename from problems/src/dynamic_programming/MinCostClimbingStairs.java rename to src/main/java/dynamic_programming/MinCostClimbingStairs.java index decdae74..d316b922 100644 --- a/problems/src/dynamic_programming/MinCostClimbingStairs.java +++ b/src/main/java/dynamic_programming/MinCostClimbingStairs.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/MinimumCostForTickets.java b/src/main/java/dynamic_programming/MinimumCostForTickets.java new file mode 100644 index 00000000..e1477c5c --- /dev/null +++ b/src/main/java/dynamic_programming/MinimumCostForTickets.java @@ -0,0 +1,85 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 05/05/2019 In a country popular for train travel, you have + * planned some train travelling one year in advance. The days of the year that you will travel is + * given as an array days. Each day is an integer from 1 to 365. + * + *

Train tickets are sold in 3 different ways: + * + *

a 1-day pass is sold for costs[0] dollars; a 7-day pass is sold for costs[1] dollars; a 30-day + * pass is sold for costs[2] dollars. The passes allow that many days of consecutive travel. For + * example, if we get a 7-day pass on day 2, then we can travel for 7 days: day 2, 3, 4, 5, 6, 7, + * and 8. + * + *

Return the minimum number of dollars you need to travel every day in the given list of days. + * + *

Example 1: + * + *

Input: days = [1,4,6,7,8,20], costs = [2,7,15] Output: 11 Explanation: For example, here is + * one way to buy passes that lets you travel your travel plan: On day 1, you bought a 1-day pass + * for costs[0] = $2, which covered day 1. On day 3, you bought a 7-day pass for costs[1] = $7, + * which covered days 3, 4, ..., 9. On day 20, you bought a 1-day pass for costs[0] = $2, which + * covered day 20. In total you spent $11 and covered all the days of your travel. Example 2: + * + *

Input: days = [1,2,3,4,5,6,7,8,9,10,30,31], costs = [2,7,15] Output: 17 Explanation: For + * example, here is one way to buy passes that lets you travel your travel plan: On day 1, you + * bought a 30-day pass for costs[2] = $15 which covered days 1, 2, ..., 30. On day 31, you bought a + * 1-day pass for costs[0] = $2 which covered day 31. In total you spent $17 and covered all the + * days of your travel. + * + *

Note: + * + *

1 <= days.length <= 365 1 <= days[i] <= 365 days is in strictly increasing order. costs.length + * == 3 1 <= costs[i] <= 1000 + * + *

Solution: O(N ^ 2 x 3) + */ +public class MinimumCostForTickets { + + public static void main(String[] args) { + int[] days = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 30, 31}; + int[] costs = {2, 7, 15}; + System.out.println(new MinimumCostForTickets().mincostTickets(days, costs)); + } + /** + * Main method + * + * @param days + * @param costs + * @return + */ + public int mincostTickets(int[] days, int[] costs) { + int[] min = new int[days.length]; + Arrays.fill(min, Integer.MAX_VALUE); + for (int i = days.length - 1; i >= 0; i--) { + for (int j = 0; j < costs.length; j++) { + if (j == 0) { + min[i] = Math.min(min[i], costs[j] + ((i + 1 >= min.length) ? 0 : min[i + 1])); + } else if (j == 1) { + int c = 0; + for (int k = i + 1; k < days.length; k++) { + if (days[k] >= (days[i] + 7)) { + c = min[k]; + break; + } + } + min[i] = Math.min(min[i], costs[j] + c); + } else { + int c = 0; + for (int k = i + 1; k < days.length; k++) { + if (days[k] >= (days[i] + 30)) { + c = min[k]; + break; + } + } + min[i] = Math.min(min[i], costs[j] + c); + } + } + } + return min[0]; + } +} diff --git a/src/main/java/dynamic_programming/MinimumCostToMergeStones.java b/src/main/java/dynamic_programming/MinimumCostToMergeStones.java new file mode 100644 index 00000000..8e0a1c80 --- /dev/null +++ b/src/main/java/dynamic_programming/MinimumCostToMergeStones.java @@ -0,0 +1,97 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 02/02/2020 There are N piles of stones arranged in a row. The + * i-th pile has stones[i] stones. + * + *

A move consists of merging exactly K consecutive piles into one pile, and the cost of this + * move is equal to the total number of stones in these K piles. + * + *

Find the minimum cost to merge all piles of stones into one pile. If it is impossible, return + * -1. + * + *

Example 1: + * + *

Input: stones = [3,2,4,1], K = 2 Output: 20 Explanation: We start with [3, 2, 4, 1]. We merge + * [3, 2] for a cost of 5, and we are left with [5, 4, 1]. We merge [4, 1] for a cost of 5, and we + * are left with [5, 5]. We merge [5, 5] for a cost of 10, and we are left with [10]. The total cost + * was 20, and this is the minimum possible. Example 2: + * + *

Input: stones = [3,2,4,1], K = 3 Output: -1 Explanation: After any merge operation, there are + * 2 piles left, and we can't merge anymore. So the task is impossible. Example 3: + * + *

Input: stones = [3,5,1,2,6], K = 3 Output: 25 Explanation: We start with [3, 5, 1, 2, 6]. We + * merge [5, 1, 2] for a cost of 8, and we are left with [3, 8, 6]. We merge [3, 8, 6] for a cost of + * 17, and we are left with [17]. The total cost was 25, and this is the minimum possible. + * + *

Note: + * + *

1 <= stones.length <= 30 2 <= K <= 30 1 <= stones[i] <= 100 + */ +public class MinimumCostToMergeStones { + public static void main(String[] args) { + int[] A = {3, 5, 1, 2, 6}; + System.out.println(new MinimumCostToMergeStones().mergeStones(A, 2)); + } + + private int[][][] DP; + private int K; + private int[] sum; + + public int mergeStones(int[] stones, int K) { + if (((stones.length - 1) % (K - 1)) != 0) return -1; + DP = new int[stones.length][stones.length][K + 1]; + this.K = K; + sum = new int[stones.length]; + sum[0] = stones[0]; + for (int i = 1; i < stones.length; i++) { + sum[i] = (sum[i - 1] + stones[i]); + } + for (int i = 0; i < stones.length; i++) { + for (int j = 0; j < stones.length; j++) { + for (int k = 1; k <= K; k++) { + if (k == 1 && i == j) { + DP[i][j][k] = 0; + } else DP[i][j][k] = 999999; + } + } + } + for (int r = 2; r <= stones.length; r++) { + for (int i = 0; i < stones.length; i++) { + int j = i + r - 1; + if (j < stones.length) { + for (int k = 2; k <= K; k++) { + int min = Integer.MAX_VALUE; + for (int t = i; t < j; t++) { + min = Math.min(min, DP[i][t][k - 1] + DP[t + 1][j][1]); + } + DP[i][j][k] = min; + } + DP[i][j][1] = DP[i][j][K] + (sum[j] - ((i - 1) >= 0 ? sum[i - 1] : 0)); + } + } + } + return DP[0][stones.length - 1][1]; + // return dp(0, stones.length - 1, 1); + } + + private int dp(int s, int e, int X) { + if (s == e) { + if (X == 1) return 0; + else return 999999; + } + if (DP[s][e][X] != 0) return DP[s][e][X]; + if (X == 1) { + DP[s][e][X] = dp(s, e, K) + sum[e] - ((s - 1) >= 0 ? sum[s - 1] : 0); + return DP[s][e][X]; + } else { + int min = Integer.MAX_VALUE; + for (int t = s; t < e; t++) { + min = Math.min(min, dp(s, t, X - 1) + dp(t + 1, e, 1)); + } + DP[s][e][X] = min; + return DP[s][e][X]; + } + } +} diff --git a/src/main/java/dynamic_programming/MinimumDifficultyOfAJobSchedule.java b/src/main/java/dynamic_programming/MinimumDifficultyOfAJobSchedule.java new file mode 100644 index 00000000..16015802 --- /dev/null +++ b/src/main/java/dynamic_programming/MinimumDifficultyOfAJobSchedule.java @@ -0,0 +1,66 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 19/02/2020 You want to schedule a list of jobs in d days. Jobs + * are dependent (i.e To work on the i-th job, you have to finish all the jobs j where 0 <= j < i). + * + *

You have to finish at least one task every day. The difficulty of a job schedule is the sum of + * difficulties of each day of the d days. The difficulty of a day is the maximum difficulty of a + * job done in that day. + * + *

Given an array of integers jobDifficulty and an integer d. The difficulty of the i-th job is + * jobDifficulty[i]. + * + *

Return the minimum difficulty of a job schedule. If you cannot find a schedule for the jobs + * return -1. + * + *

Example 1: + * + *

Input: jobDifficulty = [6,5,4,3,2,1], d = 2 Output: 7 Explanation: First day you can finish + * the first 5 jobs, total difficulty = 6. Second day you can finish the last job, total difficulty + * = 1. The difficulty of the schedule = 6 + 1 = 7 Example 2: + * + *

Input: jobDifficulty = [9,9,9], d = 4 Output: -1 Explanation: If you finish a job per day you + * will still have a free day. you cannot find a schedule for the given jobs. Example 3: + * + *

Input: jobDifficulty = [1,1,1], d = 3 Output: 3 Explanation: The schedule is one job per day. + * total difficulty will be 3. Example 4: + * + *

Input: jobDifficulty = [7,1,7,1,7,1], d = 3 Output: 15 Example 5: + * + *

Input: jobDifficulty = [11,111,22,222,33,333,44,444], d = 6 Output: 843 + * + *

Constraints: + * + *

1 <= jobDifficulty.length <= 300 0 <= jobDifficulty[i] <= 1000 1 <= d <= 10 + */ +public class MinimumDifficultyOfAJobSchedule { + public static void main(String[] args) { + int[] A = {11, 111, 22, 222, 33, 333, 44, 444}; + System.out.println(new MinimumDifficultyOfAJobSchedule().minDifficulty(A, 6)); + } + + int[][] DP; + + public int minDifficulty(int[] jobDifficulty, int d) { + DP = new int[jobDifficulty.length][d + 1]; + int result = dp(0, d, jobDifficulty); + if (result == 50000) return -1; + else return result; + } + + private int dp(int i, int d, int[] J) { + if (i >= J.length && d == 0) return 0; + else if (J.length - i < d || d <= 0) return 50000; + else if (DP[i][d] != 0) return DP[i][d]; + int max = J[i]; + int min = Integer.MAX_VALUE; + for (int k = i; k <= J.length - 1; k++) { + max = Math.max(max, J[k]); + min = Math.min(min, max + dp(k + 1, d - 1, J)); + } + DP[i][d] = min; + return min; + } +} diff --git a/src/main/java/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java b/src/main/java/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java new file mode 100644 index 00000000..a0e3198f --- /dev/null +++ b/src/main/java/dynamic_programming/MinimumDistanceToTypeAWordUsingTwoFingers.java @@ -0,0 +1,99 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 26/04/2020 + * + *

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z + * + *

You have a keyboard layout as shown above in the XY plane, where each English uppercase letter + * is located at some coordinate, for example, the letter A is located at coordinate (0,0), the + * letter B is located at coordinate (0,1), the letter P is located at coordinate (2,3) and the + * letter Z is located at coordinate (4,1). + * + *

Given the string word, return the minimum total distance to type such string using only two + * fingers. The distance between coordinates (x1,y1) and (x2,y2) is |x1 - x2| + |y1 - y2|. + * + *

Note that the initial positions of your two fingers are considered free so don't count towards + * your total distance, also your two fingers do not have to start at the first letter or the first + * two letters. + * + *

Example 1: + * + *

Input: word = "CAKE" Output: 3 Explanation: Using two fingers, one optimal way to type "CAKE" + * is: Finger 1 on letter 'C' -> cost = 0 Finger 1 on letter 'A' -> cost = Distance from letter 'C' + * to letter 'A' = 2 Finger 2 on letter 'K' -> cost = 0 Finger 2 on letter 'E' -> cost = Distance + * from letter 'K' to letter 'E' = 1 Total distance = 3 Example 2: + * + *

Input: word = "HAPPY" Output: 6 Explanation: Using two fingers, one optimal way to type + * "HAPPY" is: Finger 1 on letter 'H' -> cost = 0 Finger 1 on letter 'A' -> cost = Distance from + * letter 'H' to letter 'A' = 2 Finger 2 on letter 'P' -> cost = 0 Finger 2 on letter 'P' -> cost = + * Distance from letter 'P' to letter 'P' = 0 Finger 1 on letter 'Y' -> cost = Distance from letter + * 'A' to letter 'Y' = 4 Total distance = 6 Example 3: + * + *

Input: word = "NEW" Output: 3 Example 4: + * + *

Input: word = "YEAR" Output: 7 + * + *

Constraints: + * + *

2 <= word.length <= 300 Each word[i] is an English uppercase letter. + */ +public class MinimumDistanceToTypeAWordUsingTwoFingers { + int[][] DP; + int[][] dist; + + public static void main(String[] args) { + System.out.println(new MinimumDistanceToTypeAWordUsingTwoFingers().minimumDistance("YEAR")); + } + + public int minimumDistance(String word) { + DP = new int[word.length()][word.length()]; + dist = new int[26][26]; + char[][] chars = { + {'A', 'B', 'C', 'D', 'E', 'F'}, + {'G', 'H', 'I', 'J', 'K', 'L'}, + {'M', 'N', 'O', 'P', 'Q', 'R'}, + {'S', 'T', 'U', 'V', 'W', 'X'}, + {'Y', 'Z', ' ', ' ', ' ', ' '} + }; + for (int i = 0; i < chars.length; i++) { + for (int j = 0; j < chars[0].length; j++) { + char from = chars[i][j]; + if (from == ' ') break; + for (int k = 0; k < chars.length; k++) { + for (int l = 0; l < chars[0].length; l++) { + char to = chars[k][l]; + if (to == ' ') break; + dist[from - 'A'][to - 'A'] = Math.abs(k - i) + Math.abs(l - j); + } + } + } + } + for (int i = 0; i < word.length(); i++) { + for (int j = 0; j < word.length(); j++) { + DP[i][j] = -1; + } + } + int min = Integer.MAX_VALUE; + for (int i = 1; i < word.length(); i++) { + min = Math.min(min, dp(0, i, word)); + } + return min; + } + + private int dp(int p, int i, String S) { + if (DP[p][i] != -1) return DP[p][i]; + else { + int left = Integer.MAX_VALUE, right; + int min = Integer.MAX_VALUE; + if (p + 1 == S.length()) return 0; + if (p + 1 != i) { + left = dp(p + 1, i, S) + dist[S.charAt(p) - 'A'][S.charAt(p + 1) - 'A']; + } + right = dp(p + 1, p, S) + dist[S.charAt(i) - 'A'][S.charAt(p + 1) - 'A']; + DP[p][i] = Math.min(min, Math.min(left, right)); + return DP[p][i]; + } + } +} diff --git a/problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java b/src/main/java/dynamic_programming/MinimumNumberOfRefuelingStops.java similarity index 99% rename from problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java rename to src/main/java/dynamic_programming/MinimumNumberOfRefuelingStops.java index 2c1026be..d2185f69 100644 --- a/problems/src/dynamic_programming/MinimumNumberOfRefuelingStops.java +++ b/src/main/java/dynamic_programming/MinimumNumberOfRefuelingStops.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/MinimumNumberOfTaps.java b/src/main/java/dynamic_programming/MinimumNumberOfTaps.java new file mode 100644 index 00000000..45b1de6e --- /dev/null +++ b/src/main/java/dynamic_programming/MinimumNumberOfTaps.java @@ -0,0 +1,71 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 01/03/2020 There is a one-dimensional garden on the x-axis. The + * garden starts at the point 0 and ends at the point n. (i.e The length of the garden is n). + * + *

There are n + 1 taps located at points [0, 1, ..., n] in the garden. + * + *

Given an integer n and an integer array ranges of length n + 1 where ranges[i] (0-indexed) + * means the i-th tap can water the area [i - ranges[i], i + ranges[i]] if it was open. + * + *

Return the minimum number of taps that should be open to water the whole garden, If the garden + * cannot be watered return -1. + * + *

Example 1: + * + *

Input: n = 5, ranges = [3,4,1,1,0,0] Output: 1 Explanation: The tap at point 0 can cover the + * interval [-3,3] The tap at point 1 can cover the interval [-3,5] The tap at point 2 can cover the + * interval [1,3] The tap at point 3 can cover the interval [2,4] The tap at point 4 can cover the + * interval [4,4] The tap at point 5 can cover the interval [5,5] Opening Only the second tap will + * water the whole garden [0,5] Example 2: + * + *

Input: n = 3, ranges = [0,0,0,0] Output: -1 Explanation: Even if you activate all the four + * taps you cannot water the whole garden. Example 3: + * + *

Input: n = 7, ranges = [1,2,1,0,2,1,0,1] Output: 3 Example 4: + * + *

Input: n = 8, ranges = [4,0,0,0,0,0,0,0,4] Output: 2 Example 5: + * + *

Input: n = 8, ranges = [4,0,0,0,4,0,0,0,4] Output: 1 + * + *

Constraints: + * + *

1 <= n <= 10^4 ranges.length == n + 1 0 <= ranges[i] <= 100 + */ +public class MinimumNumberOfTaps { + public static void main(String[] args) { + int[] A = {0, 1, 2, 0, 0, 1, 1, 0}; + System.out.println(new MinimumNumberOfTaps().minTaps(7, A)); + } + + int[] DP; + + public int minTaps(int n, int[] ranges) { + DP = new int[n + 1]; + Arrays.fill(DP, -2); + return dp(0, 0, ranges, n); + } + + private int dp(int i, int prev, int[] R, int n) { + if (i > n) return 0; + else if (DP[i] != -2) return DP[i]; + else { + int min = Integer.MAX_VALUE; + int start = R[prev] > 0 ? prev : i; + for (int j = start; j < start + 100 && j <= n; j++) { + if (j - R[j] <= prev) { + int result = dp(j + R[j] + 1, j + R[j], R, n); + if (result >= 0) { + min = Math.min(min, result + 1); + } + } + } + DP[i] = (min == Integer.MAX_VALUE ? -1 : min); + return DP[i]; + } + } +} diff --git a/src/main/java/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java b/src/main/java/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java new file mode 100644 index 00000000..e4fa996d --- /dev/null +++ b/src/main/java/dynamic_programming/NonNegativeIntegersWithoutConsecutiveOnes.java @@ -0,0 +1,85 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 20/10/2019 Given a positive integer n, find the number of + * non-negative integers less than or equal to n, whose binary representations do NOT contain + * consecutive ones. + * + *

Example 1: Input: 5 Output: 5 Explanation: Here are the non-negative integers <= 5 with their + * corresponding binary representations: 0 : 0 1 : 1 2 : 10 3 : 11 4 : 100 5 : 101 Among them, only + * integer 3 disobeys the rule (two consecutive ones) and the other 5 satisfy the rule. Note: 1 <= n + * <= 109 + * + *

Solution: O(1) (30 ^ 2) For each bit we can set either '0' or '1' starting from index i to 0, + * if we set 0 then the next bit i + 1 can be either set to 0 or 1 but, if we set it to 1 then the + * next bit at position i + 1 can only be 0 because two consecutive 1s are invalid. This gives us a + * general dp formula DP[0][i] = DP[0][i + 1] + DP[1][i + 1] for bit 0 and similarly DP[1][i] = + * DP[0][i + 1]. + * + *

Lets consider an example with number = 4 (binary representation is 100). Now, the above + * approach would calculate all possible number ranging from 0 (000) -> 7 (111), lets say the count + * is x. But, we actually want to restrict until only 100. Therefore we have to calculate all valid + * states starting from 100 until 111 and lets say this is y. Now, the answer would be x - y + 1. + * Adding 1 here because the state 100 (which is a valid state) would be counted twice in x and also + * in y. For cases where a binary representation of given N is like 1100 we have to find a max + * possible valid state which occurs just before 1100 which in this case is 1010 and now calculate y + * starting from 1010 to 1111. + */ +public class NonNegativeIntegersWithoutConsecutiveOnes { + public static void main(String[] args) { + System.out.println(new NonNegativeIntegersWithoutConsecutiveOnes().findIntegers(1000000000)); + } + + public int findIntegers(int num) { + int msbIndex = 0; + for (int i = 0; i < 31; i++) { + if (((1 << i) & num) > 0) { + msbIndex = i; + } + } + int[][] DP1 = new int[2][msbIndex + 1]; // count from 0 until all possible value. + int[][] DP2 = new int[2][msbIndex + 2]; // count from given N until max possible value + for (int i = msbIndex; i >= 0; i--) { + if (i == msbIndex) { + DP1[0][msbIndex] = 1; + DP1[1][msbIndex] = 1; + } else { + DP1[0][i] = DP1[0][i + 1] + DP1[1][i + 1]; + DP1[1][i] = DP1[0][i + 1]; + } + } + // find valid state just before given num + int[] bits = new int[msbIndex + 1]; + boolean bitFlipped = false; + for (int i = msbIndex, j = 0; i >= 0; i--, j++) { + if (j == 0) { + bits[j] = 1; + } else { + if (bitFlipped) { + bits[j] = bits[j - 1] == 0 ? 1 : 0; + } else { + if (((1 << i) & num) > 0) { + if (bits[j - 1] > 0) { + bits[j] = 0; + bitFlipped = true; + } else bits[j] = 1; + } + } + } + } + DP2[0][msbIndex + 1] = 1; + for (int i = bits.length - 1; i >= 0; i--) { + if (bits[i] == 0) { + DP2[0][i] = DP2[0][i + 1] + DP2[1][i + 1]; + // if the curr bit is 0 then, we can make this 1 provided the previous bit was not 1 + if (bits[i - 1] == 0) { + DP2[1][i] = (i == bits.length - 1) ? 1 : DP1[0][i + 1]; + } + } else { + DP2[1][i] = DP2[0][i + 1]; + } + } + return (DP1[0][0] + DP1[1][0]) - (DP2[0][0] + DP2[1][0]) + 1; + } +} diff --git a/src/main/java/dynamic_programming/NumberOfDiceRollsWithTargetSum.java b/src/main/java/dynamic_programming/NumberOfDiceRollsWithTargetSum.java new file mode 100644 index 00000000..3922b23f --- /dev/null +++ b/src/main/java/dynamic_programming/NumberOfDiceRollsWithTargetSum.java @@ -0,0 +1,53 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 29/11/2019 You have d dice, and each die has f faces numbered + * 1, 2, ..., f. + * + *

Return the number of possible ways (out of fd total ways) modulo 10^9 + 7 to roll the dice so + * the sum of the face up numbers equals target. + * + *

Example 1: + * + *

Input: d = 1, f = 6, target = 3 Output: 1 Explanation: You throw one die with 6 faces. There + * is only one way to get a sum of 3. Example 2: + * + *

Input: d = 2, f = 6, target = 7 Output: 6 Explanation: You throw two dice, each with 6 faces. + * There are 6 ways to get a sum of 7: 1+6, 2+5, 3+4, 4+3, 5+2, 6+1. Example 3: + * + *

Input: d = 2, f = 5, target = 10 Output: 1 Explanation: You throw two dice, each with 5 faces. + * There is only one way to get a sum of 10: 5+5. Example 4: + * + *

Input: d = 1, f = 2, target = 3 Output: 0 Explanation: You throw one die with 2 faces. There + * is no way to get a sum of 3. Example 5: + * + *

Input: d = 30, f = 30, target = 500 Output: 222616187 Explanation: The answer must be returned + * modulo 10^9 + 7. + * + *

Constraints: + * + *

1 <= d, f <= 30 1 <= target <= 1000 + */ +public class NumberOfDiceRollsWithTargetSum { + public static void main(String[] args) { + System.out.println(new NumberOfDiceRollsWithTargetSum().numRollsToTarget(3, 3, 3)); + } + + private final int MOD = 1000000007; + + public int numRollsToTarget(int d, int f, int target) { + int[][] DP = new int[d + 1][target + 1]; + for (int i = 1; i <= Math.min(f, target); i++) { + DP[1][i] = 1; + } + for (int i = 2; i <= d; i++) { + for (int j = 1; j <= target; j++) { + for (int k = 1; k <= Math.min(f, j); k++) { + DP[i][j] = (DP[i - 1][j - k]) == 0 ? DP[i][j] : ((DP[i][j] + (DP[i - 1][j - k])) % MOD); + } + } + } + return DP[d][target]; + } +} diff --git a/problems/src/dynamic_programming/NumberOfLIS.java b/src/main/java/dynamic_programming/NumberOfLIS.java similarity index 98% rename from problems/src/dynamic_programming/NumberOfLIS.java rename to src/main/java/dynamic_programming/NumberOfLIS.java index a678340a..a6dd2ce6 100644 --- a/problems/src/dynamic_programming/NumberOfLIS.java +++ b/src/main/java/dynamic_programming/NumberOfLIS.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/NumberOfMusicPlaylists.java b/src/main/java/dynamic_programming/NumberOfMusicPlaylists.java new file mode 100644 index 00000000..e81aae24 --- /dev/null +++ b/src/main/java/dynamic_programming/NumberOfMusicPlaylists.java @@ -0,0 +1,36 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.Arrays; + +/** Created by gouthamvidyapradhan on 13/06/2020 */ +public class NumberOfMusicPlaylists { + public static void main(String[] args) { + // + } + + int[][] DP; + final int MOD = (int) 1e9 + 7; + + public int numMusicPlaylists(int N, int L, int K) { + DP = new int[L + 1][N + 1]; + for (int i = 0; i <= L; i++) { + Arrays.fill(DP[i], -1); + } + DP[0][0] = 1; + return (int) dp(L, N, K, N); + } + + private long dp(int i, int j, int K, int N) { + if (i < j) return 0; + else if (i < 0 || j < 0) return 0; + else if (DP[i][j] != -1) return DP[i][j]; + else { + long sum = 0L; + sum += ((dp(i - 1, j - 1, K, N) * (N - (j - 1))) % MOD); + sum += (dp(i - 1, j, K, N) * (Math.max(j - K, 0)) % MOD); + DP[i][j] = (int) (sum % MOD); + return DP[i][j]; + } + } +} diff --git a/src/main/java/dynamic_programming/NumberOfPathsWithMaxScore.java b/src/main/java/dynamic_programming/NumberOfPathsWithMaxScore.java new file mode 100644 index 00000000..09d2fcee --- /dev/null +++ b/src/main/java/dynamic_programming/NumberOfPathsWithMaxScore.java @@ -0,0 +1,84 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * Created by gouthamvidyapradhan on 13/04/2021 You are given a square board of characters. You can + * move on the board starting at the bottom right square marked with the character 'S'. + * + *

You need to reach the top left square marked with the character 'E'. The rest of the squares + * are labeled either with a numeric character 1, 2, ..., 9 or with an obstacle 'X'. In one move you + * can go up, left or up-left (diagonally) only if there is no obstacle there. + * + *

Return a list of two integers: the first integer is the maximum sum of numeric characters you + * can collect, and the second is the number of such paths that you can take to get that maximum + * sum, taken modulo 10^9 + 7. + * + *

In case there is no path, return [0, 0]. + * + *

Example 1: + * + *

Input: board = ["E23","2X2","12S"] Output: [7,1] Example 2: + * + *

Input: board = ["E12","1X1","21S"] Output: [4,2] Example 3: + * + *

Input: board = ["E11","XXX","11S"] Output: [0,0] + * + *

Constraints: + * + *

2 <= board.length == board[i].length <= 100 Solution: O(N x N) where N is the length of board. + */ +public class NumberOfPathsWithMaxScore { + public static void main(String[] args) { + String[] board = {"E11", "XXX", "11S"}; + List input = Arrays.stream(board).collect(Collectors.toList()); + int[] r = new NumberOfPathsWithMaxScore().pathsWithMaxScore(input); + System.out.println(r[0] + " " + r[1]); + } + + long[][] M, N; + final int[] R = {0, 1, 1}; + final int[] C = {1, 1, 0}; + int MOD = (int) 1e9 + 7; + + public int[] pathsWithMaxScore(List board) { + M = new long[board.size()][board.get(0).length()]; + N = new long[board.size()][board.get(0).length()]; + N[board.size() - 1][board.get(0).length() - 1] = 1; + for (int i = board.size() - 1; i >= 0; i--) { + for (int j = board.get(i).length() - 1; j >= 0; j--) { + char curr = board.get(i).charAt(j); + if (curr != 'X') { + int currInt = 0; + if (curr != 'S' && curr != 'E') { + currInt = Integer.parseInt(String.valueOf(curr)); + } + long currMax = -1; + for (int k = 0; k < 3; k++) { + int newR = i + R[k]; + int newC = j + C[k]; + if (newR < board.size() + && newC < board.get(0).length() + && board.get(newR).charAt(newC) != 'X' + && N[newR][newC] != 0) { + M[i][j] = Math.max(M[i][j], ((currInt + M[newR][newC]) % MOD)); + long newMax = ((currInt + M[newR][newC]) % MOD); + if (newMax > currMax) { + currMax = newMax; + N[i][j] = N[newR][newC]; + } else if (newMax == currMax) { + N[i][j] = ((N[newR][newC] + N[i][j]) % MOD); + } + } + } + } + } + } + int[] res = new int[2]; + res[0] = (int) M[0][0]; + res[1] = (int) N[0][0]; + return res; + } +} diff --git a/src/main/java/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java b/src/main/java/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java new file mode 100644 index 00000000..9da8381b --- /dev/null +++ b/src/main/java/dynamic_programming/NumberOfWaysToStayInTheSamePlace.java @@ -0,0 +1,68 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 05/04/2020 You have a pointer at index 0 in an array of size + * arrLen. At each step, you can move 1 position to the left, 1 position to the right in the array + * or stay in the same place (The pointer should not be placed outside the array at any time). + * + *

Given two integers steps and arrLen, return the number of ways such that your pointer still at + * index 0 after exactly steps steps. + * + *

Since the answer may be too large, return it modulo 10^9 + 7. + * + *

Example 1: + * + *

Input: steps = 3, arrLen = 2 Output: 4 Explanation: There are 4 differents ways to stay at + * index 0 after 3 steps. Right, Left, Stay Stay, Right, Left Right, Stay, Left Stay, Stay, Stay + * Example 2: + * + *

Input: steps = 2, arrLen = 4 Output: 2 Explanation: There are 2 differents ways to stay at + * index 0 after 2 steps Right, Left Stay, Stay Example 3: + * + *

Input: steps = 4, arrLen = 2 Output: 8 + * + *

Constraints: + * + *

1 <= steps <= 500 1 <= arrLen <= 10^6 + * + *

Solution O(S x S) where S is number of steps. This is quite a straight forward problem. Every + * state is a combination of position in the array and the number of steps. From every state we can + * traverse in three direction remain in the same position i.e (i, n - 1), move right (i + 1, n - 1) + * and move left (i - 1, n - 1). The base state will be (0, 0) which is equal to count of 1, memoize + * each state and do a dop down dp staring from state (0, N). + */ +public class NumberOfWaysToStayInTheSamePlace { + + private static final int MOD = (int) (1e9 + 7); + + public static void main(String[] args) { + System.out.println(new NumberOfWaysToStayInTheSamePlace().numWays(500, 1000000)); + } + + int[][] DP; + + public int numWays(int steps, int arrLen) { + int colLimit = arrLen < steps ? arrLen : steps; + DP = new int[colLimit + 1][steps + 1]; + for (int i = 0; i <= colLimit; i++) { + Arrays.fill(DP[i], -1); + } + DP[0][0] = 1; + return (int) dp(0, steps, arrLen); + } + + private long dp(int i, int n, int A) { + if (i < 0 || i >= A) return 0; + else if (n < 0) return 0; + if (DP[i][n] != -1) return DP[i][n]; + DP[i][n] = + (int) + (((((dp(i, n - 1, A) % MOD) + (dp(i - 1, n - 1, A) % MOD)) % MOD) + + (dp(i + 1, n - 1, A) % MOD)) + % MOD); + return DP[i][n]; + } +} diff --git a/problems/src/dynamic_programming/OddEvenJump.java b/src/main/java/dynamic_programming/OddEvenJump.java similarity index 99% rename from problems/src/dynamic_programming/OddEvenJump.java rename to src/main/java/dynamic_programming/OddEvenJump.java index 177b2d48..f7238aed 100644 --- a/problems/src/dynamic_programming/OddEvenJump.java +++ b/src/main/java/dynamic_programming/OddEvenJump.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/OnesAndZeroes.java b/src/main/java/dynamic_programming/OnesAndZeroes.java new file mode 100644 index 00000000..7f260040 --- /dev/null +++ b/src/main/java/dynamic_programming/OnesAndZeroes.java @@ -0,0 +1,65 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 01/08/2019 In the computer world, use restricted resource you + * have to generate maximum benefit is what we always want to pursue. + * + *

For now, suppose you are a dominator of m 0s and n 1s respectively. On the other hand, there + * is an array with strings consisting of only 0s and 1s. + * + *

Now your task is to find the maximum number of strings that you can form with given m 0s and n + * 1s. Each 0 and 1 can be used at most once. + * + *

Note: + * + *

The given numbers of 0s and 1s will both not exceed 100 The size of given string array won't + * exceed 600. + * + *

Example 1: + * + *

Input: Array = {"10", "0001", "111001", "1", "0"}, m = 5, n = 3 Output: 4 + * + *

Explanation: This are totally 4 strings can be formed by the using of 5 0s and 3 1s, which are + * “10,”0001”,”1”,”0” + * + *

Example 2: + * + *

Input: Array = {"10", "0", "1"}, m = 1, n = 1 Output: 2 + * + *

Explanation: You could form "10", but then you'd have nothing left. Better form "0" and "1". + * + *

Solution: O(S x m x n) For every string array position we have two choices i. pick this value + * or ii. not pick this value. Evaluate both these cases and cache the result in a dp array. + */ +public class OnesAndZeroes { + public static void main(String[] args) { + String[] str = {"10", "0", "1"}; + System.out.println(new OnesAndZeroes().findMaxForm(str, 1, 1)); + } + + public int findMaxForm(String[] strs, int m, int n) { + int[][][] dp = new int[strs.length + 1][m + 1][n + 1]; + for (int i = strs.length - 1; i >= 0; i--) { + String string = strs[i]; + int zero = 0; + int one = 0; + for (char c : string.toCharArray()) { + if (c == '0') { + zero++; + } else { + one++; + } + } + for (int p = m; p >= 0; p--) { + for (int q = n; q >= 0; q--) { + dp[i][p][q] = dp[i + 1][p][q]; + if (p - zero >= 0 && q - one >= 0) { + dp[i][p][q] = Math.max(dp[i][p][q], dp[i + 1][p - zero][q - one] + 1); + } + } + } + } + return dp[0][m][n]; + } +} diff --git a/src/main/java/dynamic_programming/OutOfBoundaryPaths.java b/src/main/java/dynamic_programming/OutOfBoundaryPaths.java new file mode 100644 index 00000000..3bf44810 --- /dev/null +++ b/src/main/java/dynamic_programming/OutOfBoundaryPaths.java @@ -0,0 +1,49 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 15/05/2019 There is an m by n grid with a ball. Given the start + * coordinate (i,j) of the ball, you can move the ball to adjacent cell or cross the grid boundary + * in four directions (up, down, left, right). However, you can at most move N times. Find out the + * number of paths to move the ball out of grid boundary. The answer may be very large, return it + * after mod 10 ^ 9 + 7. + * + *

Solution: O(m x n x N x 4) Move in all possible directions from the starting position (i, j) + * and keep track of distance traversed and ensure the distance traversed does not exceed N. Keep + * the count of number of possibilities to go out of the boundary for each cell reached. Return the + * sum in cell (a, b) + */ +public class OutOfBoundaryPaths { + + final int[] R = {1, -1, 0, 0}; + final int[] C = {0, 0, 1, -1}; + int[][][] DP; + int mod = 1000000007; + + public static void main(String[] args) { + System.out.println(new OutOfBoundaryPaths().findPaths(2, 2, 2, 0, 0)); + } + + public int findPaths(int m, int n, int N, int a, int b) { + if (N == 0) return 0; + DP = new int[m][n][N + 1]; + + for (int k = 1; k <= N; k++) { + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + for (int p = 0; p < 4; p++) { + int newR = i + R[p]; + int newC = j + C[p]; + if (newR < 0 || newC < 0 || newR >= m || newC >= n) { + DP[i][j][k] = ((DP[i][j][k] + 1) % mod); + } else { + DP[i][j][k] = (((DP[i][j][k] + DP[newR][newC][k - 1])) % mod); + } + } + } + } + } + + return DP[a][b][N]; + } +} diff --git a/problems/src/dynamic_programming/PaintHouseII.java b/src/main/java/dynamic_programming/PaintHouseII.java similarity index 98% rename from problems/src/dynamic_programming/PaintHouseII.java rename to src/main/java/dynamic_programming/PaintHouseII.java index 68c9d8a6..b22086be 100644 --- a/problems/src/dynamic_programming/PaintHouseII.java +++ b/src/main/java/dynamic_programming/PaintHouseII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/PaintHouseIII.java b/src/main/java/dynamic_programming/PaintHouseIII.java new file mode 100644 index 00000000..7b981013 --- /dev/null +++ b/src/main/java/dynamic_programming/PaintHouseIII.java @@ -0,0 +1,105 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 22/10/2020 There is a row of m houses in a small city, each + * house must be painted with one of the n colors (labeled from 1 to n), some houses that has been + * painted last summer should not be painted again. + * + *

A neighborhood is a maximal group of continuous houses that are painted with the same color. + * (For example: houses = [1,2,2,3,3,2,1,1] contains 5 neighborhoods [{1}, {2,2}, {3,3}, {2}, + * {1,1}]). + * + *

Given an array houses, an m * n matrix cost and an integer target where: + * + *

houses[i]: is the color of the house i, 0 if the house is not painted yet. cost[i][j]: is the + * cost of paint the house i with the color j+1. Return the minimum cost of painting all the + * remaining houses in such a way that there are exactly target neighborhoods, if not possible + * return -1. + * + *

Example 1: + * + *

Input: houses = [0,0,0,0,0], cost = [[1,10],[10,1],[10,1],[1,10],[5,1]], m = 5, n = 2, target + * = 3 Output: 9 Explanation: Paint houses of this way [1,2,2,1,1] This array contains target = 3 + * neighborhoods, [{1}, {2,2}, {1,1}]. Cost of paint all houses (1 + 1 + 1 + 1 + 5) = 9. Example 2: + * + *

Input: houses = [0,2,1,2,0], cost = [[1,10],[10,1],[10,1],[1,10],[5,1]], m = 5, n = 2, target + * = 3 Output: 11 Explanation: Some houses are already painted, Paint the houses of this way + * [2,2,1,2,2] This array contains target = 3 neighborhoods, [{2,2}, {1}, {2,2}]. Cost of paint the + * first and last house (10 + 1) = 11. Example 3: + * + *

Input: houses = [0,0,0,0,0], cost = [[1,10],[10,1],[1,10],[10,1],[1,10]], m = 5, n = 2, target + * = 5 Output: 5 Example 4: + * + *

Input: houses = [3,1,2,3], cost = [[1,1,1],[1,1,1],[1,1,1],[1,1,1]], m = 4, n = 3, target = 3 + * Output: -1 Explanation: Houses are already painted with a total of 4 neighborhoods + * [{3},{1},{2},{3}] different of target = 3. + * + *

Constraints: + * + *

m == houses.length == cost.length n == cost[i].length 1 <= m <= 100 1 <= n <= 20 1 <= target + * <= m 0 <= houses[i] <= n 1 <= cost[i][j] <= 10^4 + */ +public class PaintHouseIII { + public static void main(String[] args) { + // int[] h = {0,0}; + // int[][] cost = {{1,2}, {1,2}}; + int[] h = {3, 1, 2, 3}; + int[][] cost = {{1, 10}, {10, 1}, {1, 10}, {10, 1}, {1, 10}}; + int m = 5; + int n = 2; + int target = 5; + System.out.println(new PaintHouseIII().minCost(h, cost, m, n, target)); + } + + int[][][] DP; + + public int minCost(int[] houses, int[][] cost, int m, int n, int target) { + DP = new int[houses.length][target + 1][n + 1]; + for (int i = 0; i < houses.length; i++) { + for (int j = 0; j < target + 1; j++) { + Arrays.fill(DP[i][j], -2); + } + } + int result = dp(0, 0, target, cost, houses); + return result; + } + + private int dp(int i, int c, int t, int[][] cost, int[] houses) { + if (t == 0 && i == houses.length) return 0; + else if (t == -1 || i == houses.length) return -1; + else if (DP[i][t][c] != -2) return DP[i][t][c]; + else { + int min = Integer.MAX_VALUE; + if (houses[i] != 0) { + int result; + if (houses[i] == c) { + result = dp(i + 1, c, t, cost, houses); + } else { + result = dp(i + 1, houses[i], t - 1, cost, houses); + } + if (result != -1) { + if (c != 0) { + min = Math.min(min, result); + } else min = result; + } + } else { + for (int co = 1; co < cost[0].length + 1; co++) { + int result; + if (co != c) { + result = dp(i + 1, co, t - 1, cost, houses); + } else { + result = dp(i + 1, co, t, cost, houses); + } + if (result != -1) { + min = Math.min(min, cost[i][co - 1] + result); + } + } + } + DP[i][t][c] = (min == Integer.MAX_VALUE ? -1 : min); + return DP[i][t][c]; + } + } +} diff --git a/problems/src/dynamic_programming/PalindromePairs.java b/src/main/java/dynamic_programming/PalindromePairs.java similarity index 99% rename from problems/src/dynamic_programming/PalindromePairs.java rename to src/main/java/dynamic_programming/PalindromePairs.java index ebcab5c3..1ca89e4d 100644 --- a/problems/src/dynamic_programming/PalindromePairs.java +++ b/src/main/java/dynamic_programming/PalindromePairs.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/problems/src/dynamic_programming/PalindromePartitioningII.java b/src/main/java/dynamic_programming/PalindromePartitioningII.java similarity index 98% rename from problems/src/dynamic_programming/PalindromePartitioningII.java rename to src/main/java/dynamic_programming/PalindromePartitioningII.java index a04e7747..6dedd2c3 100644 --- a/problems/src/dynamic_programming/PalindromePartitioningII.java +++ b/src/main/java/dynamic_programming/PalindromePartitioningII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.Arrays; diff --git a/src/main/java/dynamic_programming/PalindromePartitioningIII.java b/src/main/java/dynamic_programming/PalindromePartitioningIII.java new file mode 100644 index 00000000..be678971 --- /dev/null +++ b/src/main/java/dynamic_programming/PalindromePartitioningIII.java @@ -0,0 +1,80 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 22/04/2020 You are given a string s containing lowercase + * letters and an integer k. You need to : + * + *

First, change some characters of s to other lowercase English letters. Then divide s into k + * non-empty disjoint substrings such that each substring is palindrome. Return the minimal number + * of characters that you need to change to divide the string. + * + *

Example 1: + * + *

Input: s = "abc", k = 2 Output: 1 Explanation: You can split the string into "ab" and "c", and + * change 1 character in "ab" to make it palindrome. Example 2: + * + *

Input: s = "aabbc", k = 3 Output: 0 Explanation: You can split the string into "aa", "bb" and + * "c", all of them are palindrome. Example 3: + * + *

Input: s = "leetcode", k = 8 Output: 0 + * + *

Constraints: + * + *

1 <= k <= s.length <= 100. s only contains lowercase English letters. + */ +public class PalindromePartitioningIII { + + public static void main(String[] args) { + System.out.println(new PalindromePartitioningIII().palindromePartition("leetcode", 8)); + } + + int[][][] DP; + + public int palindromePartition(String s, int k) { + DP = new int[s.length()][s.length()][k + 1]; + for (int i = 0; i < s.length(); i++) { + for (int j = 0; j < s.length(); j++) { + Arrays.fill(DP[i][j], -1); + } + } + return dp(0, s.length() - 1, k, s); + } + + private int dp(int i, int j, int n, String s) { + if (i == j && n == 1) return 0; + else if ((j - i + 1 < n) || (n <= 0)) return -1; + else if (DP[i][j][n] != -1) return DP[i][j][n]; + else if (n == 1) { + int result = count(s.substring(i, j + 1)); + DP[i][j][n] = result; + return result; + } else { + int min = Integer.MAX_VALUE; + for (int k = i; k < j; k++) { + int left = dp(i, k, 1, s); + int right = dp(k + 1, j, n - 1, s); + if (right != -1) { + min = Math.min(min, left + right); + } + } + if (min != Integer.MAX_VALUE) { + DP[i][j][n] = min; + return min; + } + return -1; + } + } + + private int count(String s) { + int cnt = 0; + for (int i = 0, j = s.length() - 1; i < j; i++, j--) { + if (s.charAt(i) != s.charAt(j)) { + cnt++; + } + } + return cnt; + } +} diff --git a/src/main/java/dynamic_programming/PalindromeRemoval.java b/src/main/java/dynamic_programming/PalindromeRemoval.java new file mode 100644 index 00000000..3c81a1fb --- /dev/null +++ b/src/main/java/dynamic_programming/PalindromeRemoval.java @@ -0,0 +1,50 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 12/05/2020 Given an integer array arr, in one move you can + * select a palindromic subarray arr[i], arr[i+1], ..., arr[j] where i <= j, and remove that + * subarray from the given array. Note that after removing a subarray, the elements on the left and + * on the right of that subarray move to fill the gap left by the removal. + * + *

Return the minimum number of moves needed to remove all numbers from the array. + * + *

Example 1: + * + *

Input: arr = [1,2] Output: 2 Example 2: + * + *

Input: arr = [1,3,4,1,5] Output: 3 Explanation: Remove [4] then remove [1,3,1] then remove + * [5]. + * + *

Constraints: + * + *

1 <= arr.length <= 100 1 <= arr[i] <= 20 + */ +public class PalindromeRemoval { + public static void main(String[] args) { + int[] A = {1, 3, 1, 2, 4, 2}; + System.out.println(new PalindromeRemoval().minimumMoves(A)); + } + + int[][] DP; + + public int minimumMoves(int[] arr) { + DP = new int[arr.length][arr.length]; + return dp(0, arr.length - 1, arr); + } + + private int dp(int i, int j, int[] arr) { + if (i > j) return 1; + else if (DP[i][j] != 0) return DP[i][j]; + else { + int min = Integer.MAX_VALUE; + for (int t = j; t >= i; t--) { + if (arr[i] == arr[t]) { + min = Math.min(min, dp(i + 1, t - 1, arr) + ((t + 1 > j) ? 0 : dp(t + 1, j, arr))); + } + } + DP[i][j] = min; + return min; + } + } +} diff --git a/problems/src/dynamic_programming/PalindromicSubstrings.java b/src/main/java/dynamic_programming/PalindromicSubstrings.java similarity index 98% rename from problems/src/dynamic_programming/PalindromicSubstrings.java rename to src/main/java/dynamic_programming/PalindromicSubstrings.java index cc461c24..d8dcf944 100644 --- a/problems/src/dynamic_programming/PalindromicSubstrings.java +++ b/src/main/java/dynamic_programming/PalindromicSubstrings.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/problems/src/dynamic_programming/ProfitableSchemes.java b/src/main/java/dynamic_programming/ProfitableSchemes.java similarity index 98% rename from problems/src/dynamic_programming/ProfitableSchemes.java rename to src/main/java/dynamic_programming/ProfitableSchemes.java index 0f483933..b6f3becc 100644 --- a/problems/src/dynamic_programming/ProfitableSchemes.java +++ b/src/main/java/dynamic_programming/ProfitableSchemes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** * Created by gouthamvidyapradhan on 26/03/2019 There are G people in a gang, and a list of various diff --git a/src/main/java/dynamic_programming/RemoveBoxes.java b/src/main/java/dynamic_programming/RemoveBoxes.java new file mode 100644 index 00000000..094f9497 --- /dev/null +++ b/src/main/java/dynamic_programming/RemoveBoxes.java @@ -0,0 +1,50 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; +/** + * Created by gouthamvidyapradhan on 28/05/2019 Given several boxes with different colors + * represented by different positive numbers. You may experience several rounds to remove boxes + * until there is no box left. Each time you can choose some continuous boxes with the same color + * (composed of k boxes, k >= 1), remove them and get k*k points. Find the maximum points you can + * get. + * + *

Example 1: Input: + * + *

[1, 3, 2, 2, 2, 3, 4, 3, 1] Output: 23 Explanation: [1, 3, 2, 2, 2, 3, 4, 3, 1] ----> [1, 3, + * 3, 4, 3, 1] (3*3=9 points) ----> [1, 3, 3, 3, 1] (1*1=1 points) ----> [1, 1] (3*3=9 points) ----> + * [] (2*2=4 points) Note: The number of boxes n would not exceed 100. + * + *

Solution O(N ^ 4) For each sub-array [l, r] make a dp cache and calculate maximum of [l, i][1] + * + [i + 1, r][1] or maximum of [l + 1, i - 1][n] + [i, r][1] where boxes[l] == boxes[i] where n is + * the count of repetitions + */ +public class RemoveBoxes { + + int[][][] dp; + + public static void main(String[] args) { + int[] boxes = {3, 3, 3}; + System.out.println(new RemoveBoxes().removeBoxes(boxes)); + } + + public int removeBoxes(int[] boxes) { + dp = new int[boxes.length][boxes.length][boxes.length + 1]; + return calculate(0, boxes.length - 1, 1, boxes); + } + + int calculate(int l, int r, int n, int[] boxes) { + if (l > r) return 0; + else { + if (dp[l][r][n] != 0) return dp[l][r][n]; + dp[l][r][n] = (n * n) + calculate(l + 1, r, 1, boxes); + for (int i = l + 1; i <= r; i++) { + int center = 0, next = 0; + if (boxes[l] == boxes[i]) { + center = calculate(l + 1, i - 1, 1, boxes); + next = calculate(i, r, n + 1, boxes); + } + dp[l][r][n] = Math.max(dp[l][r][n], center + next); + } + } + return dp[l][r][n]; + } +} diff --git a/src/main/java/dynamic_programming/RestoreTheArray.java b/src/main/java/dynamic_programming/RestoreTheArray.java new file mode 100644 index 00000000..abae42d0 --- /dev/null +++ b/src/main/java/dynamic_programming/RestoreTheArray.java @@ -0,0 +1,72 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 28/05/2020 + * + *

A program was supposed to print an array of integers. The program forgot to print whitespaces + * and the array is printed as a string of digits and all we know is that all integers in the array + * were in the range [1, k] and there are no leading zeros in the array. + * + *

Given the string s and the integer k. There can be multiple ways to restore the array. + * + *

Return the number of possible array that can be printed as a string s using the mentioned + * program. + * + *

The number of ways could be very large so return it modulo 10^9 + 7 + * + *

Example 1: + * + *

Input: s = "1000", k = 10000 Output: 1 Explanation: The only possible array is [1000] Example + * 2: + * + *

Input: s = "1000", k = 10 Output: 0 Explanation: There cannot be an array that was printed + * this way and has all integer >= 1 and <= 10. Example 3: + * + *

Input: s = "1317", k = 2000 Output: 8 Explanation: Possible arrays are + * [1317],[131,7],[13,17],[1,317],[13,1,7],[1,31,7],[1,3,17],[1,3,1,7] Example 4: + * + *

Input: s = "2020", k = 30 Output: 1 Explanation: The only possible array is [20,20]. [2020] is + * invalid because 2020 > 30. [2,020] is ivalid because 020 contains leading zeros. Example 5: + * + *

Input: s = "1234567890", k = 90 Output: 34 + * + *

Constraints: + * + *

1 <= s.length <= 10^5. s consists of only digits and doesn't contain leading zeros. 1 <= k <= + * 10^9. + */ +public class RestoreTheArray { + public static void main(String[] args) { + System.out.println(new RestoreTheArray().numberOfArrays("19284738192", 90)); + } + + int[] DP; + int MOD = (int) 1e9 + 7; + + public int numberOfArrays(String s, int k) { + DP = new int[s.length() + 1]; + Arrays.fill(DP, -1); + return dp(0, s, k); + } + + private int dp(int i, String s, int k) { + if (i == s.length()) return 1; + else if (DP[i] != -1) return DP[i]; + else if (s.charAt(i) == '0') return 0; + else { + long sum = 0L; + String num = ""; + for (int j = i; j < (i + 10) && j < s.length(); j++) { + num = num + s.charAt(j); + if (Long.parseLong(num) <= k) { + sum = ((sum + dp(j + 1, s, k)) % MOD); + } + } + DP[i] = (int) sum; + return DP[i]; + } + } +} diff --git a/src/main/java/dynamic_programming/RussianDollEnvelopes.java b/src/main/java/dynamic_programming/RussianDollEnvelopes.java new file mode 100644 index 00000000..2b454d20 --- /dev/null +++ b/src/main/java/dynamic_programming/RussianDollEnvelopes.java @@ -0,0 +1,72 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 05/05/2019 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) + * + *

Note: Rotation is not allowed. + * + *

Example: + * + *

Input: [[5,4],[6,4],[6,7],[2,3]] Output: 3 Explanation: The maximum number of envelopes you + * can Russian doll is 3 ([2,3] => [5,4] => [6,7]). + * + *

Solution: O(N ^ 2) Sort the envelopes based on increasing order of area and for each envelope + * iterate through all the possible envelopes which are smaller than that the current envelope and + * check the maximum possible envelopes which an be russian dolled. + */ +public class RussianDollEnvelopes { + + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[][] A = {{5, 4}, {6, 4}, {6, 7}, {2, 3}}; + System.out.println(new RussianDollEnvelopes().maxEnvelopes(A)); + } + + class Envelope { + int l, b; + + Envelope(int l, int b) { + this.l = l; + this.b = b; + } + } + /** + * @param envelopes + * @return + */ + public int maxEnvelopes(int[][] envelopes) { + if (envelopes.length == 0) return 0; + List list = new ArrayList<>(); + for (int[] row : envelopes) { + list.add(new Envelope(row[0], row[1])); + } + list.sort(((o1, o2) -> Integer.compare(o2.l * o2.b, o1.l * o1.b))); + int[] DP = new int[envelopes.length]; + Arrays.fill(DP, 1); + for (int i = list.size() - 1; i >= 0; i--) { + Envelope env = list.get(i); + for (int j = i + 1, l = list.size(); j < l; j++) { + Envelope childEnv = list.get(j); + if (env.l > childEnv.l && env.b > childEnv.b) { + DP[i] = Math.max(DP[i], DP[j] + 1); + } + } + } + int ans = 1; + for (int i : DP) { + ans = Math.max(ans, i); + } + return ans; + } +} diff --git a/src/main/java/dynamic_programming/ShortestPathVisitingAllNodes.java b/src/main/java/dynamic_programming/ShortestPathVisitingAllNodes.java new file mode 100644 index 00000000..c56069de --- /dev/null +++ b/src/main/java/dynamic_programming/ShortestPathVisitingAllNodes.java @@ -0,0 +1,105 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 16/10/2020 + * + *

An undirected, connected graph of N nodes (labeled 0, 1, 2, ..., N-1) is given as graph. + * + *

graph.length = N, and j != i is in the list graph[i] exactly once, if and only if nodes i and + * j are connected. + * + *

Return the length of the shortest path that visits every node. You may start and stop at any + * node, you may revisit nodes multiple times, and you may reuse edges. + * + *

Example 1: + * + *

Input: [[1,2,3],[0],[0],[0]] Output: 4 Explanation: One possible path is [1,0,2,0,3] Example + * 2: + * + *

Input: [[1],[0,2,4],[1,3,4],[2],[1,2]] Output: 4 Explanation: One possible path is [0,1,4,2,3] + * + *

Note: + * + *

1 <= graph.length <= 12 0 <= graph[i].length < graph.length + */ +public class ShortestPathVisitingAllNodes { + public static void main(String[] args) { + int[][] graph = {{2, 3, 4, 8}, {8}, {0}, {0, 8}, {0, 5, 6}, {4, 7}, {4}, {5}, {0, 3, 1}}; + System.out.println(new ShortestPathVisitingAllNodes().shortestPathLength(graph)); + } + + Stack stack; + Set done; + + class Node { + int v, s; + + Node(int v, int s) { + this.v = v; + this.s = s; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Node)) return false; + Node node = (Node) o; + return v == node.v && s == node.s; + } + + @Override + public int hashCode() { + return Objects.hash(v, s); + } + } + + public int shortestPathLength(int[][] G) { + int dest = (int) Math.pow(2, G.length) - 1; + int[][] DP = new int[G.length][dest + 1]; + done = new HashSet<>(); + stack = new Stack<>(); + for (int i = 0; i < G.length; i++) { + Node n = new Node(i, 1 << i); + if (!done.contains(n)) { + dfs(n, G); + } + } + for (int i = 0; i < G.length; i++) { + Arrays.fill(DP[i], Integer.MAX_VALUE); + } + while (!stack.isEmpty()) { + Node node = stack.pop(); + int[] children = G[node.v]; + int currDist = DP[node.v][node.s] == Integer.MAX_VALUE ? 0 : DP[node.v][node.s]; + for (int c : children) { + if (DP[c][node.s | (1 << c)] < Integer.MAX_VALUE + && ((currDist + 1) < DP[c][node.s | (1 << c)])) { + stack.push(new Node(c, node.s | (1 << c))); + } + DP[c][node.s | (1 << c)] = Math.min(DP[c][node.s | (1 << c)], currDist + 1); + } + } + int min = Integer.MAX_VALUE; + for (int i = 0; i < G.length; i++) { + min = Math.min(min, DP[i][dest]); + } + return min == Integer.MAX_VALUE ? 0 : min; + } + + private void dfs(Node n, int[][] graph) { + done.add(n); + int[] children = graph[n.v]; + if (children != null) { + for (int c : children) { + Node child = new Node(c, (n.s | (1 << c))); + if (!done.contains(child)) { + dfs(child, graph); + } + } + } + stack.push(n); + } +} diff --git a/src/main/java/dynamic_programming/SmallestSufficientTeam.java b/src/main/java/dynamic_programming/SmallestSufficientTeam.java new file mode 100644 index 00000000..c91247c0 --- /dev/null +++ b/src/main/java/dynamic_programming/SmallestSufficientTeam.java @@ -0,0 +1,123 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 04/06/2020 In a project, you have a list of required skills + * req_skills, and a list of people. The i-th person people[i] contains a list of skills that person + * has. + * + *

Consider a sufficient team: a set of people such that for every required skill in req_skills, + * there is at least one person in the team who has that skill. We can represent these teams by the + * index of each person: for example, team = [0, 1, 3] represents the people with skills people[0], + * people[1], and people[3]. + * + *

Return any sufficient team of the smallest possible size, represented by the index of each + * person. + * + *

You may return the answer in any order. It is guaranteed an answer exists. + * + *

Example 1: + * + *

Input: req_skills = ["java","nodejs","reactjs"], people = + * [["java"],["nodejs"],["nodejs","reactjs"]] Output: [0,2] Example 2: + * + *

Input: req_skills = ["algorithms","math","java","reactjs","csharp","aws"], people = + * [["algorithms","math","java"],["algorithms","math","reactjs"],["java","csharp","aws"],["reactjs","csharp"],["csharp","math"],["aws","java"]] + * Output: [1,2] + * + *

Constraints: + * + *

1 <= req_skills.length <= 16 1 <= people.length <= 60 1 <= people[i].length, + * req_skills[i].length, people[i][j].length <= 16 Elements of req_skills and people[i] are + * (respectively) distinct. req_skills[i][j], people[i][j][k] are lowercase English letters. Every + * skill in people[i] is a skill in req_skills. It is guaranteed a sufficient team exists. + */ +public class SmallestSufficientTeam { + + public static void main(String[] args) { + String[] req = {"java", "nodejs", "reactjs"}; + List> people = new ArrayList<>(); + people.add(Arrays.asList("java")); + people.add(Arrays.asList("nodejs")); + people.add(Arrays.asList("nodejs", "reactjs")); + int[] R = new SmallestSufficientTeam().smallestSufficientTeam(req, people); + for (int r : R) { + System.out.print(r + " "); + } + System.out.println(); + } + + private int allSkills; + Map peopleSkillSet; + Map skillMap; + final int MAX_SKILLS = 63; + final int CHOOSE_PEOPLE = 64; + + public int[] smallestSufficientTeam(String[] reqSkills, List> people) { + skillMap = new HashMap<>(); + peopleSkillSet = new HashMap<>(); + int i = 0; + for (String s : reqSkills) { + skillMap.put(s, i++); + } + for (i = 0; i < people.size(); i++) { + for (String s : people.get(i)) { + int skillIndex = skillMap.get(s); + int skills = peopleSkillSet.getOrDefault(i, 0); + skills = (skills | (1 << skillIndex)); + peopleSkillSet.put(i, skills); + } + } + int S = ((int) (Math.pow(2, reqSkills.length)) + 1); + int[][] DP = new int[S][people.size()]; + allSkills = (1 << reqSkills.length) - 1; + for (i = 0; i < DP.length; i++) { + for (int j = 0; j < DP[0].length; j++) { + DP[i][j] = -1; + } + } + int n = dp(0, 0, DP); + n &= MAX_SKILLS; + if (n == Integer.MAX_VALUE) return new int[0]; + List answer = new ArrayList<>(); + i = 0; + for (int j = 0; j < people.size(); j++) { + if (((DP[i][j] & MAX_SKILLS) == n) && (DP[i][j] & CHOOSE_PEOPLE) > 0) { + i |= (peopleSkillSet.getOrDefault(j, 0)); + answer.add(j); + n--; + } + if (n == 0) break; + } + int[] result = new int[answer.size()]; + for (int a = 0; a < result.length; a++) { + result[a] = answer.get(a); + } + return result; + } + + private int dp(int i, int skill, int[][] DP) { + if (i >= DP[0].length) { + if (skill >= allSkills) { + return 0; + } else return Integer.MAX_VALUE; + } + if (skill == allSkills) return 0; + else if (DP[skill][i] != -1) return DP[skill][i]; + else { + int withOut = dp(i + 1, skill, DP); + int with = dp(i + 1, (skill | peopleSkillSet.getOrDefault(i, 0)), DP); + with += with != Integer.MAX_VALUE ? 1 : 0; + if (Math.min(with, withOut) == Integer.MAX_VALUE) { + DP[skill][i] = Integer.MAX_VALUE; + } else + DP[skill][i] = + ((with & MAX_SKILLS) < (withOut & MAX_SKILLS)) + ? ((with & MAX_SKILLS) | CHOOSE_PEOPLE) + : (withOut & MAX_SKILLS); + return DP[skill][i]; + } + } +} diff --git a/problems/src/dynamic_programming/SplitArrayLargestSum.java b/src/main/java/dynamic_programming/SplitArrayLargestSum.java similarity index 98% rename from problems/src/dynamic_programming/SplitArrayLargestSum.java rename to src/main/java/dynamic_programming/SplitArrayLargestSum.java index 7112af7e..4e33b849 100644 --- a/problems/src/dynamic_programming/SplitArrayLargestSum.java +++ b/src/main/java/dynamic_programming/SplitArrayLargestSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/src/main/java/dynamic_programming/StickersToSpellWord.java b/src/main/java/dynamic_programming/StickersToSpellWord.java new file mode 100644 index 00000000..994dc62e --- /dev/null +++ b/src/main/java/dynamic_programming/StickersToSpellWord.java @@ -0,0 +1,106 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 14/07/2019 We are given N different types of stickers. Each + * sticker has a lowercase English word on it. + * + *

You would like to spell out the given target string by cutting individual letters from your + * collection of stickers and rearranging them. + * + *

You can use each sticker more than once if you want, and you have infinite quantities of each + * sticker. + * + *

What is the minimum number of stickers that you need to spell out the target? If the task is + * impossible, return -1. + * + *

Example 1: + * + *

Input: + * + *

["with", "example", "science"], "thehat" Output: + * + *

3 Explanation: + * + *

We can use 2 "with" stickers, and 1 "example" sticker. After cutting and rearrange the letters + * of those stickers, we can form the target "thehat". Also, this is the minimum number of stickers + * necessary to form the target string. Example 2: + * + *

Input: + * + *

["notice", "possible"], "basicbasic" Output: + * + *

-1 Explanation: + * + *

We can't form the target "basicbasic" from cutting letters from the given stickers. Note: + * + *

stickers has length in the range [1, 50]. stickers consists of lowercase English words + * (without apostrophes). target has length in the range [1, 15], and consists of lowercase English + * letters. In all test cases, all words were chosen randomly from the 1000 most common US English + * words, and the target was chosen as a concatenation of two random words. The time limit may be + * more challenging than usual. It is expected that a 50 sticker test case can be solved within 35ms + * on average. + * + *

Solution: O(2 ^ T x T x S) where T is the length of target and S is length of sticker array. + * Each state is a combination of characters selected in the target sticker plus the total count of + * stickers used. Cache the minimum count in each state and explore all the different possible + * states. + */ +public class StickersToSpellWord { + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + String[] stickers = {"bright", "neighbor", "capital"}; + + System.out.println(new StickersToSpellWord().minStickers(stickers, "originalchair")); + } + + private int destination = 0; + private int min = Integer.MAX_VALUE; + private int[][] DP; + + public int minStickers(String[] stickers, String target) { + for (int i = 0; i < target.length(); i++) { + destination |= (1 << i); + } + DP = new int[destination][target.length() + 1]; + int answer = dp(stickers, target, 0, 0); + return answer == Integer.MAX_VALUE ? -1 : answer; + } + + private int dp(String[] stickers, String target, int curr, int count) { + if (curr == destination) { + return count; + } else { + if (count > min) return Integer.MAX_VALUE; + if (DP[curr][count] != 0) return DP[curr][count]; + DP[curr][count] = Integer.MAX_VALUE; + for (String s : stickers) { + int temp = 0; + char[] arr = s.toCharArray(); + for (int i = 0, l = target.length(); i < l; i++) { + if ((curr & (1 << i)) == 0) { + char targetChar = target.charAt(i); + for (int j = 0; j < arr.length; j++) { + if (arr[j] == targetChar) { + arr[j] = '0'; + temp |= (1 << i); + break; + } + } + } + } + if (temp > 0) { + int child = (curr | temp); + int retValue = dp(stickers, target, child, count + 1); + DP[curr][count] = Math.min(DP[curr][count], retValue); + min = Math.min(min, DP[curr][count]); + } + } + return DP[curr][count]; + } + } +} diff --git a/problems/src/dynamic_programming/StoneGame.java b/src/main/java/dynamic_programming/StoneGame.java similarity index 99% rename from problems/src/dynamic_programming/StoneGame.java rename to src/main/java/dynamic_programming/StoneGame.java index 514165ed..b3869d5c 100644 --- a/problems/src/dynamic_programming/StoneGame.java +++ b/src/main/java/dynamic_programming/StoneGame.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/StoneGameIII.java b/src/main/java/dynamic_programming/StoneGameIII.java new file mode 100644 index 00000000..8b4ba08d --- /dev/null +++ b/src/main/java/dynamic_programming/StoneGameIII.java @@ -0,0 +1,98 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 16/04/2020 Alice and Bob continue their games with piles of + * stones. There are several stones arranged in a row, and each stone has an associated value which + * is an integer given in the array stoneValue. + * + *

Alice and Bob take turns, with Alice starting first. On each player's turn, that player can + * take 1, 2 or 3 stones from the first remaining stones in the row. + * + *

The score of each player is the sum of values of the stones taken. The score of each player is + * 0 initially. + * + *

The objective of the game is to end with the highest score, and the winner is the player with + * the highest score and there could be a tie. The game continues until all the stones have been + * taken. + * + *

Assume Alice and Bob play optimally. + * + *

Return "Alice" if Alice will win, "Bob" if Bob will win or "Tie" if they end the game with the + * same score. + * + *

Example 1: + * + *

Input: values = [1,2,3,7] Output: "Bob" Explanation: Alice will always lose. Her best move + * will be to take three piles and the score become 6. Now the score of Bob is 7 and Bob wins. + * Example 2: + * + *

Input: values = [1,2,3,-9] Output: "Alice" Explanation: Alice must choose all the three piles + * at the first move to win and leave Bob with negative score. If Alice chooses one pile her score + * will be 1 and the next move Bob's score becomes 5. The next move Alice will take the pile with + * value = -9 and lose. If Alice chooses two piles her score will be 3 and the next move Bob's score + * becomes 3. The next move Alice will take the pile with value = -9 and also lose. Remember that + * both play optimally so here Alice will choose the scenario that makes her win. Example 3: + * + *

Input: values = [1,2,3,6] Output: "Tie" Explanation: Alice cannot win this game. She can end + * the game in a draw if she decided to choose all the first three piles, otherwise she will lose. + * Example 4: + * + *

Input: values = [1,2,3,-1,-2,-3,7] Output: "Alice" Example 5: + * + *

Input: values = [-1,-2,-3] Output: "Tie" + * + *

Constraints: + * + *

1 <= values.length <= 50000 -1000 <= values[i] <= 1000 + */ +public class StoneGameIII { + private class State { + int a, b; + + State(int a, int b) { + this.a = a; + this.b = b; + } + } + + public static void main(String[] args) { + int[] V = {-1, -2, -3}; + System.out.println(new StoneGameIII().stoneGameIII(V)); + } + + private State[][] DP; + + public String stoneGameIII(int[] stoneValue) { + DP = new State[2][stoneValue.length]; + State result = dp(0, 0, stoneValue); + return (result.a > result.b) ? "Alice" : (result.b > result.a) ? "Bob" : "Tie"; + } + + private State dp(int i, int p, int[] stoneValue) { + if (i >= stoneValue.length) return new State(0, 0); + else if (DP[p][i] != null) return DP[p][i]; + else { + int sum = 0; + for (int j = 0; j < 3; j++) { + if (i + j >= stoneValue.length) break; + sum += (stoneValue[i + j]); + State result = dp(i + j + 1, (p + 1) % 2, stoneValue); + if (p == 0) { + if (DP[p][i] == null) { + DP[p][i] = new State((sum + result.a), result.b); + } else if (DP[p][i].a < (sum + result.a)) { + DP[p][i] = new State((sum + result.a), result.b); + } + } else { + if (DP[p][i] == null) { + DP[p][i] = new State(result.a, (sum + result.b)); + } else if (DP[p][i].b < (sum + result.b)) { + DP[p][i] = new State(result.a, (sum + result.b)); + } + } + } + return DP[p][i]; + } + } +} diff --git a/src/main/java/dynamic_programming/StoneGameIV.java b/src/main/java/dynamic_programming/StoneGameIV.java new file mode 100644 index 00000000..70060906 --- /dev/null +++ b/src/main/java/dynamic_programming/StoneGameIV.java @@ -0,0 +1,89 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 03/12/2020 Alice and Bob take turns playing a game, with Alice + * starting first. + * + *

Initially, there are n stones in a pile. On each player's turn, that player makes a move + * consisting of removing any non-zero square number of stones in the pile. + * + *

Also, if a player cannot make a move, he/she loses the game. + * + *

Given a positive integer n. Return True if and only if Alice wins the game otherwise return + * False, assuming both players play optimally. + * + *

Example 1: + * + *

Input: n = 1 Output: true Explanation: Alice can remove 1 stone winning the game because Bob + * doesn't have any moves. Example 2: + * + *

Input: n = 2 Output: false Explanation: Alice can only remove 1 stone, after that Bob removes + * the last one winning the game (2 -> 1 -> 0). Example 3: + * + *

Input: n = 4 Output: true Explanation: n is already a perfect square, Alice can win with one + * move, removing 4 stones (4 -> 0). Example 4: + * + *

Input: n = 7 Output: false Explanation: Alice can't win the game if Bob plays optimally. If + * Alice starts removing 4 stones, Bob will remove 1 stone then Alice should remove only 1 stone and + * finally Bob removes the last one (7 -> 3 -> 2 -> 1 -> 0). If Alice starts removing 1 stone, Bob + * will remove 4 stones then Alice only can remove 1 stone and finally Bob removes the last one (7 + * -> 6 -> 2 -> 1 -> 0). Example 5: + * + *

Input: n = 17 Output: false Explanation: Alice can't win the game if Bob plays optimally. + * + *

Constraints: + * + *

1 <= n <= 10^5 + */ +public class StoneGameIV { + public static void main(String[] args) { + System.out.println(new StoneGameIV().winnerSquareGame(1000)); + } + + public boolean winnerSquareGame(int n) { + Set perfectSquare = new HashSet<>(); + perfectSquare.add(1); + for (int i = 2; (long) (i * i) <= n; i++) { + genSquare(i * i, n, perfectSquare); + } + int[] pq = new int[perfectSquare.size()]; + int i = 0; + for (int s : perfectSquare) { + pq[i++] = s; + } + Arrays.sort(pq); + int[] DP = new int[n + 1]; + int status = dp(n, 0, pq, DP); + return status != 1; + } + + private int dp(int n, int p, int[] perfectSquares, int[] DP) { + if (n == 0) return 1; + else if (DP[n] != 0) return DP[n]; + else { + int result = 1; + for (int sq : perfectSquares) { + if (n < sq) break; + int r = dp(n - sq, ((p + 1) % 2), perfectSquares, DP); + if (r == 1) { + result = 2; + break; + } + } + DP[n] = result; + return result; + } + } + + private void genSquare(int sq, int limit, Set perfectSquare) { + if (!perfectSquare.contains(sq)) { + perfectSquare.add(sq); + if (((long) sq * sq) <= limit) { + genSquare(sq * sq, limit, perfectSquare); + } + } + } +} diff --git a/src/main/java/dynamic_programming/StrangePrinter.java b/src/main/java/dynamic_programming/StrangePrinter.java new file mode 100644 index 00000000..9db36a72 --- /dev/null +++ b/src/main/java/dynamic_programming/StrangePrinter.java @@ -0,0 +1,46 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 11/02/2020 There is a strange printer with the following two + * special requirements: + * + *

The printer can only print a sequence of the same character each time. At each turn, the + * printer can print new characters starting from and ending at any places, and will cover the + * original existing characters. Given a string consists of lower English letters only, your job is + * to count the minimum number of turns the printer needed in order to print it. + * + *

Example 1: Input: "aaabbb" Output: 2 Explanation: Print "aaa" first and then print "bbb". + * Example 2: Input: "aba" Output: 2 Explanation: Print "aaa" first and then print "b" from the + * second place of the string, which will cover the existing character 'a'. Hint: Length of the + * given string will not exceed 100. + */ +public class StrangePrinter { + public static void main(String[] args) { + String A = "aaaaaaa"; + System.out.println(new StrangePrinter().strangePrinter(A)); + } + + int DP[][]; + + public int strangePrinter(String s) { + DP = new int[s.length() + 1][s.length() + 1]; + return calculate(0, s.length() - 1, s); + } + + private int calculate(int i, int j, String s) { + if (i > j) return 0; + else if (DP[i][j] != 0) return DP[i][j]; + else { + DP[i][j] = calculate(i, j - 1, s) + 1; + int min = DP[i][j]; + for (int m = i; m < j; m++) { + if (s.charAt(m) == s.charAt(j)) { + min = Math.min(min, calculate(i, m, s) + calculate(m + 1, j - 1, s)); + } + } + DP[i][j] = min; + return DP[i][j]; + } + } +} diff --git a/src/main/java/dynamic_programming/TallestBillboard.java b/src/main/java/dynamic_programming/TallestBillboard.java new file mode 100644 index 00000000..fcd356c9 --- /dev/null +++ b/src/main/java/dynamic_programming/TallestBillboard.java @@ -0,0 +1,92 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 19/05/2020 + * + *

You are installing a billboard and want it to have the largest height. The billboard will have + * two steel supports, one on each side. Each steel support must be an equal height. + * + *

You are given a collection of rods that can be welded together. For example, if you have rods + * of lengths 1, 2, and 3, you can weld them together to make a support of length 6. + * + *

Return the largest possible height of your billboard installation. If you cannot support the + * billboard, return 0. + * + *

Example 1: + * + *

Input: rods = [1,2,3,6] Output: 6 Explanation: We have two disjoint subsets {1,2,3} and {6}, + * which have the same sum = 6. Example 2: + * + *

Input: rods = [1,2,3,4,5,6] Output: 10 Explanation: We have two disjoint subsets {2,3,5} and + * {4,6}, which have the same sum = 10. Example 3: + * + *

Input: rods = [1,2] Output: 0 Explanation: The billboard cannot be supported, so we return 0. + * + *

Constraints: + * + *

1 <= rods.length <= 20 1 <= rods[i] <= 1000 sum(rods[i]) <= 5000 + */ +public class TallestBillboard { + + public static void main(String[] args) { + int[] A = {1, 2, 3, 4, 5, 6}; + System.out.println(new TallestBillboard().tallestBillboard(A)); + } + + public int tallestBillboard(int[] rods) { + if (rods.length == 0) return 0; + Map leftMap = partition(rods, 0, rods.length / 2); + Map rightMap = partition(rods, (rods.length / 2) + 1, rods.length - 1); + int max = 0; + for (int d : leftMap.keySet()) { + if (rightMap.containsKey(d)) { + int m1 = leftMap.get(d); + int m2 = rightMap.get(d); + max = Math.max(max, m1 + (m2 - d)); + max = Math.max(max, m2 + (m1 - d)); + } + } + return max; + } + + private Map partition(int[] rods, int i, int j) { + if (i > j) { + Map map = new HashMap<>(); + map.put(0, 0); + return map; + } else if (i == j) { + Map map = new HashMap<>(); + map.put(rods[i], rods[i]); + map.put(0, 0); + return map; + } else { + int m = (i + (j - i) / 2); + Map left = partition(rods, i, m); + Map right = partition(rods, m + 1, j); + Map newMap = new HashMap<>(); + for (int lDiff : left.keySet()) { + int lMax = left.get(lDiff); + for (int rDiff : right.keySet()) { + int rMax = right.get(rDiff); + int r1, r2, r3, r4; + r1 = lMax; + r2 = lMax - lDiff; + r3 = rMax; + r4 = rMax - rDiff; + update(newMap, Math.abs(((r1 + r3) - (r2 + r4))), r1 + r3, r2 + r4); + update(newMap, Math.abs(((r1 + r4) - (r2 + r3))), r1 + r4, r2 + r3); + } + } + return newMap; + } + } + + private void update(Map map, int diff, int rod1, int rod2) { + if (map.getOrDefault(diff, 0) < Math.max(rod1, rod2)) { + map.put(diff, Math.max(rod1, rod2)); + } + } +} diff --git a/src/main/java/dynamic_programming/TilingARectangle.java b/src/main/java/dynamic_programming/TilingARectangle.java new file mode 100644 index 00000000..9fbf1aa7 --- /dev/null +++ b/src/main/java/dynamic_programming/TilingARectangle.java @@ -0,0 +1,101 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 18/04/2020 + * + *

Given a rectangle of size n x m, find the minimum number of integer-sided squares that tile + * the rectangle. + * + *

Example 1: + * + *

Input: n = 2, m = 3 Output: 3 Explanation: 3 squares are necessary to cover the rectangle. 2 + * (squares of 1x1) 1 (square of 2x2) Example 2: + * + *

Input: n = 5, m = 8 Output: 5 Example 3: + * + *

Input: n = 11, m = 13 Output: 6 + * + *

Constraints: + * + *

1 <= n <= 13 1 <= m <= 13 + */ +public class TilingARectangle { + + public static void main(String[] args) { + System.out.println(new TilingARectangle().tilingRectangle(11, 13)); + } + + Map DP; + + public int tilingRectangle(int n, int m) { + DP = new HashMap<>(); + boolean[][] state = new boolean[n][m]; + return dp(state, 0, n, m); + } + + private int dp(boolean[][] state, int r, int n, int m) { + if (r >= n) return 0; + int[] A = new int[m]; + for (int i = r; i < n; i++) { + for (int j = 0; j < m; j++) { + if (state[i][j]) { + A[j]++; + } + } + } + long hashCode = 1; + for (int i = 0; i < A.length; i++) { + A[i] += r; + hashCode = (hashCode * 31) + A[i]; + } + if (DP.containsKey(hashCode)) return DP.get(hashCode); + else { + int min = Integer.MAX_VALUE; + int c = m; + for (int j = 0; j < m; j++) { + if (!state[r][j]) { + c = j; + break; + } + } + int k = 1; + for (; k <= Math.min(n, m); k++) { + if (r + k > n || c + k > m) break; + else if (state[r][c + k - 1] || state[r + k - 1][c]) break; + for (int a = r; a < (r + k); a++) { + for (int b = c; b < (c + k); b++) { + state[a][b] = true; + A[b]++; + } + } + int next = n; + int j = c + k; + for (int i = r; i < n; i++) { + for (; j < m; j++) { + if (!state[i][j]) { + next = i; + break; + } + } + if (next != n) break; + j = 0; + } + int result = dp(state, next, n, m); + if (result > -1) { + min = Math.min(min, result + 1); + } + } + k--; + for (int a = r; a < (r + k); a++) { + for (int b = c; b < (c + k); b++) { + state[a][b] = false; + } + } + DP.put(hashCode, min == Integer.MAX_VALUE ? -1 : min); + return DP.get(hashCode); + } + } +} diff --git a/src/main/java/dynamic_programming/TossStrangeCoins.java b/src/main/java/dynamic_programming/TossStrangeCoins.java new file mode 100644 index 00000000..c36fba82 --- /dev/null +++ b/src/main/java/dynamic_programming/TossStrangeCoins.java @@ -0,0 +1,35 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +/** + * Created by gouthamvidyapradhan on 19/11/2019 You have some coins. The i-th coin has a probability + * prob[i] of facing heads when tossed. + * + *

Return the probability that the number of coins facing heads equals target if you toss every + * coin exactly once. + * + *

Example 1: + * + *

Input: prob = [0.4], target = 1 Output: 0.40000 Example 2: + * + *

Input: prob = [0.5,0.5,0.5,0.5,0.5], target = 0 Output: 0.03125 + */ +public class TossStrangeCoins { + public static void main(String[] args) { + double[] A = {0.4, 0.4}; + System.out.println(new TossStrangeCoins().probabilityOfHeads(A, 1)); + } + + public double probabilityOfHeads(double[] prob, int target) { + double[][] DP = new double[target + 1][prob.length]; + DP[0][0] = 1 - prob[0]; + DP[1][0] = prob[0]; + for (int c = 1; c < prob.length; c++) { + for (int t = 0; t <= target; t++) { + if (t == 0) DP[t][c] = DP[t][c - 1] * (1 - prob[c]); + else DP[t][c] = DP[t][c - 1] * (1 - prob[c]) + DP[t - 1][c - 1] * (prob[c]); + } + } + return DP[target][prob.length - 1]; + } +} diff --git a/problems/src/dynamic_programming/TwoKeysKeyboard.java b/src/main/java/dynamic_programming/TwoKeysKeyboard.java similarity index 97% rename from problems/src/dynamic_programming/TwoKeysKeyboard.java rename to src/main/java/dynamic_programming/TwoKeysKeyboard.java index f51a223e..fe790f4c 100644 --- a/problems/src/dynamic_programming/TwoKeysKeyboard.java +++ b/src/main/java/dynamic_programming/TwoKeysKeyboard.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/problems/src/dynamic_programming/UniqueBinarySearchTrees.java b/src/main/java/dynamic_programming/UniqueBinarySearchTrees.java similarity index 96% rename from problems/src/dynamic_programming/UniqueBinarySearchTrees.java rename to src/main/java/dynamic_programming/UniqueBinarySearchTrees.java index 1297b3f8..d2080f20 100644 --- a/problems/src/dynamic_programming/UniqueBinarySearchTrees.java +++ b/src/main/java/dynamic_programming/UniqueBinarySearchTrees.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; /** diff --git a/problems/src/dynamic_programming/UniqueBinarySearchTreesII.java b/src/main/java/dynamic_programming/UniqueBinarySearchTreesII.java similarity index 98% rename from problems/src/dynamic_programming/UniqueBinarySearchTreesII.java rename to src/main/java/dynamic_programming/UniqueBinarySearchTreesII.java index ec3e00b9..1036c7ca 100644 --- a/problems/src/dynamic_programming/UniqueBinarySearchTreesII.java +++ b/src/main/java/dynamic_programming/UniqueBinarySearchTreesII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/dynamic_programming/ValidPalindromeIII.java b/src/main/java/dynamic_programming/ValidPalindromeIII.java new file mode 100644 index 00000000..e3be5fad --- /dev/null +++ b/src/main/java/dynamic_programming/ValidPalindromeIII.java @@ -0,0 +1,51 @@ +/* (C) 2024 YourCompanyName */ +package dynamic_programming; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 23/04/2020 Given a string s and an integer k, find out if the + * given string is a K-Palindrome or not. + * + *

A string is K-Palindrome if it can be transformed into a palindrome by removing at most k + * characters from it. + * + *

Example 1: + * + *

Input: s = "abcdeca", k = 2 Output: true Explanation: Remove 'b' and 'e' characters. + * + *

Constraints: + * + *

1 <= s.length <= 1000 s has only lowercase English letters. 1 <= k <= s.length + */ +public class ValidPalindromeIII { + public static void main(String[] args) { + System.out.println(new ValidPalindromeIII().isValidPalindrome("abc", 0)); + } + + int[][] DP; + + public boolean isValidPalindrome(String s, int k) { + DP = new int[s.length()][s.length()]; + for (int i = 0; i < s.length(); i++) { + Arrays.fill(DP[i], -1); + } + return dp(0, s.length() - 1, s) <= k; + } + + private int dp(int i, int j, String S) { + if (i == j) return 0; + else if (i > j) return 0; + else if (DP[i][j] != -1) return DP[i][j]; + else { + int min = Integer.MAX_VALUE; + if (S.charAt(i) != S.charAt(j)) { + min = Math.min(min, Math.min(dp(i + 1, j, S), dp(i, j - 1, S)) + 1); + } else { + min = dp(i + 1, j - 1, S); + } + DP[i][j] = min; + return min; + } + } +} diff --git a/problems/src/dynamic_programming/WordBreak.java b/src/main/java/dynamic_programming/WordBreak.java similarity index 98% rename from problems/src/dynamic_programming/WordBreak.java rename to src/main/java/dynamic_programming/WordBreak.java index 6a4ed7a4..7b54b113 100644 --- a/problems/src/dynamic_programming/WordBreak.java +++ b/src/main/java/dynamic_programming/WordBreak.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/problems/src/dynamic_programming/WordBreakII.java b/src/main/java/dynamic_programming/WordBreakII.java similarity index 98% rename from problems/src/dynamic_programming/WordBreakII.java rename to src/main/java/dynamic_programming/WordBreakII.java index 9739e6be..b4e7a682 100644 --- a/problems/src/dynamic_programming/WordBreakII.java +++ b/src/main/java/dynamic_programming/WordBreakII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package dynamic_programming; import java.util.*; diff --git a/src/main/java/greedy/BoatsToSavePeople.java b/src/main/java/greedy/BoatsToSavePeople.java new file mode 100644 index 00000000..73736e0c --- /dev/null +++ b/src/main/java/greedy/BoatsToSavePeople.java @@ -0,0 +1,66 @@ +/* (C) 2024 YourCompanyName */ +package greedy; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 09/05/2019 The i-th person has weight people[i], and each boat + * can carry a maximum weight of limit. + * + *

Each boat carries at most 2 people at the same time, provided the sum of the weight of those + * people is at most limit. + * + *

Return the minimum number of boats to carry every given person. (It is guaranteed each person + * can be carried by a boat.) + * + *

Example 1: + * + *

Input: people = [1,2], limit = 3 Output: 1 Explanation: 1 boat (1, 2) Example 2: + * + *

Input: people = [3,2,2,1], limit = 3 Output: 3 Explanation: 3 boats (1, 2), (2) and (3) + * Example 3: + * + *

Input: people = [3,5,3,4], limit = 5 Output: 4 Explanation: 4 boats (3), (3), (4), (5) Note: + * + *

1 <= people.length <= 50000 1 <= people[i] <= limit <= 30000 + * + *

Solution O N log N Simple strategy is to greedy try to put in maximum possible people in a + * boat and increment the boat counter. Use TreeMap and sorting to achieve this easily + */ +public class BoatsToSavePeople { + public static void main(String[] args) { + int[] A = {3, 5, 3, 4}; + System.out.println(new BoatsToSavePeople().numRescueBoats(A, 8)); + } + + public int numRescueBoats(int[] people, int limit) { + TreeMap treeMap = new TreeMap<>(); + int boats = 0; + for (int p : people) { + treeMap.putIfAbsent(p, 0); + treeMap.put(p, treeMap.get(p) + 1); + } + Arrays.sort(people); + for (int p : people) { + if (treeMap.containsKey(p)) { + int count = treeMap.remove(p); + --count; + if (count != 0) { + treeMap.put(p, count); + } + int balance = limit - p; + Map.Entry floor = treeMap.floorEntry(balance); + if (floor != null) { + int c = floor.getValue(); + --c; + treeMap.remove(floor.getKey()); + if (c != 0) { + treeMap.put(floor.getKey(), c); + } + } + boats++; + } + } + return boats; + } +} diff --git a/src/main/java/greedy/BrokenCalculator.java b/src/main/java/greedy/BrokenCalculator.java new file mode 100644 index 00000000..24f1c25e --- /dev/null +++ b/src/main/java/greedy/BrokenCalculator.java @@ -0,0 +1,61 @@ +/* (C) 2024 YourCompanyName */ +package greedy; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 25/07/2019 On a broken calculator that has a number showing on + * its display, we can perform two operations: + * + *

Double: Multiply the number on the display by 2, or; Decrement: Subtract 1 from the number on + * the display. Initially, the calculator is displaying the number X. + * + *

Return the minimum number of operations needed to display the number Y. + * + *

Example 1: + * + *

Input: X = 2, Y = 3 Output: 2 Explanation: Use double operation and then decrement operation + * {2 -> 4 -> 3}. Example 2: + * + *

Input: X = 5, Y = 8 Output: 2 Explanation: Use decrement and then double {5 -> 4 -> 8}. + * Example 3: + * + *

Input: X = 3, Y = 10 Output: 3 Explanation: Use double, decrement and double {3 -> 6 -> 5 -> + * 10}. Example 4: + * + *

Input: X = 1024, Y = 1 Output: 1023 Explanation: Use decrement operations 1023 times. + * + *

Note: + * + *

1 <= X <= 10^9 1 <= Y <= 10^9 + * + *

Solution: O(log Y) Arrive at the solution by working backwards starting from Y. General idea + * is as follows. If Y is even then find the minimum steps required to arrive at Y by finding the + * quotient after dividing by 2. If Y is odd then find the minimum steps required to arrive at Y + 1 + * (even number) + 1 (to move backwards) + */ +public class BrokenCalculator { + public static void main(String[] args) { + // + } + + public int brokenCalc(int X, int Y) { + if (X == Y) return 0; + else if (Y < X) return X - Y; + else { + int count = 0; + while (Y > X) { + if (Y % 2 == 0) { + Y /= 2; + count++; + } else { + Y += 1; + Y /= 2; + count += 2; + } + } + if (X == Y) return count; + else return count + (X - Y); + } + } +} diff --git a/problems/src/greedy/BurstBalloons.java b/src/main/java/greedy/BurstBalloons.java similarity index 98% rename from problems/src/greedy/BurstBalloons.java rename to src/main/java/greedy/BurstBalloons.java index 0ebca988..b0795e09 100644 --- a/problems/src/greedy/BurstBalloons.java +++ b/src/main/java/greedy/BurstBalloons.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; import java.util.Arrays; diff --git a/problems/src/greedy/CourseScheduleIII.java b/src/main/java/greedy/CourseScheduleIII.java similarity index 98% rename from problems/src/greedy/CourseScheduleIII.java rename to src/main/java/greedy/CourseScheduleIII.java index e7afb7e8..0ce37550 100644 --- a/problems/src/greedy/CourseScheduleIII.java +++ b/src/main/java/greedy/CourseScheduleIII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; import java.util.Arrays; diff --git a/problems/src/greedy/GasStation.java b/src/main/java/greedy/GasStation.java similarity index 97% rename from problems/src/greedy/GasStation.java rename to src/main/java/greedy/GasStation.java index 7b0da2c2..62a2d396 100644 --- a/problems/src/greedy/GasStation.java +++ b/src/main/java/greedy/GasStation.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; /** diff --git a/problems/src/greedy/IPO.java b/src/main/java/greedy/IPO.java similarity index 99% rename from problems/src/greedy/IPO.java rename to src/main/java/greedy/IPO.java index 6b5dd2cf..049cbf93 100644 --- a/problems/src/greedy/IPO.java +++ b/src/main/java/greedy/IPO.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; /** * Created by gouthamvidyapradhan on 09/04/2019 Suppose LeetCode will start its IPO soon. In order diff --git a/problems/src/greedy/JumpGame.java b/src/main/java/greedy/JumpGame.java similarity index 96% rename from problems/src/greedy/JumpGame.java rename to src/main/java/greedy/JumpGame.java index 8ad08d96..dcb916e4 100644 --- a/problems/src/greedy/JumpGame.java +++ b/src/main/java/greedy/JumpGame.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; /** diff --git a/problems/src/greedy/JumpGameII.java b/src/main/java/greedy/JumpGameII.java similarity index 97% rename from problems/src/greedy/JumpGameII.java rename to src/main/java/greedy/JumpGameII.java index 9969fc40..5ffd6dd1 100644 --- a/problems/src/greedy/JumpGameII.java +++ b/src/main/java/greedy/JumpGameII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; /** diff --git a/problems/src/greedy/LemonadeChange.java b/src/main/java/greedy/LemonadeChange.java similarity index 98% rename from problems/src/greedy/LemonadeChange.java rename to src/main/java/greedy/LemonadeChange.java index f0aaf52d..43d4fa2c 100644 --- a/problems/src/greedy/LemonadeChange.java +++ b/src/main/java/greedy/LemonadeChange.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; /** diff --git a/problems/src/greedy/MaximumLengthOfPairChain.java b/src/main/java/greedy/MaximumLengthOfPairChain.java similarity index 98% rename from problems/src/greedy/MaximumLengthOfPairChain.java rename to src/main/java/greedy/MaximumLengthOfPairChain.java index ee8eb86c..8e363bcd 100644 --- a/problems/src/greedy/MaximumLengthOfPairChain.java +++ b/src/main/java/greedy/MaximumLengthOfPairChain.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; import java.util.Arrays; diff --git a/src/main/java/greedy/MinimumTimeToBuildBlocks.java b/src/main/java/greedy/MinimumTimeToBuildBlocks.java new file mode 100644 index 00000000..68a9f445 --- /dev/null +++ b/src/main/java/greedy/MinimumTimeToBuildBlocks.java @@ -0,0 +1,53 @@ +/* (C) 2024 YourCompanyName */ +package greedy; + +import java.util.PriorityQueue; + +/** + * Created by gouthamvidyapradhan on 05/05/2020 You are given a list of blocks, where blocks[i] = t + * means that the i-th block needs t units of time to be built. A block can only be built by exactly + * one worker. + * + *

A worker can either split into two workers (number of workers increases by one) or build a + * block then go home. Both decisions cost some time. + * + *

The time cost of spliting one worker into two workers is given as an integer split. Note that + * if two workers split at the same time, they split in parallel so the cost would be split. + * + *

Output the minimum time needed to build all blocks. + * + *

Initially, there is only one worker. + * + *

Example 1: + * + *

Input: blocks = [1], split = 1 Output: 1 Explanation: We use 1 worker to build 1 block in 1 + * time unit. Example 2: + * + *

Input: blocks = [1,2], split = 5 Output: 7 Explanation: We split the worker into 2 workers in + * 5 time units then assign each of them to a block so the cost is 5 + max(1, 2) = 7. Example 3: + * + *

Input: blocks = [1,2,3], split = 1 Output: 4 Explanation: Split 1 worker into 2, then assign + * the first worker to the last block and split the second worker into 2. Then, use the two + * unassigned workers to build the first two blocks. The cost is 1 + max(3, 1 + max(1, 2)) = 4. + * + *

Constraints: + * + *

1 <= blocks.length <= 1000 1 <= blocks[i] <= 10^5 1 <= split <= 100 + */ +public class MinimumTimeToBuildBlocks { + public static void main(String[] args) { + int[] A = {1, 2, 3}; + System.out.println(new MinimumTimeToBuildBlocks().minBuildTime(A, 2)); + } + + public int minBuildTime(int[] blocks, int split) { + PriorityQueue queue = new PriorityQueue<>(); + for (int b : blocks) queue.offer(b); + while (queue.size() != 1) { + int a = queue.poll(); + int b = queue.poll(); + queue.offer(Math.max(a, b) + split); + } + return queue.poll(); + } +} diff --git a/problems/src/greedy/NonOverlappingIntervals.java b/src/main/java/greedy/NonOverlappingIntervals.java similarity index 98% rename from problems/src/greedy/NonOverlappingIntervals.java rename to src/main/java/greedy/NonOverlappingIntervals.java index c9d9cffc..93bec062 100644 --- a/problems/src/greedy/NonOverlappingIntervals.java +++ b/src/main/java/greedy/NonOverlappingIntervals.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; import java.util.Arrays; diff --git a/src/main/java/greedy/PartitionLabels.java b/src/main/java/greedy/PartitionLabels.java new file mode 100644 index 00000000..f33c929b --- /dev/null +++ b/src/main/java/greedy/PartitionLabels.java @@ -0,0 +1,44 @@ +/* (C) 2024 YourCompanyName */ +package greedy; + +import java.util.*; + +/** Created by gouthamvidyapradhan on 30/11/2019 */ +public class PartitionLabels { + public static void main(String[] args) { + System.out.println(new PartitionLabels().partitionLabels("ababcbacadefegdehijhklij")); + } + + public List partitionLabels(String S) { + Map map = new HashMap<>(); + for (int i = 0; i < S.length(); i++) { + char c = S.charAt(i); + map.putIfAbsent(c, i); + map.remove(c); + map.put(c, i); + } + char start = S.charAt(0); + int currMax = map.get(start); + int startIndex = 0; + List list = new ArrayList<>(); + while (true) { + int i = startIndex; + for (; i <= currMax; i++) { + char c = S.charAt(i); + int pos = map.get(c); + currMax = Math.max(currMax, pos); + } + if (i > currMax && i < S.length()) { + list.add(i - startIndex); + startIndex = i; + currMax = map.get(S.charAt(i)); + } else { + if (i == S.length()) { + list.add(i - startIndex); + break; + } + } + } + return list; + } +} diff --git a/problems/src/greedy/QueueReconstructionByHeight.java b/src/main/java/greedy/QueueReconstructionByHeight.java similarity index 97% rename from problems/src/greedy/QueueReconstructionByHeight.java rename to src/main/java/greedy/QueueReconstructionByHeight.java index 2ae1f5a7..2e04f6dc 100644 --- a/problems/src/greedy/QueueReconstructionByHeight.java +++ b/src/main/java/greedy/QueueReconstructionByHeight.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; import java.util.Arrays; diff --git a/src/main/java/greedy/ReducingDishes.java b/src/main/java/greedy/ReducingDishes.java new file mode 100644 index 00000000..f21b0729 --- /dev/null +++ b/src/main/java/greedy/ReducingDishes.java @@ -0,0 +1,55 @@ +/* (C) 2024 YourCompanyName */ +package greedy; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 16/06/2020 A chef has collected data on the satisfaction level + * of his n dishes. Chef can cook any dish in 1 unit of time. + * + *

Like-time coefficient of a dish is defined as the time taken to cook that dish including + * previous dishes multiplied by its satisfaction level i.e. time[i]*satisfaction[i] + * + *

Return the maximum sum of Like-time coefficient that the chef can obtain after dishes + * preparation. + * + *

Dishes can be prepared in any order and the chef can discard some dishes to get this maximum + * value. + * + *

Example 1: + * + *

Input: satisfaction = [-1,-8,0,5,-9] Output: 14 Explanation: After Removing the second and + * last dish, the maximum total Like-time coefficient will be equal to (-1*1 + 0*2 + 5*3 = 14). Each + * dish is prepared in one unit of time. Example 2: + * + *

Input: satisfaction = [4,3,2] Output: 20 Explanation: Dishes can be prepared in any order, + * (2*1 + 3*2 + 4*3 = 20) Example 3: + * + *

Input: satisfaction = [-1,-4,-5] Output: 0 Explanation: People don't like the dishes. No dish + * is prepared. Example 4: + * + *

Input: satisfaction = [-2,5,-1,0,3,-3] Output: 35 + * + *

Constraints: + * + *

n == satisfaction.length 1 <= n <= 500 -10^3 <= satisfaction[i] <= 10^3 + */ +public class ReducingDishes { + public static void main(String[] args) { + int[] A = {4, 3, 2}; + System.out.println(new ReducingDishes().maxSatisfaction(A)); + } + + public int maxSatisfaction(int[] satisfaction) { + Queue pq = new PriorityQueue<>(((o1, o2) -> o2 - o1)); + Arrays.stream(satisfaction).forEach(pq::offer); + int max = 0, sum = 0; + while (!pq.isEmpty()) { + if ((max + sum) >= max) { + max += sum; + sum += pq.poll(); + } else break; + } + return max; + } +} diff --git a/problems/src/greedy/ScoreAfterFlippingMatrix.java b/src/main/java/greedy/ScoreAfterFlippingMatrix.java similarity index 98% rename from problems/src/greedy/ScoreAfterFlippingMatrix.java rename to src/main/java/greedy/ScoreAfterFlippingMatrix.java index 3fc6b6f1..fd7a9d1d 100644 --- a/problems/src/greedy/ScoreAfterFlippingMatrix.java +++ b/src/main/java/greedy/ScoreAfterFlippingMatrix.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; /** diff --git a/src/main/java/greedy/StringWithout3A3B.java b/src/main/java/greedy/StringWithout3A3B.java new file mode 100644 index 00000000..91c69416 --- /dev/null +++ b/src/main/java/greedy/StringWithout3A3B.java @@ -0,0 +1,61 @@ +/* (C) 2024 YourCompanyName */ +package greedy; + +/** + * Created by gouthamvidyapradhan on 07/05/2019 + * + *

Given two integers A and B, return any string S such that: + * + *

S has length A + B and contains exactly A 'a' letters, and exactly B 'b' letters; The + * substring 'aaa' does not occur in S; The substring 'bbb' does not occur in S. + * + *

Example 1: + * + *

Input: A = 1, B = 2 Output: "abb" Explanation: "abb", "bab" and "bba" are all correct answers. + * Example 2: + * + *

Input: A = 4, B = 1 Output: "aabaa" + * + *

Solution O(N) idea is to greedily try to put two a's if number of a's is > b and similarly for + * b + */ +public class StringWithout3A3B { + + public static void main(String[] args) { + System.out.println(new StringWithout3A3B().strWithout3a3b(4, 1)); + } + + public String strWithout3a3b(int A, int B) { + StringBuilder sb = new StringBuilder(); + while (A > 0 || B > 0) { + if (A > B && A > 1 && B > 0) { + sb.append("a").append("a"); + sb.append("b"); + A -= 2; + B -= 1; + } else if (B > A && B > 1 && A > 0) { + sb.append("b").append("b"); + sb.append("a"); + B -= 2; + A -= 1; + } else { + if (A > B && A > 1) { + sb.append("a"); + sb.append("a"); + A -= 2; + } else if (A > B && A > 0) { + sb.append("a"); + A -= 1; + } else if (B > A && B > 1) { + sb.append("b"); + sb.append("b"); + B -= 2; + } else { + sb.append("b"); + B -= 1; + } + } + } + return sb.toString(); + } +} diff --git a/problems/src/greedy/TaskScheduler.java b/src/main/java/greedy/TaskScheduler.java similarity index 98% rename from problems/src/greedy/TaskScheduler.java rename to src/main/java/greedy/TaskScheduler.java index d084359c..d959cc10 100644 --- a/problems/src/greedy/TaskScheduler.java +++ b/src/main/java/greedy/TaskScheduler.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package greedy; import java.util.*; diff --git a/src/main/java/greedy/TwoCityScheduling.java b/src/main/java/greedy/TwoCityScheduling.java new file mode 100644 index 00000000..495023fd --- /dev/null +++ b/src/main/java/greedy/TwoCityScheduling.java @@ -0,0 +1,67 @@ +/* (C) 2024 YourCompanyName */ +package greedy; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 15/08/2019 There are 2N people a company is planning to + * interview. The cost of flying the i-th person to city A is costs[i][0], and the cost of flying + * the i-th person to city B is costs[i][1]. + * + *

Return the minimum cost to fly every person to a city such that exactly N people arrive in + * each city. + * + *

Example 1: + * + *

Input: [[10,20],[30,200],[400,50],[30,20]] Output: 110 Explanation: The first person goes to + * city A for a cost of 10. The second person goes to city A for a cost of 30. The third person goes + * to city B for a cost of 50. The fourth person goes to city B for a cost of 20. + * + *

The total minimum cost is 10 + 30 + 50 + 20 = 110 to have half the people interviewing in each + * city. + * + *

Note: + * + *

1 <= costs.length <= 100 It is guaranteed that costs.length is even. 1 <= costs[i][0], + * costs[i][1] <= 1000 + * + *

Solution: O(N log N) The general idea is to first allocate all the candidates to city A and + * sum up the cost and mark this as MIN. Now, make pairs with (costA - CostB, i) and sort this list + * of pairs in descending order (this is a greedy way of getting to the minimum possible value) - + * take the first half of this sorted list and sum of their values and reduce this value from MIN to + * get the answer. + */ +public class TwoCityScheduling { + public static void main(String[] args) { + int[][] A = {{10, 20}, {30, 200}, {400, 50}, {30, 20}}; + System.out.println(new TwoCityScheduling().twoCitySchedCost(A)); + } + + class Pair { + int max, i; + + Pair(int max, int i) { + this.max = max; + this.i = i; + } + } + + public int twoCitySchedCost(int[][] costs) { + int min = 0; + + for (int i = 0; i < costs.length; i++) { + min += costs[i][0]; + } + + List list = new ArrayList<>(); + for (int i = 0; i < costs.length; i++) { + list.add(new Pair(costs[i][0] - costs[i][1], i)); + } + list.sort((o1, o2) -> Integer.compare(o2.max, o1.max)); + + for (int i = 0, N = (list.size() / 2); i < N; i++) { + min -= list.get(i).max; + } + return min; + } +} diff --git a/problems/src/hashing/Anagrams.java b/src/main/java/hashing/Anagrams.java similarity index 98% rename from problems/src/hashing/Anagrams.java rename to src/main/java/hashing/Anagrams.java index 6bcbba8c..85684cc5 100644 --- a/problems/src/hashing/Anagrams.java +++ b/src/main/java/hashing/Anagrams.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.ArrayList; diff --git a/src/main/java/hashing/AnalyzeUserWebsiteVisitPattern.java b/src/main/java/hashing/AnalyzeUserWebsiteVisitPattern.java new file mode 100644 index 00000000..1c128bf0 --- /dev/null +++ b/src/main/java/hashing/AnalyzeUserWebsiteVisitPattern.java @@ -0,0 +1,120 @@ +/* (C) 2024 YourCompanyName */ +package hashing; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 23/10/2019 We are given some website visits: the user with name + * username[i] visited the website website[i] at time timestamp[i]. + * + *

A 3-sequence is a list of websites of length 3 sorted in ascending order by the time of their + * visits. (The websites in a 3-sequence are not necessarily distinct.) + * + *

Find the 3-sequence visited by the largest number of users. If there is more than one + * solution, return the lexicographically smallest such 3-sequence. + * + *

Example 1: + * + *

Input: username = ["joe","joe","joe","james","james","james","james","mary","mary","mary"], + * timestamp = [1,2,3,4,5,6,7,8,9,10], website = + * ["home","about","career","home","cart","maps","home","home","about","career"] Output: + * ["home","about","career"] Explanation: The tuples in this example are: ["joe", 1, "home"] ["joe", + * 2, "about"] ["joe", 3, "career"] ["james", 4, "home"] ["james", 5, "cart"] ["james", 6, "maps"] + * ["james", 7, "home"] ["mary", 8, "home"] ["mary", 9, "about"] ["mary", 10, "career"] The + * 3-sequence ("home", "about", "career") was visited at least once by 2 users. The 3-sequence + * ("home", "cart", "maps") was visited at least once by 1 user. The 3-sequence ("home", "cart", + * "home") was visited at least once by 1 user. The 3-sequence ("home", "maps", "home") was visited + * at least once by 1 user. The 3-sequence ("cart", "maps", "home") was visited at least once by 1 + * user. + * + *

Note: + * + *

3 <= N = username.length = timestamp.length = website.length <= 50 1 <= username[i].length <= + * 10 0 <= timestamp[i] <= 10^9 1 <= website[i].length <= 10 Both username[i] and website[i] contain + * only lowercase characters. It is guaranteed that there is at least one user who visited at least + * 3 websites. No user visits two websites at the same time. + */ +public class AnalyzeUserWebsiteVisitPattern { + private class VisitCount { + String site; + int count; + + VisitCount(String site, int count) { + this.site = site; + this.count = count; + } + + public String getSite() { + return site; + } + + public int getCount() { + return count; + } + } + + private class WebsiteTime { + String website; + int time; + + WebsiteTime(String website, int time) { + this.website = website; + this.time = time; + } + + public int getTime() { + return time; + } + } + + Map> userVisitCount; + + public static void main(String[] args) { + String[] userName = { + "joe", "joe", "joe", "james", "james", "james", "james", "mary", "mary", "mary" + }; + int[] time = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + String[] website = { + "home", "about", "career", "home", "cart", "maps", "home", "home", "about", "career" + }; + List result = + new AnalyzeUserWebsiteVisitPattern().mostVisitedPattern(userName, time, website); + System.out.println(result); + } + + public List mostVisitedPattern(String[] username, int[] timestamp, String[] website) { + userVisitCount = new HashMap<>(); + for (int i = 0; i < username.length; i++) { + for (int j = i + 1; j < username.length; j++) { + if (username[i].equals(username[j])) { + for (int k = j + 1; k < username.length; k++) { + if (username[i].equals(username[j]) && username[j].equals(username[k])) { + List visits = + Arrays.asList( + new WebsiteTime(website[i], timestamp[i]), + new WebsiteTime(website[j], timestamp[j]), + new WebsiteTime(website[k], timestamp[k])); + visits.sort(Comparator.comparingInt(WebsiteTime::getTime)); + String concatinatedWebsite = + String.join( + "-", visits.get(0).website, visits.get(1).website, visits.get(2).website); + userVisitCount.putIfAbsent(concatinatedWebsite, new HashSet<>()); + userVisitCount.get(concatinatedWebsite).add(username[i]); + } + } + } + } + } + List visitCounts = new ArrayList<>(); + for (String k : userVisitCount.keySet()) { + visitCounts.add(new VisitCount(k, userVisitCount.get(k).size())); + } + visitCounts.sort( + Comparator.comparingInt(VisitCount::getCount) + .reversed() + .thenComparing(VisitCount::getSite)); + VisitCount visitCount = visitCounts.get(0); + String[] result = visitCount.getSite().split("-"); + return Arrays.asList(result[0], result[1], result[2]); + } +} diff --git a/problems/src/hashing/BrickWall.java b/src/main/java/hashing/BrickWall.java similarity index 99% rename from problems/src/hashing/BrickWall.java rename to src/main/java/hashing/BrickWall.java index 3376c5b3..33bca838 100644 --- a/problems/src/hashing/BrickWall.java +++ b/src/main/java/hashing/BrickWall.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.ArrayList; diff --git a/problems/src/hashing/ContiguousArray.java b/src/main/java/hashing/ContiguousArray.java similarity index 98% rename from problems/src/hashing/ContiguousArray.java rename to src/main/java/hashing/ContiguousArray.java index 2702df6f..481408e2 100644 --- a/problems/src/hashing/ContiguousArray.java +++ b/src/main/java/hashing/ContiguousArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.HashMap; diff --git a/problems/src/hashing/CustomSortString.java b/src/main/java/hashing/CustomSortString.java similarity index 98% rename from problems/src/hashing/CustomSortString.java rename to src/main/java/hashing/CustomSortString.java index de7e44bb..a54cfe4c 100644 --- a/problems/src/hashing/CustomSortString.java +++ b/src/main/java/hashing/CustomSortString.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.*; diff --git a/problems/src/hashing/DistributeCandies.java b/src/main/java/hashing/DistributeCandies.java similarity index 98% rename from problems/src/hashing/DistributeCandies.java rename to src/main/java/hashing/DistributeCandies.java index 9b8d18f5..473888a7 100644 --- a/problems/src/hashing/DistributeCandies.java +++ b/src/main/java/hashing/DistributeCandies.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.*; diff --git a/problems/src/hashing/GroupAnagrams.java b/src/main/java/hashing/GroupAnagrams.java similarity index 98% rename from problems/src/hashing/GroupAnagrams.java rename to src/main/java/hashing/GroupAnagrams.java index 69251926..be1b90e6 100644 --- a/problems/src/hashing/GroupAnagrams.java +++ b/src/main/java/hashing/GroupAnagrams.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.ArrayList; diff --git a/problems/src/hashing/GroupsOfSpecialEquivalentStrings.java b/src/main/java/hashing/GroupsOfSpecialEquivalentStrings.java similarity index 98% rename from problems/src/hashing/GroupsOfSpecialEquivalentStrings.java rename to src/main/java/hashing/GroupsOfSpecialEquivalentStrings.java index fd37ad63..958de35f 100644 --- a/problems/src/hashing/GroupsOfSpecialEquivalentStrings.java +++ b/src/main/java/hashing/GroupsOfSpecialEquivalentStrings.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.*; diff --git a/problems/src/hashing/KdiffPairsInanArray.java b/src/main/java/hashing/KdiffPairsInanArray.java similarity index 98% rename from problems/src/hashing/KdiffPairsInanArray.java rename to src/main/java/hashing/KdiffPairsInanArray.java index ab5ef28a..c724a8fe 100644 --- a/problems/src/hashing/KdiffPairsInanArray.java +++ b/src/main/java/hashing/KdiffPairsInanArray.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.HashMap; diff --git a/src/main/java/hashing/LargestUniqueNumber.java b/src/main/java/hashing/LargestUniqueNumber.java new file mode 100644 index 00000000..1d2fb3a0 --- /dev/null +++ b/src/main/java/hashing/LargestUniqueNumber.java @@ -0,0 +1,43 @@ +/* (C) 2024 YourCompanyName */ +package hashing; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 26/11/2019 Given an array of integers A, return the largest + * integer that only occurs once. + * + *

If no integer occurs once, return -1. + * + *

Example 1: + * + *

Input: [5,7,3,9,4,9,8,3,1] Output: 8 Explanation: The maximum integer in the array is 9 but it + * is repeated. The number 8 occurs only once, so it's the answer. Example 2: + * + *

Input: [9,9,8,8] Output: -1 Explanation: There is no number that occurs only once. + * + *

Note: + * + *

1 <= A.length <= 2000 0 <= A[i] <= 1000 + */ +public class LargestUniqueNumber { + public static void main(String[] args) { + // + } + + public int largestUniqueNumber(int[] A) { + Map map = new HashMap<>(); + for (int i : A) { + map.putIfAbsent(i, 0); + int v = map.get(i) + 1; + map.put(i, v); + } + int max = -1; + for (int k : map.keySet()) { + if (map.get(k) == 1) { + max = Math.max(max, k); + } + } + return max; + } +} diff --git a/problems/src/hashing/MaximumSizeSubarraySumEqualsk.java b/src/main/java/hashing/MaximumSizeSubarraySumEqualsk.java similarity index 98% rename from problems/src/hashing/MaximumSizeSubarraySumEqualsk.java rename to src/main/java/hashing/MaximumSizeSubarraySumEqualsk.java index 9616f9a4..219cd4a8 100644 --- a/problems/src/hashing/MaximumSizeSubarraySumEqualsk.java +++ b/src/main/java/hashing/MaximumSizeSubarraySumEqualsk.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.HashMap; diff --git a/src/main/java/hashing/NumberOfAtoms.java b/src/main/java/hashing/NumberOfAtoms.java new file mode 100644 index 00000000..0fbdccbe --- /dev/null +++ b/src/main/java/hashing/NumberOfAtoms.java @@ -0,0 +1,149 @@ +/* (C) 2024 YourCompanyName */ +package hashing; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 06/08/2019 Given a chemical formula (given as a string), return + * the count of each atom. + * + *

An atomic element always starts with an uppercase character, then zero or more lowercase + * letters, representing the name. + * + *

1 or more digits representing the count of that element may follow if the count is greater + * than 1. If the count is 1, no digits will follow. For example, H2O and H2O2 are possible, but + * H1O2 is impossible. + * + *

Two formulas concatenated together produce another formula. For example, H2O2He3Mg4 is also a + * formula. + * + *

A formula placed in parentheses, and a count (optionally added) is also a formula. For + * example, (H2O2) and (H2O2)3 are formulas. + * + *

Given a formula, output the count of all elements as a string in the following form: the first + * name (in sorted order), followed by its count (if that count is more than 1), followed by the + * second name (in sorted order), followed by its count (if that count is more than 1), and so on. + * + *

Example 1: Input: formula = "H2O" Output: "H2O" Explanation: The count of elements are {'H': + * 2, 'O': 1}. Example 2: Input: formula = "Mg(OH)2" Output: "H2MgO2" Explanation: The count of + * elements are {'H': 2, 'Mg': 1, 'O': 2}. Example 3: Input: formula = "K4(ON(SO3)2)2" Output: + * "K4N2O14S4" Explanation: The count of elements are {'K': 4, 'N': 2, 'O': 14, 'S': 4}. Note: + * + *

All atom names consist of lowercase letters, except for the first character which is + * uppercase. The length of formula will be in the range [1, 1000]. formula will only consist of + * letters, digits, and round parentheses, and is a valid formula as defined in the problem. + * + *

Solution O(N ^ 2) Recursively solve each substring within round braces as subformula. Consider + * each subformula as right subformula and each each subformula before the round braces as left + * subformula - sum up value of both left and right subformula to get the answer. + */ +public class NumberOfAtoms { + public static void main(String[] args) { + String result = new NumberOfAtoms().countOfAtoms("K4(((K4)K4)2)2"); + System.out.println(result); + } + + public String countOfAtoms(String formula) { + Map atomCountResult = new NumberOfAtoms().countOfAtoms(formula, 0); + List sortedKeys = new ArrayList<>(atomCountResult.keySet()); + sortedKeys.sort(Comparator.naturalOrder()); + StringBuilder result = new StringBuilder(); + for (String k : sortedKeys) { + int count = atomCountResult.get(k); + if (count > 1) { + result.append(k).append(count); + } else result.append(k); + } + return result.toString(); + } + + private Map countOfAtoms(String formula, int startPos) { + Map left = new HashMap<>(); + StringBuilder atom = new StringBuilder(); + StringBuilder atomCount = new StringBuilder(); + for (int i = startPos; i < formula.length(); ) { + char c = formula.charAt(i); + if (c >= 'A' && c <= 'Z') { + if (atom.length() > 0) { + int count = 1; + if (atomCount.length() > 0) { + count = Integer.parseInt(atomCount.toString()); + } + String atomKey = atom.toString(); + if (left.containsKey(atomKey)) { + left.put(atomKey, left.get(atomKey) + count); + } else left.put(atom.toString(), count); + atom = new StringBuilder(); + atomCount = new StringBuilder(); + } + atom.append(c); + i++; + } else if (c >= 'a' && c <= 'z') { + atom.append(c); + i++; + } else if (c >= '0' && c <= '9') { + atomCount.append(c); + i++; + } else { + // this is equal to '(' + if (atom.length() > 0) { + int count = 1; + if (atomCount.length() > 0) { + count = Integer.parseInt(atomCount.toString()); + } + String atomKey = atom.toString(); + if (left.containsKey(atomKey)) { + left.put(atomKey, left.get(atomKey) + count); + } else left.put(atom.toString(), count); + atom = new StringBuilder(); + atomCount = new StringBuilder(); + } + int j = i, count = 0; + for (int l = formula.length(); j < l; j++) { + if (formula.charAt(j) == '(') { + count++; + } else if (formula.charAt(j) == ')') { + count--; + } + if (count == 0) break; + } + Map right = countOfAtoms(formula.substring(i + 1, j), 0); + j++; + StringBuilder rightAtomCount = new StringBuilder(); + for (int l = formula.length(); j < l; j++) { + if (formula.charAt(j) >= '0' && formula.charAt(j) <= '9') { + rightAtomCount.append(formula.charAt(j)); + } else break; + } + if (rightAtomCount.length() > 0) { + int mulFactor = Integer.parseInt(rightAtomCount.toString()); + for (String k : right.keySet()) { + right.put(k, right.get(k) * mulFactor); + } + } + left = merge(left, right); + i = j; + } + } + if (atom.length() > 0) { + int count = 1; + if (atomCount.length() > 0) { + count = Integer.parseInt(atomCount.toString()); + } + String atomKey = atom.toString(); + if (left.containsKey(atomKey)) { + left.put(atomKey, left.get(atomKey) + count); + } else left.put(atom.toString(), count); + } + return left; + } + + private Map merge(Map left, Map right) { + for (String k : left.keySet()) { + if (right.containsKey(k)) { + right.put(k, right.get(k) + left.get(k)); + } else right.put(k, left.get(k)); + } + return right; + } +} diff --git a/problems/src/hashing/PartitionLabels.java b/src/main/java/hashing/PartitionLabels.java similarity index 98% rename from problems/src/hashing/PartitionLabels.java rename to src/main/java/hashing/PartitionLabels.java index 0b00ccdd..6b5bc435 100644 --- a/problems/src/hashing/PartitionLabels.java +++ b/src/main/java/hashing/PartitionLabels.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.ArrayList; diff --git a/problems/src/hashing/ShortEncodingOfWords.java b/src/main/java/hashing/ShortEncodingOfWords.java similarity index 98% rename from problems/src/hashing/ShortEncodingOfWords.java rename to src/main/java/hashing/ShortEncodingOfWords.java index 56b80a15..ada03526 100644 --- a/problems/src/hashing/ShortEncodingOfWords.java +++ b/src/main/java/hashing/ShortEncodingOfWords.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.*; diff --git a/problems/src/hashing/SortCharByFrequency.java b/src/main/java/hashing/SortCharByFrequency.java similarity index 98% rename from problems/src/hashing/SortCharByFrequency.java rename to src/main/java/hashing/SortCharByFrequency.java index 29e40bc7..1f1aec8a 100644 --- a/problems/src/hashing/SortCharByFrequency.java +++ b/src/main/java/hashing/SortCharByFrequency.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.ArrayList; diff --git a/src/main/java/hashing/StringTransformsIntoAnotherString.java b/src/main/java/hashing/StringTransformsIntoAnotherString.java new file mode 100644 index 00000000..20932803 --- /dev/null +++ b/src/main/java/hashing/StringTransformsIntoAnotherString.java @@ -0,0 +1,52 @@ +/* (C) 2024 YourCompanyName */ +package hashing; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 23/10/2019 Given two strings str1 and str2 of the same length, + * determine whether you can transform str1 into str2 by doing zero or more conversions. + * + *

In one conversion you can convert all occurrences of one character in str1 to any other + * lowercase English character. + * + *

Return true if and only if you can transform str1 into str2. + * + *

Example 1: + * + *

Input: str1 = "aabcc", str2 = "ccdee" Output: true Explanation: Convert 'c' to 'e' then 'b' to + * 'd' then 'a' to 'c'. Note that the order of conversions matter. Example 2: + * + *

Input: str1 = "leetcode", str2 = "codeleet" Output: false Explanation: There is no way to + * transform str1 to str2. + * + *

Note: + * + *

1 <= str1.length == str2.length <= 10^4 Both str1 and str2 contain only lowercase English + * letters. + */ +public class StringTransformsIntoAnotherString { + public static void main(String[] args) { + System.out.println(new StringTransformsIntoAnotherString().canConvert("ab", "ba")); + } + + public boolean canConvert(String str1, String str2) { + if (str1.length() != str2.length()) return false; + if (str1.equals(str2)) return true; + Map mapping = new HashMap<>(); + for (int i = 0; i < str1.length(); i++) { + char c1 = str1.charAt(i); + char c2 = str2.charAt(i); + if (mapping.containsKey(c1)) { + if (mapping.get(c1) != c2) return false; + } else { + mapping.put(c1, c2); + } + } + Set set = new HashSet<>(); + for (char k : mapping.keySet()) { + set.add(mapping.get(k)); + } + return (set.size() < 26); + } +} diff --git a/problems/src/hashing/SubstringConcatenationOfWords.java b/src/main/java/hashing/SubstringConcatenationOfWords.java similarity index 98% rename from problems/src/hashing/SubstringConcatenationOfWords.java rename to src/main/java/hashing/SubstringConcatenationOfWords.java index 1c23716e..73eceaf0 100644 --- a/problems/src/hashing/SubstringConcatenationOfWords.java +++ b/src/main/java/hashing/SubstringConcatenationOfWords.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.ArrayList; diff --git a/problems/src/hashing/TwoSum.java b/src/main/java/hashing/TwoSum.java similarity index 97% rename from problems/src/hashing/TwoSum.java rename to src/main/java/hashing/TwoSum.java index 5e1bba45..0c321989 100644 --- a/problems/src/hashing/TwoSum.java +++ b/src/main/java/hashing/TwoSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; import java.util.HashMap; diff --git a/problems/src/hashing/ValidAnagram.java b/src/main/java/hashing/ValidAnagram.java similarity index 97% rename from problems/src/hashing/ValidAnagram.java rename to src/main/java/hashing/ValidAnagram.java index 0fb2a6c9..97b51a97 100644 --- a/problems/src/hashing/ValidAnagram.java +++ b/src/main/java/hashing/ValidAnagram.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package hashing; /** diff --git a/problems/src/heap/Candy.java b/src/main/java/heap/Candy.java similarity index 99% rename from problems/src/heap/Candy.java rename to src/main/java/heap/Candy.java index 387389a2..0f1b657c 100644 --- a/problems/src/heap/Candy.java +++ b/src/main/java/heap/Candy.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package heap; import java.util.*; diff --git a/src/main/java/heap/DistantBarcodes.java b/src/main/java/heap/DistantBarcodes.java new file mode 100644 index 00000000..54ce859b --- /dev/null +++ b/src/main/java/heap/DistantBarcodes.java @@ -0,0 +1,81 @@ +/* (C) 2024 YourCompanyName */ +package heap; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 04/12/2019 In a warehouse, there is a row of barcodes, where + * the i-th barcode is barcodes[i]. + * + *

Rearrange the barcodes so that no two adjacent barcodes are equal. You may return any answer, + * and it is guaranteed an answer exists. + * + *

Example 1: + * + *

Input: [1,1,1,2,2,2] Output: [2,1,2,1,2,1] Example 2: + * + *

Input: [1,1,1,1,2,2,3,3] Output: [1,3,1,3,2,1,2,1] + * + *

Note: + * + *

1 <= barcodes.length <= 10000 1 <= barcodes[i] <= 10000 + */ +public class DistantBarcodes { + public static void main(String[] args) { + int[] barcode = {1, 1, 1, 2, 2, 2}; + int[] result = new DistantBarcodes().rearrangeBarcodes(barcode); + for (int i : result) { + System.out.print(i + " "); + } + System.out.println(); + } + + class Node { + int value, count, rank; + + Node(int value, int count, int rank) { + this.value = value; + this.count = count; + this.rank = rank; + } + } + + public int[] rearrangeBarcodes(int[] barcodes) { + PriorityQueue pq = + new PriorityQueue<>( + (o1, o2) -> { + int r = Integer.compare(o2.count, o1.count); + return r == 0 ? Integer.compare(o1.rank, o2.rank) : r; + }); + Map map = new HashMap<>(); + for (int b : barcodes) { + map.putIfAbsent(b, 0); + map.put(b, map.get(b) + 1); + } + for (int k : map.keySet()) { + pq.offer(new Node(k, map.get(k), -1)); + } + int[] result = new int[barcodes.length]; + int i = 0; + int rank = 0; + while (!pq.isEmpty()) { + Node node = pq.poll(); + result[i++] = node.value; + node.count -= 1; + node.rank = rank++; + if (!pq.isEmpty()) { + Node next = pq.poll(); + result[i++] = next.value; + next.count -= 1; + next.rank = rank++; + if (next.count > 0) { + pq.offer(next); + } + } + if (node.count > 0) { + pq.offer(node); + } + } + return result; + } +} diff --git a/problems/src/heap/FreqStack.java b/src/main/java/heap/FreqStack.java similarity index 99% rename from problems/src/heap/FreqStack.java rename to src/main/java/heap/FreqStack.java index 58944403..78ca3dce 100644 --- a/problems/src/heap/FreqStack.java +++ b/src/main/java/heap/FreqStack.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package heap; import java.util.*; diff --git a/src/main/java/heap/KClosestPointsToOrigin.java b/src/main/java/heap/KClosestPointsToOrigin.java new file mode 100644 index 00000000..d15fe579 --- /dev/null +++ b/src/main/java/heap/KClosestPointsToOrigin.java @@ -0,0 +1,67 @@ +/* (C) 2024 YourCompanyName */ +package heap; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 30/11/2019 We have a list of points on the plane. Find the K + * closest points to the origin (0, 0). + * + *

(Here, the distance between two points on a plane is the Euclidean distance.) + * + *

You may return the answer in any order. The answer is guaranteed to be unique (except for the + * order that it is in.) + * + *

Example 1: + * + *

Input: points = [[1,3],[-2,2]], K = 1 Output: [[-2,2]] Explanation: The distance between (1, + * 3) and the origin is sqrt(10). The distance between (-2, 2) and the origin is sqrt(8). Since + * sqrt(8) < sqrt(10), (-2, 2) is closer to the origin. We only want the closest K = 1 points from + * the origin, so the answer is just [[-2,2]]. Example 2: + * + *

Input: points = [[3,3],[5,-1],[-2,4]], K = 2 Output: [[3,3],[-2,4]] (The answer [[-2,4],[3,3]] + * would also be accepted.) + * + *

Note: + * + *

1 <= K <= points.length <= 10000 -10000 < points[i][0] < 10000 -10000 < points[i][1] < 10000 + */ +public class KClosestPointsToOrigin { + public static void main(String[] args) { + int[][] A = {{3, 3}, {5, -1}, {-2, 4}}; + int[][] ans = new KClosestPointsToOrigin().kClosest(A, 2); + System.out.println(); + } + + class Point { + int a, b; + + Point(int a, int b) { + this.a = a; + this.b = b; + } + + public long distance() { + return (long) (a * a) + (long) (b * b); + } + } + + public int[][] kClosest(int[][] points, int K) { + PriorityQueue pq = + new PriorityQueue<>((o1, o2) -> Long.compare(o2.distance(), o1.distance())); + for (int[] p : points) { + pq.offer(new Point(p[0], p[1])); + if (pq.size() > K) { + pq.poll(); + } + } + int[][] ans = new int[K][2]; + int i = 0; + while (!pq.isEmpty()) { + Point point = pq.poll(); + ans[i][0] = point.a; + ans[i++][1] = point.b; + } + return ans; + } +} diff --git a/problems/src/heap/MeetingRoomsII.java b/src/main/java/heap/MeetingRoomsII.java similarity index 98% rename from problems/src/heap/MeetingRoomsII.java rename to src/main/java/heap/MeetingRoomsII.java index 50a013de..33131b41 100644 --- a/problems/src/heap/MeetingRoomsII.java +++ b/src/main/java/heap/MeetingRoomsII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package heap; import java.util.Arrays; diff --git a/src/main/java/heap/ReachableNodesInSubdividedGraph.java b/src/main/java/heap/ReachableNodesInSubdividedGraph.java new file mode 100644 index 00000000..00c85813 --- /dev/null +++ b/src/main/java/heap/ReachableNodesInSubdividedGraph.java @@ -0,0 +1,118 @@ +/* (C) 2024 YourCompanyName */ +package heap; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 07/05/2019 Starting with an undirected graph (the "original + * graph") with nodes from 0 to N-1, subdivisions are made to some of the edges. + * + *

The graph is given as follows: edges[k] is a list of integer pairs (i, j, n) such that (i, j) + * is an edge of the original graph, + * + *

and n is the total number of new nodes on that edge. + * + *

Then, the edge (i, j) is deleted from the original graph, n new nodes (x_1, x_2, ..., x_n) are + * added to the original graph, + * + *

and n+1 new edges (i, x_1), (x_1, x_2), (x_2, x_3), ..., (x_{n-1}, x_n), (x_n, j) are added to + * the original graph. + * + *

Now, you start at node 0 from the original graph, and in each move, you travel along one edge. + * + *

Return how many nodes you can reach in at most M moves. + * + *

Example 1: + * + *

Input: edges = [[0,1,10],[0,2,1],[1,2,2]], M = 6, N = 3 Output: 13 Explanation: The nodes that + * are reachable in the final graph after M = 6 moves are indicated below. + * + *

Example 2: + * + *

Input: edges = [[0,1,4],[1,2,6],[0,2,8],[1,3,1]], M = 10, N = 4 Output: 23 + * + *

Note: + * + *

0 <= edges.length <= 10000 0 <= edges[i][0] < edges[i][1] < N There does not exist any i != j + * for which edges[i][0] == edges[j][0] and edges[i][1] == edges[j][1]. The original graph has no + * parallel edges. 0 <= edges[i][2] <= 10000 0 <= M <= 10^9 1 <= N <= 3000 A reachable node is a + * node that can be travelled to using at most M moves starting from node 0. + * + *

Solution: O(E log N) E is the length of edges and N is the number of nodes. The n nodes on a + * edge form a weight and thus the graph becomes a weighted graph. Keep track of number of moves + * available and run a Dijkstra's algorithm. + */ +public class ReachableNodesInSubdividedGraph { + + /** + * Main method + * + * @param args + */ + public static void main(String[] args) { + int[][] edges = {{0, 1, 1000}, {0, 2, 1}, {1, 2, 1}}; + System.out.println(new ReachableNodesInSubdividedGraph().reachableNodes(edges, 200, 3)); + } + + static class Node { + int n, w; + + Node(int n, int w) { + this.n = n; + this.w = w; + } + } + + public int reachableNodes(int[][] edges, int M, int N) { + Map> graph = new HashMap<>(); + for (int[] e : edges) { + graph.putIfAbsent(e[0], new ArrayList<>()); + graph.get(e[0]).add(new Node(e[1], e[2] + 1)); + + graph.putIfAbsent(e[1], new ArrayList<>()); + graph.get(e[1]).add(new Node(e[0], e[2] + 1)); + } + + PriorityQueue pq = new PriorityQueue<>(Comparator.comparingInt(o -> o.w)); + Map distance = new HashMap<>(); + int count = 0; + pq.offer(new Node(0, 0)); + while (!pq.isEmpty()) { + Node curr = pq.poll(); + if (!distance.containsKey(curr.n)) { + count += 1; + distance.put(curr.n, curr.w); + List children = graph.get(curr.n); + if (children != null) { + for (Node c : children) { + if (!distance.containsKey(c.n)) { + int availableMoves = M - curr.w; + int nodesInBetween = c.w - 1; + if (nodesInBetween >= availableMoves) { + count += availableMoves; + } else { + count += nodesInBetween; + if (availableMoves >= c.w) { + Node child = new Node(c.n, distance.get(curr.n) + c.w); + pq.offer(child); + } + } + } else { + int childAvailableMoves = M - distance.get(c.n); + int nodesInBetween = c.w - 1; + int unvisitedNodes = nodesInBetween - childAvailableMoves; + if (unvisitedNodes > 0) { + int availableMovesForCurr = M - distance.get(curr.n); + count += + (unvisitedNodes >= availableMovesForCurr + ? availableMovesForCurr + : unvisitedNodes); + } + } + } + } + } + } + return count; + } +} diff --git a/problems/src/heap/SlidingWindowMaximum.java b/src/main/java/heap/SlidingWindowMaximum.java similarity index 98% rename from problems/src/heap/SlidingWindowMaximum.java rename to src/main/java/heap/SlidingWindowMaximum.java index 495ae420..138f78fe 100644 --- a/problems/src/heap/SlidingWindowMaximum.java +++ b/src/main/java/heap/SlidingWindowMaximum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package heap; import java.util.ArrayDeque; diff --git a/problems/src/heap/SmallestRotationWithHighestScore.java b/src/main/java/heap/SmallestRotationWithHighestScore.java similarity index 99% rename from problems/src/heap/SmallestRotationWithHighestScore.java rename to src/main/java/heap/SmallestRotationWithHighestScore.java index faefc394..35cf6be0 100644 --- a/problems/src/heap/SmallestRotationWithHighestScore.java +++ b/src/main/java/heap/SmallestRotationWithHighestScore.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package heap; import java.util.Comparator; diff --git a/problems/src/heap/TheSkylineProblem.java b/src/main/java/heap/TheSkylineProblem.java similarity index 99% rename from problems/src/heap/TheSkylineProblem.java rename to src/main/java/heap/TheSkylineProblem.java index 6cf65f95..ad19755a 100644 --- a/problems/src/heap/TheSkylineProblem.java +++ b/src/main/java/heap/TheSkylineProblem.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package heap; import java.util.*; diff --git a/problems/src/heap/TopKFrequentWords.java b/src/main/java/heap/TopKFrequentWords.java similarity index 98% rename from problems/src/heap/TopKFrequentWords.java rename to src/main/java/heap/TopKFrequentWords.java index f0bf249b..7774d477 100644 --- a/problems/src/heap/TopKFrequentWords.java +++ b/src/main/java/heap/TopKFrequentWords.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package heap; import java.util.*; diff --git a/problems/src/linked_list/DeleteNode.java b/src/main/java/linked_list/DeleteNode.java similarity index 97% rename from problems/src/linked_list/DeleteNode.java rename to src/main/java/linked_list/DeleteNode.java index 28479dcf..7b935e4c 100644 --- a/problems/src/linked_list/DeleteNode.java +++ b/src/main/java/linked_list/DeleteNode.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; /** diff --git a/problems/src/linked_list/IntersectionOfTwoLists.java b/src/main/java/linked_list/IntersectionOfTwoLists.java similarity index 98% rename from problems/src/linked_list/IntersectionOfTwoLists.java rename to src/main/java/linked_list/IntersectionOfTwoLists.java index e52392c8..b3abc9dd 100644 --- a/problems/src/linked_list/IntersectionOfTwoLists.java +++ b/src/main/java/linked_list/IntersectionOfTwoLists.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; /** diff --git a/problems/src/linked_list/LinkedListCycle.java b/src/main/java/linked_list/LinkedListCycle.java similarity index 97% rename from problems/src/linked_list/LinkedListCycle.java rename to src/main/java/linked_list/LinkedListCycle.java index 3b7bfa56..b9bcc130 100644 --- a/problems/src/linked_list/LinkedListCycle.java +++ b/src/main/java/linked_list/LinkedListCycle.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; import java.util.HashSet; diff --git a/problems/src/linked_list/MergeKSortedLists.java b/src/main/java/linked_list/MergeKSortedLists.java similarity index 98% rename from problems/src/linked_list/MergeKSortedLists.java rename to src/main/java/linked_list/MergeKSortedLists.java index 3797b0d6..c128fce3 100644 --- a/problems/src/linked_list/MergeKSortedLists.java +++ b/src/main/java/linked_list/MergeKSortedLists.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; /** diff --git a/problems/src/linked_list/MergeTwoSortedList.java b/src/main/java/linked_list/MergeTwoSortedList.java similarity index 97% rename from problems/src/linked_list/MergeTwoSortedList.java rename to src/main/java/linked_list/MergeTwoSortedList.java index 24fc4678..c3a5f87c 100644 --- a/problems/src/linked_list/MergeTwoSortedList.java +++ b/src/main/java/linked_list/MergeTwoSortedList.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; /** diff --git a/problems/src/linked_list/MiddleOfLinkedList.java b/src/main/java/linked_list/MiddleOfLinkedList.java similarity index 97% rename from problems/src/linked_list/MiddleOfLinkedList.java rename to src/main/java/linked_list/MiddleOfLinkedList.java index ec5a0a37..a75150d8 100644 --- a/problems/src/linked_list/MiddleOfLinkedList.java +++ b/src/main/java/linked_list/MiddleOfLinkedList.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; /** diff --git a/src/main/java/linked_list/NextGreaterNodeInLinkedList.java b/src/main/java/linked_list/NextGreaterNodeInLinkedList.java new file mode 100644 index 00000000..b5e4a196 --- /dev/null +++ b/src/main/java/linked_list/NextGreaterNodeInLinkedList.java @@ -0,0 +1,94 @@ +/* (C) 2024 YourCompanyName */ +package linked_list; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 31/07/2019 We are given a linked list with head as the first + * node. Let's number the nodes in the list: node_1, node_2, node_3, ... etc. + * + *

Each node may have a next larger value: for node_i, next_larger(node_i) is the node_j.val such + * that j > i, node_j.val > node_i.val, and j is the smallest possible choice. If such a j does not + * exist, the next larger value is 0. + * + *

Return an array of integers answer, where answer[i] = next_larger(node_{i+1}). + * + *

Note that in the example inputs (not outputs) below, arrays such as [2,1,5] represent the + * serialization of a linked list with a head node value of 2, second node value of 1, and third + * node value of 5. + * + *

Example 1: + * + *

Input: [2,1,5] Output: [5,5,0] Example 2: + * + *

Input: [2,7,4,3,5] Output: [7,0,5,5,0] Example 3: + * + *

Input: [1,7,5,1,9,2,5,1] Output: [7,9,9,9,0,5,0,0] + * + *

Note: + * + *

1 <= node.val <= 10^9 for each node in the linked list. The given list has length in the range + * [0, 10000]. + * + *

Solution O(N) solve the problem in the inverse order starting from the tail of the list. + * Maintain a stack of values and on each iteration pop() all the values from the stack which are + * smaller then the current element. + */ +public class NextGreaterNodeInLinkedList { + + public static class ListNode { + int val; + ListNode next; + + ListNode(int x) { + val = x; + } + } + + private List result; + + public static void main(String[] args) { + ListNode node = new ListNode(1); + node.next = new ListNode(2); + new NextGreaterNodeInLinkedList().nextLargerNodes(node); + } + + public int[] nextLargerNodes(ListNode head) { + result = new ArrayList<>(); + find(head, result); + Collections.reverse(result); + int[] answer = new int[result.size()]; + for (int i = 0, l = result.size(); i < l; i++) { + answer[i] = result.get(i); + } + return answer; + } + + private Stack find(ListNode head, List answer) { + if (head == null) { + return new Stack<>(); + } + Stack stack = find(head.next, answer); + if (stack.isEmpty()) { + answer.add(0); + stack.push(head.val); + } else { + if (stack.peek() > head.val) { + answer.add(stack.peek()); + stack.push(head.val); + } else { + while (!stack.isEmpty() && stack.peek() <= head.val) { + stack.pop(); + } + if (stack.isEmpty()) { + stack.push(head.val); + answer.add(0); + } else { + answer.add(stack.peek()); + stack.push(head.val); + } + } + } + return stack; + } +} diff --git a/problems/src/linked_list/PaliandromeList.java b/src/main/java/linked_list/PaliandromeList.java similarity index 98% rename from problems/src/linked_list/PaliandromeList.java rename to src/main/java/linked_list/PaliandromeList.java index b8ea89d1..6629d699 100644 --- a/problems/src/linked_list/PaliandromeList.java +++ b/src/main/java/linked_list/PaliandromeList.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; /** diff --git a/problems/src/linked_list/ReverseLinkedList.java b/src/main/java/linked_list/ReverseLinkedList.java similarity index 97% rename from problems/src/linked_list/ReverseLinkedList.java rename to src/main/java/linked_list/ReverseLinkedList.java index 6109d070..e7b00d28 100644 --- a/problems/src/linked_list/ReverseLinkedList.java +++ b/src/main/java/linked_list/ReverseLinkedList.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; /** Created by gouthamvidyapradhan on 24/02/2017. Reverse a singly linked list. */ diff --git a/problems/src/linked_list/ReverseNodesKGroup.java b/src/main/java/linked_list/ReverseNodesKGroup.java similarity index 98% rename from problems/src/linked_list/ReverseNodesKGroup.java rename to src/main/java/linked_list/ReverseNodesKGroup.java index f300fb3b..a253c32e 100644 --- a/problems/src/linked_list/ReverseNodesKGroup.java +++ b/src/main/java/linked_list/ReverseNodesKGroup.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; /** diff --git a/src/main/java/linked_list/SplitLinkedListInParts.java b/src/main/java/linked_list/SplitLinkedListInParts.java new file mode 100644 index 00000000..e0a43138 --- /dev/null +++ b/src/main/java/linked_list/SplitLinkedListInParts.java @@ -0,0 +1,96 @@ +/* (C) 2024 YourCompanyName */ +package linked_list; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 06/08/2019 Given a (singly) linked list with head node root, + * write a function to split the linked list into k consecutive linked list "parts". + * + *

The length of each part should be as equal as possible: no two parts should have a size + * differing by more than 1. This may lead to some parts being null. + * + *

The parts should be in order of occurrence in the input list, and parts occurring earlier + * should always have a size greater than or equal parts occurring later. + * + *

Return a List of ListNode's representing the linked list parts that are formed. + * + *

Examples 1->2->3->4, k = 5 // 5 equal parts [ [1], [2], [3], [4], null ] Example 1: Input: + * root = [1, 2, 3], k = 5 Output: [[1],[2],[3],[],[]] Explanation: The input and each element of + * the output are ListNodes, not arrays. For example, the input root has root.val = 1, root.next.val + * = 2, \root.next.next.val = 3, and root.next.next.next = null. The first element output[0] has + * output[0].val = 1, output[0].next = null. The last element output[4] is null, but it's string + * representation as a ListNode is []. Example 2: Input: root = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], k = + * 3 Output: [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]] Explanation: The input has been split into + * consecutive parts with size difference at most 1, and earlier parts are a larger size than the + * later parts. Note: + * + *

The length of root will be in the range [0, 1000]. Each value of a node in the input will be + * an integer in the range [0, 999]. k will be an integer in the range [1, 50]. + * + *

Solution O(N) do a linear scan and split the array by required size. + */ +public class SplitLinkedListInParts { + public static class ListNode { + int val; + ListNode next; + + ListNode(int x) { + val = x; + } + } + + public static void main(String[] args) { + ListNode root = new ListNode(1); + root.next = new ListNode(2); + root.next.next = new ListNode(3); + ListNode[] result = new SplitLinkedListInParts().splitListToParts(root, 5); + System.out.println(result); + } + + public ListNode[] splitListToParts(ListNode root, int k) { + List list = new ArrayList<>(); + while (root != null) { + list.add(root.val); + root = root.next; + } + int tempK = k; + int N = list.size(); + List result = new ArrayList<>(); + ListNode head = new ListNode(-1); + ListNode prev = head; + int i = 0, j = 0; + int count = 0; + int P = N / tempK; + if ((N % tempK) > 0) { + P++; + } + for (; j < N; ) { + if (j - i < P) { + prev.next = new ListNode(list.get(j)); + prev = prev.next; + j++; + count++; + } else { + result.add(head.next); + i = j; + head = new ListNode(-1); + prev = head; + tempK--; + P = (N - count) / tempK; + if (((N - count) % tempK) > 0) { + P++; + } + } + } + result.add(head.next); + while (result.size() < k) { + result.add(null); + } + ListNode[] nodes = new ListNode[result.size()]; + for (int l = 0; l < result.size(); l++) { + nodes[l] = result.get(l); + } + return nodes; + } +} diff --git a/problems/src/linked_list/SwapNodesInPairs.java b/src/main/java/linked_list/SwapNodesInPairs.java similarity index 98% rename from problems/src/linked_list/SwapNodesInPairs.java rename to src/main/java/linked_list/SwapNodesInPairs.java index a74da9a1..66e4a432 100644 --- a/problems/src/linked_list/SwapNodesInPairs.java +++ b/src/main/java/linked_list/SwapNodesInPairs.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package linked_list; /** diff --git a/problems/src/math/AddDigits.java b/src/main/java/math/AddDigits.java similarity index 95% rename from problems/src/math/AddDigits.java rename to src/main/java/math/AddDigits.java index 62a46a3c..2fd67cf4 100644 --- a/problems/src/math/AddDigits.java +++ b/src/main/java/math/AddDigits.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/problems/src/math/AddTwoNumbers.java b/src/main/java/math/AddTwoNumbers.java similarity index 98% rename from problems/src/math/AddTwoNumbers.java rename to src/main/java/math/AddTwoNumbers.java index 89e6a6fb..fcd60431 100644 --- a/problems/src/math/AddTwoNumbers.java +++ b/src/main/java/math/AddTwoNumbers.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/src/main/java/math/Base7.java b/src/main/java/math/Base7.java new file mode 100644 index 00000000..1037a6e4 --- /dev/null +++ b/src/main/java/math/Base7.java @@ -0,0 +1,32 @@ +/* (C) 2024 YourCompanyName */ +package math; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 01/08/2019 Given an integer, return its base 7 string + * representation. + * + *

Example 1: Input: 100 Output: "202" Example 2: Input: -7 Output: "-10" Note: The input will be + * in range of [-1e7, 1e7]. + */ +public class Base7 { + public static void main(String[] args) { + // + } + + public String convertToBase7(int num) { + Integer.toString(7, 7); + if (num == 0) return "0"; + int q = Math.abs(num), r; + StringBuilder sb = new StringBuilder(); + while (q != 0) { + r = q % 7; + sb.append(r); + q /= 7; + } + if (num < 0) { + return "-" + sb.reverse().toString(); + } else return sb.reverse().toString(); + } +} diff --git a/problems/src/math/BulbSwitcherII.java b/src/main/java/math/BulbSwitcherII.java similarity index 97% rename from problems/src/math/BulbSwitcherII.java rename to src/main/java/math/BulbSwitcherII.java index 53196e8d..e7c04b80 100644 --- a/problems/src/math/BulbSwitcherII.java +++ b/src/main/java/math/BulbSwitcherII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/problems/src/math/CountPrimes.java b/src/main/java/math/CountPrimes.java similarity index 96% rename from problems/src/math/CountPrimes.java rename to src/main/java/math/CountPrimes.java index ce212ea9..ee971487 100644 --- a/problems/src/math/CountPrimes.java +++ b/src/main/java/math/CountPrimes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; import java.util.BitSet; diff --git a/problems/src/math/CouplesHoldingHands.java b/src/main/java/math/CouplesHoldingHands.java similarity index 98% rename from problems/src/math/CouplesHoldingHands.java rename to src/main/java/math/CouplesHoldingHands.java index 65bbc71e..6d81c96b 100644 --- a/problems/src/math/CouplesHoldingHands.java +++ b/src/main/java/math/CouplesHoldingHands.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/src/main/java/math/DecodedStringAtIndex.java b/src/main/java/math/DecodedStringAtIndex.java new file mode 100644 index 00000000..357f7947 --- /dev/null +++ b/src/main/java/math/DecodedStringAtIndex.java @@ -0,0 +1,71 @@ +/* (C) 2024 YourCompanyName */ +package math; + +/** + * Created by gouthamvidyapradhan on 21/07/2019 An encoded string S is given. To find and write the + * decoded string to a tape, the encoded string is read one character at a time and the following + * steps are taken: + * + *

If the character read is a letter, that letter is written onto the tape. If the character read + * is a digit (say d), the entire current tape is repeatedly written d-1 more times in total. Now + * for some encoded string S, and an index K, find and return the K-th letter (1 indexed) in the + * decoded string. + * + *

Example 1: + * + *

Input: S = "leet2code3", K = 10 Output: "o" Explanation: The decoded string is + * "leetleetcodeleetleetcodeleetleetcode". The 10th letter in the string is "o". Example 2: + * + *

Input: S = "ha22", K = 5 Output: "h" Explanation: The decoded string is "hahahaha". The 5th + * letter is "h". Example 3: + * + *

Input: S = "a2345678999999999999999", K = 1 Output: "a" Explanation: The decoded string is "a" + * repeated 8301530446056247680 times. The 1st letter is "a". + * + *

Note: + * + *

2 <= S.length <= 100 S will only contain lowercase letters and digits 2 through 9. S starts + * with a letter. 1 <= K <= 10^9 The decoded string is guaranteed to have less than 2^63 letters. + * + *

Solution: General idea is as shown below example: If S = "leet2" and K = 6 the answer is "e" + * which is same as finding answer for K = 2. As soon as the product exceeds the total value of K as + * in this case the product of 4 (leet) x 2 is 8 and 8 clearly exceeds 6 therefore we can reduce K + * to 8 - 6 = 2 and start from the beginning once again. Repeat the same process until we reach the + * answer. + */ +public class DecodedStringAtIndex { + public static void main(String[] args) { + System.out.println( + new DecodedStringAtIndex().decodeAtIndex("a2345678999999999999999", 1000000000)); + } + + public String decodeAtIndex(String S, int K) { + long product = 0; + char lastC = S.charAt(0); + for (int i = 0, l = S.length(); i < l; ) { + char c = S.charAt(i); + if (Character.isLetter(c)) { + lastC = c; + product++; + i++; + if (K == product) break; + } else { + long temp = (product * Integer.parseInt(String.valueOf(c))); + if (temp == K) break; + else { + if (temp > K) { + long x = (K / product); + if ((product * x) == K) break; + K -= (product * x); + i = 0; + product = 0; + } else { + product = temp; + i++; + } + } + } + } + return String.valueOf(lastC); + } +} diff --git a/problems/src/math/ExcelSheetColumnTitle.java b/src/main/java/math/ExcelSheetColumnTitle.java similarity index 96% rename from problems/src/math/ExcelSheetColumnTitle.java rename to src/main/java/math/ExcelSheetColumnTitle.java index e6f9e7e5..9b523996 100644 --- a/problems/src/math/ExcelSheetColumnTitle.java +++ b/src/main/java/math/ExcelSheetColumnTitle.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/problems/src/math/GlobalAndLocalInversions.java b/src/main/java/math/GlobalAndLocalInversions.java similarity index 97% rename from problems/src/math/GlobalAndLocalInversions.java rename to src/main/java/math/GlobalAndLocalInversions.java index eb974f0e..444dca0e 100644 --- a/problems/src/math/GlobalAndLocalInversions.java +++ b/src/main/java/math/GlobalAndLocalInversions.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/src/main/java/math/LargestComponentSizebyCommonFactor.java b/src/main/java/math/LargestComponentSizebyCommonFactor.java new file mode 100644 index 00000000..59df14d8 --- /dev/null +++ b/src/main/java/math/LargestComponentSizebyCommonFactor.java @@ -0,0 +1,161 @@ +/* (C) 2024 YourCompanyName */ +package math; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * Created by gouthamvidyapradhan on 20/08/2019 Given a non-empty array of unique positive integers + * A, consider the following graph: + * + *

There are A.length nodes, labelled A[0] to A[A.length - 1]; There is an edge between A[i] and + * A[j] if and only if A[i] and A[j] share a common factor greater than 1. Return the size of the + * largest connected component in the graph. + * + *

Example 1: + * + *

Input: [4,6,15,35] Output: 4 + * + *

Example 2: + * + *

Input: [20,50,9,63] Output: 2 + * + *

Example 3: + * + *

Input: [2,3,6,7,4,12,21,39] Output: 8 + * + *

Note: + * + *

1 <= A.length <= 20000 1 <= A[i] <= 100000 + * + *

Solution: O(primes upto max[A[i]] x N) Find all the primes upto maximum of A[i] and build + * components (using union-find) by finding all the numbers in A[] which are divisible by each prime + * number - keep track of size of each component and return the size of the largest component. + */ +public class LargestComponentSizebyCommonFactor { + private static class UnionFind { + private int[] p; + private int[] rank; + private int[] size; + + UnionFind(int s) { + this.p = new int[s]; + this.rank = new int[s]; + this.size = new int[s]; + init(); + } + /** Initialize with its same index as its parent */ + private void init() { + for (int i = 0; i < p.length; i++) { + p[i] = i; + size[i] = 1; + } + } + /** + * Find the representative vertex + * + * @param i + * @return + */ + private int findSet(int i) { + if (p[i] != i) { + p[i] = findSet(p[i]); + } + return p[i]; + } + + /** + * Perform union of two vertex + * + * @param i + * @param j + * @return true if union is performed successfully, false otherwise + */ + public boolean union(int i, int j) { + int x = findSet(i); + int y = findSet(j); + if (x != y) { + if (rank[x] > rank[y]) { + p[y] = p[x]; + size[x] = size[x] + size[y]; + } else { + p[x] = p[y]; + size[y] = size[x] + size[y]; + if (rank[x] == rank[y]) { + rank[y]++; // increment the rank + } + } + return true; + } + return false; + } + + /** + * is attached to roof + * + * @param i + * @return + */ + public int size(int i) { + return size[findSet(i)]; + } + } + + public static void main(String[] args) { + int[] A = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + System.out.println(new LargestComponentSizebyCommonFactor().largestComponentSize(A)); + } + + public int largestComponentSize(int[] A) { + int max = 0; + for (int a : A) { + max = Math.max(max, a); + } + UnionFind unionFind = new UnionFind(max + 1); + List primeNums = primes(max, A); + int answer = 1; + for (int p : primeNums) { + int curr = -1; + for (int a : A) { + if ((a % p) == 0) { + if (curr != -1) { + unionFind.union(curr, a); + } else curr = a; + } + } + answer = Math.max(answer, unionFind.size(curr)); + } + return answer; + } + + private List primes(int N, int[] A) { + boolean[] P = new boolean[N + 1]; + int[] pF = new int[N + 1]; + int sqRt = (int) Math.sqrt(N); + for (int i = 2; i <= sqRt; i++) { + if (!P[i]) { + for (int j = 2; ; j++) { + if (i * j > N) break; + P[i * j] = true; + if (pF[i * j] == 0) { + pF[i * j] = i; + } + } + } + } + Map result = new HashMap<>(); + for (int a : A) { + if (a == 1) continue; + int n = pF[a]; + while (n != 0) { + result.putIfAbsent(n, 0); + result.put(n, result.get(n) + 1); + a /= n; + n = pF[a]; + } + result.putIfAbsent(a, 0); + result.put(a, result.get(a) + 1); + } + return result.keySet().stream().filter(x -> result.get(x) > 1).collect(Collectors.toList()); + } +} diff --git a/src/main/java/math/MinimumIndexSumOfTwoLists.java b/src/main/java/math/MinimumIndexSumOfTwoLists.java new file mode 100644 index 00000000..19acde3b --- /dev/null +++ b/src/main/java/math/MinimumIndexSumOfTwoLists.java @@ -0,0 +1,61 @@ +/* (C) 2024 YourCompanyName */ +package math; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 09/10/2019 Suppose Andy and Doris want to choose a restaurant + * for dinner, and they both have a list of favorite restaurants represented by strings. + * + *

You need to help them find out their common interest with the least list index sum. If there + * is a choice tie between answers, output all of them with no order requirement. You could assume + * there always exists an answer. + * + *

Example 1: Input: ["Shogun", "Tapioca Express", "Burger King", "KFC"] ["Piatti", "The Grill at + * Torrey Pines", "Hungry Hunter Steakhouse", "Shogun"] Output: ["Shogun"] Explanation: The only + * restaurant they both like is "Shogun". Example 2: Input: ["Shogun", "Tapioca Express", "Burger + * King", "KFC"] ["KFC", "Shogun", "Burger King"] Output: ["Shogun"] Explanation: The restaurant + * they both like and have the least index sum is "Shogun" with index sum 1 (0+1). Note: The length + * of both lists will be in the range of [1, 1000]. The length of strings in both lists will be in + * the range of [1, 30]. The index is starting from 0 to the list length minus 1. No duplicates in + * both lists. + * + *

Solution O(N) Maintain a hashmap of restaurant_name with index for one of the list. In the + * first iteration calculate the minimum of sum of indices and in the second iteration add the + * restaurant name to the list if any sum of indices equals the minimum. + */ +public class MinimumIndexSumOfTwoLists { + public static void main(String[] args) { + // + } + + public String[] findRestaurant(String[] list1, String[] list2) { + Map index = new HashMap<>(); + for (int i = 0; i < list2.length; i++) { + String s = list2[i]; + index.put(s, i); + } + int min = Integer.MAX_VALUE; + List list = new ArrayList<>(); + for (int i = 0; i < list1.length; i++) { + if (index.containsKey(list1[i])) { + if (i + index.get(list1[i]) <= min) { + min = i + index.get(list1[i]); + } + } + } + for (int i = 0; i < list1.length; i++) { + if (index.containsKey(list1[i])) { + if (i + index.get(list1[i]) == min) { + list.add(list1[i]); + } + } + } + String[] ans = new String[list.size()]; + int i = 0; + for (String s : list) { + ans[i++] = s; + } + return ans; + } +} diff --git a/src/main/java/math/NthDigit.java b/src/main/java/math/NthDigit.java new file mode 100644 index 00000000..eb02406d --- /dev/null +++ b/src/main/java/math/NthDigit.java @@ -0,0 +1,28 @@ +/* (C) 2024 YourCompanyName */ +package math; + +/** Created by gouthamvidyapradhan on 05/11/2019 */ +public class NthDigit { + public static void main(String[] args) { + System.out.println(new NthDigit().findNthDigit(1000000000)); + } + + public int findNthDigit(int n) { + if (n >= 1 && n <= 9) return n; + long sum = 0L; + for (int i = 0; ; i++) { + long pow = (9 * (new Double(Math.pow(10, i)).longValue())) * (i + 1); + sum += pow; + if (sum >= n) { + long diff = (long) n - (sum - pow); + long num = diff / (i + 1); + long mod = diff % (i + 1); + long result = new Double(Math.pow(10, i)).intValue() + (num - 1) + (mod > 0 ? 1 : 0); + String resultStr = String.valueOf(result); + return (mod == 0) + ? Integer.parseInt(String.valueOf(resultStr.charAt(resultStr.length() - 1))) + : Integer.parseInt(String.valueOf(resultStr.charAt((int) mod - 1))); + } + } + } +} diff --git a/problems/src/math/NthMagicalNumber.java b/src/main/java/math/NthMagicalNumber.java similarity index 98% rename from problems/src/math/NthMagicalNumber.java rename to src/main/java/math/NthMagicalNumber.java index c25560b6..9f957863 100644 --- a/problems/src/math/NthMagicalNumber.java +++ b/src/main/java/math/NthMagicalNumber.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; import java.math.BigInteger; diff --git a/src/main/java/math/ProjectionAreaOf3DShapes.java b/src/main/java/math/ProjectionAreaOf3DShapes.java new file mode 100644 index 00000000..1416f844 --- /dev/null +++ b/src/main/java/math/ProjectionAreaOf3DShapes.java @@ -0,0 +1,74 @@ +/* (C) 2024 YourCompanyName */ +package math; +/** + * Created by gouthamvidyapradhan on 09/05/2019 + * + *

On a N * N grid, we place some 1 * 1 * 1 cubes that are axis-aligned with the x, y, and z + * axes. + * + *

Each value v = grid[i][j] represents a tower of v cubes placed on top of grid cell (i, j). + * + *

Now we view the projection of these cubes onto the xy, yz, and zx planes. + * + *

A projection is like a shadow, that maps our 3 dimensional figure to a 2 dimensional plane. + * + *

Here, we are viewing the "shadow" when looking at the cubes from the top, the front, and the + * side. + * + *

Return the total area of all three projections. + * + *

Example 1: + * + *

Input: [[2]] Output: 5 Example 2: + * + *

Input: [[1,2],[3,4]] Output: 17 Explanation: Here are the three projections ("shadows") of the + * shape made with each axis-aligned plane. + * + *

Example 3: + * + *

Input: [[1,0],[0,2]] Output: 8 Example 4: + * + *

Input: [[1,1,1],[1,0,1],[1,1,1]] Output: 14 Example 5: + * + *

Input: [[2,2,2],[2,1,2],[2,2,2]] Output: 21 + * + *

Note: + * + *

1 <= grid.length = grid[0].length <= 50 0 <= grid[i][j] <= 50 + * + *

Solution O(N x N) project the view on all three different planes. For top view its pretty + * simple because area of each cube is just 1 * 1, for all other planes take the maximum value of + * each grid. Sum up values on each planes + */ +public class ProjectionAreaOf3DShapes { + public static void main(String[] args) { + // + } + + public int projectionArea(int[][] grid) { + int area = 0; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid.length; j++) { + area += (grid[i][j] > 0 ? 1 : 0); + } + } + + for (int i = 0; i < grid.length; i++) { + int max = 0; + for (int j = 0; j < grid[0].length; j++) { + max = Math.max(max, grid[i][j]); + } + area += max; + } + + for (int i = 0; i < grid[0].length; i++) { + int max = 0; + for (int j = 0; j < grid.length; j++) { + max = Math.max(max, grid[j][i]); + } + area += max; + } + + return area; + } +} diff --git a/src/main/java/math/RangeAdditionII.java b/src/main/java/math/RangeAdditionII.java new file mode 100644 index 00000000..17f197e4 --- /dev/null +++ b/src/main/java/math/RangeAdditionII.java @@ -0,0 +1,45 @@ +/* (C) 2024 YourCompanyName */ +package math; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 09/10/2019 Given an m * n matrix M initialized with all 0's and + * several update operations. + * + *

Operations are represented by a 2D array, and each operation is represented by an array with + * two positive integers a and b, which means M[i][j] should be added by one for all 0 <= i < a and + * 0 <= j < b. + * + *

You need to count and return the number of maximum integers in the matrix after performing all + * the operations. + * + *

Example 1: Input: m = 3, n = 3 operations = [[2,2],[3,3]] Output: 4 Explanation: Initially, M + * = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] + * + *

After performing [2,2], M = [[1, 1, 0], [1, 1, 0], [0, 0, 0]] + * + *

After performing [3,3], M = [[2, 2, 1], [2, 2, 1], [1, 1, 1]] + * + *

So the maximum integer in M is 2, and there are four of it in M. So return 4. Note: The range + * of m and n is [1,40000]. The range of a is [1,m], and the range of b is [1,n]. The range of + * operations size won't exceed 10,000. + * + *

Solution: O(N) where N is the number of operations. For every operation, keep track of minimum + * of each row and column and return the product of minR x minC + */ +public class RangeAdditionII { + public static void main(String[] args) { + // + } + + public int maxCount(int m, int n, int[][] ops) { + int minR = m; + int minC = n; + for (int[] v : ops) { + minR = Math.min(minR, v[0]); + minC = Math.min(minC, v[1]); + } + return minR * minC; + } +} diff --git a/problems/src/math/ReachingPoints.java b/src/main/java/math/ReachingPoints.java similarity index 98% rename from problems/src/math/ReachingPoints.java rename to src/main/java/math/ReachingPoints.java index 2297a7c8..36036e4c 100644 --- a/problems/src/math/ReachingPoints.java +++ b/src/main/java/math/ReachingPoints.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/src/main/java/math/RectangleOverlap.java b/src/main/java/math/RectangleOverlap.java new file mode 100644 index 00000000..dd8d32b2 --- /dev/null +++ b/src/main/java/math/RectangleOverlap.java @@ -0,0 +1,37 @@ +/* (C) 2024 YourCompanyName */ +package math; + +/** + * Created by gouthamvidyapradhan on 30/11/2019 A rectangle is represented as a list [x1, y1, x2, + * y2], where (x1, y1) are the coordinates of its bottom-left corner, and (x2, y2) are the + * coordinates of its top-right corner. + * + *

Two rectangles overlap if the area of their intersection is positive. To be clear, two + * rectangles that only touch at the corner or edges do not overlap. + * + *

Given two (axis-aligned) rectangles, return whether they overlap. + * + *

Example 1: + * + *

Input: rec1 = [0,0,2,2], rec2 = [1,1,3,3] Output: true Example 2: + * + *

Input: rec1 = [0,0,1,1], rec2 = [1,0,2,1] Output: false Notes: + * + *

Both rectangles rec1 and rec2 are lists of 4 integers. All coordinates in rectangles will be + * between -10^9 and 10^9. + */ +public class RectangleOverlap { + public static void main(String[] args) { + int[] A = {0, 0, 2, 2}; + int[] B = {1, 1, 3, 3}; + System.out.println(new RectangleOverlap().isRectangleOverlap(A, B)); + } + + public boolean isRectangleOverlap(int[] rec1, int[] rec2) { + boolean x = + ((rec1[0] >= rec2[0] && rec1[0] < rec2[2]) || (rec2[0] >= rec1[0] && rec2[0] < rec1[2])); + boolean y = + ((rec1[1] >= rec2[1] && rec1[1] < rec2[3]) || (rec2[1] >= rec1[1] && rec2[1] < rec1[3])); + return x && y; + } +} diff --git a/problems/src/math/RomanToInteger.java b/src/main/java/math/RomanToInteger.java similarity index 97% rename from problems/src/math/RomanToInteger.java rename to src/main/java/math/RomanToInteger.java index 6e45b23c..273ec3c4 100644 --- a/problems/src/math/RomanToInteger.java +++ b/src/main/java/math/RomanToInteger.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; import java.util.HashMap; diff --git a/problems/src/math/RotateFunction.java b/src/main/java/math/RotateFunction.java similarity index 98% rename from problems/src/math/RotateFunction.java rename to src/main/java/math/RotateFunction.java index f3abf97b..c634ea54 100644 --- a/problems/src/math/RotateFunction.java +++ b/src/main/java/math/RotateFunction.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/src/main/java/math/SmallestRangeI.java b/src/main/java/math/SmallestRangeI.java new file mode 100644 index 00000000..fa5e1bb0 --- /dev/null +++ b/src/main/java/math/SmallestRangeI.java @@ -0,0 +1,44 @@ +/* (C) 2024 YourCompanyName */ +package math; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 22/08/2019 Given an array A of integers, for each integer A[i] + * we may choose any x with -K <= x <= K, and add x to A[i]. + * + *

After this process, we have some array B. + * + *

Return the smallest possible difference between the maximum value of B and the minimum value + * of B. + * + *

Example 1: + * + *

Input: A = [1], K = 0 Output: 0 Explanation: B = [1] Example 2: + * + *

Input: A = [0,10], K = 2 Output: 6 Explanation: B = [2,8] Example 3: + * + *

Input: A = [1,3,6], K = 3 Output: 0 Explanation: B = [3,3,3] or B = [4,4,4] + * + *

Note: + * + *

1 <= A.length <= 10000 0 <= A[i] <= 10000 0 <= K <= 10000 + */ +public class SmallestRangeI { + public static void main(String[] args) { + // + } + + public int smallestRangeI(int[] A, int K) { + Arrays.sort(A); + if (A.length == 0 || A.length == 1) return 0; + else { + int low = A[0]; + int high = A[A.length - 1]; + int l = low + (K); + int r = high - (K); + if (r > l) return r - l; + else return 0; + } + } +} diff --git a/problems/src/math/SolveTheEquation.java b/src/main/java/math/SolveTheEquation.java similarity index 98% rename from problems/src/math/SolveTheEquation.java rename to src/main/java/math/SolveTheEquation.java index c17e48c7..b829ad6c 100644 --- a/problems/src/math/SolveTheEquation.java +++ b/src/main/java/math/SolveTheEquation.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/problems/src/math/SquirrelSimulation.java b/src/main/java/math/SquirrelSimulation.java similarity index 98% rename from problems/src/math/SquirrelSimulation.java rename to src/main/java/math/SquirrelSimulation.java index a2a681f1..4b40f2f3 100644 --- a/problems/src/math/SquirrelSimulation.java +++ b/src/main/java/math/SquirrelSimulation.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; /** diff --git a/src/main/java/math/SuperWashingMachines.java b/src/main/java/math/SuperWashingMachines.java new file mode 100644 index 00000000..35fa07d5 --- /dev/null +++ b/src/main/java/math/SuperWashingMachines.java @@ -0,0 +1,56 @@ +/* (C) 2024 YourCompanyName */ +package math; + +import java.util.Arrays; + +/** + * Created by gouthamvidyapradhan on 30/01/2020 You have n super washing machines on a line. + * Initially, each washing machine has some dresses or is empty. + * + *

For each move, you could choose any m (1 ≤ m ≤ n) washing machines, and pass one dress of each + * washing machine to one of its adjacent washing machines at the same time . + * + *

Given an integer array representing the number of dresses in each washing machine from left to + * right on the line, you should find the minimum number of moves to make all the washing machines + * have the same number of dresses. If it is not possible to do it, return -1. + * + *

Example1 + * + *

Input: [1,0,5] + * + *

Output: 3 + * + *

Explanation: 1st move: 1 0 <-- 5 => 1 1 4 2nd move: 1 <-- 1 <-- 4 => 2 1 3 3rd move: 2 1 <-- 3 + * => 2 2 2 Example2 + * + *

Input: [0,3,0] + * + *

Output: 2 + * + *

Explanation: 1st move: 0 <-- 3 0 => 1 2 0 2nd move: 1 2 --> 0 => 1 1 1 Example3 + * + *

Input: [0,2,0] + * + *

Output: -1 + * + *

Explanation: It's impossible to make all the three washing machines have the same number of + * dresses. Note: The range of n is [1, 10000]. The range of dresses number in a super washing + * machine is [0, 1e5]. + */ +public class SuperWashingMachines { + public static void main(String[] args) { + // + } + + public int findMinMoves(int[] machines) { + long sum = Arrays.stream(machines).asLongStream().sum(); + if (((sum / machines.length) < 0) || ((sum % machines.length) != 0)) return -1; + int n = (int) (sum / machines.length); + int count = 0, moves = Integer.MIN_VALUE; + for (int i = 0; i < machines.length; i++) { + count += (machines[i] - n); + moves = Math.max(moves, Math.max(Math.abs(count), (machines[i] - n))); + } + return moves; + } +} diff --git a/problems/src/math/WaterAndJugProblem.java b/src/main/java/math/WaterAndJugProblem.java similarity index 97% rename from problems/src/math/WaterAndJugProblem.java rename to src/main/java/math/WaterAndJugProblem.java index fabc0ada..dfc239b0 100644 --- a/problems/src/math/WaterAndJugProblem.java +++ b/src/main/java/math/WaterAndJugProblem.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package math; import java.math.BigInteger; diff --git a/problems/src/reservoir_sampling/RandomPickIndex.java b/src/main/java/reservoir_sampling/RandomPickIndex.java similarity index 98% rename from problems/src/reservoir_sampling/RandomPickIndex.java rename to src/main/java/reservoir_sampling/RandomPickIndex.java index 519ecf1b..68d6e750 100644 --- a/problems/src/reservoir_sampling/RandomPickIndex.java +++ b/src/main/java/reservoir_sampling/RandomPickIndex.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package reservoir_sampling; import java.util.Random; diff --git a/problems/src/stack/BasicCalculator.java b/src/main/java/stack/BasicCalculator.java similarity index 98% rename from problems/src/stack/BasicCalculator.java rename to src/main/java/stack/BasicCalculator.java index 165dc496..5338b314 100644 --- a/problems/src/stack/BasicCalculator.java +++ b/src/main/java/stack/BasicCalculator.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; import java.util.Stack; diff --git a/problems/src/stack/DecodeString.java b/src/main/java/stack/DecodeString.java similarity index 98% rename from problems/src/stack/DecodeString.java rename to src/main/java/stack/DecodeString.java index 39d021cc..1e03fb91 100644 --- a/problems/src/stack/DecodeString.java +++ b/src/main/java/stack/DecodeString.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; import java.util.Stack; diff --git a/src/main/java/stack/DecodedStringAtIndex.java b/src/main/java/stack/DecodedStringAtIndex.java new file mode 100644 index 00000000..47f8d3f8 --- /dev/null +++ b/src/main/java/stack/DecodedStringAtIndex.java @@ -0,0 +1,69 @@ +/* (C) 2024 YourCompanyName */ +package stack; + +import java.util.Stack; + +/** Created by gouthamvidyapradhan on 12/05/2019 */ +public class DecodedStringAtIndex { + + public static void main(String[] args) { + System.out.println(new DecodedStringAtIndex().decodeAtIndex("ha22", 5)); + } + + class Node { + String S; + long count; + int multiple; + + Node(String S, long count, int multiple) { + this.S = S; + this.count = count; + this.multiple = multiple; + } + } + + public String decodeAtIndex(String S, int K) { + Stack stack = new Stack<>(); + StringBuilder sb = new StringBuilder(); + char prev = ' '; + for (char c : S.toCharArray()) { + if (Character.isDigit(c)) { + String currStr = sb.toString(); + long len = 0L; + if (!stack.isEmpty()) { + len = stack.peek().count * stack.peek().multiple; + } + stack.push( + new Node(currStr, len + (currStr.length()), Integer.parseInt(String.valueOf(c)))); + if (((len + (currStr.length())) * Integer.parseInt(String.valueOf(c))) >= K) { + break; + } + prev = c; + } else { + if (Character.isDigit(prev)) { + sb = new StringBuilder(); + } + sb.append(c); + prev = c; + } + } + while (!stack.isEmpty()) { + Node top = stack.peek(); + long l = top.count; + if (K <= l) { + return String.valueOf(top.S.charAt((int) l - K - 1)); + } + long mod = (K % l); + if (mod == 0) { + return String.valueOf(top.S.charAt(top.S.length() - 1)); + } + if (l - top.S.length() < mod) { + long i = l - mod; + return String.valueOf(top.S.charAt(top.S.length() - (int) i - 1)); + } else { + stack.pop(); + } + } + return ""; + } +} diff --git a/problems/src/stack/ExclusiveTimeOfFunctions.java b/src/main/java/stack/ExclusiveTimeOfFunctions.java similarity index 99% rename from problems/src/stack/ExclusiveTimeOfFunctions.java rename to src/main/java/stack/ExclusiveTimeOfFunctions.java index bf0f8cec..23890ad6 100644 --- a/problems/src/stack/ExclusiveTimeOfFunctions.java +++ b/src/main/java/stack/ExclusiveTimeOfFunctions.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; import java.util.ArrayList; diff --git a/problems/src/stack/LargestRectangleInHistogram.java b/src/main/java/stack/LargestRectangleInHistogram.java similarity index 98% rename from problems/src/stack/LargestRectangleInHistogram.java rename to src/main/java/stack/LargestRectangleInHistogram.java index aff156a4..9c53b2e6 100644 --- a/problems/src/stack/LargestRectangleInHistogram.java +++ b/src/main/java/stack/LargestRectangleInHistogram.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; import java.util.Stack; diff --git a/problems/src/stack/LongestValidParentheses.java b/src/main/java/stack/LongestValidParentheses.java similarity index 98% rename from problems/src/stack/LongestValidParentheses.java rename to src/main/java/stack/LongestValidParentheses.java index f4b6bb38..3535b33d 100644 --- a/problems/src/stack/LongestValidParentheses.java +++ b/src/main/java/stack/LongestValidParentheses.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; import java.util.*; diff --git a/problems/src/stack/MaximalRectangle.java b/src/main/java/stack/MaximalRectangle.java similarity index 98% rename from problems/src/stack/MaximalRectangle.java rename to src/main/java/stack/MaximalRectangle.java index 2a710592..8d56347e 100644 --- a/problems/src/stack/MaximalRectangle.java +++ b/src/main/java/stack/MaximalRectangle.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; import java.util.Stack; diff --git a/problems/src/stack/MinStack.java b/src/main/java/stack/MinStack.java similarity index 98% rename from problems/src/stack/MinStack.java rename to src/main/java/stack/MinStack.java index 512846f5..07948d21 100644 --- a/problems/src/stack/MinStack.java +++ b/src/main/java/stack/MinStack.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; import java.util.Stack; diff --git a/problems/src/stack/MyQueue.java b/src/main/java/stack/MyQueue.java similarity index 98% rename from problems/src/stack/MyQueue.java rename to src/main/java/stack/MyQueue.java index a5547f48..d15ba1f7 100644 --- a/problems/src/stack/MyQueue.java +++ b/src/main/java/stack/MyQueue.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; import java.util.Stack; diff --git a/src/main/java/stack/StudentAttendanceRecordII.java b/src/main/java/stack/StudentAttendanceRecordII.java new file mode 100644 index 00000000..753d2f35 --- /dev/null +++ b/src/main/java/stack/StudentAttendanceRecordII.java @@ -0,0 +1,58 @@ +/* (C) 2024 YourCompanyName */ +package stack; + +/** + * Created by gouthamvidyapradhan on 10/05/2019 Given a positive integer n, return the number of all + * possible attendance records with length n, which will be regarded as rewardable. The answer may + * be very large, return it after mod 109 + 7. + * + *

A student attendance record is a string that only contains the following three characters: + * + *

'A' : Absent. 'L' : Late. 'P' : Present. A record is regarded as rewardable if it doesn't + * contain more than one 'A' (absent) or more than two continuous 'L' (late). + * + *

Example 1: Input: n = 2 Output: 8 Explanation: There are 8 records with length 2 will be + * regarded as rewardable: "PP" , "AP", "PA", "LP", "PL", "AL", "LA", "LL" Only "AA" won't be + * regarded as rewardable owing to more than one absent times. Note: The value of n won't exceed + * 100,000. + * + *

Solution O(N): Start with a base case for a single days attendance record which is 'A', 'P' + * and 'L' so, in total there are three possible records. Now, keep adding a new possible attendance + * record to all the above three possibilities. Now, since we cannot have a combination such as 'AA' + * we can maintain a variable with count of combinations which already has one 'A' in it and + * similarly maintain a combination which already has two 'L's it it, only one 'L' and only 'P' in + * it - keep incrementing the count of each of the variables when a new combination belongs to any + * one of this. Continue upto n and sum up the all the variables and return the answer % 10 ^ 9 + 7 + */ +public class StudentAttendanceRecordII { + public static void main(String[] args) { + System.out.println(new StudentAttendanceRecordII().checkRecord(5)); + } + + int mod = 1000000007; + + public int checkRecord(int n) { + if (n == 0) return 1; + int P = 1; + int A = 1; + int LA = 0, LX = 1, LLA = 0, LLX = 0; + for (int i = n - 1; i > 0; i--) { + int temP = (((P + LX) % mod) + LLX) % mod; + int tempLX = P; + int tempLA = A; + int tempLLX = LX; + int tempLLA = LA; + int tempA = + ((((((((((P + LX) % mod) + LLX) % mod) + A) % mod) + LA) % mod) + LLA) + % mod); // A + LA + LLA + // is because we can add P to each of these forming PA, PLA and PLLA + P = temP; + LX = tempLX; + LA = tempLA; + LLX = tempLLX; + LLA = tempLLA; + A = tempA; + } + return ((((((((((P + LX) % mod) + LA) % mod) + LLX) % mod) + LLA) % mod) + A) % mod); + } +} diff --git a/problems/src/stack/ValidParentheses.java b/src/main/java/stack/ValidParentheses.java similarity index 97% rename from problems/src/stack/ValidParentheses.java rename to src/main/java/stack/ValidParentheses.java index d9d77afd..fbe69062 100644 --- a/problems/src/stack/ValidParentheses.java +++ b/src/main/java/stack/ValidParentheses.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package stack; import java.util.HashMap; diff --git a/problems/src/string/AddBinary.java b/src/main/java/string/AddBinary.java similarity index 97% rename from problems/src/string/AddBinary.java rename to src/main/java/string/AddBinary.java index 9f813def..5eb80046 100644 --- a/problems/src/string/AddBinary.java +++ b/src/main/java/string/AddBinary.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/problems/src/string/CompareVersionNumbers.java b/src/main/java/string/CompareVersionNumbers.java similarity index 98% rename from problems/src/string/CompareVersionNumbers.java rename to src/main/java/string/CompareVersionNumbers.java index bffac314..c45f221e 100644 --- a/problems/src/string/CompareVersionNumbers.java +++ b/src/main/java/string/CompareVersionNumbers.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.StringTokenizer; diff --git a/problems/src/string/CountAndSay.java b/src/main/java/string/CountAndSay.java similarity index 97% rename from problems/src/string/CountAndSay.java rename to src/main/java/string/CountAndSay.java index 55536426..e50983a4 100644 --- a/problems/src/string/CountAndSay.java +++ b/src/main/java/string/CountAndSay.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/problems/src/string/ExcelSheetColumnNumber.java b/src/main/java/string/ExcelSheetColumnNumber.java similarity index 96% rename from problems/src/string/ExcelSheetColumnNumber.java rename to src/main/java/string/ExcelSheetColumnNumber.java index 889aa710..f0ecd7e2 100644 --- a/problems/src/string/ExcelSheetColumnNumber.java +++ b/src/main/java/string/ExcelSheetColumnNumber.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/problems/src/string/FindTheClosestPalindrome.java b/src/main/java/string/FindTheClosestPalindrome.java similarity index 99% rename from problems/src/string/FindTheClosestPalindrome.java rename to src/main/java/string/FindTheClosestPalindrome.java index f9c3e096..86459c41 100644 --- a/problems/src/string/FindTheClosestPalindrome.java +++ b/src/main/java/string/FindTheClosestPalindrome.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/FindWordsThatCanBeFormedbyCharacters.java b/src/main/java/string/FindWordsThatCanBeFormedbyCharacters.java new file mode 100644 index 00000000..6a16bf0b --- /dev/null +++ b/src/main/java/string/FindWordsThatCanBeFormedbyCharacters.java @@ -0,0 +1,64 @@ +/* (C) 2024 YourCompanyName */ +package string; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 28/08/2019 You are given an array of strings words and a string + * chars. + * + *

A string is good if it can be formed by characters from chars (each character can only be used + * once). + * + *

Return the sum of lengths of all good strings in words. + * + *

Example 1: + * + *

Input: words = ["cat","bt","hat","tree"], chars = "atach" Output: 6 Explanation: The strings + * that can be formed are "cat" and "hat" so the answer is 3 + 3 = 6. Example 2: + * + *

Input: words = ["hello","world","leetcode"], chars = "welldonehoneyr" Output: 10 Explanation: + * The strings that can be formed are "hello" and "world" so the answer is 5 + 5 = 10. + * + *

Note: + * + *

1 <= words.length <= 1000 1 <= words[i].length, chars.length <= 100 All strings contain + * lowercase English letters only. + * + *

Solution Do a linear check for each of the words and each of the characters and sum up the + * lengths. Keep a hashmap of key-values to avoid picking the same character again. + */ +public class FindWordsThatCanBeFormedbyCharacters { + public static void main(String[] args) { + String[] A = {"cat", "bt", "hat", "problems/src/tree"}; + String chars = "atach"; + new FindWordsThatCanBeFormedbyCharacters().countCharacters(A, chars); + } + + public int countCharacters(String[] words, String chars) { + Map countMap = new HashMap<>(); + for (char c : chars.toCharArray()) { + countMap.putIfAbsent(c, 0); + countMap.put(c, countMap.get(c) + 1); + } + int ans = 0; + for (String s : words) { + Map subMap = new HashMap<>(); + for (char c : s.toCharArray()) { + subMap.putIfAbsent(c, 0); + subMap.put(c, subMap.get(c) + 1); + } + boolean possible = true; + for (char k : subMap.keySet()) { + if (!countMap.containsKey(k) || subMap.get(k) > countMap.get(k)) { + possible = false; + break; + } + } + if (possible) { + ans += s.length(); + } + } + return ans; + } +} diff --git a/problems/src/string/FirstUniqueCharacterInAString.java b/src/main/java/string/FirstUniqueCharacterInAString.java similarity index 96% rename from problems/src/string/FirstUniqueCharacterInAString.java rename to src/main/java/string/FirstUniqueCharacterInAString.java index 13e9a8c5..9eabdc6a 100644 --- a/problems/src/string/FirstUniqueCharacterInAString.java +++ b/src/main/java/string/FirstUniqueCharacterInAString.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/problems/src/string/ImplementStrStr.java b/src/main/java/string/ImplementStrStr.java similarity index 97% rename from problems/src/string/ImplementStrStr.java rename to src/main/java/string/ImplementStrStr.java index 11349152..a2e52a32 100644 --- a/problems/src/string/ImplementStrStr.java +++ b/src/main/java/string/ImplementStrStr.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/problems/src/string/IsomorphicStrings.java b/src/main/java/string/IsomorphicStrings.java similarity index 98% rename from problems/src/string/IsomorphicStrings.java rename to src/main/java/string/IsomorphicStrings.java index f9c44de5..5956e51d 100644 --- a/problems/src/string/IsomorphicStrings.java +++ b/src/main/java/string/IsomorphicStrings.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.HashMap; diff --git a/problems/src/string/KeyboardRow.java b/src/main/java/string/KeyboardRow.java similarity index 97% rename from problems/src/string/KeyboardRow.java rename to src/main/java/string/KeyboardRow.java index f91ff886..ab25ecfe 100644 --- a/problems/src/string/KeyboardRow.java +++ b/src/main/java/string/KeyboardRow.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** * Created by gouthamvidyapradhan on 09/04/2019 diff --git a/problems/src/string/LongestCommonPrefix.java b/src/main/java/string/LongestCommonPrefix.java similarity index 96% rename from problems/src/string/LongestCommonPrefix.java rename to src/main/java/string/LongestCommonPrefix.java index 4d220ccf..f6ec92c0 100644 --- a/problems/src/string/LongestCommonPrefix.java +++ b/src/main/java/string/LongestCommonPrefix.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/problems/src/string/LongestPalindrome.java b/src/main/java/string/LongestPalindrome.java similarity index 97% rename from problems/src/string/LongestPalindrome.java rename to src/main/java/string/LongestPalindrome.java index 9c6f69bf..5e90a731 100644 --- a/problems/src/string/LongestPalindrome.java +++ b/src/main/java/string/LongestPalindrome.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** * Created by gouthamvidyapradhan on 20/03/2019 Given a string which consists of lowercase or diff --git a/problems/src/string/LongestWordInDictonary.java b/src/main/java/string/LongestWordInDictonary.java similarity index 98% rename from problems/src/string/LongestWordInDictonary.java rename to src/main/java/string/LongestWordInDictonary.java index 85968ef0..e0ab0776 100644 --- a/problems/src/string/LongestWordInDictonary.java +++ b/src/main/java/string/LongestWordInDictonary.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.*; diff --git a/src/main/java/string/MinimumAddtoMakeParenthesesValid.java b/src/main/java/string/MinimumAddtoMakeParenthesesValid.java new file mode 100644 index 00000000..eaa5cb7b --- /dev/null +++ b/src/main/java/string/MinimumAddtoMakeParenthesesValid.java @@ -0,0 +1,54 @@ +/* (C) 2024 YourCompanyName */ +package string; + +/** + * Created by gouthamvidyapradhan on 20/08/2019 Given a string S of '(' and ')' parentheses, we add + * the minimum number of parentheses ( '(' or ')', and in any positions ) so that the resulting + * parentheses string is valid. + * + *

Formally, a parentheses string is valid if and only if: + * + *

It is the empty string, or It can be written as AB (A concatenated with B), where A and B are + * valid strings, or It can be written as (A), where A is a valid string. Given a parentheses + * string, return the minimum number of parentheses we must add to make the resulting string valid. + * + *

Example 1: + * + *

Input: "())" Output: 1 Example 2: + * + *

Input: "(((" Output: 3 Example 3: + * + *

Input: "()" Output: 0 Example 4: + * + *

Input: "()))((" Output: 4 + * + *

Note: + * + *

S.length <= 1000 S only consists of '(' and ')' characters. + * + *

Solution O(N) Keep track of count of open parentheses, when ever a closed parentheses appear + * if the count of open parentheses is greater than 0 then decrement this value (identifying that + * there is a matching parentheses already), if the count is 0 then there is a miss match with + * parentheses and hence add one to the result. The final answer is the total of result + open + * parentheses + */ +public class MinimumAddtoMakeParenthesesValid { + public static void main(String[] args) { + System.out.println(new MinimumAddtoMakeParenthesesValid().minAddToMakeValid("()))((")); + } + + public int minAddToMakeValid(String S) { + int result = 0; + int open = 0; + for (char c : S.toCharArray()) { + if (c == '(') { + open++; + } else if (c == ')') { + if (open > 0) { + open--; + } else result++; + } + } + return result + open; + } +} diff --git a/problems/src/string/MonotoneIncreasingDigits.java b/src/main/java/string/MonotoneIncreasingDigits.java similarity index 98% rename from problems/src/string/MonotoneIncreasingDigits.java rename to src/main/java/string/MonotoneIncreasingDigits.java index e354b7a1..238ba12f 100644 --- a/problems/src/string/MonotoneIncreasingDigits.java +++ b/src/main/java/string/MonotoneIncreasingDigits.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/problems/src/string/MultiplyStrings.java b/src/main/java/string/MultiplyStrings.java similarity index 98% rename from problems/src/string/MultiplyStrings.java rename to src/main/java/string/MultiplyStrings.java index 5d98ddc7..cce90724 100644 --- a/problems/src/string/MultiplyStrings.java +++ b/src/main/java/string/MultiplyStrings.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/problems/src/string/NumberOfMatchingSubsequences.java b/src/main/java/string/NumberOfMatchingSubsequences.java similarity index 97% rename from problems/src/string/NumberOfMatchingSubsequences.java rename to src/main/java/string/NumberOfMatchingSubsequences.java index 1fb85193..a873117b 100644 --- a/problems/src/string/NumberOfMatchingSubsequences.java +++ b/src/main/java/string/NumberOfMatchingSubsequences.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/problems/src/string/OneEditDistance.java b/src/main/java/string/OneEditDistance.java similarity index 97% rename from problems/src/string/OneEditDistance.java rename to src/main/java/string/OneEditDistance.java index b06af63e..657391c4 100644 --- a/problems/src/string/OneEditDistance.java +++ b/src/main/java/string/OneEditDistance.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/problems/src/string/PermutationInString.java b/src/main/java/string/PermutationInString.java similarity index 98% rename from problems/src/string/PermutationInString.java rename to src/main/java/string/PermutationInString.java index 3a908c28..b9998019 100644 --- a/problems/src/string/PermutationInString.java +++ b/src/main/java/string/PermutationInString.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/PushDominoes.java b/src/main/java/string/PushDominoes.java new file mode 100644 index 00000000..2514d9ae --- /dev/null +++ b/src/main/java/string/PushDominoes.java @@ -0,0 +1,76 @@ +/* (C) 2024 YourCompanyName */ +package string; + +/** + * Created by gouthamvidyapradhan on 24/07/2019 There are N dominoes in a line, and we place each + * domino vertically upright. + * + *

In the beginning, we simultaneously push some of the dominoes either to the left or to the + * right. + * + *

After each second, each domino that is falling to the left pushes the adjacent domino on the + * left. + * + *

Similarly, the dominoes falling to the right push their adjacent dominoes standing on the + * right. + * + *

When a vertical domino has dominoes falling on it from both sides, it stays still due to the + * balance of the forces. + * + *

For the purposes of this question, we will consider that a falling domino expends no + * additional force to a falling or already fallen domino. + * + *

Given a string "S" representing the initial state. S[i] = 'L', if the i-th domino has been + * pushed to the left; S[i] = 'R', if the i-th domino has been pushed to the right; S[i] = '.', if + * the i-th domino has not been pushed. + * + *

Return a string representing the final state. + * + *

Example 1: + * + *

Input: ".L.R...LR..L.." Output: "LL.RR.LLRRLL.." Example 2: + * + *

Input: "RR.L" Output: "RR.L" Explanation: The first domino expends no additional force on the + * second domino. Note: + * + *

0 <= N <= 10^5 String dominoes contains only 'L', 'R' and '.' Solution: O(N) + */ +public class PushDominoes { + public static void main(String[] args) { + System.out.println(new PushDominoes().pushDominoes("RR.L")); + } + + public String pushDominoes(String dominoes) { + int R = -1, L = -1; + char[] A = dominoes.toCharArray(); + for (int i = 0; i < A.length; i++) { + if (A[i] == 'L') { + if (R > L) { + int d = (i - R); + int st; + st = R + d / 2; + if ((d % 2) == 0) { + A[st] = '.'; + } + for (int j = st + 1; j < i; j++) { + A[j] = 'L'; + } + } else { + for (int j = (L == -1 ? 0 : L); j < i; j++) { + A[j] = 'L'; + } + } + L = i; + } else { + if (A[i] == 'R') { + R = i; + } else { + if (R > L) { + A[i] = 'R'; + } + } + } + } + return String.valueOf(A); + } +} diff --git a/src/main/java/string/ReconstructOriginalDigitsFromEnglish.java b/src/main/java/string/ReconstructOriginalDigitsFromEnglish.java new file mode 100644 index 00000000..92efa05d --- /dev/null +++ b/src/main/java/string/ReconstructOriginalDigitsFromEnglish.java @@ -0,0 +1,97 @@ +/* (C) 2024 YourCompanyName */ +package string; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 04/06/2019 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" Example 2: Input: "fviefuro" + * + *

Output: "45" + * + *

Solution: O(N) General idea is to note some unique characters in english representation of a + * digit such as 'x' 'x' can occur only in digit 6, similarly for 'z' it can occur only for digit 0 + * and likewise. Keep a character frequency hashmap and decrement the count as and when a new digit + * is formed. Sort the digits and return a concatenated string. + */ +public class ReconstructOriginalDigitsFromEnglish { + public static void main(String[] args) { + System.out.println( + new ReconstructOriginalDigitsFromEnglish() + .originalDigits( + "fviefurofviefurofviefurofviefurofviefurofviefurofviefurofviefurofviefurofviefuro")); + } + + public String originalDigits(String s) { + Map map = new HashMap<>(); + for (char c : s.toCharArray()) { + map.putIfAbsent(c, 0); + map.put(c, map.get(c) + 1); + } + Map intMap = new HashMap<>(); + if (map.containsKey('x')) { + update(map, intMap, 6, 'x', Arrays.asList('s', 'i', 'x')); + } + if (map.containsKey('g')) { + update(map, intMap, 8, 'g', Arrays.asList('e', 'i', 'g', 'h', 't')); + } + if (map.containsKey('w')) { + update(map, intMap, 2, 'w', Arrays.asList('t', 'w', 'o')); + } + if (map.containsKey('z')) { + update(map, intMap, 0, 'z', Arrays.asList('z', 'e', 'r', 'o')); + } + if (map.containsKey('u')) { + update(map, intMap, 4, 'u', Arrays.asList('f', 'o', 'u', 'r')); + } + if (map.containsKey('f')) { + update(map, intMap, 5, 'f', Arrays.asList('f', 'i', 'v', 'e')); + } + if (map.containsKey('v')) { + update(map, intMap, 7, 'v', Arrays.asList('s', 'e', 'v', 'e', 'n')); + } + if (map.containsKey('i')) { + update(map, intMap, 9, 'i', Arrays.asList('n', 'i', 'n', 'e')); + } + if (map.containsKey('t')) { + update(map, intMap, 3, 't', Arrays.asList('t', 'h', 'r', 'e', 'e')); + } + if (map.containsKey('o')) { + update(map, intMap, 1, 'o', Arrays.asList('o', 'n', 'e')); + } + Set keys = intMap.keySet(); + List list = new ArrayList<>(keys); + list.sort(Comparator.comparingInt(o -> o)); + StringBuilder sb = new StringBuilder(); + for (int i : list) { + int count = intMap.get(i); + while (count-- > 0) { + sb.append(i); + } + } + return sb.toString(); + } + + private void update( + Map map, + Map intMap, + int num, + char id, + List list) { + if (map.containsKey(id)) { + int count = map.get(id); + intMap.put(num, count); + while (count-- > 0) { + for (char c : list) { + map.put(c, map.get(c) - 1); + } + } + } + } +} diff --git a/problems/src/string/RepeatedSubstringPattern.java b/src/main/java/string/RepeatedSubstringPattern.java similarity index 97% rename from problems/src/string/RepeatedSubstringPattern.java rename to src/main/java/string/RepeatedSubstringPattern.java index 2479e6bc..c0a31d9e 100644 --- a/problems/src/string/RepeatedSubstringPattern.java +++ b/src/main/java/string/RepeatedSubstringPattern.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/problems/src/string/ReplaceWords.java b/src/main/java/string/ReplaceWords.java similarity index 99% rename from problems/src/string/ReplaceWords.java rename to src/main/java/string/ReplaceWords.java index 7c2dede5..b85be6ba 100644 --- a/problems/src/string/ReplaceWords.java +++ b/src/main/java/string/ReplaceWords.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.Arrays; diff --git a/src/main/java/string/ReverseStringII.java b/src/main/java/string/ReverseStringII.java new file mode 100644 index 00000000..7550f99e --- /dev/null +++ b/src/main/java/string/ReverseStringII.java @@ -0,0 +1,38 @@ +/* (C) 2024 YourCompanyName */ +package string; + +/** + * Created by gouthamvidyapradhan on 30/07/2019 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. + * Example: Input: s = "abcdefg", k = 2 Output: "bacdfeg" Restrictions: The string consists of lower + * English letters only. Length of the given string and k will in the range [1, 10000] + * + *

Solution O(N) + */ +public class ReverseStringII { + public static void main(String[] args) { + System.out.println(new ReverseStringII().reverseStr("abcdefg", 2)); + } + + public String reverseStr(String s, int k) { + StringBuilder sb = new StringBuilder(); + for (int i = 0, l = s.length(); i < l; i++) { + if (i % (2 * k) == 0) { + int count = 0; + StringBuilder temp = new StringBuilder(); + while (count < k && i < l) { + temp.append(s.charAt(i)); + count++; + i++; + } + sb.append(temp.reverse()); + } + if (i < l) { + sb.append(s.charAt(i)); + } + } + return sb.toString(); + } +} diff --git a/problems/src/string/ReverseWordsII.java b/src/main/java/string/ReverseWordsII.java similarity index 98% rename from problems/src/string/ReverseWordsII.java rename to src/main/java/string/ReverseWordsII.java index 7aa9f9c0..ba001240 100644 --- a/problems/src/string/ReverseWordsII.java +++ b/src/main/java/string/ReverseWordsII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/problems/src/string/ReverseWordsInAString.java b/src/main/java/string/ReverseWordsInAString.java similarity index 98% rename from problems/src/string/ReverseWordsInAString.java rename to src/main/java/string/ReverseWordsInAString.java index e930ab84..6e71c8c2 100644 --- a/problems/src/string/ReverseWordsInAString.java +++ b/src/main/java/string/ReverseWordsInAString.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.ArrayList; diff --git a/problems/src/string/RotateString.java b/src/main/java/string/RotateString.java similarity index 97% rename from problems/src/string/RotateString.java rename to src/main/java/string/RotateString.java index 02978688..548bb2fe 100644 --- a/problems/src/string/RotateString.java +++ b/src/main/java/string/RotateString.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/problems/src/string/ShortestPalindrome.java b/src/main/java/string/ShortestPalindrome.java similarity index 98% rename from problems/src/string/ShortestPalindrome.java rename to src/main/java/string/ShortestPalindrome.java index 66df78de..ef68c011 100644 --- a/problems/src/string/ShortestPalindrome.java +++ b/src/main/java/string/ShortestPalindrome.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/problems/src/string/SimplifyPath.java b/src/main/java/string/SimplifyPath.java similarity index 97% rename from problems/src/string/SimplifyPath.java rename to src/main/java/string/SimplifyPath.java index e500171f..0f4ab3bc 100644 --- a/problems/src/string/SimplifyPath.java +++ b/src/main/java/string/SimplifyPath.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.ArrayDeque; diff --git a/src/main/java/string/SplitConcatenatedStrings.java b/src/main/java/string/SplitConcatenatedStrings.java new file mode 100644 index 00000000..139605c1 --- /dev/null +++ b/src/main/java/string/SplitConcatenatedStrings.java @@ -0,0 +1,67 @@ +/* (C) 2024 YourCompanyName */ +package string; + +/** + * Created by gouthamvidyapradhan on 10/05/2019 Given a list of strings, you could concatenate these + * strings together into a loop, where for each string you could choose to reverse it or not. Among + * all the possible loops, you need to find the lexicographically biggest string after cutting the + * loop, which will make the looped string into a regular one. + * + *

Specifically, to find the lexicographically biggest string, you need to experience two phases: + * + *

Concatenate all the strings into a loop, where you can reverse some strings or not and connect + * them in the same order as given. Cut and make one breakpoint in any place of the loop, which will + * make the looped string into a regular one starting from the character at the cutpoint. And your + * job is to find the lexicographically biggest one among all the possible regular strings. + * + *

Example: Input: "abc", "xyz" Output: "zyxcba" Explanation: You can get the looped string + * "-abcxyz-", "-abczyx-", "-cbaxyz-", "-cbazyx-", where '-' represents the looped status. The + * answer string came from the fourth looped one, where you could cut from the middle character 'a' + * and get "zyxcba". Note: The input strings will only contain lowercase letters. The total length + * of all the strings will not over 1,000. + */ +public class SplitConcatenatedStrings { + public static void main(String[] args) { + String[] A = {"abc"}; + System.out.println(new SplitConcatenatedStrings().splitLoopedString(A)); + } + + public String splitLoopedString(String[] strs) { + String max = ""; + for (int i = 0; i < strs.length; i++) { + String s = strs[i]; + String result = findMax(strs, (i + 1) % strs.length); + + String ans; + for (int k = 0, l = s.length(); k < l; k++) { + StringBuilder sb = new StringBuilder(); + String start = s.substring(k); + String end = s.substring(0, k); + ans = sb.append(start).append(result).append(end).toString(); + max = max.compareTo(ans) > 0 ? max : ans; + } + + s = new StringBuilder(s).reverse().toString(); + for (int k = 0, l = s.length(); k < l; k++) { + StringBuilder sb = new StringBuilder(); + String start = s.substring(k); + String end = s.substring(0, k); + ans = sb.append(start).append(result).append(end).toString(); + max = max.compareTo(ans) > 0 ? max : ans; + } + } + return max; + } + + private String findMax(String[] strs, int i) { + int c = 1; + StringBuilder sb = new StringBuilder(); + for (int j = i, l = strs.length; c < l; j = (j + 1) % l, c++) { + String nextStr = strs[j]; + String reverse = new StringBuilder(nextStr).reverse().toString(); + String result = nextStr.compareTo(reverse) > 0 ? nextStr : reverse; + sb.append(result); + } + return sb.toString(); + } +} diff --git a/src/main/java/string/StampingTheSequence.java b/src/main/java/string/StampingTheSequence.java new file mode 100644 index 00000000..1ba7694d --- /dev/null +++ b/src/main/java/string/StampingTheSequence.java @@ -0,0 +1,123 @@ +/* (C) 2024 YourCompanyName */ +package string; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * Created by gouthamvidyapradhan on 12/10/2019 You want to form a target string of lowercase + * letters. + * + *

At the beginning, your sequence is target.length '?' marks. You also have a stamp of lowercase + * letters. + * + *

On each turn, you may place the stamp over the sequence, and replace every letter in the + * sequence with the corresponding letter from the stamp. You can make up to 10 * target.length + * turns. + * + *

For example, if the initial sequence is "?????", and your stamp is "abc", then you may make + * "abc??", "?abc?", "??abc" in the first turn. (Note that the stamp must be fully contained in the + * boundaries of the sequence in order to stamp.) + * + *

If the sequence is possible to stamp, then return an array of the index of the left-most + * letter being stamped at each turn. If the sequence is not possible to stamp, return an empty + * array. + * + *

For example, if the sequence is "ababc", and the stamp is "abc", then we could return the + * answer [0, 2], corresponding to the moves "?????" -> "abc??" -> "ababc". + * + *

Also, if the sequence is possible to stamp, it is guaranteed it is possible to stamp within 10 + * * target.length moves. Any answers specifying more than this number of moves will not be + * accepted. + * + *

Example 1: + * + *

Input: stamp = "abc", target = "ababc" Output: [0,2] ([1,0,2] would also be accepted as an + * answer, as well as some other answers.) Example 2: + * + *

Input: stamp = "abca", target = "aabcaca" Output: [3,0,1] + * + *

Note: + * + *

1 <= stamp.length <= target.length <= 1000 stamp and target only contain lowercase letters. + * + *

Solution: O(N ^ 2) General idea is to work the answer in the reverse order. For example if the + * target string is 'aaabb' and stamp is 'aabb' then first stamp would be at 0 resulting in aabb? + * and the next stamp would be at 1 resulting in 'aaabb' Consider each window of size = stamp.size + * from index 0 (call this window at index i). For every window keep track of matched indices and + * unmatched indices. Also, additionally Maintain a general-matched-index set containing all the + * indices that are already matched. For every window, if all the characters at each index of stamp + * sequence and target sequence match then add the window index to the answer also additionally + * revisit every widow index that have been previously visited in starting from i - 1 to 0 and + * verify if any window contains all the matched indices this can be checked by verifying the + * unmatched set at each widow to general-matched-index - if any of the window satisfy this + * condition then add this window index to the answer. Return the answer in the reverse order. + */ +public class StampingTheSequence { + public static void main(String[] args) { + int[] ans = new StampingTheSequence().movesToStamp("abca", "aaaaaaaaabcaaca"); + for (int a : ans) System.out.print(a + " "); + } + + private class Window { + Set matched, unmatched; + + Window(Set matched, Set unmatched) { + this.matched = matched; + this.unmatched = unmatched; + } + } + + public int[] movesToStamp(String stamp, String target) { + List windows = new ArrayList<>(); + Set matchedTarget = new HashSet<>(); + Stack answer = new Stack<>(); + for (int i = 0; i <= target.length() - stamp.length(); i++) { + Window current = new Window(new HashSet<>(), new HashSet<>()); + for (int j = i, s = 0; j < (i + stamp.length()); j++, s++) { + if (stamp.charAt(s) == target.charAt(j) || matchedTarget.contains(j)) { + current.matched.add(j); + } else current.unmatched.add(j); + } + if (current.unmatched.isEmpty()) { + answer.push(i); + matchedTarget.addAll(current.matched); + for (int k = windows.size() - 1; k >= 0; k--) { + if (!windows.get(k).unmatched.isEmpty()) { + Set newUnmatched = + windows + .get(k) + .unmatched + .stream() + .filter(u -> !matchedTarget.contains(u)) + .collect(Collectors.toSet()); + windows.get(k).unmatched = newUnmatched; + if (newUnmatched.isEmpty()) { + Set newMatched = + windows + .get(k) + .matched + .stream() + .filter(m -> !matchedTarget.contains(m)) + .collect(Collectors.toSet()); + if (!newMatched.isEmpty()) { + answer.push(k); + matchedTarget.addAll(newMatched); + } + } + } else break; + } + } + windows.add(current); + } + if (matchedTarget.size() == target.length()) { + int[] finalAns = new int[answer.size()]; + int i = 0; + while (!answer.isEmpty()) { + finalAns[i++] = answer.pop(); + } + return finalAns; + } + return new int[] {}; + } +} diff --git a/problems/src/string/StringCompression.java b/src/main/java/string/StringCompression.java similarity index 98% rename from problems/src/string/StringCompression.java rename to src/main/java/string/StringCompression.java index 160afa09..5c2144aa 100644 --- a/problems/src/string/StringCompression.java +++ b/src/main/java/string/StringCompression.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/problems/src/string/StringToInteger.java b/src/main/java/string/StringToInteger.java similarity index 98% rename from problems/src/string/StringToInteger.java rename to src/main/java/string/StringToInteger.java index da4e8235..fb5df48f 100644 --- a/problems/src/string/StringToInteger.java +++ b/src/main/java/string/StringToInteger.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/src/main/java/string/StudentAttendanceRecordI.java b/src/main/java/string/StudentAttendanceRecordI.java new file mode 100644 index 00000000..da553682 --- /dev/null +++ b/src/main/java/string/StudentAttendanceRecordI.java @@ -0,0 +1,30 @@ +/* (C) 2024 YourCompanyName */ +package string; + +/** + * Created by gouthamvidyapradhan on 10/05/2019 You are given a string representing an attendance + * record for a student. The record only contains the following three characters: 'A' : Absent. 'L' + * : Late. 'P' : Present. A student could be rewarded if his attendance record doesn't contain more + * than one 'A' (absent) or more than two continuous 'L' (late). + * + *

You need to return whether the student could be rewarded according to his attendance record. + * + *

Example 1: Input: "PPALLP" Output: True Example 2: Input: "PPALLL" Output: False + * + *

Solution O(N) Simple linear check + */ +public class StudentAttendanceRecordI { + public static void main(String[] args) {} + + public boolean checkRecord(String s) { + int count = 0; + for (int c : s.toCharArray()) { + if (c == 'A') { + count++; + } + if (count > 1) return false; + } + if (s.contains("LLL")) return false; + return true; + } +} diff --git a/problems/src/string/TextJustification.java b/src/main/java/string/TextJustification.java similarity index 98% rename from problems/src/string/TextJustification.java rename to src/main/java/string/TextJustification.java index e17b5b13..a8cb70c9 100644 --- a/problems/src/string/TextJustification.java +++ b/src/main/java/string/TextJustification.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.ArrayList; diff --git a/problems/src/string/ValidPalindrome.java b/src/main/java/string/ValidPalindrome.java similarity index 97% rename from problems/src/string/ValidPalindrome.java rename to src/main/java/string/ValidPalindrome.java index 7295d3cd..384ec3ac 100644 --- a/problems/src/string/ValidPalindrome.java +++ b/src/main/java/string/ValidPalindrome.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/problems/src/string/ValidPalindromeII.java b/src/main/java/string/ValidPalindromeII.java similarity index 97% rename from problems/src/string/ValidPalindromeII.java rename to src/main/java/string/ValidPalindromeII.java index 2cc37d09..37114591 100644 --- a/problems/src/string/ValidPalindromeII.java +++ b/src/main/java/string/ValidPalindromeII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** diff --git a/problems/src/string/ValidWordAbbreviation.java b/src/main/java/string/ValidWordAbbreviation.java similarity index 98% rename from problems/src/string/ValidWordAbbreviation.java rename to src/main/java/string/ValidWordAbbreviation.java index bf5dfbae..5630c91b 100644 --- a/problems/src/string/ValidWordAbbreviation.java +++ b/src/main/java/string/ValidWordAbbreviation.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; /** * Created by gouthamvidyapradhan on 20/03/2019 Given a non-empty string s and an abbreviation abbr, diff --git a/src/main/java/string/ValidWordSquare.java b/src/main/java/string/ValidWordSquare.java new file mode 100644 index 00000000..6b5a8f3e --- /dev/null +++ b/src/main/java/string/ValidWordSquare.java @@ -0,0 +1,78 @@ +/* (C) 2024 YourCompanyName */ +package string; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 04/06/2019 Given a sequence of words, check whether it forms a + * valid word square. + * + *

A sequence of words forms a valid word square if the kth row and column read the exact same + * string, where 0 ≤ k < max(numRows, numColumns). + * + *

Note: The number of words given is at least 1 and does not exceed 500. Word length will be at + * least 1 and does not exceed 500. Each word contains only lowercase English alphabet a-z. Example + * 1: + * + *

Input: [ "abcd", "bnrt", "crmy", "dtye" ] + * + *

Output: true + * + *

Explanation: The first row and first column both read "abcd". The second row and second column + * both read "bnrt". The third row and third column both read "crmy". The fourth row and fourth + * column both read "dtye". + * + *

Therefore, it is a valid word square. Example 2: + * + *

Input: [ "abcd", "bnrt", "crm", "dt" ] + * + *

Output: true + * + *

Explanation: The first row and first column both read "abcd". The second row and second column + * both read "bnrt". The third row and third column both read "crm". The fourth row and fourth + * column both read "dt". + * + *

Therefore, it is a valid word square. Example 3: + * + *

Input: [ "ball", "area", "read", "lady" ] + * + *

Output: false + * + *

Explanation: The third row reads "read" while the third column reads "lead". + * + *

Therefore, it is NOT a valid word square. + * + *

Solution: O(N x M) where N is number of words and M is max length of a string. Save strings + * for each column and each row in a array and compare them both. + */ +public class ValidWordSquare { + public static void main(String[] args) { + List arr = Arrays.asList("abcd", "bnrt", "crmy", "dtye"); + System.out.println(new ValidWordSquare().validWordSquare(arr)); + } + + public boolean validWordSquare(List words) { + List newList = new ArrayList<>(); + int max = 0; + for (int i = 0; i < words.size(); i++) { + max = Math.max(max, words.get(i).length()); + } + + for (int i = 0; i < max; i++) { + StringBuilder sb = new StringBuilder(); + for (String w : words) { + if (i < w.length()) { + sb.append(w.charAt(i)); + } else break; + } + newList.add(sb.toString()); + } + + if (words.size() != newList.size()) return false; + + for (int i = 0, l = words.size(); i < l; i++) { + if (!words.get(i).equals(newList.get(i))) return false; + } + return true; + } +} diff --git a/src/main/java/string/ValidateIPAddress.java b/src/main/java/string/ValidateIPAddress.java new file mode 100644 index 00000000..a1df8914 --- /dev/null +++ b/src/main/java/string/ValidateIPAddress.java @@ -0,0 +1,96 @@ +/* (C) 2024 YourCompanyName */ +package string; + +/** + * Created by gouthamvidyapradhan on 01/08/2019 Write a function to check whether an input string is + * a valid IPv4 address or IPv6 address or neither. + * + *

IPv4 addresses are canonically represented in dot-decimal notation, which consists of four + * decimal numbers, each ranging from 0 to 255, separated by dots ("."), e.g.,172.16.254.1; + * + *

Besides, leading zeros in the IPv4 is invalid. For example, the address 172.16.254.01 is + * invalid. + * + *

IPv6 addresses are represented as eight groups of four hexadecimal digits, each group + * representing 16 bits. The groups are separated by colons (":"). For example, the address + * 2001:0db8:85a3:0000:0000:8a2e:0370:7334 is a valid one. Also, we could omit some leading zeros + * among four hexadecimal digits and some low-case characters in the address to upper-case ones, so + * 2001:db8:85a3:0:0:8A2E:0370:7334 is also a valid IPv6 address(Omit leading zeros and using upper + * cases). + * + *

However, we don't replace a consecutive group of zero value with a single empty group using + * two consecutive colons (::) to pursue simplicity. For example, 2001:0db8:85a3::8A2E:0370:7334 is + * an invalid IPv6 address. + * + *

Besides, extra leading zeros in the IPv6 is also invalid. For example, the address + * 02001:0db8:85a3:0000:0000:8a2e:0370:7334 is invalid. + * + *

Note: You may assume there is no extra space or special characters in the input string. + * + *

Example 1: Input: "172.16.254.1" + * + *

Output: "IPv4" + * + *

Explanation: This is a valid IPv4 address, return "IPv4". Example 2: Input: + * "2001:0db8:85a3:0:0:8A2E:0370:7334" + * + *

Output: "IPv6" + * + *

Explanation: This is a valid IPv6 address, return "IPv6". Example 3: Input: "256.256.256.256" + * + *

Output: "Neither" + * + *

Explanation: This is neither a IPv4 address nor a IPv6 address. + * + *

Solution: O(N) split the string by each '.' or ':' and then validate each parts. + */ +public class ValidateIPAddress { + public static void main(String[] args) { + + System.out.println( + new ValidateIPAddress().validIPAddress("02001:0db8:85a3:0000:0000:8a2e:0370:7334")); + } + + public String validIPAddress(String IP) { + if (IP.contains(".")) { + if (IP.endsWith(".") || IP.startsWith(".")) return "Neither"; + String[] ipv4 = IP.split("\\."); + if (ipv4.length != 4) return "Neither"; + else { + for (String part : ipv4) { + if (part.isEmpty()) return "Neither"; + if (part.length() > 1 && part.startsWith("0")) return "Neither"; + else { + if (part.length() > 3) return "Neither"; + for (char c : part.toCharArray()) { + if (c < '0' || c > '9') return "Neither"; + } + int value = Integer.parseInt(part); + if (value < 0 || value > 255) return "Neither"; + } + } + } + return "IPv4"; + } else if (IP.contains(":")) { + if (IP.endsWith(":") || IP.startsWith(":")) return "Neither"; + String[] ipv6 = IP.split(":"); + if (ipv6.length != 8) return "Neither"; + else { + for (String part : ipv6) { + if (part.isEmpty()) return "Neither"; + if (part.length() > 4) return "Neither"; + else { + for (char c : part.toCharArray()) { + if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { + + } else { + return "Neither"; + } + } + } + } + } + return "IPv6"; + } else return "Neither"; + } +} diff --git a/problems/src/string/ZigZagConversion.java b/src/main/java/string/ZigZagConversion.java similarity index 98% rename from problems/src/string/ZigZagConversion.java rename to src/main/java/string/ZigZagConversion.java index 5867fba1..182e0015 100644 --- a/problems/src/string/ZigZagConversion.java +++ b/src/main/java/string/ZigZagConversion.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package string; import java.util.ArrayList; diff --git a/problems/src/tree/AllNodesDistanceKInBinaryTree.java b/src/main/java/tree/AllNodesDistanceKInBinaryTree.java similarity index 99% rename from problems/src/tree/AllNodesDistanceKInBinaryTree.java rename to src/main/java/tree/AllNodesDistanceKInBinaryTree.java index e65c19f0..aba385bb 100644 --- a/problems/src/tree/AllNodesDistanceKInBinaryTree.java +++ b/src/main/java/tree/AllNodesDistanceKInBinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.*; diff --git a/problems/src/tree/AllPossibleFullBinaryTrees.java b/src/main/java/tree/AllPossibleFullBinaryTrees.java similarity index 98% rename from problems/src/tree/AllPossibleFullBinaryTrees.java rename to src/main/java/tree/AllPossibleFullBinaryTrees.java index fc66fafa..0925a91c 100644 --- a/problems/src/tree/AllPossibleFullBinaryTrees.java +++ b/src/main/java/tree/AllPossibleFullBinaryTrees.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.*; diff --git a/problems/src/tree/AverageOfLevelsInBinaryTree.java b/src/main/java/tree/AverageOfLevelsInBinaryTree.java similarity index 98% rename from problems/src/tree/AverageOfLevelsInBinaryTree.java rename to src/main/java/tree/AverageOfLevelsInBinaryTree.java index aba33987..d136b3ed 100644 --- a/problems/src/tree/AverageOfLevelsInBinaryTree.java +++ b/src/main/java/tree/AverageOfLevelsInBinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.ArrayDeque; diff --git a/problems/src/tree/BSTtoDoublyLinkedList.java b/src/main/java/tree/BSTtoDoublyLinkedList.java similarity index 97% rename from problems/src/tree/BSTtoDoublyLinkedList.java rename to src/main/java/tree/BSTtoDoublyLinkedList.java index 3e450d61..087bd4dc 100644 --- a/problems/src/tree/BSTtoDoublyLinkedList.java +++ b/src/main/java/tree/BSTtoDoublyLinkedList.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/BinarayTreeRightSideView.java b/src/main/java/tree/BinarayTreeRightSideView.java similarity index 98% rename from problems/src/tree/BinarayTreeRightSideView.java rename to src/main/java/tree/BinarayTreeRightSideView.java index 9e29e495..360ade9e 100644 --- a/problems/src/tree/BinarayTreeRightSideView.java +++ b/src/main/java/tree/BinarayTreeRightSideView.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.ArrayList; diff --git a/problems/src/tree/BinaryTreeInorderTraversal.java b/src/main/java/tree/BinaryTreeInorderTraversal.java similarity index 97% rename from problems/src/tree/BinaryTreeInorderTraversal.java rename to src/main/java/tree/BinaryTreeInorderTraversal.java index b52a1cfb..31c4d8a5 100644 --- a/problems/src/tree/BinaryTreeInorderTraversal.java +++ b/src/main/java/tree/BinaryTreeInorderTraversal.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.ArrayList; diff --git a/problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java b/src/main/java/tree/BinaryTreeLongestConsecutiveSequenceII.java similarity index 98% rename from problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java rename to src/main/java/tree/BinaryTreeLongestConsecutiveSequenceII.java index ab4b3146..3505a092 100644 --- a/problems/src/tree/BinaryTreeLongestConsecutiveSequenceII.java +++ b/src/main/java/tree/BinaryTreeLongestConsecutiveSequenceII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/BinaryTreeMaximumPathSum.java b/src/main/java/tree/BinaryTreeMaximumPathSum.java similarity index 98% rename from problems/src/tree/BinaryTreeMaximumPathSum.java rename to src/main/java/tree/BinaryTreeMaximumPathSum.java index 8ab9ad11..44e80fb0 100644 --- a/problems/src/tree/BinaryTreeMaximumPathSum.java +++ b/src/main/java/tree/BinaryTreeMaximumPathSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/BinaryTreePaths.java b/src/main/java/tree/BinaryTreePaths.java similarity index 96% rename from problems/src/tree/BinaryTreePaths.java rename to src/main/java/tree/BinaryTreePaths.java index 35a098d9..e15fabd1 100644 --- a/problems/src/tree/BinaryTreePaths.java +++ b/src/main/java/tree/BinaryTreePaths.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.ArrayList; diff --git a/problems/src/tree/BinaryTreePostorderTraversal.java b/src/main/java/tree/BinaryTreePostorderTraversal.java similarity index 97% rename from problems/src/tree/BinaryTreePostorderTraversal.java rename to src/main/java/tree/BinaryTreePostorderTraversal.java index 6a5d369d..53c465e7 100644 --- a/problems/src/tree/BinaryTreePostorderTraversal.java +++ b/src/main/java/tree/BinaryTreePostorderTraversal.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.*; diff --git a/src/main/java/tree/BinaryTreeTilt.java b/src/main/java/tree/BinaryTreeTilt.java new file mode 100644 index 00000000..21feebec --- /dev/null +++ b/src/main/java/tree/BinaryTreeTilt.java @@ -0,0 +1,55 @@ +/* (C) 2024 YourCompanyName */ +package tree; +/** + * Created by gouthamvidyapradhan on 14/08/2019 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 Output: 1 Explanation: Tilt of node 2 : 0 Tilt of node 3 : 0 Tilt of + * node 1 : |2-3| = 1 Tilt of binary tree : 0 + 0 + 1 = 1 Note: + * + *

The sum of node values in any subtree won't exceed the range of 32-bit integer. All the tilt + * values won't exceed the range of 32-bit integer. + * + *

Solution: Find tilt of left node and find tilt of right node and return left + right + curr to + * its parent. + */ +public class BinaryTreeTilt { + + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public static void main(String[] args) { + TreeNode node = new TreeNode(1); + node.left = new TreeNode(2); + node.right = new TreeNode(3); + System.out.println(new BinaryTreeTilt().findTilt(node)); + } + + int sum = 0; + + public int findTilt(TreeNode root) { + if (root == null) return 0; + tilt(root); + return sum; + } + + private int tilt(TreeNode node) { + if (node == null) return 0; + int left = tilt(node.left); + int right = tilt(node.right); + sum += Math.abs(left - right); + return left + right + node.val; + } +} diff --git a/problems/src/tree/BoundaryOfBinaryTree.java b/src/main/java/tree/BoundaryOfBinaryTree.java similarity index 99% rename from problems/src/tree/BoundaryOfBinaryTree.java rename to src/main/java/tree/BoundaryOfBinaryTree.java index 2dd6260a..708e86e7 100644 --- a/problems/src/tree/BoundaryOfBinaryTree.java +++ b/src/main/java/tree/BoundaryOfBinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.*; diff --git a/problems/src/tree/ClosestBinarySearchTreeValue.java b/src/main/java/tree/ClosestBinarySearchTreeValue.java similarity index 98% rename from problems/src/tree/ClosestBinarySearchTreeValue.java rename to src/main/java/tree/ClosestBinarySearchTreeValue.java index 4d2cd451..843ec3eb 100644 --- a/problems/src/tree/ClosestBinarySearchTreeValue.java +++ b/src/main/java/tree/ClosestBinarySearchTreeValue.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/ClosestLeafInABinaryTree.java b/src/main/java/tree/ClosestLeafInABinaryTree.java similarity index 99% rename from problems/src/tree/ClosestLeafInABinaryTree.java rename to src/main/java/tree/ClosestLeafInABinaryTree.java index e08b5e8a..7afc7ba4 100644 --- a/problems/src/tree/ClosestLeafInABinaryTree.java +++ b/src/main/java/tree/ClosestLeafInABinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.*; diff --git a/src/main/java/tree/ConstructBinaryTreefromString.java b/src/main/java/tree/ConstructBinaryTreefromString.java new file mode 100644 index 00000000..a73aae56 --- /dev/null +++ b/src/main/java/tree/ConstructBinaryTreefromString.java @@ -0,0 +1,88 @@ +/* (C) 2024 YourCompanyName */ +package tree; + +/** + * Created by gouthamvidyapradhan on 30/07/2019 You need to construct a binary tree from a string + * consisting of parenthesis and integers. + * + *

The whole input represents a binary tree. It contains an integer followed by zero, one or two + * pairs of parenthesis. The integer represents the root's value and a pair of parenthesis contains + * a child binary tree with the same structure. + * + *

You always start to construct the left child node of the parent first if it exists. + * + *

Example: Input: "4(2(3)(1))(6(5))" Output: return the tree root node representing the + * following tree: + * + *

4 / \ 2 6 /\ / 3 1 5 + * + *

Note: There will only be '(', ')', '-' and '0' ~ '9' in the input string. An empty tree is + * represented by "" instead of "()". + * + *

Solution: O(N ^ 2) Form a node for every number and treat the first sub-string within round + * braces as left node and the second sub-string within the round braces as the right node. + * Recursively solve each substring within the round braces. + */ +public class ConstructBinaryTreefromString { + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public static void main(String[] args) { + System.out.println(new ConstructBinaryTreefromString().str2tree("4(2(3)(1))(6(5))")); + } + + private TreeNode str2tree(String s) { + if (s == null || s.isEmpty()) return null; + TreeNode current; + StringBuilder num = new StringBuilder(); + boolean isNeg = false; + int i = 0; + for (; i < s.length(); i++) { + if (s.charAt(i) == '-') { + isNeg = true; + } else if (s.charAt(i) >= '0' && s.charAt(i) <= '9') { + num.append(s.charAt(i)); + } else break; + } + if (isNeg) { + current = new TreeNode(Integer.parseInt(num.toString()) * -1); + } else current = new TreeNode(Integer.parseInt(num.toString())); + int count = 0; + StringBuilder left = new StringBuilder(); + for (; i < s.length(); i++) { + if (s.charAt(i) == '(') { + count++; + } else if (s.charAt(i) == ')') { + count--; + } + left.append(s.charAt(i)); + if (count == 0) { + break; + } + } + i++; + String leftStr = ""; + String rightStr = ""; + if (i < s.length()) { + rightStr = s.substring(i); + } + if (left.length() > 0) { + leftStr = left.subSequence(1, left.length() - 1).toString(); + } + if (rightStr.length() > 0) { + rightStr = rightStr.substring(1, rightStr.length() - 1); + } + TreeNode leftNode = str2tree(leftStr); + TreeNode rightNode = str2tree(rightStr); + current.left = leftNode; + current.right = rightNode; + return current; + } +} diff --git a/problems/src/tree/ConstructStringFromBinaryTree.java b/src/main/java/tree/ConstructStringFromBinaryTree.java similarity index 98% rename from problems/src/tree/ConstructStringFromBinaryTree.java rename to src/main/java/tree/ConstructStringFromBinaryTree.java index 7c63b612..28138cbf 100644 --- a/problems/src/tree/ConstructStringFromBinaryTree.java +++ b/src/main/java/tree/ConstructStringFromBinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/ConvertBSTToGreaterTree.java b/src/main/java/tree/ConvertBSTToGreaterTree.java similarity index 97% rename from problems/src/tree/ConvertBSTToGreaterTree.java rename to src/main/java/tree/ConvertBSTToGreaterTree.java index ff3b0a4f..2c84753f 100644 --- a/problems/src/tree/ConvertBSTToGreaterTree.java +++ b/src/main/java/tree/ConvertBSTToGreaterTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/ConvertSortedArrayToBST.java b/src/main/java/tree/ConvertSortedArrayToBST.java similarity index 96% rename from problems/src/tree/ConvertSortedArrayToBST.java rename to src/main/java/tree/ConvertSortedArrayToBST.java index c2033157..60317bea 100644 --- a/problems/src/tree/ConvertSortedArrayToBST.java +++ b/src/main/java/tree/ConvertSortedArrayToBST.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/DiameterOfBinaryTree.java b/src/main/java/tree/DiameterOfBinaryTree.java similarity index 97% rename from problems/src/tree/DiameterOfBinaryTree.java rename to src/main/java/tree/DiameterOfBinaryTree.java index 3f0954d3..0d41b272 100644 --- a/problems/src/tree/DiameterOfBinaryTree.java +++ b/src/main/java/tree/DiameterOfBinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/EqualTreePartition.java b/src/main/java/tree/EqualTreePartition.java similarity index 98% rename from problems/src/tree/EqualTreePartition.java rename to src/main/java/tree/EqualTreePartition.java index c4c44535..c90a1280 100644 --- a/problems/src/tree/EqualTreePartition.java +++ b/src/main/java/tree/EqualTreePartition.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/FindBottomLeftTreeValue.java b/src/main/java/tree/FindBottomLeftTreeValue.java similarity index 75% rename from problems/src/tree/FindBottomLeftTreeValue.java rename to src/main/java/tree/FindBottomLeftTreeValue.java index 2de54d84..86ee8a57 100644 --- a/problems/src/tree/FindBottomLeftTreeValue.java +++ b/src/main/java/tree/FindBottomLeftTreeValue.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** @@ -12,7 +13,9 @@ * *

1 / \ 2 3 / / \ 4 5 6 / 7 * - *

Output: 7 Note: You may assume the tree (i.e., the given root node) is not NULL. + *

Output: 7 Note: You may assume the tree (i.e., the given root node) is not NULL. Solution: + * O(N) do a inorder search to find the left most value. Keep a level counter to keep track of what + * level you are at when you do a inorder search. */ public class FindBottomLeftTreeValue { private int max = 0, result; @@ -39,18 +42,18 @@ public static void main(String[] args) throws Exception { } public int findBottomLeftValue(TreeNode root) { - preorder(root, 1); + inorder(root, 1); return result; } - private void preorder(TreeNode node, int level) { + private void inorder(TreeNode node, int level) { if (node != null) { if (level > max) { result = node.val; max = level; } - preorder(node.left, level + 1); - preorder(node.right, level + 1); + inorder(node.left, level + 1); + inorder(node.right, level + 1); } } } diff --git a/src/main/java/tree/FindLargestValueInEachTreeRow.java b/src/main/java/tree/FindLargestValueInEachTreeRow.java new file mode 100644 index 00000000..a54e869b --- /dev/null +++ b/src/main/java/tree/FindLargestValueInEachTreeRow.java @@ -0,0 +1,66 @@ +/* (C) 2024 YourCompanyName */ +package tree; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 01/08/2019 You need to find the largest value in each row of a + * binary tree. + * + *

Example: Input: + * + *

1 / \ 3 2 / \ \ 5 3 9 + * + *

Output: [1, 3, 9] Solution: O(N) do a bfs to check largest in each row. + */ +public class FindLargestValueInEachTreeRow { + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + Map maxRow = new HashMap<>(); + + class Node { + int row; + TreeNode val; + + Node(int row, TreeNode val) { + this.row = row; + this.val = val; + } + } + + public List largestValues(TreeNode root) { + if (root == null) return new ArrayList<>(); + Queue queue = new ArrayDeque<>(); + queue.offer(new Node(0, root)); + while (!queue.isEmpty()) { + Node top = queue.poll(); + maxRow.putIfAbsent(top.row, top.val.val); + maxRow.put(top.row, Math.max(maxRow.get(top.row), top.val.val)); + if (top.val.left != null) { + queue.offer(new Node(top.row + 1, top.val.left)); + } + if (top.val.right != null) { + queue.offer(new Node(top.row + 1, top.val.right)); + } + } + List answer = new ArrayList<>(); + List keyList = new ArrayList<>(maxRow.keySet()); + keyList.sort(Integer::compareTo); + for (int k : keyList) { + answer.add(maxRow.get(k)); + } + return answer; + } + + public static void main(String[] args) { + // + } +} diff --git a/problems/src/tree/FlattenBinaryTree.java b/src/main/java/tree/FlattenBinaryTree.java similarity index 98% rename from problems/src/tree/FlattenBinaryTree.java rename to src/main/java/tree/FlattenBinaryTree.java index dfcaad3c..274e45fd 100644 --- a/problems/src/tree/FlattenBinaryTree.java +++ b/src/main/java/tree/FlattenBinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/FlipBinaryTree.java b/src/main/java/tree/FlipBinaryTree.java new file mode 100644 index 00000000..b1e0e41a --- /dev/null +++ b/src/main/java/tree/FlipBinaryTree.java @@ -0,0 +1,61 @@ +/* (C) 2024 YourCompanyName */ +package tree; + +import java.util.*; + +/** Created by gouthamvidyapradhan on 26/01/2020 */ +public class FlipBinaryTree { + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public static void main(String[] args) { + // + } + + private int i, count; + private List result; + + public List flipMatchVoyage(TreeNode root, int[] voyage) { + i = 0; + count = 0; + result = new ArrayList<>(); + inorderCount(root); + if (count != voyage.length) return Arrays.asList(-1); + preorder(root, voyage); + if (i == voyage.length) return result; + return Arrays.asList(-1); + } + + private void inorderCount(TreeNode node) { + if (node != null) { + count++; + inorderCount(node.left); + inorderCount(node.right); + } + } + + private void preorder(TreeNode node, int[] voyage) { + if (node != null) { + if (voyage[i] == node.val) { + i++; + } + if (node.left != null && node.right != null) { + if (voyage[i] == node.right.val) { + TreeNode temp = node.left; + node.left = node.right; + node.right = temp; + result.add(node.val); + } + } + preorder(node.left, voyage); + preorder(node.right, voyage); + } + } +} diff --git a/src/main/java/tree/FlipEquivalentBinaryTrees.java b/src/main/java/tree/FlipEquivalentBinaryTrees.java new file mode 100644 index 00000000..03c3d6f4 --- /dev/null +++ b/src/main/java/tree/FlipEquivalentBinaryTrees.java @@ -0,0 +1,131 @@ +/* (C) 2024 YourCompanyName */ +package tree; + +/** + * Created by gouthamvidyapradhan on 06/08/2019 For a binary tree T, we can define a flip operation + * as follows: choose any node, and swap the left and right child subtrees. + * + *

A binary tree X is flip equivalent to a binary tree Y if and only if we can make X equal to Y + * after some number of flip operations. + * + *

Write a function that determines whether two binary trees are flip equivalent. The trees are + * given by root nodes root1 and root2. + * + *

Example 1: + * + *

Input: root1 = [1,2,3,4,5,6,null,null,null,7,8], root2 = + * [1,3,2,null,6,4,5,null,null,null,null,8,7] Output: true Explanation: We flipped at nodes with + * values 1, 3, and 5. Flipped Trees Diagram + * + *

Note: + * + *

Each tree will have at most 100 nodes. Each value in each tree will be a unique integer in the + * range [0, 99]. Solution O(N ^ 2) Since the node values are unique general idea is to find the + * node on right tree for every node on the left tree and check if the values need to be swapped, if + * yes then swap the node's left and right child in the left tree. After this operation is complete + * check if both the trees are equal + */ +public class FlipEquivalentBinaryTrees { + + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public static void main(String[] args) { + TreeNode node = new TreeNode(1); + node.left = new TreeNode(2); + node.left.left = new TreeNode(4); + node.left.right = new TreeNode(5); + node.left.right.left = new TreeNode(7); + node.left.right.right = new TreeNode(8); + node.right = new TreeNode(3); + node.right.left = new TreeNode(6); + + TreeNode node1 = new TreeNode(1); + node1.left = new TreeNode(3); + node1.left.right = new TreeNode(6); + node1.right = new TreeNode(2); + node1.right.left = new TreeNode(4); + node1.right.right = new TreeNode(5); + node1.right.right.left = new TreeNode(8); + node1.right.right.right = new TreeNode(7); + System.out.println(new FlipEquivalentBinaryTrees().flipEquiv(node, node1)); + } + + public boolean flipEquiv(TreeNode root1, TreeNode root2) { + flip(root1, root2); + return checkIfBothAreSame(root1, root2); + } + + private boolean checkIfBothAreSame(TreeNode root1, TreeNode root2) { + if (root1 == null && root2 == null) return true; + else if (root1 == null) return false; + else if (root2 == null) return false; + else { + if (root1.val != root2.val) return false; + if (!checkIfBothAreSame(root1.left, root2.left)) return false; + return checkIfBothAreSame(root1.right, root2.right); + } + } + + private void flip(TreeNode root1, TreeNode root2) { + if (root1 != null) { + TreeNode result = find(root2, root1.val); + boolean valid = true; + if (result != null) { + if (root1.left == null) { + if (result.right != null) { + valid = false; + } + } + if (root1.right == null) { + if (result.left != null) { + valid = false; + } + } + if (root1.left != null) { + if (result.right == null) { + valid = false; + } else { + if (root1.left.val != result.right.val) { + valid = false; + } + } + } + if (root1.right != null) { + if (result.left == null) { + valid = false; + } else { + if (root1.right.val != result.left.val) { + valid = false; + } + } + } + if (valid) { + TreeNode temp = result.left; + result.left = result.right; + result.right = temp; + } + } + flip(root1.left, root2); + flip(root1.right, root2); + } + } + + private TreeNode find(TreeNode node, int value) { + if (node != null) { + if (node.val == value) return node; + TreeNode left = find(node.left, value); + if (left != null) return left; + TreeNode right = find(node.right, value); + if (right != null) return right; + } + return null; + } +} diff --git a/problems/src/tree/InorderSuccessorInBST.java b/src/main/java/tree/InorderSuccessorInBST.java similarity index 98% rename from problems/src/tree/InorderSuccessorInBST.java rename to src/main/java/tree/InorderSuccessorInBST.java index 3150230e..6d25ae6f 100644 --- a/problems/src/tree/InorderSuccessorInBST.java +++ b/src/main/java/tree/InorderSuccessorInBST.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/InsufficientNodesinRoottoLeafPaths.java b/src/main/java/tree/InsufficientNodesinRoottoLeafPaths.java new file mode 100644 index 00000000..da5338fd --- /dev/null +++ b/src/main/java/tree/InsufficientNodesinRoottoLeafPaths.java @@ -0,0 +1,57 @@ +/* (C) 2024 YourCompanyName */ +package tree; + +/** Created by gouthamvidyapradhan on 29/01/2020 */ +public class InsufficientNodesinRoottoLeafPaths { + public static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public static void main(String[] args) { + TreeNode root = new TreeNode(1); + root.left = new TreeNode(2); + root.left.left = new TreeNode(-5); + root.right = new TreeNode(-3); + root.right.left = new TreeNode(4); + System.out.println(new InsufficientNodesinRoottoLeafPaths().sufficientSubset(root, -1)); + } + + public TreeNode sufficientSubset(TreeNode root, int limit) { + long result = dfs(root, 0, limit); + if (result < limit) return null; + else return root; + } + + private long dfs(TreeNode node, long curr, int limit) { + if (node == null) return Integer.MIN_VALUE; + long sumLeft = dfs(node.left, curr + node.val, limit); + long sumRight = dfs(node.right, curr + node.val, limit); + if (sumLeft == Integer.MIN_VALUE && sumRight == Integer.MIN_VALUE) { + return node.val; + } else if (sumLeft == Integer.MIN_VALUE) { + if ((sumRight + curr + node.val) < limit) { + node.right = null; + } + return node.val + sumRight; + } else if (sumRight == Integer.MIN_VALUE) { + if ((sumLeft + curr + node.val) < limit) { + node.left = null; + } + return node.val + sumLeft; + } else { + if ((sumLeft + curr + node.val) < limit) { + node.left = null; + } + if ((sumRight + curr + node.val) < limit) { + node.right = null; + } + return Math.max(node.val + sumLeft, node.val + sumRight); + } + } +} diff --git a/problems/src/tree/LCA.java b/src/main/java/tree/LCA.java similarity index 97% rename from problems/src/tree/LCA.java rename to src/main/java/tree/LCA.java index ccd284d4..0d9f52ee 100644 --- a/problems/src/tree/LCA.java +++ b/src/main/java/tree/LCA.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/LargestBSTSubtree.java b/src/main/java/tree/LargestBSTSubtree.java similarity index 98% rename from problems/src/tree/LargestBSTSubtree.java rename to src/main/java/tree/LargestBSTSubtree.java index 4b58398b..04d7edaa 100644 --- a/problems/src/tree/LargestBSTSubtree.java +++ b/src/main/java/tree/LargestBSTSubtree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/LeafSimilarTrees.java b/src/main/java/tree/LeafSimilarTrees.java new file mode 100644 index 00000000..d5247e5e --- /dev/null +++ b/src/main/java/tree/LeafSimilarTrees.java @@ -0,0 +1,58 @@ +/* (C) 2024 YourCompanyName */ +package tree; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 23/08/2019 Consider all the leaves of a binary tree. From left + * to right order, the values of those leaves form a leaf value sequence. + * + *

For example, in the given tree above, the leaf value sequence is (6, 7, 4, 9, 8). + * + *

Two binary trees are considered leaf-similar if their leaf value sequence is the same. + * + *

Return true if and only if the two given trees with head nodes root1 and root2 are + * leaf-similar. + * + *

Solution: Do a inorder traversal for each trree and keep track of all the leaf nodes of the + * tree in a list. Compare the list and return the answer. + */ +public class LeafSimilarTrees { + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + public static void main(String[] args) {} + + public boolean leafSimilar(TreeNode root1, TreeNode root2) { + List list1 = new ArrayList<>(); + List list2 = new ArrayList<>(); + inorder(root1, list1); + inorder(root2, list2); + if (list1.size() != list2.size()) return false; + else { + for (int i = 0, l = list1.size(); i < l; i++) { + if (list1.get(i).intValue() != list2.get(i).intValue()) { + return false; + } + } + } + return true; + } + + private void inorder(TreeNode node, List list) { + if (node != null) { + if (node.left == null && node.right == null) { + list.add(node.val); + } + inorder(node.left, list); + inorder(node.right, list); + } + } +} diff --git a/problems/src/tree/LowestCommonAncestorBST.java b/src/main/java/tree/LowestCommonAncestorBST.java similarity index 97% rename from problems/src/tree/LowestCommonAncestorBST.java rename to src/main/java/tree/LowestCommonAncestorBST.java index 80591d92..48df25f1 100644 --- a/problems/src/tree/LowestCommonAncestorBST.java +++ b/src/main/java/tree/LowestCommonAncestorBST.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/MaximumBinaryTree.java b/src/main/java/tree/MaximumBinaryTree.java similarity index 98% rename from problems/src/tree/MaximumBinaryTree.java rename to src/main/java/tree/MaximumBinaryTree.java index d8b47275..f23823aa 100644 --- a/problems/src/tree/MaximumBinaryTree.java +++ b/src/main/java/tree/MaximumBinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/src/main/java/tree/MaximumLevelSumofABinaryTree.java b/src/main/java/tree/MaximumLevelSumofABinaryTree.java new file mode 100644 index 00000000..6e0b7763 --- /dev/null +++ b/src/main/java/tree/MaximumLevelSumofABinaryTree.java @@ -0,0 +1,64 @@ +/* (C) 2024 YourCompanyName */ +package tree; + +import java.util.*; + +/** + * Created by gouthamvidyapradhan on 28/08/2019 Given the root of a binary tree, the level of its + * root is 1, the level of its children is 2, and so on. + * + *

Return the smallest level X such that the sum of all the values of nodes at level X is + * maximal. + * + *

Example 1: + * + *

Input: [1,7,0,7,-8,null,null] Output: 2 Explanation: Level 1 sum = 1. Level 2 sum = 7 + 0 = 7. + * Level 3 sum = 7 + -8 = -1. So we return the level with the maximum sum which is level 2. + * + *

Note: + * + *

The number of nodes in the given tree is between 1 and 10^4. -10^5 <= node.val <= 10^5 + * + *

Solution: Keep a hashmap key-value pairs where key is the level and value is the sum of values + * at that level, do a inorder search in the tree and sum up the values at each level. + */ +public class MaximumLevelSumofABinaryTree { + public class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } + } + + Map levelMap; + + public static void main(String[] args) { + // + } + + public int maxLevelSum(TreeNode root) { + levelMap = new HashMap<>(); + inorder(root, 1); + int max = Integer.MIN_VALUE; + int ans = 0; + for (int k : levelMap.keySet()) { + if (levelMap.get(k) > max) { + max = levelMap.get(k); + ans = k; + } + } + return ans; + } + + private void inorder(TreeNode root, int level) { + if (root != null) { + levelMap.putIfAbsent(level, 0); + levelMap.put(level, levelMap.get(level) + root.val); + inorder(root.left, level + 1); + inorder(root.right, level + 1); + } + } +} diff --git a/problems/src/tree/MaximumWidthOfBinaryTree.java b/src/main/java/tree/MaximumWidthOfBinaryTree.java similarity index 98% rename from problems/src/tree/MaximumWidthOfBinaryTree.java rename to src/main/java/tree/MaximumWidthOfBinaryTree.java index 9536e1d2..6b419e8c 100644 --- a/problems/src/tree/MaximumWidthOfBinaryTree.java +++ b/src/main/java/tree/MaximumWidthOfBinaryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.ArrayList; diff --git a/problems/src/tree/MinimumAbsoluteDifferenceInBST.java b/src/main/java/tree/MinimumAbsoluteDifferenceInBST.java similarity index 97% rename from problems/src/tree/MinimumAbsoluteDifferenceInBST.java rename to src/main/java/tree/MinimumAbsoluteDifferenceInBST.java index 7be241e4..a3b3d40a 100644 --- a/problems/src/tree/MinimumAbsoluteDifferenceInBST.java +++ b/src/main/java/tree/MinimumAbsoluteDifferenceInBST.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/MostFrequentSubtreeSum.java b/src/main/java/tree/MostFrequentSubtreeSum.java similarity index 98% rename from problems/src/tree/MostFrequentSubtreeSum.java rename to src/main/java/tree/MostFrequentSubtreeSum.java index 1f0a0261..e801de74 100644 --- a/problems/src/tree/MostFrequentSubtreeSum.java +++ b/src/main/java/tree/MostFrequentSubtreeSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.ArrayList; diff --git a/problems/src/tree/NextRightPointer.java b/src/main/java/tree/NextRightPointer.java similarity index 98% rename from problems/src/tree/NextRightPointer.java rename to src/main/java/tree/NextRightPointer.java index f082e2ad..a49b5f7b 100644 --- a/problems/src/tree/NextRightPointer.java +++ b/src/main/java/tree/NextRightPointer.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.ArrayDeque; diff --git a/problems/src/tree/NextRightPointerII.java b/src/main/java/tree/NextRightPointerII.java similarity index 98% rename from problems/src/tree/NextRightPointerII.java rename to src/main/java/tree/NextRightPointerII.java index 644e5536..a70faea4 100644 --- a/problems/src/tree/NextRightPointerII.java +++ b/src/main/java/tree/NextRightPointerII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/PathSumIII.java b/src/main/java/tree/PathSumIII.java similarity index 98% rename from problems/src/tree/PathSumIII.java rename to src/main/java/tree/PathSumIII.java index cb911281..bac60064 100644 --- a/problems/src/tree/PathSumIII.java +++ b/src/main/java/tree/PathSumIII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.HashMap; diff --git a/problems/src/tree/PostorderToBT.java b/src/main/java/tree/PostorderToBT.java similarity index 98% rename from problems/src/tree/PostorderToBT.java rename to src/main/java/tree/PostorderToBT.java index 3ca60f7f..655a528f 100644 --- a/problems/src/tree/PostorderToBT.java +++ b/src/main/java/tree/PostorderToBT.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.HashMap; diff --git a/problems/src/tree/PreorderToBT.java b/src/main/java/tree/PreorderToBT.java similarity index 97% rename from problems/src/tree/PreorderToBT.java rename to src/main/java/tree/PreorderToBT.java index 06729549..23958b59 100644 --- a/problems/src/tree/PreorderToBT.java +++ b/src/main/java/tree/PreorderToBT.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.HashMap; diff --git a/problems/src/tree/RecoverBinarySearchTree.java b/src/main/java/tree/RecoverBinarySearchTree.java similarity index 98% rename from problems/src/tree/RecoverBinarySearchTree.java rename to src/main/java/tree/RecoverBinarySearchTree.java index d2b0d907..e18c7f91 100644 --- a/problems/src/tree/RecoverBinarySearchTree.java +++ b/src/main/java/tree/RecoverBinarySearchTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/SameTree.java b/src/main/java/tree/SameTree.java similarity index 97% rename from problems/src/tree/SameTree.java rename to src/main/java/tree/SameTree.java index ca8b2c16..69bf6a81 100644 --- a/problems/src/tree/SameTree.java +++ b/src/main/java/tree/SameTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/SerializeAndDeserializeNAryTree.java b/src/main/java/tree/SerializeAndDeserializeNAryTree.java similarity index 99% rename from problems/src/tree/SerializeAndDeserializeNAryTree.java rename to src/main/java/tree/SerializeAndDeserializeNAryTree.java index 03487353..a525061a 100644 --- a/problems/src/tree/SerializeAndDeserializeNAryTree.java +++ b/src/main/java/tree/SerializeAndDeserializeNAryTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.*; diff --git a/problems/src/tree/SortedArrayToBST.java b/src/main/java/tree/SortedArrayToBST.java similarity index 97% rename from problems/src/tree/SortedArrayToBST.java rename to src/main/java/tree/SortedArrayToBST.java index e445c34c..dcb3d57f 100644 --- a/problems/src/tree/SortedArrayToBST.java +++ b/src/main/java/tree/SortedArrayToBST.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/SplitBST.java b/src/main/java/tree/SplitBST.java similarity index 98% rename from problems/src/tree/SplitBST.java rename to src/main/java/tree/SplitBST.java index 19f74cd4..741c68c6 100644 --- a/problems/src/tree/SplitBST.java +++ b/src/main/java/tree/SplitBST.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/SubtreeOfAnotherTree.java b/src/main/java/tree/SubtreeOfAnotherTree.java similarity index 97% rename from problems/src/tree/SubtreeOfAnotherTree.java rename to src/main/java/tree/SubtreeOfAnotherTree.java index eef75737..026ba64b 100644 --- a/problems/src/tree/SubtreeOfAnotherTree.java +++ b/src/main/java/tree/SubtreeOfAnotherTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/SumofLeftLeaves.java b/src/main/java/tree/SumofLeftLeaves.java similarity index 96% rename from problems/src/tree/SumofLeftLeaves.java rename to src/main/java/tree/SumofLeftLeaves.java index 9c5391fd..7d6bf15d 100644 --- a/problems/src/tree/SumofLeftLeaves.java +++ b/src/main/java/tree/SumofLeftLeaves.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/SymmetricTree.java b/src/main/java/tree/SymmetricTree.java similarity index 97% rename from problems/src/tree/SymmetricTree.java rename to src/main/java/tree/SymmetricTree.java index cfda674a..f167a51e 100644 --- a/problems/src/tree/SymmetricTree.java +++ b/src/main/java/tree/SymmetricTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/TwoSumIV.java b/src/main/java/tree/TwoSumIV.java similarity index 97% rename from problems/src/tree/TwoSumIV.java rename to src/main/java/tree/TwoSumIV.java index ddac36cf..9e32e2a5 100644 --- a/problems/src/tree/TwoSumIV.java +++ b/src/main/java/tree/TwoSumIV.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.HashSet; diff --git a/problems/src/tree/ValidBinarySearchTree.java b/src/main/java/tree/ValidBinarySearchTree.java similarity index 98% rename from problems/src/tree/ValidBinarySearchTree.java rename to src/main/java/tree/ValidBinarySearchTree.java index 87d36ab1..bb0fbb18 100644 --- a/problems/src/tree/ValidBinarySearchTree.java +++ b/src/main/java/tree/ValidBinarySearchTree.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; /** diff --git a/problems/src/tree/ZigZagTraversal.java b/src/main/java/tree/ZigZagTraversal.java similarity index 97% rename from problems/src/tree/ZigZagTraversal.java rename to src/main/java/tree/ZigZagTraversal.java index 1b114e16..5236a18c 100644 --- a/problems/src/tree/ZigZagTraversal.java +++ b/src/main/java/tree/ZigZagTraversal.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package tree; import java.util.ArrayList; diff --git a/problems/src/two_pointers/FourSum.java b/src/main/java/two_pointers/FourSum.java similarity index 98% rename from problems/src/two_pointers/FourSum.java rename to src/main/java/two_pointers/FourSum.java index 95896184..0eeb74d8 100644 --- a/problems/src/two_pointers/FourSum.java +++ b/src/main/java/two_pointers/FourSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; import java.util.ArrayList; diff --git a/src/main/java/two_pointers/LastSubstringInLexicographicalOrder.java b/src/main/java/two_pointers/LastSubstringInLexicographicalOrder.java new file mode 100644 index 00000000..4b9195c2 --- /dev/null +++ b/src/main/java/two_pointers/LastSubstringInLexicographicalOrder.java @@ -0,0 +1,69 @@ +/* (C) 2024 YourCompanyName */ +package two_pointers; +/** + * Created by gouthamvidyapradhan on 30/08/2019 Given a string s, return the last substring of s in + * lexicographical order. + * + *

Example 1: + * + *

Input: "abab" Output: "bab" Explanation: The substrings are ["a", "ab", "aba", "abab", "b", + * "ba", "bab"]. The lexicographically maximum substring is "bab". Example 2: + * + *

Input: "leetcode" Output: "tcode" + * + *

Note: + * + *

1 <= s.length <= 4 * 10^5 s contains only lowercase English letters. + * + *

Solution O(N) General idea is as below. Fix the index 0 as the answer initially and start + * iterating the string character by character, if a char is encountered with is greater than the + * current answer then mark this as the answer, if it is same as the current answer then this new + * char can be a potential candidate for a answer hence mark this as a candidate and start comparing + * all the further characters of candidate char and all further chars of current answer if any point + * the char further down the candidate is greater than the char further down the current answer then + * mark the new candidate as the answer. + */ +public class LastSubstringInLexicographicalOrder { + public static void main(String[] args) { + System.out.println(new LastSubstringInLexicographicalOrder().lastSubstring("babcbd")); + } + + public String lastSubstring(String s) { + int currAns = 0; + int candidate = -1; + int prevIndex = 1; + for (int i = 1, l = s.length(); i < l; i++) { + if (candidate != -1) { + if (s.charAt(i) == s.charAt(prevIndex)) { + prevIndex++; + } else if (s.charAt(i) > s.charAt(prevIndex)) { + if (s.charAt(i) > s.charAt(candidate)) { + currAns = i; + candidate = -1; + prevIndex = currAns + 1; + } else if (s.charAt(i) == s.charAt(candidate)) { + currAns = candidate; + candidate = i; + prevIndex = currAns + 1; + } else { + currAns = candidate; + candidate = -1; + prevIndex = currAns + 1; + } + } else { + candidate = -1; + prevIndex = currAns + 1; + } + } else { + if (s.charAt(i) > s.charAt(currAns)) { + currAns = i; + candidate = -1; + prevIndex = currAns + 1; + } else if (s.charAt(i) == s.charAt(currAns)) { + candidate = i; + } + } + } + return s.substring(currAns); + } +} diff --git a/problems/src/two_pointers/LongestSubstringWitoutRepeats.java b/src/main/java/two_pointers/LongestSubstringWitoutRepeats.java similarity index 97% rename from problems/src/two_pointers/LongestSubstringWitoutRepeats.java rename to src/main/java/two_pointers/LongestSubstringWitoutRepeats.java index 5ca40efd..85b80c54 100644 --- a/problems/src/two_pointers/LongestSubstringWitoutRepeats.java +++ b/src/main/java/two_pointers/LongestSubstringWitoutRepeats.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; import java.util.HashMap; diff --git a/problems/src/two_pointers/MinimumSizeSubarraySum.java b/src/main/java/two_pointers/MinimumSizeSubarraySum.java similarity index 98% rename from problems/src/two_pointers/MinimumSizeSubarraySum.java rename to src/main/java/two_pointers/MinimumSizeSubarraySum.java index ac983997..0800c502 100644 --- a/problems/src/two_pointers/MinimumSizeSubarraySum.java +++ b/src/main/java/two_pointers/MinimumSizeSubarraySum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; /** diff --git a/problems/src/two_pointers/MinimumWindowSubstring.java b/src/main/java/two_pointers/MinimumWindowSubstring.java similarity index 98% rename from problems/src/two_pointers/MinimumWindowSubstring.java rename to src/main/java/two_pointers/MinimumWindowSubstring.java index 79f2bfd3..fa1f641d 100644 --- a/problems/src/two_pointers/MinimumWindowSubstring.java +++ b/src/main/java/two_pointers/MinimumWindowSubstring.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; /** diff --git a/problems/src/two_pointers/MoveZeroes.java b/src/main/java/two_pointers/MoveZeroes.java similarity index 96% rename from problems/src/two_pointers/MoveZeroes.java rename to src/main/java/two_pointers/MoveZeroes.java index c3ec945f..460f09df 100644 --- a/problems/src/two_pointers/MoveZeroes.java +++ b/src/main/java/two_pointers/MoveZeroes.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; /** diff --git a/problems/src/two_pointers/NumberOfMatchingSubsequences.java b/src/main/java/two_pointers/NumberOfMatchingSubsequences.java similarity index 98% rename from problems/src/two_pointers/NumberOfMatchingSubsequences.java rename to src/main/java/two_pointers/NumberOfMatchingSubsequences.java index d41408ed..6eca1354 100644 --- a/problems/src/two_pointers/NumberOfMatchingSubsequences.java +++ b/src/main/java/two_pointers/NumberOfMatchingSubsequences.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; /** diff --git a/problems/src/two_pointers/RemoveDuplicates.java b/src/main/java/two_pointers/RemoveDuplicates.java similarity index 97% rename from problems/src/two_pointers/RemoveDuplicates.java rename to src/main/java/two_pointers/RemoveDuplicates.java index 34fb1352..749db9a4 100644 --- a/problems/src/two_pointers/RemoveDuplicates.java +++ b/src/main/java/two_pointers/RemoveDuplicates.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; /** diff --git a/problems/src/two_pointers/RemoveDuplicatesII.java b/src/main/java/two_pointers/RemoveDuplicatesII.java similarity index 97% rename from problems/src/two_pointers/RemoveDuplicatesII.java rename to src/main/java/two_pointers/RemoveDuplicatesII.java index e2c302d6..db90a4ab 100644 --- a/problems/src/two_pointers/RemoveDuplicatesII.java +++ b/src/main/java/two_pointers/RemoveDuplicatesII.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; /** diff --git a/problems/src/two_pointers/SmallestRange.java b/src/main/java/two_pointers/SmallestRange.java similarity index 98% rename from problems/src/two_pointers/SmallestRange.java rename to src/main/java/two_pointers/SmallestRange.java index 90152485..73e4cb4c 100644 --- a/problems/src/two_pointers/SmallestRange.java +++ b/src/main/java/two_pointers/SmallestRange.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; import java.util.ArrayList; diff --git a/problems/src/two_pointers/SubarrayProductLessThanK.java b/src/main/java/two_pointers/SubarrayProductLessThanK.java similarity index 98% rename from problems/src/two_pointers/SubarrayProductLessThanK.java rename to src/main/java/two_pointers/SubarrayProductLessThanK.java index 75ccbba9..5d255e71 100644 --- a/problems/src/two_pointers/SubarrayProductLessThanK.java +++ b/src/main/java/two_pointers/SubarrayProductLessThanK.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; /** * Created by gouthamvidyapradhan on 17/02/2018. Your are given an array of positive integers nums. diff --git a/src/main/java/two_pointers/SubarraysWithKDifferentIntegers.java b/src/main/java/two_pointers/SubarraysWithKDifferentIntegers.java new file mode 100644 index 00000000..9728d4fd --- /dev/null +++ b/src/main/java/two_pointers/SubarraysWithKDifferentIntegers.java @@ -0,0 +1,56 @@ +/* (C) 2024 YourCompanyName */ +package two_pointers; +/** + * Created by gouthamvidyapradhan on 25/07/2019 Given an array A of positive integers, call a + * (contiguous, not necessarily distinct) subarray of A good if the number of different integers in + * that subarray is exactly K. + * + *

(For example, [1,2,3,1,2] has 3 different integers: 1, 2, and 3.) + * + *

Return the number of good subarrays of A. + * + *

Example 1: + * + *

Input: A = [1,2,1,2,3], K = 2 Output: 7 Explanation: Subarrays formed with exactly 2 different + * integers: [1,2], [2,1], [1,2], [2,3], [1,2,1], [2,1,2], [1,2,1,2]. Example 2: + * + *

Input: A = [1,2,1,3,4], K = 3 Output: 3 Explanation: Subarrays formed with exactly 3 different + * integers: [1,2,1,3], [2,1,3], [1,3,4]. + * + *

Note: + * + *

1 <= A.length <= 20000 1 <= A[i] <= A.length 1 <= K <= A.length Solution: O(N) General idea is + * to find subarraysWithKDistinct(A, atMost(K)) - subarraysWithKDistinct(A, atMost(K - 1)). + */ +public class SubarraysWithKDifferentIntegers { + public static void main(String[] args) { + int[] A = {1, 2, 1, 2, 3}; + SubarraysWithKDifferentIntegers task = new SubarraysWithKDifferentIntegers(); + System.out.println(task.subarraysWithKDistinct(A, 2)); + } + + public int subarraysWithKDistinct(int[] A, int K) { + return calculate(A, K) - calculate(A, K - 1); + } + + private int calculate(int[] A, int K) { + int count = 0; + int[] frequency = new int[A.length + 1]; + int currCount = 0; + for (int i = 0, j = 0; i < A.length; i++) { + frequency[A[i]]++; + if (frequency[A[i]] == 1) { + currCount++; + } + while (currCount > K) { + frequency[A[j]]--; + if (frequency[A[j]] == 0) { + currCount--; + } + j++; + } + count += (i - j + 1); + } + return count; + } +} diff --git a/problems/src/two_pointers/ThreeSum.java b/src/main/java/two_pointers/ThreeSum.java similarity index 98% rename from problems/src/two_pointers/ThreeSum.java rename to src/main/java/two_pointers/ThreeSum.java index 42ab17e0..5f928fd9 100644 --- a/problems/src/two_pointers/ThreeSum.java +++ b/src/main/java/two_pointers/ThreeSum.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; import java.util.ArrayList; diff --git a/problems/src/two_pointers/ThreeSumClosest.java b/src/main/java/two_pointers/ThreeSumClosest.java similarity index 98% rename from problems/src/two_pointers/ThreeSumClosest.java rename to src/main/java/two_pointers/ThreeSumClosest.java index 97329084..98f9118c 100644 --- a/problems/src/two_pointers/ThreeSumClosest.java +++ b/src/main/java/two_pointers/ThreeSumClosest.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; import java.util.Arrays; diff --git a/problems/src/two_pointers/TrappingRainWater.java b/src/main/java/two_pointers/TrappingRainWater.java similarity index 97% rename from problems/src/two_pointers/TrappingRainWater.java rename to src/main/java/two_pointers/TrappingRainWater.java index cf8d3f06..a2462374 100644 --- a/problems/src/two_pointers/TrappingRainWater.java +++ b/src/main/java/two_pointers/TrappingRainWater.java @@ -1,3 +1,4 @@ +/* (C) 2024 YourCompanyName */ package two_pointers; /**