├── .vscode └── settings.json ├── README.md └── src ├── Array ├── DiagonalTraverse │ ├── DiagonalTraverse.java │ └── DiagonalTraverse.py ├── DuplicateZeros │ ├── DuplicateZeros.java │ └── DuplicateZeros.py ├── EncodeAndDecodeStrings │ └── EncodeAndDecodeStrings.java ├── FindPivotIndex │ ├── FindPivotIndex.java │ └── FindPivotIndex.py ├── LongestCommonPrefix │ └── LongestCommonPrefix.java ├── MinimumTimeDifference │ ├── MinimumTimeDifference.java │ └── MinimumTimeDifference.py ├── NextPermutation │ └── NextPermutation.java ├── PascalsTriangle │ ├── PascalsTriangle.java │ └── PascalsTriangle.py ├── ProductOfArrayExceptSelf │ ├── ProductOfArrayExceptSelf.java │ └── ProductOfArrayExceptSelf.py ├── ReorderDataInLogFiles │ └── ReorderDataInLogFiles.java ├── RobotBoundedInCircle │ └── RobotBoundedInCircle.java ├── SpiralMatrix │ ├── SpiralMatrix.java │ ├── SpiralMatrix.py │ ├── SpiralMatrixII.java │ └── SpiralMatrixII.py ├── SubarraySumEqualsK │ └── SubarraySumEqualsK.java ├── ZigZagConversion │ ├── ZigZagConversion.java │ └── ZigZagConversion.py └── groupAnagrams │ └── groupAnagrams.java ├── Backtracking ├── CombinationsSum │ ├── CombinationSum1.java │ ├── CombinationSum2.java │ └── CombinationSum3.java ├── DifferentWaysToAddParentheses │ └── DifferentWaysToAddParentheses.java ├── GenerateParentheses │ └── GenerateParentheses.java ├── LetterCombinationsOfAPhoneNumber │ └── LetterCombinationsOfAPhoneNumber.java ├── NQueens │ └── NQueens.java ├── PalindromePartitioning │ └── PalindromePartitioning.java ├── Permutations │ ├── Permutations1.java │ └── Permutations2.java ├── ReconstructItinerary │ └── ReconstructItinerary.java ├── RestoreIpAddresses │ └── RestoreIpAddresses.java ├── RobotRoomCleaner │ └── RobotRoomCleaner.java ├── Subset │ ├── Subset1.java │ └── Subset2.java ├── SukoduSolver │ └── SukoduSolver.java └── WordSearch │ ├── WordSearch.java │ └── WordSearch2.java ├── BinarySearch ├── FindFirstAndLastPositionOfElementInSortedArray │ └── FindFirstAndLastPositionOfElementInSortedArray.java ├── FindKClosestElements │ └── FindKClosestElements.java ├── FindMinimumInRotatedSortedArray │ ├── FindMinimumInRotatedSortedArray.java │ └── FindMinimumInRotatedSortedArrayII.java ├── FindPeakElement │ └── FindPeakElement.java ├── FindSmallestLetterGreaterThanTarget │ └── FindSmallestLetterGreaterThanTarget.java ├── SearchInRotatedSortedArray │ └── SearchInRotatedSortedArray.java └── TimeBasedKeyValueStore │ ├── TimeBasedKeyValueStoreBinarySearch.java │ └── TimeBasedKeyValueStoreTreeMap ├── DPDecisionMaking ├── BestTimeToBuyandSellStock │ ├── BestTimeToBuyandSellStock.java │ └── BestTimetoBuyandSellStockII.java └── JumpGame │ ├── JumpGame_Bottom_up.java │ └── JumpGame_Top_Down.java ├── DP_Distinct ├── ClimbStairs │ └── ClimbStairs.java ├── CoinChange2 │ └── CoinChange2.java ├── CombinationSum4 │ └── CombinationSum4.java ├── ConcatenatedWords │ └── ConcatenatedWords.java ├── CountOfSubsetSum │ ├── CountOfSubsetSumBruteForce.java │ ├── CountOfSubsetSumDP.java │ └── CountOfSubsetSumTopDown.java ├── DecodeWays │ └── DecodeWays.java ├── Knapsack │ ├── KnapsackBruteForce.java │ ├── KnapsackDP.java │ └── KnapsackTopDown.java ├── MinimumSubsetSumDifference │ ├── MinimumSubsetSumDifferencTopDown.java │ └── MinimumSubsetSumDifferenceBruteForce.java ├── PartitionEqualSubsetSum │ └── PartitionEqualSubsetSum.java ├── UniqueBinarySearchTrees │ ├── UniqueBinarySearchTrees_Bottom_Up.java │ └── UniqueBinarySearchTrees_Top_Down.java ├── UniquePaths │ ├── UniquePaths.java │ └── UniquePathsII.java └── WordBreak │ └── WordBreak.java ├── DP_IntegerPartition ├── IntegerBreak │ ├── IntegerBreak_BottomUp.java │ └── IntegerBreak_TopDown.java └── PerfectSquares │ ├── PerfectSquares_BottomUp.java │ └── PerfectSquares_TopDown.java ├── DP_Min_Max_Path_to_Target ├── CoinChange │ ├── CoinChange_bottom_up.java │ └── CoinChange_top_down.java ├── EditDistance │ └── EditDistance.java ├── MaximalSquare │ ├── MaximalSquare_bottom_up.java │ └── MaximalSquare_top_down.java ├── MaximumProductSubarray │ └── MaximumProductSubarray.java ├── MinCostClimbingStairs │ ├── MinCostClimbingStairs_bottom_up.java │ └── MinCostClimbingStairs_top_down.java ├── MinimumFallingPathSum │ ├── MinimumFallingPathSum_bottom_up.java │ └── MinimumFallingPathSum_top_down.java ├── MinimumPathSum │ ├── MinimumPathSum_bottom_up.java │ └── MinimumPathSum_top_down.java └── Triangle │ └── Triangle.java ├── DP_StockTrading └── BestTimeToBuyAndSellStockWithCooldown │ └── BestTimeToBuyAndSellStockWithCooldown.java ├── DP_Subsequence ├── DistinctSubsequences │ ├── DistinctSubsequenceTopDown.java │ └── DistinctSubsequencesBottomUp.java ├── InterleavingString │ ├── InterleavingString_Bottom_up.java │ └── InterleavingString_TopDown.java ├── LongestCommonSubsequence │ ├── LongestCommonSubsequence_bottom_up.java │ └── LongestCommonSubsequence_top_down.java ├── LongestIncreasingSubsequence │ └── LongestIncreasingSubsequence_bottom_up.java ├── LongestPalindromicSubsequence │ └── LongestPalindromicSubsequence.java ├── MaximumLengthOfRepeatedSubarray │ └── MaximumLengthOfRepeatedSubarray.java ├── MaximumSubarray │ └── MaximumSubarray.java ├── NumberOfLongestIncreasingSubsequence │ └── NumberOfLongestIncreasingSubsequence.java └── Word BreakII │ └── Word BreakII_Top_Down.java ├── Deque └── SlidingWindowMaximum │ └── SlidingWindowMaximum.java ├── Design ├── FileSystem │ └── FileSystem.java ├── LFUCache │ ├── LFUCache_DoublyLinkedList.java │ └── LFUCache_LinkedHashset.java └── MapSumPairs │ └── MapSumPairs.java ├── DesignPattern ├── MediatorPattern │ ├── Problem.cs │ └── Solution.cs ├── ObserverPattern │ ├── Problem.cs │ ├── Solution_PullStyle.cs │ └── Solution_PushStyle.cs ├── StatePattern │ ├── Problem.cs │ └── Solution.cs ├── StrategyPattern │ ├── Problem.cs │ └── Solution.cs └── TemplateMethodPattern │ ├── Problem.cs │ └── Solution.cs ├── Greedy └── ReorganizeString │ └── ReorganizeString.java ├── LinkedList ├── AddTwoNumbers │ └── AddTwoNumbers.java ├── CopyListwithRandomPointer │ └── CopyListwithRandomPointer.java ├── FlattenAMultilevelDoublyLinkedList │ └── FlattenAMultilevelDoublyLinkedList.java ├── InsertintoaSortedCircularLinkedList │ └── InsertintoaSortedCircularLinkedList.java ├── IntersectionofTwoLinkedLists │ └── IntersectionofTwoLinkedLists.java ├── MergekSortedLists │ └── MergekSortedLists.java ├── OddEvenLinkedList │ └── OddEvenLinkedList.java ├── PartitionList │ └── PartitionList.java ├── RemoveDuplicatesFromSortedListII │ └── RemoveDuplicatesFromSortedListII.java ├── ReverseLinkedList │ └── ReverseLinkedList.java ├── ReverseLinkedListII │ └── ReverseLinkedListII.java ├── ReverseNodesinKGroup │ └── ReverseNodesinKGroup.java ├── RotateList │ └── RotateList.java ├── SortList │ └── SortList.java └── SwapNodesinPairs │ ├── SwapNodesinPairs_Iterative.java │ └── SwapNodesinPairs_Recursive.java ├── Object_Oriented_Programming ├── Abstraction │ ├── Abstraction.java │ └── Interface.java ├── Encapsulation │ └── Encapsulation.java ├── Inheritance │ └── Inheritance.java ├── Polymorphism │ └── Polymorphism.java └── s3_Abstract_Class_vs_interface.PNG ├── SOLID_Principles ├── DependencyInversion │ ├── Problem.cs │ └── Solution.cs ├── InterfaceSegregation │ ├── Problem.cs │ └── Solution.cs ├── LiskovSubstituition │ ├── Problem.cs │ └── Solution.cs ├── OpenClosed │ ├── Problem.cs │ └── Solution.cs └── SingleResponsibility │ ├── Problem.cs │ └── Solution.cs ├── Search ├── CloneGraph │ ├── CloneGraphBFS.java │ └── CloneGraphDFS.java ├── GraphValidTree │ └── GraphValidTree.java ├── IsGraphBipartite │ ├── IsGraphBipartiteBFS.java │ └── IsGraphBipartiteDFS.java ├── MakingALargeIsland │ └── MakingALargeIsland.java ├── NetworkDelayTime │ └── NetworkDelayTime.java ├── NumberOfDistinctIslands │ ├── NumberOfDistinctIslandsBFS.java │ └── NumberOfDistinctIslandsDFS.java ├── NumberOfIslands │ └── NumberOfIslands.java ├── NumberOfProvinces │ └── NumberOfProvinces.java ├── PacificAtlanticWaterFlow │ ├── PacificAtlanticWaterFlowBFS.java │ └── PacificAtlanticWaterFlowDFS.java ├── ShortestPathInBinaryMatrix │ └── ShortestPathInBinaryMatrix.java ├── SurroundedRegions │ └── SurroundedRegions.java ├── WallsAndGates │ ├── WallsAndGatesBFS.java │ └── WallsAndGatesDFS.java └── WordLadder │ └── WordLadder.java ├── SlidingWindow ├── LongestRepeatingCharacterReplacement │ └── LongestRepeatingCharacterReplacement.java ├── LongestSubstringWithAtMostKDistinctCharacters │ └── LongestSubstringWithAtMostKDistinctCharacters.java ├── LongestSubstringWithAtMostTwoDistinctCharacters │ └── LongestSubstringWithAtMostTwoDistinctCharacters.java ├── LongestSubstringWithoutRepeatingCharacters │ └── LongestSubstringWithoutRepeatingCharacters.java ├── MaxConsecutiveOnes │ ├── MaxConsecutiveOnes.java │ ├── MaxConsecutiveOnes2.java │ └── MaxConsecutiveOnes3.java ├── MinimumSizeSubarraySum │ └── MinimumSizeSubarraySum.java ├── MinimumWindowSubstring │ └── MinimumWindowSubstring.java └── PermutationInString │ └── PermutationInString.java ├── Sort ├── CourseSchedule │ ├── CourseSchedule1.java │ └── CourseSchedule2.java ├── FindMedianfromDataStream │ └── FindMedianfromDataStream.java ├── InsertInterval │ └── InsertInterval.java ├── IntervalListIntersections │ └── IntervalListIntersections.java ├── KClosestPointsToOrigin │ ├── KClosestPointsToOrigin.java │ └── KClosestPointsToOrigin.py ├── MeetingRooms │ ├── MeetingRooms1.java │ └── MeetingRooms2.java ├── MergeIntervals │ └── MergeIntervals.java ├── Non-overlappingIntervals │ └── Non-overlappingIntervals.java ├── SlidingWindowMedian │ └── SlidingWindowMedian.java ├── SortCharactersByFrequency │ ├── SortCharactersByFrequency.java │ └── SortCharactersByFrequency.py └── TopKFrequentElements │ ├── TopKFrequentElements.java │ └── TopKFrequentElements.py ├── Stack&Queue ├── BasicCalculator │ └── BasicCalculator.java ├── BasicCalculatorII │ └── BasicCalculatorII.java ├── BasicCalculatorIII │ └── BasicCalculatorIII.java ├── DailyTemperatures │ └── DailyTemperatures.java ├── ImplementQueueUsingStacks │ └── ImplementQueueUsingStacks.java ├── ImplementStackUsingQueues │ └── ImplementStackUsingQueues.java ├── MinStack │ └── MinStack.java ├── NextGreaterElement │ └── NextGreaterElement.java ├── NextGreaterElementII │ └── NextGreaterElementII.java └── ValidParentheses │ └── ValidParentheses.java ├── Tree ├── BalancedBinaryTree │ ├── BalancedBinaryTree.java │ └── BalancedBinaryTree.py ├── BinaryTreeBFSGuide │ ├── AverageofLevelsinBinaryTree │ │ ├── AverageofLevelsinBinaryTree.java │ │ └── AverageofLevelsinBinaryTree.py │ ├── BinaryTreeLevelOrderTraversal │ │ ├── BinaryTreeLevelOrderTraversal.java │ │ └── BinaryTreeLevelOrderTraversal.py │ ├── BinaryTreeZigzagLevelOrderTraversal │ │ ├── BinaryTreeZigzagLevelOrderTraversal.java │ │ └── BinaryTreeZigzagLevelOrderTraversal.py │ └── PopulatingNextRightPointersinEachNode │ │ ├── PopulatingNextRightPointersinEachNode.java │ │ └── PopulatingNextRightPointersinEachNode.py ├── BinaryTreeInorderTraversal │ ├── BinaryTreeInorderTraversal_Iterative.java │ ├── BinaryTreeInorderTraversal_Iterative.py │ ├── BinaryTreeInorderTraversal_Recursive.java │ └── BinaryTreeInorderTraversal_Recursive.py ├── BinaryTreeMaximumPathSum │ ├── BinaryTreeMaximumPathSum.java │ └── BinaryTreeMaximumPathSum.py ├── BinaryTreePostorderTraversal │ ├── BinaryTreePostorderTraversal_Recursive.java │ ├── BinaryTreePostorderTraversal_Recursive.py │ ├── BinaryTreePostorderTraversal_iterative.java │ └── BinaryTreePostorderTraversal_iterative.py ├── BinaryTreePreorderTraversal │ ├── BinaryTreePreorderTraversal_Iterative.java │ ├── BinaryTreePreorderTraversal_Iterative.py │ ├── BinaryTreePreorderTraversal_Recursive.java │ └── BinaryTreePreorderTraversal_Recursive.py ├── ConstructBinaryTreefromInorderandPostorderTraversal │ ├── ConstructBinaryTreefromInorderandPostorderTraversal.java │ └── ConstructBinaryTreefromInorderandPostorderTraversal.py ├── ConstructBinaryTreefromPreorderandInorderTraversal │ ├── ConstructBinaryTreefromPreorderandInorderTraversal.java │ └── ConstructBinaryTreefromPreorderandInorderTraversal.py ├── ConstructBinaryTreefromPreorderandPostorderTraversal │ ├── ConstructBinaryTreefromPreorderandPostorderTraversal.java │ └── ConstructBinaryTreefromPreorderandPostorderTraversal.py ├── ConvertBinarySearchTreeToSortedDoublyLinkedList │ └── ConvertBinarySearchTreeToSortedDoublyLinkedList.java ├── DiameterOfBinaryTree │ ├── DiameterOfBinaryTree.java │ └── DiameterOfBinaryTree.py ├── FindDuplicateSubtrees │ ├── FindDuplicateSubtrees.java │ └── FindDuplicateSubtrees.py ├── ImplementTrie │ └── ImplementTrie.java ├── LowestCommonAncestorofaBinarySearchTree │ └── LowestCommonAncestorofaBinarySearchTree.java ├── LowestCommonAncestorofaBinaryTree │ ├── LowestCommonAncestorofaBinaryTree.java │ └── LowestCommonAncestorofaBinaryTree.py ├── PathSum │ ├── PathSum1.java │ ├── PathSum1.py │ ├── PathSum2.java │ └── PathSum2.py ├── PopulatingNextRightPointersinEachNodeII │ ├── PopulatingNextRightPointersinEachNodeII.java │ └── PopulatingNextRightPointersinEachNodeII.py ├── SerializeandDeserializeBinaryTree │ ├── SerializeandDeserializeBinaryTree.java │ └── SerializeandDeserializeBinaryTree.py ├── SerializeandDeserializeN-aryTree │ ├── SerializeandDeserializeN-aryTree_BFS.java │ └── SerializeandDeserializeN-aryTree_DFS.java ├── SymmetricTree │ ├── SymmetricTree.java │ └── SymmetricTree.py └── UnionFind │ └── NumberOfConnectedComponentsInAnUndirectedGraph │ └── NumberOfConnectedComponentsInAnUndirectedGraph.java └── TwoPointers ├── 3Sum ├── 3Sum.java ├── 3SumClosest.java └── 3SumSmaller.java ├── ContainerWithMostWater └── ContainerWithMostWater.java ├── LinkedListDeletion ├── RemoveLinkedListElements │ └── RemoveLinkedListElements.java └── RemoveNthFromEndOfList │ └── RemoveNthFromEndOfList.java ├── MiddleNodeOfList └── MiddleNodeOfList.java ├── MoveZeroes └── MoveZeroes.java ├── PalindromeLinkedList └── PalindromeLinkedList.java ├── PartitionLabels └── PartitionLabels.java ├── RemoveDuplicatesfromSortedArray ├── RemoveDuplicatesfromSortedArray.java └── RemoveDuplicatesfromSortedArrayII.java ├── ReorderList └── ReorderList.java ├── SortColors └── SortColors.java ├── SquaresOfASortedArray └── SquaresOfASortedArray.java ├── TrappingRainWater └── TrappingRainWater.java └── TwoSum ├── TwoSum.java └── TwoSumII.java /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "java.project.sourcePaths": [ 3 | "src/SukoduSolver" 4 | ] 5 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Code Solution 2 | 3 | Welcome to Code Solution. Here is where I will share my code solution for my YouTube Channels. 4 | 5 | For Leetcode (Algorithms & Data Structures) please checkout: [here](https://www.youtube.com/c/EricProgramming/featured). 6 | 7 | For Full Stack Software Development please checkout: [here](https://www.youtube.com/channel/UCOXRjenlq9PmlTqd_JhAbMQ). 8 | -------------------------------------------------------------------------------- /src/Array/DiagonalTraverse/DiagonalTraverse.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | int m; 3 | int n; 4 | public int[] findDiagonalOrder(int[][] mat) { 5 | m = mat.length; 6 | n = mat[0].length; 7 | int[] res = new int[m * n]; 8 | 9 | //Traverse the list 10 | int row = 0, col = 0, index = 0; 11 | 12 | while(row < m && col < n){ 13 | res[index++] = mat[row][col]; 14 | if(traverseUp(row, col)){ 15 | if(withBoundary(row - 1, col + 1)){ 16 | row--; 17 | col++; 18 | }else if(withBoundary(row, col + 1)){ 19 | col++; 20 | }else{ 21 | row++; 22 | } 23 | }else{ 24 | if(withBoundary(row + 1, col - 1)){ 25 | row++; 26 | col--; 27 | }else if(withBoundary(row + 1, col)){ 28 | row++; 29 | }else{ 30 | col++; 31 | } 32 | } 33 | } 34 | return res; 35 | } 36 | private boolean traverseUp(int row, int col){ 37 | return (row + col) % 2 == 0; 38 | } 39 | private boolean withBoundary(int row, int col){ 40 | if(row < 0 || m <= row) return false; 41 | if(col < 0 || n <= col) return false; 42 | return true; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Array/DiagonalTraverse/DiagonalTraverse.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def findDiagonalOrder(self, mat: List[List[int]]) -> List[int]: 3 | 4 | m = len(mat) 5 | n = len(mat[0]) 6 | 7 | def is_traverse_up(row, col): 8 | # if even number we are traversing up right 9 | return (row + col) % 2 == 0 10 | 11 | def is_with_in_boundary(row, col): 12 | return 0 <= row and 0 <= col and row < m and col < n 13 | 14 | res = [] 15 | row = col = 0 16 | 17 | for i in range(m * n): 18 | res.append(mat[row][col]) 19 | 20 | if is_traverse_up(row, col): 21 | if is_with_in_boundary(row - 1, col + 1): 22 | row -= 1 23 | col += 1 24 | elif is_with_in_boundary(row, col + 1): 25 | col += 1 26 | else: 27 | row += 1 28 | else: 29 | if is_with_in_boundary(row+1, col-1): 30 | row += 1 31 | col -= 1 32 | elif is_with_in_boundary(row+1, col): 33 | row += 1 34 | else: 35 | col += 1 36 | return res 37 | -------------------------------------------------------------------------------- /src/Array/DuplicateZeros/DuplicateZeros.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public void duplicateZeros(int[] arr) { 3 | Queue queue = new LinkedList<>(); 4 | for(int i = 0; i < arr.length; i++){ 5 | if(arr[i] == 0){ 6 | queue.add(0); 7 | queue.add(0); 8 | }else{ 9 | queue.add(arr[i]); 10 | } 11 | Integer first = queue.poll(); 12 | arr[i] = first; 13 | } 14 | } 15 | } 16 | 17 | /*** 18 | Brute force: 19 | N^2 20 | 21 | for num in arr 22 | if num is zero 23 | shift all elements on the right to the right by one 24 | 25 | Optimized: 26 | O(N) 27 | 28 | arr = [1,0,0,2,3,0,0,4] 29 | ^ 30 | Queue=[5,0,0] 31 | 32 | 33 | 34 | 35 | ***/ 36 | -------------------------------------------------------------------------------- /src/Array/DuplicateZeros/DuplicateZeros.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | class Solution: 4 | def duplicateZeros(self, arr: List[int]) -> None: 5 | """ 6 | Do not return anything, modify arr in-place instead. 7 | """ 8 | queue = deque() 9 | 10 | for i in range(len(arr)): 11 | if arr[i] == 0: 12 | queue.append(0) 13 | queue.append(0) 14 | else: 15 | queue.append(arr[i]) 16 | 17 | arr[i] = queue.popleft() 18 | -------------------------------------------------------------------------------- /src/Array/FindPivotIndex/FindPivotIndex.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int pivotIndex(int[] nums) { 3 | //1. Get Sum of the array 4 | int sum = 0; 5 | for(int num : nums){ 6 | sum += num; 7 | } 8 | //2. Define the leftSum & rightSum 9 | int leftSum = 0, rightSum = sum; 10 | 11 | //Find the pivot index 12 | for(int i = 0; i < nums.length; i++){ 13 | rightSum -= nums[i]; 14 | if(leftSum == rightSum) return i; 15 | leftSum += nums[i]; 16 | } 17 | //3. return -1 if can't find it 18 | return -1; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Array/FindPivotIndex/FindPivotIndex.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def pivotIndex(self, nums: List[int]) -> int: 3 | n = len(nums) 4 | left_sum = [0] * n 5 | 6 | for i in range(1, n): 7 | left_sum[i] = left_sum[i - 1] + nums[i - 1] 8 | 9 | right_sum = [0] * n 10 | 11 | for i in reversed(range(n - 1)): 12 | right_sum[i] = right_sum[i + 1] + nums[i + 1] 13 | 14 | for i in range(n): 15 | if left_sum[i] == right_sum[i]: 16 | return i 17 | 18 | return -1 19 | -------------------------------------------------------------------------------- /src/Array/LongestCommonPrefix/LongestCommonPrefix.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public String longestCommonPrefix(String[] strs) { 3 | int n = strs.length; 4 | if(n == 0) return ""; 5 | String prefix = strs[0]; 6 | for(int i = 1; i < n; i++){ 7 | String cur = strs[i]; 8 | while(cur.indexOf(prefix) != 0){ 9 | prefix = prefix.substring(0, prefix.length() - 1); 10 | } 11 | } 12 | return prefix; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Array/MinimumTimeDifference/MinimumTimeDifference.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def findMinDifference(self, timePoints: List[str]) -> int: 3 | 4 | def convert_to_minutes(time: str) -> int: 5 | time_arr = time.split(":") 6 | return int(time_arr[0]) * 60 + int(time_arr[1]) 7 | 8 | times = set() 9 | max_minutes = 0 10 | 11 | for time in timePoints: 12 | minutes = convert_to_minutes(time) 13 | if minutes in times: 14 | return 0 15 | else: 16 | times.add(minutes) 17 | max_minutes = max(minutes, max_minutes) 18 | 19 | pre_minutes = None 20 | min_diff = one_day_in_minutes = 24 * 60 21 | 22 | for cur_minutes in range(max_minutes, -1, -1): 23 | if cur_minutes in times: 24 | if pre_minutes is not None: 25 | min_diff = min(min_diff, pre_minutes - cur_minutes, 26 | (cur_minutes + one_day_in_minutes) - pre_minutes) 27 | pre_minutes = cur_minutes 28 | 29 | # Compare min minutes with max minutes 30 | min_diff = min( 31 | min_diff, (pre_minutes + one_day_in_minutes) - max_minutes) 32 | 33 | return min_diff 34 | -------------------------------------------------------------------------------- /src/Array/NextPermutation/NextPermutation.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public void nextPermutation(int[] nums) { 3 | //Base case 4 | int n = nums.length; 5 | if(n < 2) return; 6 | 7 | //Step 1: find elements to replace 8 | int cur = n - 2, pre = n - 1; 9 | while(0 <= cur){ 10 | if(nums[cur] < nums[pre]) break; 11 | cur--; 12 | pre--; 13 | } 14 | if(0 <= cur){ 15 | int replaceIndex = n - 1; 16 | while(0 < replaceIndex){ 17 | if(nums[cur] < nums[replaceIndex]) break; 18 | replaceIndex--; 19 | } 20 | swap(nums, replaceIndex, cur); 21 | } 22 | reverse(nums, pre, n - 1); 23 | } 24 | private void swap(int[] nums, int i1, int i2){ 25 | int temp = nums[i1]; 26 | nums[i1] = nums[i2]; 27 | nums[i2] = temp; 28 | } 29 | private void reverse(int[] nums, int start, int end){ 30 | while(start < end){ 31 | swap(nums, start, end); 32 | start++; 33 | end--; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Array/PascalsTriangle/PascalsTriangle.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public List> generate(int numRows) { 3 | //define list 4 | List> res = new LinkedList<>(); 5 | 6 | //add 1 to the first row 7 | List firstRow = new LinkedList<>(); 8 | firstRow.add(1); 9 | res.add(firstRow); 10 | //iterate from row index 1 to row index numRows - 1 11 | for(int i = 1; i < numRows; i++){ 12 | List curRow = new LinkedList<>(); 13 | //1. add the left border 1 14 | curRow.add(1); 15 | List preRow = res.get(i - 1); 16 | //2. iterate 1 to current row index to add each sum 17 | for(int j = 1; j < i; j++){ 18 | int val = preRow.get(j) + preRow.get(j - 1); 19 | curRow.add(val); 20 | } 21 | //3. Add the right border 1 22 | curRow.add(1); 23 | 24 | res.add(curRow); 25 | } 26 | //return the list 27 | return res; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Array/PascalsTriangle/PascalsTriangle.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def generate(self, numRows: int) -> List[List[int]]: 3 | res = [[1]] 4 | 5 | for i in range(1, numRows): 6 | cur_level = [1] 7 | pre_level = res[i - 1] 8 | for j in range(1, i): 9 | cur_level.append(pre_level[j - 1] + pre_level[j]) 10 | cur_level.append(1) 11 | res.append(cur_level) 12 | return res 13 | -------------------------------------------------------------------------------- /src/Array/ProductOfArrayExceptSelf/ProductOfArrayExceptSelf.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int[] productExceptSelf(int[] nums) { 3 | int[] res = new int[nums.length]; 4 | 5 | //Get prefix 6 | res[0] = 1; 7 | for(int i = 1; i < res.length; i++){ 8 | res[i] = res[i - 1] * nums[i - 1]; 9 | } 10 | 11 | //Get product array except self 12 | int postFix = 1; 13 | for(int i = res.length - 1; i >= 0; i--){ 14 | res[i] *= postFix; 15 | postFix *= nums[i]; 16 | } 17 | return res; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Array/ProductOfArrayExceptSelf/ProductOfArrayExceptSelf.py: -------------------------------------------------------------------------------- 1 | from typing import * 2 | 3 | 4 | class Solution: 5 | def productExceptSelf(self, nums: List[int]) -> List[int]: 6 | # 1. Calculate the prefix 7 | res = [1] 8 | for i in range(1, len(nums)): 9 | res.append(res[i - 1] * nums[i - 1]) 10 | 11 | # 2. use the array to calculate the product except self 12 | postfix = 1 13 | for i in range(len(nums) - 1, -1, -1): 14 | prefix = res[i] 15 | res[i] = postfix * prefix 16 | postfix *= nums[i] 17 | 18 | return res 19 | -------------------------------------------------------------------------------- /src/Array/ReorderDataInLogFiles/ReorderDataInLogFiles.java: -------------------------------------------------------------------------------- 1 | import java.util.Collection; 2 | import java.util.Collections; 3 | 4 | class Solution { 5 | public String[] reorderLogFiles(String[] logs) { 6 | Arrays.sort(logs, (log1, log2) -> { 7 | String[] arr1 = splitStr(log1); 8 | String[] arr2 = splitStr(log2); 9 | 10 | boolean isNum1 = isNumber(arr1[1].charAt(0)); 11 | boolean isNum2 = isNumber(arr2[1].charAt(0)); 12 | if (isNum1 && isNum2) 13 | return 0; 14 | else if (isNum1) 15 | return 1; 16 | else if (isNum2) 17 | return -1; 18 | boolean isSameContent = arr1[1].equals(arr2[1]); 19 | if (isSameContent) 20 | return arr1[0].compareTo(arr2[0]); 21 | return arr1[1].compareTo(arr2[1]); 22 | }); 23 | Collections.sort(list); 24 | return logs; 25 | } 26 | 27 | private String[] splitStr(String log) { 28 | return log.split(" ", 2); 29 | } 30 | 31 | private boolean isNumber(char curChar) { 32 | return '0' <= curChar && curChar <= '9'; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Array/RobotBoundedInCircle/RobotBoundedInCircle.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | final int UP = 0; 3 | final int LEFT = 1; 4 | final int DOWN = 2; 5 | final int RIGHT = 3; 6 | final int ORIGIN_DIRECTION = UP; 7 | public boolean isRobotBounded(String instructions) { 8 | int curDirection = ORIGIN_DIRECTION; 9 | int row = 0, col = 0; 10 | 11 | for(char curChar : instructions.toCharArray()){ 12 | if(curChar == 'G'){ 13 | if(curDirection == UP){ 14 | row--; 15 | }else if(curDirection == DOWN){ 16 | row++; 17 | }else if(curDirection == LEFT){ 18 | col--; 19 | }else if(curDirection == RIGHT){ 20 | col++; 21 | } 22 | }else if(curChar == 'L'){ 23 | curDirection++; 24 | if(curDirection > RIGHT){ 25 | curDirection = UP; 26 | } 27 | }else if(curChar == 'R') { 28 | curDirection--; 29 | if(curDirection < UP){ 30 | curDirection = RIGHT; 31 | } 32 | } 33 | } 34 | boolean posChanged = row != 0 || col != 0; 35 | if(!posChanged) return true; 36 | if(curDirection != ORIGIN_DIRECTION) return true; 37 | return false; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Array/SpiralMatrix/SpiralMatrix.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public List spiralOrder(int[][] matrix) { 3 | //Define borders 4 | int m = matrix.length, n = matrix[0].length; 5 | int left = 0, right = n - 1, top = 0, down = m - 1; 6 | 7 | //Define result arr 8 | Integer[] res = new Integer[m * n]; 9 | int index = 0; 10 | 11 | while(index < res.length){ 12 | //Traverse right 13 | for(int i = left; i <= right && index < res.length; i++){ 14 | res[index++] = matrix[top][i]; 15 | } 16 | top++; 17 | //Traverse down 18 | for(int i = top; i <= down && index < res.length; i++){ 19 | res[index++] = matrix[i][right]; 20 | } 21 | right--; 22 | //Traverse left 23 | for(int i = right; i >= left && index < res.length; i--){ 24 | res[index++] = matrix[down][i]; 25 | } 26 | down--; 27 | //Traverse top 28 | for(int i = down; i >= top && index < res.length; i--){ 29 | res[index++] = matrix[i][left]; 30 | } 31 | left++; 32 | } 33 | return Arrays.asList(res); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Array/SpiralMatrix/SpiralMatrix.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def spiralOrder(self, matrix: List[List[int]]) -> List[int]: 3 | res = [] 4 | row_begin = 0 5 | col_begin = 0 6 | row_end = len(matrix)-1 7 | col_end = len(matrix[0])-1 8 | total = len(matrix) * len(matrix[0]) 9 | while len(res) < total: 10 | for i in range(col_begin,col_end+1): 11 | res.append(matrix[row_begin][i]) 12 | row_begin += 1 13 | for i in range(row_begin,row_end+1): 14 | res.append(matrix[i][col_end]) 15 | col_end -= 1 16 | if (row_begin <= row_end): 17 | for i in range(col_end,col_begin-1,-1): 18 | res.append(matrix[row_end][i]) 19 | row_end -= 1 20 | if (col_begin <= col_end): 21 | for i in range(row_end,row_begin-1,-1): 22 | res.append(matrix[i][col_begin]) 23 | col_begin += 1 24 | return res 25 | -------------------------------------------------------------------------------- /src/Array/SpiralMatrix/SpiralMatrixII.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int[][] generateMatrix(int n) { 3 | //Define variables 4 | int[][] res = new int[n][n]; 5 | int left = 0, right = n - 1, top = 0, down = n - 1; 6 | int counter = 1, total = n * n; 7 | 8 | //Spiral Traverse 9 | while(counter <= total){ 10 | //Traverse Left 11 | for(int i = left; i <= right; i++){ 12 | res[top][i] = counter++; 13 | } 14 | top++; 15 | //Traverse down 16 | for(int i = top; i <= down; i++){ 17 | res[i][right] = counter++; 18 | } 19 | right--; 20 | //Traverse right 21 | for(int i = right; i >= left; i--){ 22 | res[down][i] = counter++; 23 | } 24 | down--; 25 | //Traverse top 26 | for(int i = down; i >= top; i--){ 27 | res[i][left] = counter++; 28 | } 29 | left++; 30 | } 31 | return res; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Array/SpiralMatrix/SpiralMatrixII.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def generateMatrix(self, n: int) -> List[List[int]]: 3 | # 1. Create the 2d array 4 | res = [[0] * n for i in range(n)] 5 | 6 | # 2. Traverse in spiral order to fill the array 7 | top = left = 0 # border 8 | right = down = n - 1 # border 9 | counter = 1 10 | 11 | while counter <= n * n: 12 | # Top row 13 | for col in range(left, right + 1): 14 | res[top][col] = counter 15 | counter += 1 16 | top += 1 17 | 18 | # Right col 19 | for row in range(top, down + 1): 20 | res[row][right] = counter 21 | counter += 1 22 | right -= 1 23 | 24 | # down row or bottom row 25 | for col in range(right, left - 1, -1): 26 | res[down][col] = counter 27 | counter += 1 28 | down -= 1 29 | 30 | # left col 31 | for row in range(down, top - 1, -1): 32 | res[row][left] = counter 33 | counter += 1 34 | left += 1 35 | 36 | return res 37 | -------------------------------------------------------------------------------- /src/Array/SubarraySumEqualsK/SubarraySumEqualsK.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int subarraySum(int[] nums, int k) { 3 | HashMap hm = new HashMap<>(); 4 | int curSum = 0; 5 | hm.put(0, 1); 6 | int Counter = 0; 7 | for(int i = 0; i < nums.length; i++){ 8 | curSum += nums[i]; 9 | int ps2 = curSum - k; 10 | if(hm.containsKey(ps2)){ 11 | Counter += hm.get(ps2); 12 | } 13 | hm.put(curSum, hm.getOrDefault(curSum, 0) + 1); 14 | } 15 | return Counter; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Array/ZigZagConversion/ZigZagConversion.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public String convert(String s, int numRows) { 3 | //Define StringBuilders 4 | StringBuilder[] sbs = new StringBuilder[numRows]; 5 | for(int i = 0; i < numRows; i++){ 6 | sbs[i] = new StringBuilder(); 7 | } 8 | 9 | //Define Variables 10 | char[] arr = s.toCharArray(); 11 | int n = arr.length; 12 | int index = 0; 13 | 14 | //Traverse zig zag 15 | while(index < n){ 16 | //Go down 17 | for(int j = 0; j < numRows && index < n; j++){ 18 | sbs[j].append(arr[index++]); 19 | } 20 | //Go Up before start 21 | for(int j = numRows - 2; j > 0 && index < n; j--){ 22 | sbs[j].append(arr[index++]); 23 | } 24 | } 25 | 26 | //Combine all stringbuilders into one 27 | StringBuilder res = sbs[0]; 28 | for(int i = 1; i < numRows; i++){ 29 | res.append(sbs[i].toString()); 30 | } 31 | return res.toString(); 32 | } 33 | } 34 | 35 | 36 | /** 37 | P A H N 38 | A P L S I I G 39 | Y I R 40 | **/ 41 | -------------------------------------------------------------------------------- /src/Array/ZigZagConversion/ZigZagConversion.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def convert(self, s: str, numRows: int) -> str: 3 | # 1. Create n number of lists 4 | lists = [] 5 | for i in range(numRows): 6 | lists.append([]) 7 | 8 | # 2. Traverse the string in zig zag order 9 | index = 0 10 | while index < len(s): 11 | # Go down 12 | for i in range(numRows): 13 | if index == len(s): 14 | break 15 | lists[i].append(s[index]) 16 | index += 1 17 | 18 | # Go up 19 | for i in range(numRows - 2, 0, -1): 20 | if index == len(s): 21 | break 22 | lists[i].append(s[index]) 23 | index += 1 24 | 25 | # 3. Combine the lists into one str 26 | res = "" 27 | for cur_list in lists: 28 | res += "".join(cur_list) 29 | 30 | return res 31 | -------------------------------------------------------------------------------- /src/Array/groupAnagrams/groupAnagrams.java: -------------------------------------------------------------------------------- 1 | //O(n*k) 2 | class Solution { 3 | public List> groupAnagrams(String[] strs) { 4 | //Keep a table to group all the anagrams together 5 | Map> map = new HashMap<>(); 6 | 7 | for(String str : strs){ 8 | //Sort the string to get the key 9 | String key = generateKey(str); 10 | //Add the current string to the current table 11 | if(!map.containsKey(key)){ 12 | map.put(key, new LinkedList<>()); 13 | } 14 | List list = map.get(key); 15 | list.add(str); 16 | } 17 | return new ArrayList<>(map.values()); 18 | } 19 | private String generateKey(String str){ 20 | int[] map = new int[26]; 21 | char[] arr = str.toCharArray(); 22 | //O(k) to convert to map {a: 1, b: 0 ....} 23 | for(char curChar : arr){ 24 | map[curChar - 'a']++; 25 | } 26 | StringBuilder sb = new StringBuilder(); 27 | //O(26) to convert to "1#0#..." 28 | for(int num : map){ 29 | sb.append(num); 30 | sb.append("#"); 31 | } 32 | return sb.toString(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Backtracking/CombinationsSum/CombinationSum1.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class CombinationSum1 { 4 | List> res = new LinkedList<>(); 5 | int[] candidates; 6 | 7 | public List> combinationSum(int[] candidates, int target) { 8 | this.candidates = candidates; 9 | helper(target, new LinkedList(), 0); 10 | return res; 11 | } 12 | 13 | private void helper(int target, List comb, int index) { 14 | // Check if we found a combination 15 | if (target == 0) { 16 | List temp = new LinkedList<>(comb); 17 | res.add(temp); 18 | return; 19 | } 20 | // DFS all the paths 21 | for (int i = index; i < candidates.length; i++) { 22 | int curSum = target - candidates[i]; 23 | // Check if out of bound 24 | if (curSum < 0) 25 | continue; 26 | comb.add(candidates[i]); 27 | helper(curSum, comb, i);// We can still reuse the same element dfs down the path 28 | comb.remove(comb.size() - 1); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Backtracking/CombinationsSum/CombinationSum2.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class CombinationSum2 { 4 | List> res = new LinkedList<>(); 5 | int[] candidates; 6 | 7 | public List> combinationSum2(int[] candidates, int target) { 8 | Arrays.sort(candidates); 9 | this.candidates = candidates; 10 | helper(target, 0, new LinkedList()); 11 | return res; 12 | } 13 | 14 | private void helper(int targetSum, int index, List comb) { 15 | // Check if the target sum is finished 16 | if (targetSum == 0) { 17 | res.add(new LinkedList(comb)); 18 | return; 19 | } 20 | 21 | // DFS all paths 22 | for (int i = index; i < candidates.length; i++) { 23 | if (i != index && candidates[i] == candidates[i - 1]) 24 | continue; 25 | int sum = targetSum - candidates[i]; 26 | 27 | if (sum < 0) 28 | break;// break because the array is sorted 29 | 30 | comb.add(candidates[i]); 31 | helper(sum, i + 1, comb); 32 | comb.remove(comb.size() - 1); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Backtracking/CombinationsSum/CombinationSum3.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class CombinationSum3 { 4 | List> res = new LinkedList<>(); 5 | 6 | public List> combinationSum3(int k, int n) { 7 | helper(k, n, new LinkedList(), 1); 8 | return res; 9 | } 10 | 11 | private void helper(int len, int sum, List comb, int curElement) { 12 | // Check if we found a combination 13 | if (sum == 0 && len == 0) { 14 | res.add(new LinkedList(comb)); 15 | return; 16 | } 17 | // Check if the length is out of bound 18 | if (len == 0) 19 | return; 20 | 21 | // DFS all paths 22 | for (int i = curElement; i <= 9; i++) { 23 | int newSum = sum - i; 24 | if (newSum < 0) 25 | break; 26 | comb.add(i); 27 | helper(len - 1, newSum, comb, i + 1); 28 | comb.remove(comb.size() - 1); 29 | } 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Backtracking/GenerateParentheses/GenerateParentheses.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | List res = new LinkedList<>(); 3 | public List generateParenthesis(int n) { 4 | dfs(new StringBuilder(), 0, n); 5 | return res; 6 | } 7 | private void dfs(StringBuilder sb, int close, int n){ 8 | if(n == 0 && close == 0){ 9 | res.add(sb.toString()); 10 | return; 11 | } 12 | 13 | //Add open parenthese 14 | if(n > 0){ 15 | sb.append('('); 16 | dfs(sb, close + 1, n - 1); 17 | sb.setLength(sb.length() - 1); 18 | } 19 | //Add close parenthese 20 | if(close > 0){ 21 | sb.append(')'); 22 | dfs(sb, close - 1, n); 23 | sb.setLength(sb.length() - 1); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Backtracking/LetterCombinationsOfAPhoneNumber/LetterCombinationsOfAPhoneNumber.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | Map phone = new HashMap<>() {{ 3 | put('2', "abc"); 4 | put('3', "def"); 5 | put('4', "ghi"); 6 | put('5', "jkl"); 7 | put('6', "mno"); 8 | put('7', "pqrs"); 9 | put('8', "tuv"); 10 | put('9', "wxyz"); 11 | }}; 12 | char[] digitsArr; 13 | List res = new LinkedList<>(); 14 | public List letterCombinations(String digits) { 15 | digitsArr = digits.toCharArray(); 16 | //Base case 17 | if(digitsArr.length != 0){ 18 | dfs(0, new StringBuilder()); 19 | } 20 | return res; 21 | } 22 | private void dfs(int index, StringBuilder sb){ 23 | //Base case 24 | if(index == digitsArr.length) { 25 | res.add(sb.toString()); 26 | return; 27 | } 28 | String characters = phone.get(digitsArr[index]); 29 | for(char curChar : characters.toCharArray()){ 30 | sb.append(curChar); 31 | dfs(index + 1, sb); 32 | sb.setLength(sb.length() - 1); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Backtracking/PalindromePartitioning/PalindromePartitioning.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | List> res = new LinkedList<>(); 3 | String s; 4 | char[] arr; 5 | public List> partition(String s) { 6 | this.s = s; 7 | this.arr = s.toCharArray(); 8 | helper(0, new LinkedList()); 9 | return res; 10 | } 11 | private void helper(int index, List comb){ 12 | if(index >= arr.length) { 13 | res.add(new LinkedList<>(comb)); 14 | return; 15 | } 16 | 17 | for(int i = index; i < arr.length; i++){ 18 | if(!isPalindrome(index, i)) continue; 19 | comb.add(s.substring(index, i + 1)); 20 | helper(i + 1, comb); 21 | comb.remove(comb.size() - 1); 22 | } 23 | } 24 | private boolean isPalindrome(int L, int R){ 25 | while(L < R){ 26 | if(arr[L] != arr[R]) return false; 27 | L++; 28 | R--; 29 | } 30 | return true; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Backtracking/Permutations/Permutations1.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Permutations1 { 4 | List> res = new LinkedList<>(); 5 | 6 | public List> permute(int[] nums) { 7 | List list = new LinkedList<>(); 8 | for (int num : nums) { 9 | list.add(num); 10 | } 11 | helper(list, new LinkedList<>()); 12 | return res; 13 | } 14 | 15 | private void helper(List list, List curComb) { 16 | if (list.isEmpty()) { 17 | List temp = new LinkedList<>(curComb); 18 | res.add(temp); 19 | return; 20 | } 21 | for (int i = 0; i < list.size(); i++) { 22 | Integer val = list.remove(i); 23 | curComb.add(val); 24 | helper(list, curComb); 25 | // Reverse the changes to get ready for the next iteration 26 | curComb.remove(curComb.size() - 1); 27 | list.add(i, val); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Backtracking/Permutations/Permutations2.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Permutations2 { 4 | List> res = new LinkedList<>(); 5 | 6 | public List> permuteUnique(int[] nums) { 7 | Map hm = new HashMap<>(); 8 | for (int num : nums) { 9 | hm.put(num, hm.getOrDefault(num, 0) + 1); 10 | } 11 | helper(new LinkedList<>(), hm); 12 | return res; 13 | } 14 | 15 | private void helper(List curComb, Map hm) { 16 | if (hm.isEmpty()) { 17 | List temp = new LinkedList<>(curComb); 18 | res.add(temp); 19 | return; 20 | } 21 | Set set = new HashSet<>(hm.keySet()); 22 | for (Integer key : set) { 23 | if (hm.get(key) == 1) { 24 | hm.remove(key); 25 | } else { 26 | hm.put(key, hm.get(key) - 1); 27 | } 28 | curComb.add(key); 29 | helper(curComb, hm); 30 | // Reverse the changes to get ready for the next iteration 31 | curComb.remove(curComb.size() - 1); 32 | hm.put(key, hm.getOrDefault(key, 0) + 1); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Backtracking/Subset/Subset1.java: -------------------------------------------------------------------------------- 1 | public class Subset1 { 2 | List> res = new LinkedList<>(); 3 | int[] nums; 4 | 5 | public List> subsets(int[] nums) { 6 | this.nums = nums; 7 | helper(0, new LinkedList()); 8 | return res; 9 | } 10 | 11 | private void helper(int index, List comb) { 12 | res.add(new LinkedList<>(comb)); 13 | for (int i = index; i < nums.length; i++) { 14 | comb.add(nums[i]); 15 | helper(i + 1, comb); 16 | comb.remove(comb.size() - 1); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Backtracking/Subset/Subset2.java: -------------------------------------------------------------------------------- 1 | public class Subset2 { 2 | List> res = new LinkedList<>(); 3 | int[] arr; 4 | 5 | public List> subsetsWithDup(int[] nums) { 6 | arr = nums; 7 | Arrays.sort(arr); 8 | helper(new LinkedList<>(), 0); 9 | return res; 10 | } 11 | 12 | private void helper(List sub, int curIdx) { 13 | res.add(new ArrayList<>(sub)); 14 | for (int i = curIdx; i < arr.length; i++) { 15 | if (i != curIdx && arr[i] == arr[i - 1]) 16 | continue; 17 | sub.add(arr[i]); 18 | helper(sub, i + 1); 19 | sub.remove(sub.size() - 1); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/BinarySearch/FindFirstAndLastPositionOfElementInSortedArray/FindFirstAndLastPositionOfElementInSortedArray.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | int[] arr; 3 | public int[] searchRange(int[] nums, int target) { 4 | int[] res = new int[]{-1,-1}; 5 | if(nums.length == 0) return res; 6 | arr = nums; 7 | res[0] = findLeft(target); 8 | res[1] = findRight(target); 9 | return res; 10 | } 11 | private int findLeft(int target){ 12 | int left = 0, right = arr.length - 1; 13 | while(left + 1 < right){ 14 | int mid = left + (right - left) / 2; 15 | if(arr[mid] < target){ 16 | left = mid; 17 | }else{ 18 | right = mid; 19 | } 20 | } 21 | if(arr[left] == target) return left; 22 | if(arr[right] == target) return right; 23 | return -1; 24 | } 25 | private int findRight(int target){ 26 | int left = 0, right = arr.length - 1; 27 | while(left + 1 < right){ 28 | int mid = left + (right - left) / 2; 29 | if(arr[mid] <= target){ 30 | left = mid; 31 | }else{ 32 | right = mid; 33 | } 34 | } 35 | if(arr[right] == target) return right; 36 | if(arr[left] == target) return left; 37 | return -1; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/BinarySearch/FindKClosestElements/FindKClosestElements.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public List findClosestElements(int[] arr, int k, int x) { 3 | int left = 0, right = arr.length - k; 4 | while(left < right){ 5 | int mid = (left + right) / 2; 6 | if(x - arr[mid] > arr[mid + k] - x){ 7 | left = mid + 1; 8 | }else{ 9 | right = mid; 10 | } 11 | } 12 | List res = new LinkedList<>(); 13 | for(int i = left; i < left + k; i++){ 14 | res.add(arr[i]); 15 | } 16 | return res; 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /src/BinarySearch/FindMinimumInRotatedSortedArray/FindMinimumInRotatedSortedArray.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int findMin(int[] nums) { 3 | //define pointers 4 | int L = 0, N = nums.length, R = N - 1; 5 | //base case: if array is already sorted & not rotated 6 | if(nums[L] < nums[R]) return nums[L]; 7 | 8 | //binary search 9 | while(L + 1 < R){ 10 | int mid = (L + R)/2; 11 | //1. if nums[mid] < nums[R] then min is at the left side 12 | if(nums[mid] < nums[R]){ 13 | R = mid; 14 | } 15 | //2. if nums[mid] > nums[R] then min is at the right side 16 | else{ 17 | L = mid; 18 | } 19 | } 20 | 21 | 22 | //return the smallest value between nums[L] and nums[R] 23 | return Math.min(nums[R], nums[L]); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/BinarySearch/FindMinimumInRotatedSortedArray/FindMinimumInRotatedSortedArrayII.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int findMin(int[] nums) { 3 | //define pointers 4 | int L = 0, N = nums.length, R = N - 1; 5 | //base case: if array is already sorted & not rotated 6 | if(nums[L] < nums[R]) return nums[L]; 7 | 8 | //binary search 9 | while(L + 1 < R){ 10 | int mid = (L + R)/2; 11 | //1. if nums[mid] <= nums[R] then min is at the left side 12 | if(nums[mid] <= nums[R]){ 13 | R--; 14 | } 15 | //2. if nums[mid] > nums[R] then min is at the right side 16 | else{ 17 | L++; 18 | } 19 | } 20 | //return the smallest value between nums[L] and nums[R] 21 | return Math.min(nums[R],nums[L]); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/BinarySearch/FindPeakElement/FindPeakElement.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int findPeakElement(int[] nums) { 3 | int left = 0, n = nums.length, right = n - 1; 4 | //Base case 5 | if(n == 1) return left; 6 | 7 | while(left < right){ 8 | int mid = (left + right) / 2; 9 | if(nums[mid] > nums[mid + 1]){ 10 | right = mid; 11 | }else{ 12 | left = mid + 1; 13 | } 14 | } 15 | return left; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/BinarySearch/FindSmallestLetterGreaterThanTarget/FindSmallestLetterGreaterThanTarget.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public char nextGreatestLetter(char[] letters, char target) { 3 | //Base case 4 | int n = letters.length; 5 | if(target < letters[0] || letters[n - 1] <= target) return letters[0]; 6 | 7 | int left = 0, right = n - 1; 8 | while(left + 1 < right){ 9 | int mid = (left + right) / 2; 10 | if(target < letters[mid]){ 11 | right = mid; 12 | }else{ 13 | left = mid; 14 | } 15 | } 16 | 17 | return letters[right]; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/BinarySearch/SearchInRotatedSortedArray/SearchInRotatedSortedArray.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int search(int[] nums, int target) { 3 | int left = 0, right = nums.length - 1; 4 | 5 | while(left + 1 < right){ 6 | int mid = (left + right) / 2; 7 | if(nums[left] < nums[mid]){ 8 | if(nums[left] <= target && target <= nums[mid]){ 9 | right = mid; 10 | }else{ 11 | left = mid; 12 | } 13 | }else{ 14 | if(nums[mid] <= target && target <= nums[right]){ 15 | left = mid; 16 | }else{ 17 | right = mid; 18 | } 19 | } 20 | } 21 | if(nums[left] == target) return left; 22 | if(nums[right] == target) return right; 23 | 24 | return -1; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/BinarySearch/TimeBasedKeyValueStore/TimeBasedKeyValueStoreTreeMap: -------------------------------------------------------------------------------- 1 | class TimeMap { 2 | Map> map = new HashMap<>(); 3 | /** Initialize your data structure here. */ 4 | public TimeMap() { 5 | 6 | } 7 | 8 | public void set(String key, String value, int timestamp) { 9 | if(!map.containsKey(key)){ 10 | map.put(key, new TreeMap<>()); 11 | } 12 | TreeMap treeMap = map.get(key); 13 | treeMap.put(timestamp, value); 14 | } 15 | 16 | public String get(String key, int timestamp) { 17 | if(!map.containsKey(key)) return ""; 18 | 19 | TreeMap treeMap = map.get(key); 20 | 21 | //greatest key less than or equal to the given key 22 | Integer smallTimeStamp = treeMap.floorKey(timestamp); 23 | if(smallTimeStamp == null){ 24 | return ""; 25 | } 26 | return treeMap.get(smallTimeStamp); 27 | } 28 | } 29 | 30 | /** 31 | * Your TimeMap object will be instantiated and called as such: 32 | * TimeMap obj = new TimeMap(); 33 | * obj.set(key,value,timestamp); 34 | * String param_2 = obj.get(key,timestamp); 35 | */ 36 | -------------------------------------------------------------------------------- /src/DPDecisionMaking/BestTimeToBuyandSellStock/BestTimeToBuyandSellStock.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int maxProfit(int[] prices) { 3 | int N = prices.length; 4 | if(N < 2) return 0; 5 | int min = prices[0], maxP = 0; 6 | for(int i = 1; i < N; i++){ 7 | maxP = Math.max(prices[i]-min, maxP); 8 | min = Math.min(prices[i], min); 9 | } 10 | return maxP; 11 | } 12 | } 13 | /** 14 | [7,6,6,6,6,4] 15 | [7,1,5,3,6,4] 16 | **/ 17 | -------------------------------------------------------------------------------- /src/DPDecisionMaking/BestTimeToBuyandSellStock/BestTimetoBuyandSellStockII.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int maxProfit(int[] prices) { 3 | int minPrice = Integer.MAX_VALUE;//Keep track min price 4 | int maxProfit = 0;//Keep track of maxprofit 5 | int sum = 0;//track the max total profit 6 | for(int num : prices){ 7 | minPrice = Math.min(minPrice, num); 8 | maxProfit = Math.max(maxProfit, num - minPrice); 9 | if(maxProfit > 0){ 10 | sum += maxProfit; 11 | //reset to find new profit 12 | maxProfit = 0; 13 | minPrice = num; 14 | } 15 | } 16 | return sum; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/DPDecisionMaking/JumpGame/JumpGame_Bottom_up.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | 3 | public boolean canJump(int[] nums) { 4 | int n = nums.length, goal = n - 1; 5 | for(int i = n - 2; i >= 0; i--){ 6 | if(i + nums[i] >= goal){ 7 | goal = i; 8 | } 9 | } 10 | return goal == 0; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/DPDecisionMaking/JumpGame/JumpGame_Top_Down.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | Boolean[] cache; 3 | int[] nums; 4 | public boolean canJump(int[] nums) { 5 | int n = nums.length; 6 | this.nums = nums; 7 | this.cache = new Boolean[n]; 8 | return dfs(0); 9 | } 10 | private boolean dfs(int index){ 11 | //Base case 12 | if(nums.length - 1 <= index) return true; 13 | 14 | if(cache[index] != null) return cache[index]; 15 | 16 | int maxJump = nums[index]; 17 | 18 | for(int i = 1; i <= maxJump; i++){ 19 | boolean res = dfs(index + i); 20 | if(res){ 21 | cache[index] = true; 22 | return cache[index]; 23 | } 24 | } 25 | return cache[index] = false; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/DP_Distinct/ClimbStairs/ClimbStairs.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int climbStairs(int n) { 3 | if(n < 4) return n; 4 | int prev1 = 3, prev2 = 2, curUniqueWays = 0; 5 | for(int i = 4; i <= n; i++){ 6 | //current unique way = previous unique ways + second previous unique ways 7 | curUniqueWays = prev2 + prev1; 8 | prev2 = prev1; 9 | prev1 = curUniqueWays; 10 | } 11 | return curUniqueWays; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/DP_Distinct/CoinChange2/CoinChange2.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int change(int amount, int[] coins) { 3 | int N = coins.length, A = amount; 4 | int[][] cache = new int[N][A + 1]; 5 | //Build the first row 6 | cache[0][0] = 1; 7 | for(int col = 1; col <= A; col++){ 8 | int remainAmount = col - coins[0]; 9 | if(remainAmount < 0) continue; 10 | cache[0][col] = cache[0][remainAmount]; 11 | } 12 | //Build the remaining rows 13 | for(int row = 1; row < N; row++){ 14 | cache[row][0] = 1; 15 | for(int col = 1; col <= A; col++){ 16 | int skip = cache[row - 1][col]; 17 | int take = 0; 18 | if(col - coins[row] >= 0){ 19 | take = cache[row][col - coins[row]]; 20 | } 21 | int totalUniqueWays = skip + take; 22 | cache[row][col] = totalUniqueWays; 23 | } 24 | } 25 | return cache[N - 1][A]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/DP_Distinct/CombinationSum4/CombinationSum4.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int combinationSum4(int[] nums, int target) { 3 | int[] cache = new int[target + 1]; 4 | cache[0] = 1; 5 | for(int i = 1; i < target + 1; i++){ 6 | int curSum = i; 7 | for(int num : nums){ 8 | if(curSum - num >= 0){ 9 | cache[curSum] += cache[curSum - num]; 10 | } 11 | } 12 | } 13 | return cache[target]; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/DP_Distinct/ConcatenatedWords/ConcatenatedWords.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | Set dict; 3 | Boolean[] cache; 4 | public List findAllConcatenatedWordsInADict(String[] words) { 5 | dict = new HashSet<>(Arrays.asList(words)); 6 | List res = new LinkedList<>(); 7 | for(String word: words){ 8 | dict.remove(word); 9 | int n = word.length(); 10 | cache = new Boolean[n]; 11 | if(word.length() != 0 && isCancat(0, word.toCharArray())){ 12 | res.add(word); 13 | } 14 | dict.add(word); 15 | } 16 | return res; 17 | } 18 | 19 | private boolean isCancat(int start, char[] arr){ 20 | int end = arr.length - 1; 21 | if(start > end) return true; 22 | 23 | if(cache[start] != null) return cache[start]; 24 | 25 | StringBuilder sb = new StringBuilder(); 26 | 27 | cache[start] = false; 28 | for(int index = start; index <= end; index++){ 29 | sb.append(arr[index]); 30 | if(dict.contains(sb.toString())){ 31 | cache[start] = isCancat(index + 1, arr); 32 | } 33 | if(cache[start]) break; 34 | } 35 | return cache[start]; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/DP_Distinct/CountOfSubsetSum/CountOfSubsetSumBruteForce.java: -------------------------------------------------------------------------------- 1 | public class CountOfSubsetSumBruteForce { 2 | private int[] arr; 3 | 4 | public CountOfSubsetSumBruteForce(int[] arr) { 5 | this.arr = arr; 6 | } 7 | 8 | public int SolveCountOfSubsetSum(int num) { 9 | return helper(0, num); 10 | } 11 | 12 | private int helper(int index, int curSum) { 13 | if (curSum == 0) 14 | return 1; 15 | if (curSum < 0 || index >= arr.length) 16 | return 0; 17 | 18 | int take = helper(index + 1, curSum - arr[index]); 19 | int skip = helper(index + 1, curSum); 20 | return skip + take; 21 | } 22 | 23 | public static void main(String[] args) { 24 | /** 25 | * Input: values = [1, 1, 2, 3] sum = 4 26 | * 27 | * Output: 3 28 | */ 29 | CountOfSubsetSumBruteForce test0 = new CountOfSubsetSumBruteForce(new int[] { 1, 1, 2, 3 }); 30 | System.out.println(test0.SolveCountOfSubsetSum(4));// <--- expect 3 31 | 32 | /** 33 | * Input: values = [1, 2, 7, 1, 5] sum = 9 34 | * 35 | * Output: 3 36 | */ 37 | 38 | CountOfSubsetSumBruteForce test1 = new CountOfSubsetSumBruteForce(new int[] { 1, 2, 7, 1, 5 }); 39 | System.out.println(test1.SolveCountOfSubsetSum(9));// <--- expect 3 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/DP_Distinct/DecodeWays/DecodeWays.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int numDecodings(String s) { 3 | char[] arr = s.toCharArray(); 4 | int[] cache = new int[arr.length]; 5 | int n = cache.length; 6 | for(int i = n - 1; i >= 0; i--){ 7 | if(arr[i] == '0'){ 8 | continue; 9 | } 10 | if(i == n - 1){ 11 | cache[i] = 1; 12 | continue; 13 | } 14 | String str = s.substring(i, i + 2); 15 | if(Integer.parseInt(str) > 26){ 16 | cache[i] = cache[i + 1]; 17 | }else if(i == n - 2){ 18 | cache[i] = cache[i + 1] + 1; 19 | } 20 | else{ 21 | cache[i] = cache[i + 1] + cache[i + 2]; 22 | } 23 | } 24 | return cache[0]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/DP_Distinct/PartitionEqualSubsetSum/PartitionEqualSubsetSum.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | Boolean[][] cache; 3 | public boolean canPartition(int[] nums) { 4 | int sum = 0; 5 | for(int num : nums){ 6 | sum += num; 7 | } 8 | if(sum % 2 != 0){ 9 | return false; 10 | } 11 | //we need even sum 12 | int half = sum / 2; 13 | cache = new Boolean[nums.length][half + 1]; 14 | for(int row = 0; row < cache.length; row++){ 15 | cache[row][0] = true; 16 | } 17 | for(int curSum = 1; curSum < cache[0].length; curSum++){ 18 | if(curSum == nums[0]){ 19 | cache[0][curSum] = true; 20 | }else{ 21 | cache[0][curSum] = false; 22 | } 23 | } 24 | for(int curNumIndex = 1; curNumIndex < cache.length; curNumIndex++){ 25 | for(int curSum = 1; curSum < cache[0].length; curSum++){ 26 | boolean take = false; 27 | int diff = curSum - nums[curNumIndex]; 28 | if(diff >= 0){ 29 | take = cache[curNumIndex - 1][diff]; 30 | } 31 | boolean skip = cache[curNumIndex - 1][curSum]; 32 | cache[curNumIndex][curSum] = skip || take; 33 | } 34 | } 35 | return cache[nums.length - 1][half]; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/DP_Distinct/UniqueBinarySearchTrees/UniqueBinarySearchTrees_Bottom_Up.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int numTrees(int n) { 3 | int[] cache = new int[n + 1]; 4 | cache[0] = 1; 5 | cache[1] = 1; 6 | for(int curN = 2; curN <= n; curN++){ 7 | int total = 0; 8 | for(int num = 1; num <= curN; num++){ 9 | int leftNodes = num - 1; 10 | int leftTotalBST = cache[leftNodes]; 11 | int rightNodes = curN - num; 12 | int rightTotalBST = cache[rightNodes]; 13 | total += (leftTotalBST * rightTotalBST); 14 | } 15 | cache[curN] = total; 16 | } 17 | return cache[n]; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/DP_Distinct/UniqueBinarySearchTrees/UniqueBinarySearchTrees_Top_Down.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | Integer[] cache; 3 | public int numTrees(int n) { 4 | cache = new Integer[n + 1]; 5 | return dfs(n); 6 | } 7 | private int dfs(int n){ 8 | //Base case 9 | if(n < 2) return 1; 10 | 11 | //Check cache 12 | if(cache[n] != null) return cache[n]; 13 | 14 | int total = 0; 15 | for(int curNum = 1; curNum <= n; curNum++){ 16 | int leftN = curNum - 1; 17 | int leftTotalBST = dfs(leftN); 18 | int rightN = n - curNum; 19 | int rightTotalBST = dfs(rightN); 20 | total += (leftTotalBST * rightTotalBST); 21 | } 22 | 23 | cache[n] = total; 24 | return total; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/DP_Distinct/UniquePaths/UniquePaths.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int uniquePaths(int m, int n) { 3 | int[][] cache = new int[m][n]; 4 | for(int[] row: cache){ 5 | Arrays.fill(row, 1); 6 | } 7 | for(int i = m - 2; i >= 0; i--){ 8 | for(int j = n - 2; j >= 0; j--){ 9 | int bottom = cache[i + 1][j]; 10 | int right = cache[i][j + 1]; 11 | cache[i][j] = bottom + right; 12 | } 13 | } 14 | return cache[0][0]; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/DP_Distinct/UniquePaths/UniquePathsII.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int uniquePathsWithObstacles(int[][] obstacleGrid) { 3 | int[][] grid = obstacleGrid; 4 | int m = grid.length, n = grid[0].length; 5 | int[][] cache = new int[m + 1][n + 1]; 6 | 7 | for(int i = m - 1; i >= 0; i--){ 8 | for(int j = n - 1; j >= 0; j--){ 9 | if(grid[i][j] == 1) continue; 10 | if(i == m - 1 && j == n - 1){ 11 | cache[i][j] = 1; 12 | }else{ 13 | int bottom = cache[i + 1][j]; 14 | int right = cache[i][j + 1]; 15 | cache[i][j] = bottom + right; 16 | } 17 | } 18 | } 19 | return cache[0][0]; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/DP_Distinct/WordBreak/WordBreak.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | Set dict; 3 | HashMap cache = new HashMap<>(); 4 | public boolean wordBreak(String s, List wordDict) { 5 | dict = new HashSet<>(wordDict); 6 | return helper(s); 7 | } 8 | private boolean helper(String s){ 9 | if(s == null || s.length() == 0) return true; 10 | if(cache.containsKey(s)){ 11 | return cache.get(s); 12 | } 13 | int n = s.length(); 14 | for(int i = 1; i <= n; i++){ 15 | String Left = s.substring(0, i); 16 | String Right = s.substring(i, n); 17 | if(dict.contains(Left) && helper(Right)){ 18 | cache.put(s, true); 19 | return true; 20 | } 21 | } 22 | cache.put(s, false); 23 | return false; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/DP_IntegerPartition/IntegerBreak/IntegerBreak_BottomUp.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int integerBreak(int n) { 3 | int[] cache = new int[n + 1]; 4 | cache[0] = 0; 5 | cache[1] = 0; 6 | cache[2] = 1; 7 | for(int num = 3; num <= n; num++){ 8 | for(int i = 1; i < num; i++){ 9 | int curMaxProduct = Math.max(cache[num - i], num - i); 10 | cache[num] = Math.max(cache[num], curMaxProduct * i); 11 | } 12 | } 13 | return cache[n]; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/DP_IntegerPartition/IntegerBreak/IntegerBreak_TopDown.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | Integer[] cache; 3 | 4 | public int integerBreak(int n) { 5 | cache = new Integer[n + 1]; 6 | return dfs(n); 7 | } 8 | 9 | private int dfs(int n) { 10 | if (n < 2) 11 | return 0; 12 | 13 | if (cache[n] != null) 14 | return cache[n]; 15 | 16 | int maxProductForN = 0; 17 | for (int i = 1; i < n; i++) { 18 | int curMaxProduct = Math.max(dfs(n - i), n - i); 19 | maxProductForN = Math.max(curMaxProduct * i, maxProductForN); 20 | } 21 | cache[n] = maxProductForN; 22 | return maxProductForN; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/DP_IntegerPartition/PerfectSquares/PerfectSquares_BottomUp.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int numSquares(int n) { 3 | int[] cache = new int[n + 1]; 4 | 5 | cache[0] = 0; 6 | 7 | for(int num = 1; num <= n; num++){ 8 | cache[num] = Integer.MAX_VALUE; 9 | for(int i = 1; i * i <= num; i++){ 10 | cache[num] = Math.min(cache[num], cache[num - (i * i)] + 1); 11 | } 12 | } 13 | return cache[n]; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/DP_IntegerPartition/PerfectSquares/PerfectSquares_TopDown.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | Integer[] cache; 3 | public int numSquares(int n) { 4 | cache = new Integer[n + 1]; 5 | return dfs(n); 6 | } 7 | private int dfs(int n){ 8 | //base case 9 | if(n == 0) return 0; 10 | 11 | if(cache[n] != null) return cache[n]; 12 | 13 | cache[n] = Integer.MAX_VALUE; 14 | for(int i = 1; i * i <= n; i++){ 15 | cache[n] = Math.min(cache[n], dfs(n - (i * i)) + 1); 16 | } 17 | return cache[n]; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/DP_Min_Max_Path_to_Target/CoinChange/CoinChange_bottom_up.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int coinChange(int[] coins, int amount) { 3 | int[] cache = new int[amount + 1]; 4 | Arrays.fill(cache, amount + 1); 5 | 6 | //total amount of coins to make up amount 0 is 0 7 | cache[0] = 0; 8 | 9 | for(int i = 1; i < amount + 1; i++){ 10 | int curAmount = i; 11 | for(int coin : coins){ 12 | if(curAmount - coin >= 0){ 13 | cache[curAmount] = Math.min(cache[curAmount - coin] + 1, cache[curAmount]); 14 | } 15 | } 16 | } 17 | return cache[amount] == amount + 1 ? -1 : cache[amount]; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/DP_Min_Max_Path_to_Target/CoinChange/CoinChange_top_down.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | int[] arr; 3 | Integer[] cache; 4 | public int coinChange(int[] coins, int amount) { 5 | arr = coins; 6 | cache = new Integer[amount + 1]; 7 | return helper(amount); 8 | } 9 | private int helper(int amount){ 10 | //base case 11 | if (amount == 0) return 0; 12 | //-1 mean not found 13 | if (amount < 0) return -1; 14 | if(cache[amount] != null){ 15 | return cache[amount]; 16 | } 17 | int min = Integer.MAX_VALUE; 18 | for(int num : arr){ 19 | int res = helper(amount - num); 20 | if(res != -1){ 21 | min = Math.min(min, res + 1); 22 | } 23 | } 24 | //If min is still MAX VALUE then we need -1 for min 25 | min = min == Integer.MAX_VALUE ? -1 : min; 26 | //if the amount = x, what is the minimum coins we need to make up this amount 27 | cache[amount] = min; 28 | return min; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/DP_Min_Max_Path_to_Target/EditDistance/EditDistance.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int minDistance(String word1, String word2) { 3 | //Define Vars 4 | char[] s1 = word1.toCharArray(); 5 | char[] s2 = word2.toCharArray(); 6 | int m = s1.length, n = s2.length; 7 | int[][] cache = new int[m + 1][n + 1]; 8 | 9 | //Build the first row 10 | for(int i = 0; i < n + 1; i++){ 11 | cache[0][i] = i; 12 | } 13 | //Build the remaining rows 14 | for(int i = 1; i < m + 1; i++){ 15 | cache[i][0] = i; 16 | for(int j = 1; j < n + 1; j++){ 17 | if(s1[i - 1] == s2[j - 1]){ 18 | cache[i][j] = cache[i - 1][j - 1]; 19 | }else{ 20 | int replace = cache[i - 1][j - 1]; 21 | int delete = cache[i - 1][j]; 22 | int insert = cache[i][j - 1]; 23 | cache[i][j] = Math.min(replace, Math.min(delete, insert)) + 1; 24 | } 25 | } 26 | } 27 | return cache[m][n]; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/DP_Min_Max_Path_to_Target/MaximalSquare/MaximalSquare_bottom_up.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int maximalSquare(char[][] matrix) { 3 | int m = matrix.length, n = matrix[0].length; 4 | int[][] cache = new int[m + 1][n + 1]; 5 | 6 | int maxWidth = 0; 7 | 8 | for(int i = 1; i < m + 1; i++){ 9 | for(int j = 1; j < n + 1; j++){ 10 | if(matrix[i - 1][j - 1] == '1'){ 11 | int top = cache[i - 1][j]; 12 | int left = cache[i][j - 1]; 13 | int topLeft = cache[i - 1][j - 1]; 14 | int min = Math.min(top, Math.min(left, topLeft)); 15 | cache[i][j] = min + 1; 16 | 17 | //Update the max width 18 | maxWidth = Math.max(maxWidth, cache[i][j]); 19 | } 20 | } 21 | } 22 | return maxWidth * maxWidth; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/DP_Min_Max_Path_to_Target/MaximumProductSubarray/MaximumProductSubarray.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int maxProduct(int[] nums) { 3 | int max_so_far = nums[0], min_so_far = nums[0], res = nums[0]; 4 | int N = nums.length; 5 | for(int i = 1; i < N; i++){ 6 | int tempMax = max_so_far; 7 | max_so_far = Math.max(nums[i], Math.max(max_so_far * nums[i], min_so_far * nums[i])); 8 | min_so_far = Math.min(nums[i], Math.min(tempMax * nums[i], min_so_far * nums[i])); 9 | res = Math.max(res, max_so_far); 10 | } 11 | return res; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/DP_Min_Max_Path_to_Target/MinCostClimbingStairs/MinCostClimbingStairs_bottom_up.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int minCostClimbingStairs(int[] cost) { 3 | int prev1 = 0, prev2 = 0; 4 | int N = cost.length; 5 | for(int i = N - 1; i >= 0; i--){ 6 | int minCostForCurrentStair = Math.min(prev1, prev2) + cost[i]; 7 | prev2 = prev1; 8 | prev1 = minCostForCurrentStair; 9 | 10 | } 11 | return Math.min(prev2, prev1); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/DP_Min_Max_Path_to_Target/MinCostClimbingStairs/MinCostClimbingStairs_top_down.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | int[] cost; 3 | Integer[] cache; 4 | public int minCostClimbingStairs(int[] cost) { 5 | this.cost = cost; 6 | this.cache = new Integer[cost.length]; 7 | int one = helper(0); 8 | this.cache = new Integer[cost.length]; 9 | int two = helper(1); 10 | return Math.min(one, two); 11 | } 12 | private int helper(int index){ 13 | if(index >= cost.length) return 0; 14 | if(cache[index] != null) return cache[index]; 15 | int takeStep1 = helper(index + 1); 16 | int takeStep2 = helper(index + 2); 17 | cache[index] = Math.min(takeStep1, takeStep2) + cost[index]; 18 | return cache[index]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/DP_Min_Max_Path_to_Target/MinimumFallingPathSum/MinimumFallingPathSum_bottom_up.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | int N; 3 | int[][] matrix; 4 | public int minFallingPathSum(int[][] matrix) { 5 | this.N = matrix.length; 6 | this.matrix = matrix; 7 | for(int row = N - 2; row >= 0; row--){ 8 | for(int col = 0; col < N; col++){ 9 | int bottom = helper(row + 1, col); 10 | int bottomLeft = helper(row + 1, col - 1); 11 | int bottomRight = helper(row + 1, col + 1); 12 | matrix[row][col] = Math.min(bottom, Math.min(bottomLeft, bottomRight)) + matrix[row][col]; 13 | } 14 | } 15 | int min = Integer.MAX_VALUE; 16 | for(int i = 0; i < N; i++){ 17 | min = Math.min(min, matrix[0][i]); 18 | } 19 | return min; 20 | } 21 | private int helper(int row, int col){ 22 | if(row < 0 || row >= N || col < 0 || col >= N) return Integer.MAX_VALUE; 23 | return matrix[row][col]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/DP_Min_Max_Path_to_Target/MinimumFallingPathSum/MinimumFallingPathSum_top_down.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | int N; 3 | int[][] matrix; 4 | Integer[][] cache; 5 | public int minFallingPathSum(int[][] matrix) { 6 | this.N = matrix.length; 7 | this.matrix = matrix; 8 | cache = new Integer[N][N]; 9 | int minPathSumToBottom = Integer.MAX_VALUE; 10 | for(int i = 0; i < N; i++){ 11 | minPathSumToBottom = Math.min(minPathSumToBottom, helper(0,i)); 12 | } 13 | return minPathSumToBottom; 14 | } 15 | private int helper(int row, int col){ 16 | //base case 17 | if(row < 0 || row >= N || col < 0 || col >= N) return Integer.MAX_VALUE; 18 | 19 | if(row == N - 1) return matrix[row][col]; 20 | 21 | if(cache[row][col] != null) return cache[row][col]; 22 | 23 | int bottom = helper(row + 1, col); 24 | int bottomLeft = helper(row + 1, col - 1); 25 | int bottomRight = helper(row + 1, col + 1); 26 | 27 | int minPathSumToBottom = Math.min(bottom, Math.min(bottomLeft, bottomRight)); 28 | 29 | cache[row][col] = minPathSumToBottom + matrix[row][col]; 30 | 31 | return cache[row][col]; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/DP_Min_Max_Path_to_Target/MinimumPathSum/MinimumPathSum_bottom_up.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int minPathSum(int[][] grid) { 3 | int M = grid.length, N = grid[0].length; 4 | Integer[][] cache = new Integer[M][N]; 5 | cache[0][0] = grid[0][0]; 6 | //Build the first row 7 | for(int col = 1; col < N; col++){ 8 | cache[0][col] = cache[0][col - 1] + grid[0][col]; 9 | } 10 | //Build the remaining rows 11 | for(int row = 1; row < M; row++){ 12 | //define the first element 13 | cache[row][0] = grid[row][0] + cache[row - 1][0]; 14 | 15 | //compute the remaining elements 16 | for(int col = 1; col < N; col++){ 17 | int top = cache[row - 1][col]; 18 | int left = cache[row][col - 1]; 19 | cache[row][col] = Math.min(top, left) + grid[row][col]; 20 | } 21 | } 22 | return cache[M - 1][N - 1]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/DP_Min_Max_Path_to_Target/MinimumPathSum/MinimumPathSum_top_down.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | int[][] grid; 3 | Integer[][] cache; 4 | int M; 5 | int N; 6 | public int minPathSum(int[][] grid) { 7 | this.grid = grid; 8 | M = grid.length; 9 | N = grid[0].length; 10 | this.cache = new Integer[M][N]; 11 | return helper(0,0); 12 | } 13 | private int helper(int row, int col){ 14 | //base case 15 | if(row >= M || col >= N) return Integer.MAX_VALUE; 16 | 17 | //Found the bottom right 18 | if(row == M - 1 && col == N - 1) return grid[row][col]; 19 | 20 | //Check if we pre computed 21 | if(cache[row][col] != null) return cache[row][col]; 22 | 23 | //Minimum Path sum for right & down 24 | int right = helper(row, col + 1); 25 | int down = helper(row + 1, col); 26 | 27 | //Save the computed result 28 | cache[row][col] = Math.min(right, down) + grid[row][col]; 29 | 30 | return cache[row][col]; 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/DP_StockTrading/BestTimeToBuyAndSellStockWithCooldown/BestTimeToBuyAndSellStockWithCooldown.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int maxProfit(int[] prices) { 3 | int n = prices.length; 4 | int[] maxProfitBuyStartAt = new int[n]; 5 | for (int buy = n - 2; buy >= 0; buy--) { 6 | // What's the max profit if i buy at this position 7 | for (int sell = buy + 1; sell < n; sell++) { 8 | if (prices[sell] < prices[buy]) 9 | continue; 10 | int profit = prices[sell] - prices[buy]; 11 | if (sell + 2 < n) { 12 | profit += maxProfitBuyStartAt[sell + 2]; 13 | } 14 | maxProfitBuyStartAt[buy] = Math.max(maxProfitBuyStartAt[buy], profit); 15 | } 16 | // What's the max profit if i start buy at current position 17 | maxProfitBuyStartAt[buy] = Math.max(maxProfitBuyStartAt[buy], maxProfitBuyStartAt[buy + 1]); 18 | } 19 | return maxProfitBuyStartAt[0]; 20 | } 21 | 22 | } 23 | 24 | 25 | /** 26 | [1,2,3,0,2] 27 | ^ ^ 28 | 29 | [1,2,3,0,2] 30 | ^ ^ 31 | **/ 32 | -------------------------------------------------------------------------------- /src/DP_Subsequence/DistinctSubsequences/DistinctSubsequenceTopDown.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | Integer[][] cache; 3 | char[] sArr, tArr; 4 | int sLen, tLen; 5 | public int numDistinct(String s, String t) { 6 | sArr = s.toCharArray(); 7 | tArr = t.toCharArray(); 8 | sLen = sArr.length; 9 | tLen = tArr.length; 10 | 11 | //Base case 12 | if(sLen < tLen) return 0; 13 | 14 | cache = new Integer[tLen][sLen]; 15 | 16 | return dfs(tLen - 1, sLen - 1); 17 | } 18 | private int dfs(int tIndex, int sIndex){ 19 | //Base case 20 | if(0 <= sIndex && tIndex < 0) return 1;// s="a" t="" 21 | if(sIndex < 0 && tIndex < 0) return 1; //s="" t="" 22 | if(sIndex < 0 && 0 <= tIndex) return 0; // s="" t="a" 23 | 24 | if(cache[tIndex][sIndex] != null) return cache[tIndex][sIndex]; 25 | 26 | if(sArr[sIndex] == tArr[tIndex]){ 27 | cache[tIndex][sIndex] = dfs(tIndex - 1, sIndex - 1) + dfs(tIndex, sIndex - 1); 28 | }else{ 29 | cache[tIndex][sIndex] = dfs(tIndex, sIndex - 1); 30 | } 31 | 32 | return cache[tIndex][sIndex]; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/DP_Subsequence/DistinctSubsequences/DistinctSubsequencesBottomUp.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int numDistinct(String s, String t) { 3 | char[] sArr = s.toCharArray(), tArr = t.toCharArray(); 4 | int sLen = sArr.length, tLen = tArr.length; 5 | 6 | //Base case 7 | if(sLen < tLen) return 0; 8 | 9 | int[][] cache = new int[tLen + 1][sLen + 1]; 10 | 11 | //Build the first row 12 | Arrays.fill(cache[0], 1); 13 | 14 | for(int row = 1; row <= tLen; row++){ 15 | for(int col = 1; col <= sLen; col++){ 16 | if(sArr[col - 1] == tArr[row - 1]){ 17 | cache[row][col] = cache[row - 1][col - 1] + cache[row][col - 1]; 18 | }else{ 19 | cache[row][col] = cache[row][col - 1]; 20 | } 21 | } 22 | } 23 | return cache[tLen][sLen]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/DP_Subsequence/LongestCommonSubsequence/LongestCommonSubsequence_bottom_up.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int longestCommonSubsequence(String text1, String text2) { 3 | int t1 = text1.length(), t2 = text2.length(); 4 | int[][] cache = new int[t1 + 1][t2 + 1]; 5 | char[] t1Arr = text1.toCharArray(); 6 | char[] t2Arr = text2.toCharArray(); 7 | for(int i = 0; i < t1 + 1; i++){ 8 | for(int j = 0; j < t2 + 1; j++){ 9 | if(j == 0 || i == 0) continue; 10 | if(t1Arr[i - 1] == t2Arr[j - 1]){ 11 | cache[i][j] = 1 + cache[i - 1][j - 1]; 12 | }else{ 13 | cache[i][j] = Math.max(cache[i - 1][j], cache[i][j - 1]); 14 | } 15 | } 16 | } 17 | return cache[t1][t2]; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/DP_Subsequence/LongestCommonSubsequence/LongestCommonSubsequence_top_down.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | String text1; 3 | String text2; 4 | Integer[][] cache; 5 | 6 | public int longestCommonSubsequence(String text1, String text2) { 7 | this.text1 = text1; 8 | this.text2 = text2; 9 | int t1 = text1.length(); 10 | int t2 = text2.length(); 11 | cache = new Integer[t1 + 1][t2 + 1]; 12 | return helper(t1, t2); 13 | } 14 | 15 | public int helper(int t1, int t2) { 16 | if (t1 == 0 || t2 == 0) 17 | return 0; 18 | if (cache[t1][t2] != null) 19 | return cache[t1][t2]; 20 | if (text1.charAt(t1 - 1) == text2.charAt(t2 - 1)) { 21 | return 1 + helper(t1 - 1, t2 - 1); 22 | } 23 | int opt1 = helper(t1 - 1, t2); 24 | int opt2 = helper(t1, t2 - 1); 25 | cache[t1][t2] = Math.max(opt1, opt2); 26 | return cache[t1][t2]; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/DP_Subsequence/LongestIncreasingSubsequence/LongestIncreasingSubsequence_bottom_up.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int lengthOfLIS(int[] nums) { 3 | int N = nums.length; 4 | int[] cache = new int[N]; 5 | 6 | cache[N - 1] = 1; 7 | int maxLIS = 1; 8 | 9 | for(int i = N - 2; i >= 0; i--){ 10 | int maxLISForRemainingElements = 0; 11 | int curVal = nums[i]; 12 | for(int j = i + 1; j < N; j++){ 13 | if(curVal < nums[j]){ 14 | maxLISForRemainingElements = Math.max(maxLISForRemainingElements, cache[j]); 15 | } 16 | } 17 | cache[i] = maxLISForRemainingElements + 1; 18 | maxLIS = Math.max(maxLIS, cache[i]); 19 | } 20 | 21 | return maxLIS; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/DP_Subsequence/LongestPalindromicSubsequence/LongestPalindromicSubsequence.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int longestPalindromeSubseq(String s) { 3 | char[] arr = s.toCharArray(); 4 | 5 | int N = arr.length; 6 | 7 | int[][] cache = new int[N][N]; 8 | 9 | for(int i = N - 1; i >= 0; i--){ 10 | cache[i][i] = 1; 11 | for(int j = i + 1; j < N; j++){ 12 | if(arr[i] == arr[j]){ 13 | cache[i][j] = 2; 14 | if(i + 1 < j){ 15 | cache[i][j] += cache[i + 1][j - 1]; 16 | } 17 | }else{ 18 | cache[i][j] = Math.max(cache[i + 1][j], cache[i][j - 1]); 19 | } 20 | } 21 | } 22 | return cache[0][N - 1]; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/DP_Subsequence/MaximumLengthOfRepeatedSubarray/MaximumLengthOfRepeatedSubarray.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int findLength(int[] nums1, int[] nums2) { 3 | int m = nums1.length, n = nums2.length; 4 | int[][] cache = new int[m + 1][n + 1]; 5 | int maxValue = 0; 6 | for(int row = 1; row <= m; row++){ 7 | for(int col = 1; col <= n; col++){ 8 | int num1 = nums1[row - 1]; 9 | int num2 = nums2[col - 1]; 10 | if(num1 == num2){ 11 | cache[row][col] = cache[row - 1][col - 1] + 1; 12 | } 13 | maxValue = Math.max(maxValue, cache[row][col]); 14 | } 15 | } 16 | return maxValue; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/DP_Subsequence/MaximumSubarray/MaximumSubarray.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int maxSubArray(int[] nums) { 3 | int cur = nums[0], max = cur; 4 | for(int i = 1; i < nums.length; i++){ 5 | cur = Math.max(cur + nums[i], nums[i]); 6 | max = Math.max(max, cur); 7 | } 8 | return max; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/DP_Subsequence/NumberOfLongestIncreasingSubsequence/NumberOfLongestIncreasingSubsequence.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int findNumberOfLIS(int[] nums) { 3 | int N = nums.length; 4 | // Base case 5 | if (N == 1) 6 | return 1; 7 | 8 | int[] cacheLIS = new int[N], cacheFreq = new int[N]; 9 | cacheLIS[N - 1] = 1; 10 | cacheFreq[N - 1] = 1; 11 | int maxLIS = 1; 12 | 13 | for (int i = N - 2; i >= 0; i--) { 14 | for (int j = i + 1; j < N; j++) { 15 | if (nums[i] < nums[j]) { 16 | if (cacheLIS[i] < cacheLIS[j]) { 17 | cacheLIS[i] = cacheLIS[j]; 18 | cacheFreq[i] = cacheFreq[j]; 19 | } else if (cacheLIS[i] == cacheLIS[j]) { 20 | cacheFreq[i] += cacheFreq[j]; 21 | } 22 | } 23 | } 24 | cacheLIS[i]++; 25 | cacheFreq[i] = Math.max(cacheFreq[i], 1); 26 | maxLIS = Math.max(maxLIS, cacheLIS[i]); 27 | } 28 | int total = 0; 29 | for (int i = 0; i < N; i++) { 30 | if (cacheLIS[i] == maxLIS) { 31 | total += cacheFreq[i]; 32 | } 33 | } 34 | return total; 35 | } 36 | } 37 | 38 | /** 39 | 1,3,5,4,7 40 | ^ 41 | 42 | 4,3,2,2,1 43 | 44 | 2,2,1,1,1 45 | **/ 46 | -------------------------------------------------------------------------------- /src/DP_Subsequence/Word BreakII/Word BreakII_Top_Down.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | Set wordDict; 3 | Map> cache = new HashMap<>(); 4 | 5 | public List wordBreak(String s, List wordDict) { 6 | this.wordDict = new HashSet<>(wordDict); 7 | return DFS(s); 8 | } 9 | 10 | private List DFS(String s) { 11 | if (cache.containsKey(s)) 12 | return cache.get(s); 13 | 14 | LinkedList res = new LinkedList(); 15 | if (s.length() == 0) { 16 | res.add(""); 17 | return res; 18 | } 19 | for (String word : wordDict) { 20 | if (s.startsWith(word)) { 21 | List sublist = DFS(s.substring(word.length())); 22 | for (String sub : sublist) 23 | res.add(word + (sub.isEmpty() ? "" : " ") + sub); 24 | } 25 | } 26 | cache.put(s, res); 27 | return res; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Deque/SlidingWindowMaximum/SlidingWindowMaximum.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int[] maxSlidingWindow(int[] nums, int k) { 3 | Deque deque = new LinkedList<>(); 4 | int left = 0, right = 0, n = nums.length; 5 | List res = new ArrayList<>(); 6 | while(right < n){ 7 | //Expand the window 8 | while(!deque.isEmpty() && deque.peekLast() < nums[right]){ 9 | deque.pollLast(); 10 | } 11 | deque.offerLast(nums[right]); 12 | 13 | //Shrink the window 14 | if(k <= right - left + 1){ 15 | //Get the max in current window 16 | res.add(deque.peekFirst()); 17 | 18 | //update the deque 19 | if(deque.peekFirst() == nums[left++]){ 20 | deque.pollFirst(); 21 | } 22 | } 23 | 24 | right++; 25 | } 26 | 27 | //Convert to int[] 28 | int[] resArr = new int[res.size()]; 29 | for(int i = 0; i < res.size(); i++){ 30 | resArr[i] = res.get(i); 31 | } 32 | return resArr; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Design/MapSumPairs/MapSumPairs.java: -------------------------------------------------------------------------------- 1 | class Trie{ 2 | Map children = new HashMap<>(); 3 | int val = 0; 4 | } 5 | class MapSum { 6 | Trie root; 7 | Map map; 8 | /** Initialize your data structure here. */ 9 | public MapSum() { 10 | root = new Trie(); 11 | map = new HashMap<>(); 12 | } 13 | 14 | public void insert(String key, int val) { 15 | Trie temp = root; 16 | char[] arr = key.toCharArray(); 17 | for(char cur : arr){ 18 | if(!temp.children.containsKey(cur)){ 19 | temp.children.put(cur, new Trie()); 20 | } 21 | temp = temp.children.get(cur); 22 | temp.val += val; 23 | if(map.containsKey(key)){ 24 | temp.val -= map.get(key); 25 | } 26 | } 27 | map.put(key, val); 28 | } 29 | 30 | public int sum(String prefix) { 31 | Trie temp = root; 32 | char[] arr = prefix.toCharArray(); 33 | for(char cur : arr){ 34 | if(!temp.children.containsKey(cur)){ 35 | return 0; 36 | } 37 | temp = temp.children.get(cur); 38 | } 39 | return temp.val; 40 | } 41 | } 42 | 43 | /** 44 | * Your MapSum object will be instantiated and called as such: 45 | * MapSum obj = new MapSum(); 46 | * obj.insert(key,val); 47 | * int param_2 = obj.sum(prefix); 48 | */ 49 | -------------------------------------------------------------------------------- /src/DesignPattern/MediatorPattern/Problem.cs: -------------------------------------------------------------------------------- 1 | class UIControl 2 | { 3 | 4 | } 5 | class ListBox : UIControl 6 | { 7 | private string selection; 8 | 9 | public string Selection { get => selection; set => selection = value; } 10 | } 11 | class TextBox : UIControl 12 | { 13 | private string content; 14 | 15 | public string Content { get => content; set => content = value; } 16 | } 17 | 18 | class Button : UIControl 19 | { 20 | private bool isEnabled; 21 | 22 | public bool IsEnabled { get => isEnabled; set => isEnabled = value; } 23 | } 24 | -------------------------------------------------------------------------------- /src/DesignPattern/ObserverPattern/Problem.cs: -------------------------------------------------------------------------------- 1 | class DataSource 2 | { 3 | private int value; 4 | 5 | public int Value { get => value; set => this.value = value; } 6 | } 7 | class SpreadSheet 8 | { 9 | 10 | } 11 | class Chart 12 | { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/DesignPattern/ObserverPattern/Solution_PushStyle.cs: -------------------------------------------------------------------------------- 1 | //Observable 2 | class Subject 3 | { 4 | public List observers = new List(); 5 | public void AddObserver(Observer observer) 6 | { 7 | observers.Add(observer); 8 | } 9 | public void RemoveObserver(Observer observer) 10 | { 11 | observers.Remove(observer); 12 | } 13 | public void NotifyObservers(int value) 14 | { 15 | foreach (var observer in observers) 16 | { 17 | observer.Update(value); 18 | } 19 | } 20 | } 21 | class DataSource : Subject 22 | { 23 | private int value; 24 | 25 | public int Value 26 | { 27 | get => value; 28 | set 29 | { 30 | this.value = value; 31 | NotifyObservers(value); 32 | } 33 | } 34 | } 35 | interface Observer 36 | { 37 | void Update(int value); 38 | } 39 | class SpreadSheet : Observer 40 | { 41 | public void Update(int value) 42 | { 43 | throw new System.NotImplementedException(); 44 | } 45 | } 46 | class Chart : Observer 47 | { 48 | public void Update(int value) 49 | { 50 | throw new System.NotImplementedException(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/DesignPattern/StatePattern/Solution.cs: -------------------------------------------------------------------------------- 1 | //Why not abstract class? 2 | //We use abstract class if we want to provide common code to child class 3 | public interface ITool 4 | { 5 | void mouseDown(); 6 | void mouseUp(); 7 | } 8 | public class Canvas 9 | { 10 | private ITool curTool; 11 | 12 | internal ITool CurTool { get => curTool; set => curTool = value; } 13 | 14 | public void mouseDown() 15 | { 16 | curTool.mouseDown(); 17 | } 18 | public void mouseUp() 19 | { 20 | curTool.mouseUp(); 21 | } 22 | } 23 | 24 | public class SelectionTool : ITool 25 | { 26 | public void mouseDown() 27 | { 28 | throw new System.NotImplementedException(); 29 | } 30 | 31 | public void mouseUp() 32 | { 33 | throw new System.NotImplementedException(); 34 | } 35 | } 36 | 37 | public class BrushTool : ITool 38 | { 39 | public void mouseDown() 40 | { 41 | throw new System.NotImplementedException(); 42 | } 43 | 44 | public void mouseUp() 45 | { 46 | throw new System.NotImplementedException(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/DesignPattern/StrategyPattern/Problem.cs: -------------------------------------------------------------------------------- 1 | /** 2 | * Problem: 3 | * - This ImageStore violates the SR Principle 4 | * - Hard to maintain 5 | * 6 | */ 7 | public class ImageStorage 8 | { 9 | private Compressor compressor; 10 | 11 | public ImageStorage(Compressor compressor) 12 | { 13 | this.compressor = compressor; 14 | } 15 | 16 | public void store(string fileName) 17 | { 18 | switch (compressor) 19 | { 20 | case Compressor.JPEG: 21 | System.Console.WriteLine("Do something"); 22 | break; 23 | case Compressor.PNG: 24 | System.Console.WriteLine("Do something else"); 25 | break; 26 | default: 27 | break; 28 | } 29 | //then store the fileName 30 | } 31 | } 32 | public enum Compressor 33 | { 34 | JPEG, 35 | PNG, 36 | } 37 | -------------------------------------------------------------------------------- /src/DesignPattern/StrategyPattern/Solution.cs: -------------------------------------------------------------------------------- 1 | public class ImageStorage 2 | { 3 | public void store(string fileName, ICompressor compressor) 4 | { 5 | compressor.compress(); 6 | //then store the fileName 7 | } 8 | } 9 | public interface ICompressor 10 | { 11 | void compress(); 12 | } 13 | public class JPEGCompressor : ICompressor 14 | { 15 | public void compress() 16 | { 17 | throw new System.NotImplementedException(); 18 | } 19 | } 20 | public class PNGCompressor : ICompressor 21 | { 22 | public void compress() 23 | { 24 | throw new System.NotImplementedException(); 25 | } 26 | } 27 | 28 | public enum Compressor 29 | { 30 | JPEG, 31 | PNG, 32 | } 33 | -------------------------------------------------------------------------------- /src/DesignPattern/TemplateMethodPattern/Problem.cs: -------------------------------------------------------------------------------- 1 | /** 2 | Problem: 3 | - Code duplication 4 | - No code structure 5 | **/ 6 | public class TransferMoneyTask 7 | { 8 | private AuditLog auditLog; 9 | 10 | public TransferMoneyTask(AuditLog auditLog) 11 | { 12 | this.auditLog = auditLog; 13 | } 14 | 15 | public void Execute() 16 | { 17 | this.auditLog.Record(); 18 | //Transfer funds 19 | } 20 | } 21 | public class GenerateReportTask 22 | { 23 | private AuditLog auditLog; 24 | 25 | public GenerateReportTask(AuditLog auditLog) 26 | { 27 | this.auditLog = auditLog; 28 | } 29 | 30 | public void Execute() 31 | { 32 | this.auditLog.Record(); 33 | //Generate Report 34 | } 35 | } 36 | public class AuditLog 37 | { 38 | public void Record() 39 | { 40 | //Log data 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/DesignPattern/TemplateMethodPattern/Solution.cs: -------------------------------------------------------------------------------- 1 | public class TransferMoneyTask : Task 2 | { 3 | public TransferMoneyTask(AuditLog auditLog) : base(auditLog) { } 4 | 5 | protected override void DoExecute() 6 | { 7 | throw new System.NotImplementedException(); 8 | } 9 | } 10 | public class GenerateReportTask : Task 11 | { 12 | public GenerateReportTask(AuditLog auditLog) : base(auditLog) { } 13 | 14 | protected override void DoExecute() 15 | { 16 | throw new System.NotImplementedException(); 17 | } 18 | } 19 | 20 | public abstract class Task 21 | { 22 | private AuditLog auditLog; 23 | 24 | public Task(AuditLog auditLog) 25 | { 26 | this.auditLog = auditLog; 27 | } 28 | public void Execute() 29 | { 30 | this.auditLog.Record(); 31 | this.DoExecute(); 32 | } 33 | protected abstract void DoExecute(); 34 | 35 | } 36 | public class AuditLog 37 | { 38 | public void Record() 39 | { 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/LinkedList/AddTwoNumbers/AddTwoNumbers.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public ListNode addTwoNumbers(ListNode l1, ListNode l2) { 3 | ListNode dummy = new ListNode(), res = dummy; 4 | int carry = 0; 5 | 6 | //Traverse the lists 7 | while(l1 != null || l2 != null){ 8 | int l1Val = l1 == null ? 0 : l1.val; 9 | int l2Val = l2 == null ? 0 : l2.val; 10 | int sum = l1Val + l2Val + carry; 11 | if(sum > 9){ 12 | carry = 1; 13 | }else{ 14 | carry = 0; 15 | } 16 | res.next = new ListNode(sum % 10); 17 | res = res.next; 18 | if(l1 != null){ 19 | l1 = l1.next; 20 | } 21 | if(l2 != null){ 22 | l2 = l2.next; 23 | } 24 | } 25 | 26 | //Add carry over 27 | if(carry > 0){ 28 | res.next = new ListNode(carry); 29 | } 30 | return dummy.next; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/LinkedList/FlattenAMultilevelDoublyLinkedList/FlattenAMultilevelDoublyLinkedList.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public Node flatten(Node head) { 3 | dfs(head); 4 | return head; 5 | } 6 | private Node dfs(Node node){ 7 | Node pre = null; 8 | while(node != null){ 9 | pre = node; 10 | if(node.child != null){ 11 | //Change the tail node 12 | Node tail = dfs(node.child); 13 | tail.next = node.next; 14 | if(node.next != null){ 15 | node.next.prev = tail; 16 | } 17 | 18 | //Change the head node 19 | node.next = node.child; 20 | node.child.prev = node; 21 | node.child = null; 22 | 23 | //Reset the pointers 24 | node = tail.next; 25 | pre = tail; 26 | }else{ 27 | node = node.next; 28 | } 29 | } 30 | return pre; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/LinkedList/InsertintoaSortedCircularLinkedList/InsertintoaSortedCircularLinkedList.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public Node insert(Node head, int insertVal) { 3 | Node insertNode = new Node(insertVal); 4 | 5 | //Base case 6 | if(head == null){ 7 | insertNode.next = insertNode; 8 | return insertNode; 9 | }; 10 | 11 | //Pointer 12 | Node cur = head; 13 | 14 | //Find the right position to insert 15 | while(cur.next != head){ 16 | int curVal = cur.val, nexVal = cur.next.val; 17 | if(curVal > nexVal){ 18 | //Case 1: insertVal bigger than all neighbor nodes 19 | if(curVal < insertVal && nexVal < insertVal) break; 20 | //Case 2: insertVal smaller than all neighbor nodes 21 | if(curVal > insertVal && nexVal > insertVal) break; 22 | } 23 | //Case 3 insertVal is in between neighbor nodes 24 | if(curVal <= insertVal && insertVal <= nexVal) break; 25 | cur = cur.next; 26 | } 27 | //Insert at the current position 28 | Node nex = cur.next; 29 | cur.next = insertNode; 30 | insertNode.next = nex; 31 | return head; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/LinkedList/IntersectionofTwoLinkedLists/IntersectionofTwoLinkedLists.java: -------------------------------------------------------------------------------- 1 | public class Solution { 2 | public ListNode getIntersectionNode(ListNode headA, ListNode headB) { 3 | ListNode A = headA, B = headB; 4 | if(A == null || B == null) return null; 5 | while(A != B){ 6 | A = A == null ? headB : A.next; 7 | B = B == null ? headA : B.next; 8 | } 9 | return A; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/LinkedList/MergekSortedLists/MergekSortedLists.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public ListNode mergeKLists(ListNode[] lists) { 3 | //Define the min heap 4 | Queue minHeap = new PriorityQueue<>((a,b)-> a.val - b.val); 5 | 6 | for(ListNode node : lists){ 7 | if(node == null) continue; 8 | minHeap.add(node); 9 | } 10 | 11 | ListNode dummy = new ListNode(); 12 | ListNode cur = dummy; 13 | 14 | while(!minHeap.isEmpty()){ 15 | ListNode top = minHeap.poll(); 16 | cur.next = top; 17 | cur = cur.next; 18 | if(top.next != null){ 19 | minHeap.add(top.next); 20 | } 21 | } 22 | return dummy.next; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/LinkedList/OddEvenLinkedList/OddEvenLinkedList.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public ListNode oddEvenList(ListNode head) { 3 | //base case 4 | if(head == null || head.next == null) return head; 5 | 6 | //define head node of OddList & EvenList 7 | ListNode OddList = head, EvenList = head.next; 8 | 9 | //define curOdd and curEven 10 | ListNode curOdd = OddList, curEven = EvenList; 11 | 12 | //while curOdd & curEven is not null 13 | while(curOdd.next != null && curEven.next != null){ 14 | //1. curOdd.next = curEven.next then curOdd = curOdd.next 15 | curOdd.next = curEven.next; 16 | curOdd = curOdd.next; 17 | 18 | //2. curEven.next = curOdd.next then curEven = curEven.next 19 | curEven.next = curOdd.next; 20 | curEven = curEven.next; 21 | } 22 | 23 | //Tail node of OddList or curOdd.next = head node of the even list 24 | curOdd.next = EvenList; 25 | //return head of odd list 26 | return OddList; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/LinkedList/PartitionList/PartitionList.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public ListNode partition(ListNode head, int x) { 3 | //Base case 4 | if(head == null || head.next == null) return head; 5 | 6 | ListNode dummyMin = new ListNode(), dummyMax = new ListNode(); 7 | ListNode min = dummyMin, max = dummyMax; 8 | 9 | //Traverse the list 10 | while(head != null){ 11 | if(head.val < x){ 12 | min.next = head; 13 | min = min.next; 14 | }else{ 15 | max.next = head; 16 | max = max.next; 17 | } 18 | head = head.next; 19 | } 20 | 21 | //merge two sub lists 22 | min.next = dummyMax.next; 23 | max.next = null; 24 | return dummyMin.next; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/LinkedList/RemoveDuplicatesFromSortedListII/RemoveDuplicatesFromSortedListII.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * public class ListNode { 4 | * int val; 5 | * ListNode next; 6 | * ListNode() {} 7 | * ListNode(int val) { this.val = val; } 8 | * ListNode(int val, ListNode next) { this.val = val; this.next = next; } 9 | * } 10 | */ 11 | class Solution { 12 | public ListNode deleteDuplicates(ListNode head) { 13 | //Base case 14 | if(head == null || head.next == null) return head; 15 | 16 | ListNode dummy = new ListNode(); 17 | dummy.next = head; 18 | 19 | ListNode pre = dummy, cur = head; 20 | 21 | while(cur != null){ 22 | if(cur.next != null && cur.val == cur.next.val){ 23 | while(cur.next != null && cur.val == cur.next.val){ 24 | cur = cur.next; 25 | } 26 | pre.next = cur.next; 27 | }else{ 28 | pre = cur; 29 | } 30 | cur = cur.next; 31 | } 32 | 33 | return dummy.next; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/LinkedList/ReverseLinkedList/ReverseLinkedList.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public ListNode reverseList(ListNode head) { 3 | //Base Case 4 | if(head == null || head.next == null) return head; 5 | 6 | ListNode pre = null, cur = head; 7 | 8 | //Traverse the list 9 | while(cur != null){ 10 | ListNode nex = cur.next; 11 | cur.next = pre; 12 | pre = cur; 13 | cur = nex; 14 | } 15 | return pre; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/LinkedList/ReverseLinkedListII/ReverseLinkedListII.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public ListNode reverseBetween(ListNode head, int left, int right) { 3 | //base case 4 | if(head.next == null) return head; 5 | if(left == right) return head; 6 | 7 | //define pre and cur 8 | ListNode dummy = new ListNode(); 9 | dummy.next = head; 10 | ListNode pre = dummy; 11 | ListNode cur = head; 12 | 13 | //Move pre and cur into the right position 14 | for(int i = 1; i < left; i++){ 15 | pre = cur; 16 | cur = cur.next; 17 | } 18 | //reverse the sublist 19 | int connections = right - left; 20 | ListNode nex; 21 | for(int i = 0; i < connections; i++){ 22 | nex = cur.next; 23 | cur.next = nex.next; 24 | nex.next = pre.next; 25 | pre.next = nex; 26 | } 27 | 28 | //return head node 29 | return dummy.next; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/LinkedList/ReverseNodesinKGroup/ReverseNodesinKGroup.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public ListNode reverseKGroup(ListNode head, int k) { 3 | //base case 4 | if(head.next == null) return head; 5 | if(k == 1) return head; 6 | 7 | //define pre and cur 8 | ListNode dummy = new ListNode(); 9 | dummy.next = head; 10 | ListNode pre = dummy, cur = head; 11 | 12 | //reverse the list 13 | while(cur != null){ 14 | boolean space = checkHasSpace(k, cur); 15 | if(space){ 16 | pre = reverse(pre, cur, k); 17 | cur = pre.next; 18 | }else{ 19 | break; 20 | } 21 | } 22 | //return the head 23 | return dummy.next; 24 | } 25 | private boolean checkHasSpace(int k, ListNode cur){ 26 | for(int i = 1; i <= k; i++){ 27 | if(cur == null) return false; 28 | cur = cur.next; 29 | } 30 | return true; 31 | } 32 | private ListNode reverse(ListNode pre, ListNode cur, int k){ 33 | for(int i = 0; i < k - 1; i++){ 34 | ListNode nex = cur.next; 35 | cur.next = nex.next; 36 | nex.next = pre.next; 37 | pre.next = nex; 38 | } 39 | return cur; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/LinkedList/RotateList/RotateList.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public ListNode rotateRight(ListNode head, int k) { 3 | //Base case 4 | if(k == 0 || head == null || head.next == null) return head; 5 | 6 | //Convert to circular LL 7 | int size = 0; 8 | ListNode pre = null, cur = head; 9 | while(cur != null){ 10 | size++; 11 | pre = cur; 12 | cur = cur.next; 13 | } 14 | pre.next = head; 15 | 16 | //Traverse to the head node 17 | k = k % size; 18 | int rotate = size - k; 19 | pre = null; 20 | for(int i = 0; i < rotate; i++){ 21 | pre = head; 22 | head = head.next; 23 | } 24 | pre.next = null; 25 | return head; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/LinkedList/SwapNodesinPairs/SwapNodesinPairs_Iterative.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public ListNode swapPairs(ListNode head) { 3 | //base case 4 | if(head == null || head.next == null) return head; 5 | 6 | //define pre and cur 7 | ListNode dummy = new ListNode(); 8 | dummy.next = head; 9 | ListNode pre = dummy; 10 | ListNode cur = head; 11 | 12 | //swap nodes 13 | while(cur != null && cur.next != null){ 14 | ListNode nex = cur.next; 15 | cur.next = nex.next; 16 | nex.next = pre.next; 17 | pre.next = nex; 18 | 19 | //move cur and pre one to the right 20 | pre = cur; 21 | cur = cur.next; 22 | } 23 | 24 | //return the head node 25 | return dummy.next; 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/LinkedList/SwapNodesinPairs/SwapNodesinPairs_Recursive.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public ListNode swapPairs(ListNode head) { 3 | //base case 4 | if(head == null || head.next == null) return head; 5 | 6 | ListNode nex = head.next; 7 | ListNode temp = nex.next; 8 | head.next = swapPairs(temp); 9 | nex.next = head; 10 | return nex; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Object_Oriented_Programming/Abstraction/Interface.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | public class Interface { 4 | interface Animal { 5 | public void eat(); 6 | 7 | public void sound(); 8 | 9 | public void printNoLegs(); 10 | 11 | } 12 | 13 | interface Bird { 14 | static int NUMBEROFLEGS = 2; 15 | 16 | public void fly(); 17 | 18 | } 19 | 20 | static class Eagle implements Animal, Bird { 21 | public void eat() { 22 | System.out.println("Eats reptiles and animals."); 23 | } 24 | 25 | public void sound() { 26 | System.out.println("Has a high-pitched whistling sound."); 27 | } 28 | 29 | public void fly() { 30 | System.out.println("Flies up to 10,000 feet."); 31 | } 32 | 33 | public void printNoLegs() { 34 | System.out.println(NUMBEROFLEGS); 35 | } 36 | } 37 | 38 | public static void main(String[] args) { 39 | Eagle myEagle = new Eagle(); 40 | myEagle.eat(); 41 | myEagle.sound(); 42 | myEagle.fly(); 43 | myEagle.printNoLegs(); 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Object_Oriented_Programming/Encapsulation/Encapsulation.java: -------------------------------------------------------------------------------- 1 | public class Encapsulation { 2 | public static class Product { 3 | private int price; 4 | 5 | // Getter methods 6 | public int getPrice() { 7 | return price; 8 | } 9 | 10 | // Setter methods 11 | public void setPrice(int price) { 12 | if (0 < price && price < 100) { 13 | this.price = price; 14 | } else { 15 | System.out.println("Sorry, " + price + " is outside of the range"); 16 | } 17 | } 18 | } 19 | 20 | public static void main(String[] args) { 21 | Product product = new Product(); 22 | product.setPrice(-1); 23 | product.setPrice(2); 24 | System.out.println(product.getPrice()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Object_Oriented_Programming/Inheritance/Inheritance.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | public class Inheritance { 5 | public static void main(String[] args) { 6 | Eagle eagle = new Eagle(); 7 | Tiger tiger = new Tiger(); 8 | List animals = new ArrayList<>(); 9 | animals.add(eagle); 10 | animals.add(tiger); 11 | for (Animal animal : animals) { 12 | System.out.println("I am a " + animal.name); 13 | animal.eat(); 14 | animal.sleep(); 15 | } 16 | } 17 | 18 | static class Animal { 19 | public void eat() { 20 | System.out.println("I can eat..."); 21 | } 22 | 23 | public String name; 24 | 25 | public void sleep() { 26 | System.out.println("I can sleep..."); 27 | } 28 | } 29 | 30 | static class Eagle extends Animal { 31 | public Eagle() { 32 | name = "eagle"; 33 | } 34 | 35 | public void birdJump() { 36 | System.out.println("Jump"); 37 | } 38 | } 39 | 40 | static class Tiger extends Animal { 41 | public Tiger() { 42 | name = "tiger"; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Object_Oriented_Programming/s3_Abstract_Class_vs_interface.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eric-programming/CodeSolution/a31def34b35fe9d1dc17f3333d446a32b1499c08/src/Object_Oriented_Programming/s3_Abstract_Class_vs_interface.PNG -------------------------------------------------------------------------------- /src/SOLID_Principles/DependencyInversion/Problem.cs: -------------------------------------------------------------------------------- 1 | class OnlineStore 2 | { 3 | private Paypal paymentProcessor; 4 | 5 | public OnlineStore(Paypal paymentProcessor) 6 | { 7 | this.paymentProcessor = paymentProcessor; 8 | } 9 | 10 | public void makeAPaymentForAComputer(int quantity) 11 | { 12 | this.paymentProcessor.makeAPaymentWithPaypal(quantity * 10); 13 | } 14 | } 15 | class Paypal 16 | { 17 | public void makeAPaymentWithPaypal(int val) 18 | { 19 | 20 | } 21 | } 22 | class Stripe 23 | { 24 | public void makeAPaymentWithStripe(int val) 25 | { 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/SOLID_Principles/DependencyInversion/Solution.cs: -------------------------------------------------------------------------------- 1 | class OnlineStore 2 | { 3 | private IPaymentProcessor paymentProcessor; 4 | 5 | public OnlineStore(IPaymentProcessor paymentProcessor) 6 | { 7 | this.paymentProcessor = paymentProcessor; 8 | } 9 | 10 | public void makeAPaymentForAComputer(int quantity) 11 | { 12 | this.paymentProcessor.makeAPayment(quantity * 10); 13 | } 14 | } 15 | 16 | interface IPaymentProcessor 17 | { 18 | public void makeAPayment(int total); 19 | } 20 | 21 | class Paypal : IPaymentProcessor 22 | { 23 | public void makeAPayment(int total) 24 | { 25 | this.makeAPaymentWithPaypal(total); 26 | } 27 | 28 | public void makeAPaymentWithPaypal(int val) 29 | { 30 | 31 | } 32 | } 33 | class Stripe : IPaymentProcessor 34 | { 35 | public void makeAPayment(int total) 36 | { 37 | this.makeAPaymentWithStripe(total); 38 | } 39 | 40 | public void makeAPaymentWithStripe(int val) 41 | { 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/SOLID_Principles/InterfaceSegregation/Problem.cs: -------------------------------------------------------------------------------- 1 | interface IHtmlNode 2 | { 3 | public void Click(); 4 | 5 | public void Type(); 6 | } 7 | 8 | class Button : IHtmlNode 9 | { 10 | public void Click() 11 | { 12 | throw new System.NotImplementedException(); 13 | } 14 | 15 | public void Type() 16 | { 17 | throw new System.NotImplementedException(); 18 | } 19 | } 20 | 21 | class InputBox : IHtmlNode 22 | { 23 | public void Click() 24 | { 25 | throw new System.NotImplementedException(); 26 | } 27 | 28 | public void Type() 29 | { 30 | throw new System.NotImplementedException(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/SOLID_Principles/InterfaceSegregation/Solution.cs: -------------------------------------------------------------------------------- 1 | interface IHtmlButtonNode 2 | { 3 | public void Click(); 4 | 5 | } 6 | interface IHtmlInputNode 7 | { 8 | public void Type(); 9 | } 10 | 11 | class Button : IHtmlButtonNode 12 | { 13 | public void Click() 14 | { 15 | throw new System.NotImplementedException(); 16 | } 17 | } 18 | 19 | class InputBox : IHtmlInputNode 20 | { 21 | public void Type() 22 | { 23 | throw new System.NotImplementedException(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/SOLID_Principles/LiskovSubstituition/Problem.cs: -------------------------------------------------------------------------------- 1 | class Rectangle 2 | { 3 | int width, height; 4 | public void setWidth(int w) 5 | { 6 | width = w; 7 | } 8 | public void setHeight(int h) 9 | { 10 | height = h; 11 | } 12 | //...Additional features 13 | } 14 | 15 | class Square : Rectangle 16 | { 17 | int width; 18 | public void setWidth(int w = 5) 19 | { 20 | width = w; 21 | } 22 | public void setHeight(int h = 6) 23 | { 24 | width = h; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/SOLID_Principles/LiskovSubstituition/Solution.cs: -------------------------------------------------------------------------------- 1 | class Rectangle : Shape 2 | { 3 | int width, height; 4 | public void setWidth(int w) 5 | { 6 | width = w; 7 | } 8 | public void setHeight(int h) 9 | { 10 | height = h; 11 | } 12 | } 13 | 14 | class Square : Shape 15 | { 16 | int width; 17 | public void setWidth(int w = 5) 18 | { 19 | width = w; 20 | } 21 | } 22 | class Shape 23 | { 24 | //Additional Features ... 25 | } 26 | -------------------------------------------------------------------------------- /src/SOLID_Principles/OpenClosed/Problem.cs: -------------------------------------------------------------------------------- 1 | class Pen 2 | { 3 | public void write() 4 | { 5 | 6 | } 7 | public void earse() 8 | { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/SOLID_Principles/OpenClosed/Solution.cs: -------------------------------------------------------------------------------- 1 | abstract class Pen 2 | { 3 | public void write() 4 | { 5 | 6 | } 7 | public void earse() 8 | { 9 | 10 | } 11 | } 12 | 13 | class Highlighter : Pen 14 | { 15 | public void highLightThings() 16 | { 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/SOLID_Principles/SingleResponsibility/Problem.cs: -------------------------------------------------------------------------------- 1 | class Product 2 | { 3 | public int price; 4 | public string productName; 5 | public Product(int price, string productName) 6 | { 7 | this.price = price; 8 | this.productName = productName; 9 | } 10 | public void CalculateGST() 11 | { 12 | 13 | } 14 | public void CalculatePST() 15 | { 16 | 17 | } 18 | public void CalculateDiscount() 19 | { 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/SOLID_Principles/SingleResponsibility/Solution.cs: -------------------------------------------------------------------------------- 1 | class Product 2 | { 3 | public int price; 4 | public string productName; 5 | public Product(int price, string productName) 6 | { 7 | this.price = price; 8 | this.productName = productName; 9 | } 10 | } 11 | class Calculate 12 | { 13 | public void CalculateGST() 14 | { 15 | 16 | } 17 | public void CalculatePST() 18 | { 19 | 20 | } 21 | public void CalculateDiscount() 22 | { 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Search/CloneGraph/CloneGraphDFS.java: -------------------------------------------------------------------------------- 1 | /* 2 | // Definition for a Node. 3 | class Node { 4 | public int val; 5 | public List neighbors; 6 | public Node() { 7 | val = 0; 8 | neighbors = new ArrayList(); 9 | } 10 | public Node(int _val) { 11 | val = _val; 12 | neighbors = new ArrayList(); 13 | } 14 | public Node(int _val, ArrayList _neighbors) { 15 | val = _val; 16 | neighbors = _neighbors; 17 | } 18 | } 19 | */ 20 | 21 | class Solution { 22 | Map map = new HashMap<>(); 23 | public Node cloneGraph(Node node) { 24 | //Base case 25 | if(node == null) return null; 26 | if(map.containsKey(node)){ 27 | return map.get(node); 28 | }else{ 29 | map.put(node, new Node(node.val)); 30 | } 31 | Node newNode = map.get(node); 32 | 33 | List neighbors = node.neighbors; 34 | 35 | for(Node curNode : neighbors){ 36 | Node newCurNode = cloneGraph(curNode); 37 | newNode.neighbors.add(newCurNode); 38 | } 39 | return newNode; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Search/IsGraphBipartite/IsGraphBipartiteDFS.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | Boolean[] color; 3 | final boolean RED = true; 4 | final boolean GREEN = false; 5 | int[][] graph; 6 | 7 | public boolean isBipartite(int[][] graph) { 8 | this.graph = graph; 9 | int n = graph.length; 10 | color = new Boolean[n]; 11 | for(int i = 0; i < n; i++){ 12 | if(color[i] == null){ 13 | color[i] = RED; 14 | if(!dfs(i)) return false; 15 | } 16 | } 17 | return true; 18 | } 19 | 20 | private boolean dfs(int node) { 21 | int[] list = graph[node]; 22 | for (int curNode : list) { 23 | if (color[curNode] == null) { 24 | color[curNode] = !color[node]; 25 | if(!dfs(curNode)) return false; 26 | } else if (color[curNode] == color[node]) { 27 | return false; 28 | } 29 | } 30 | return true; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Search/WallsAndGates/WallsAndGatesBFS.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class Solution { 4 | private static final int ROOM = Integer.MAX_VALUE; 5 | private static final int GATE = 0; 6 | private static final int[][] DIRECTIONS = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } }; 7 | 8 | public void wallsAndGates(int[][] rooms) { 9 | int m = rooms.length; 10 | int n = rooms[0].length; 11 | Queue q = new LinkedList<>(); 12 | for (int row = 0; row < m; row++) { 13 | for (int col = 0; col < n; col++) { 14 | if (rooms[row][col] == GATE) { 15 | q.add(new int[] { row, col }); 16 | } 17 | } 18 | } 19 | while (!q.isEmpty()) { 20 | int[] point = q.poll(); 21 | int row = point[0]; 22 | int col = point[1]; 23 | for (int[] direction : DIRECTIONS) { 24 | int nextRow = row + direction[0]; 25 | int nextCol = col + direction[1]; 26 | if (nextRow < 0 || nextCol < 0 || nextRow >= m || nextCol >= n || rooms[nextRow][nextCol] != ROOM) { 27 | continue; 28 | } 29 | rooms[nextRow][nextCol] = rooms[row][col] + 1; 30 | q.add(new int[] { nextRow, nextCol }); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Search/WallsAndGates/WallsAndGatesDFS.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | final int WALL = -1; 3 | final int GATE = 0; 4 | final int ROOM = Integer.MAX_VALUE; 5 | int[][] arr; 6 | public void wallsAndGates(int[][] rooms) { 7 | arr = rooms; 8 | for(int i = 0; i < rooms.length; i++){ 9 | for(int j = 0; j < rooms[0].length; j++){ 10 | if(rooms[i][j] == GATE){ 11 | dfs(i, j, 0); 12 | } 13 | } 14 | } 15 | } 16 | private void dfs(int rows, int cols, int distance){ 17 | //rows is out bound 18 | if(rows < 0 || rows >= arr.length) return; 19 | if(cols < 0 || cols >= arr[0].length) return; 20 | //if cur distance is smaller than distance 21 | if(arr[rows][cols] < distance) return; 22 | arr[rows][cols] = distance; 23 | dfs(rows + 1, cols, distance + 1); 24 | dfs(rows - 1, cols, distance + 1); 25 | dfs(rows, cols + 1, distance + 1); 26 | dfs(rows, cols - 1, distance + 1); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/SlidingWindow/LongestRepeatingCharacterReplacement/LongestRepeatingCharacterReplacement.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int characterReplacement(String s, int k) { 3 | char[] arr = s.toCharArray(); 4 | int left = 0, right = 0, n = arr.length; 5 | 6 | //Define table 7 | Map hm = new HashMap<>(); 8 | 9 | //define maxLen and mostFreq 10 | int maxLen = 0, mostFreq = 0; 11 | 12 | //find longest repeating character replacement 13 | while(right < n){ 14 | //Expand the window 15 | hm.put(arr[right], hm.getOrDefault(arr[right], 0) + 1); 16 | mostFreq = Math.max(mostFreq, hm.get(arr[right])); 17 | 18 | //Shrink the window if we need to replace more than k char 19 | if((right - left + 1) - mostFreq > k){ 20 | hm.put(arr[left], hm.get(arr[left]) - 1); 21 | left++; 22 | } 23 | maxLen = Math.max(maxLen, right - left + 1); 24 | right++; 25 | } 26 | return maxLen; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/SlidingWindow/LongestSubstringWithAtMostKDistinctCharacters/LongestSubstringWithAtMostKDistinctCharacters.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int lengthOfLongestSubstringKDistinct(String s, int k) { 3 | Map map = new HashMap<>(); 4 | 5 | char[] arr = s.toCharArray(); 6 | int left = 0, right = 0, n = arr.length; 7 | int longestLen = 0; 8 | 9 | while(right < n){ 10 | //Expand the window 11 | map.put(arr[right], map.getOrDefault(arr[right], 0) + 1); 12 | 13 | //Shrink the window if window size exceeds the k distinct characters 14 | while(k < map.size()){ 15 | if(map.get(arr[left]) == 1){ 16 | map.remove(arr[left]); 17 | }else{ 18 | map.put(arr[left], map.get(arr[left]) - 1); 19 | } 20 | left++; 21 | } 22 | 23 | //Update the longest length 24 | longestLen = Math.max(longestLen, right - left + 1); 25 | 26 | right++; 27 | } 28 | 29 | return longestLen; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/SlidingWindow/LongestSubstringWithAtMostTwoDistinctCharacters/LongestSubstringWithAtMostTwoDistinctCharacters.java: -------------------------------------------------------------------------------- 1 | /** 2 | Good questions to ask in the interview: 3 | - what if there is only one distinct character in the string? 4 | - Do we only have lowercase letters? 5 | - Is 'A' the same as 'a' ? 6 | 7 | **/ 8 | 9 | class Solution { 10 | public int lengthOfLongestSubstringTwoDistinct(String s) { 11 | //Define pointers 12 | char[] arr = s.toCharArray(); 13 | int left = 0, right = 0, n = arr.length; 14 | int longestLen = Integer.MIN_VALUE; 15 | Map map = new HashMap<>(); 16 | 17 | while(right < n){ 18 | //Expand window 19 | map.put(arr[right], map.getOrDefault(arr[right], 0) + 1); 20 | 21 | //Shrink the window if the window don't qualify the condition 22 | while(2 < map.size()){ 23 | if(map.get(arr[left]) == 1){ 24 | map.remove(arr[left]); 25 | }else{ 26 | map.put(arr[left], map.get(arr[left]) - 1); 27 | } 28 | left++; 29 | } 30 | 31 | //Keep track of the longest substring length 32 | longestLen = Math.max(longestLen, right - left + 1); 33 | 34 | right++; 35 | } 36 | return longestLen; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/SlidingWindow/LongestSubstringWithoutRepeatingCharacters/LongestSubstringWithoutRepeatingCharacters.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int lengthOfLongestSubstring(String s) { 3 | //Define pointers 4 | char[] arr = s.toCharArray(); 5 | int n = arr.length, left = 0, right = 0; 6 | Map map = new HashMap<>(); 7 | int longestLen = Integer.MIN_VALUE; 8 | 9 | while(right < n){ 10 | //Expand window 11 | map.put(arr[right], map.getOrDefault(arr[right], 0) + 1); 12 | 13 | //Shrink the window if this is repeating characters 14 | while(map.size() < right - left + 1){ 15 | if(map.get(arr[left]) == 1){ 16 | map.remove(arr[left]); 17 | }else{ 18 | map.put(arr[left], map.get(arr[left]) - 1); 19 | } 20 | left++; 21 | } 22 | 23 | longestLen = Math.max(longestLen, right - left + 1); 24 | 25 | right++; 26 | } 27 | if(longestLen == Integer.MIN_VALUE) return 0; 28 | 29 | return longestLen; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/SlidingWindow/MaxConsecutiveOnes/MaxConsecutiveOnes.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int findMaxConsecutiveOnes(int[] nums) { 3 | int maxLen = 0; 4 | 5 | int left = 0; 6 | 7 | for(int right = 0; right < nums.length; right++){ 8 | if(nums[right] == 0){ 9 | left = right + 1; 10 | }else{ 11 | maxLen = Math.max(right - left + 1, maxLen); 12 | } 13 | } 14 | 15 | return maxLen; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/SlidingWindow/MaxConsecutiveOnes/MaxConsecutiveOnes2.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int findMaxConsecutiveOnes(int[] nums) { 3 | int zeroCounter = 0; 4 | int left = 0, right = 0, n = nums.length; 5 | int maxLen = 0; 6 | 7 | while(right < n){ 8 | //Expand the window 9 | if(nums[right] == 0){ 10 | zeroCounter++; 11 | } 12 | 13 | //Shrink the window ONLY if zeroCounter is bigger than one 14 | while(zeroCounter > 1){ 15 | if(nums[left++] == 0){ 16 | zeroCounter--; 17 | } 18 | } 19 | 20 | //update the maxLen 21 | maxLen = Math.max(maxLen, right - left + 1); 22 | 23 | //move the right pointer one to the right 24 | right++; 25 | } 26 | 27 | return maxLen; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/SlidingWindow/MaxConsecutiveOnes/MaxConsecutiveOnes3.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int longestOnes(int[] nums, int k) { 3 | int zeroCounter = 0; 4 | int left = 0, right = 0, n = nums.length; 5 | int maxLen = 0; 6 | 7 | while(right < n){ 8 | //Expand the window 9 | if(nums[right] == 0){ 10 | zeroCounter++; 11 | } 12 | 13 | //Shrink the window ONLY if zeroCounter is bigger than k 14 | while(zeroCounter > k){ 15 | if(nums[left++] == 0){ 16 | zeroCounter--; 17 | } 18 | } 19 | 20 | //update the maxLen 21 | maxLen = Math.max(maxLen, right - left + 1); 22 | 23 | //move the right pointer one to the right 24 | right++; 25 | } 26 | 27 | return maxLen; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/SlidingWindow/MinimumSizeSubarraySum/MinimumSizeSubarraySum.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int minSubArrayLen(int target, int[] nums) { 3 | int minLen = Integer.MAX_VALUE; 4 | 5 | //Define pointers 6 | int left = 0, n = nums.length, right = 0; 7 | 8 | int sum = 0; 9 | while(right < n){ 10 | //Expand the window 11 | sum += nums[right]; 12 | 13 | //Shrink the window 14 | while(target <= sum){ 15 | int size = right - left + 1; 16 | minLen = Math.min(size, minLen); 17 | sum -= nums[left++]; 18 | } 19 | 20 | right++; 21 | } 22 | 23 | if(minLen == Integer.MAX_VALUE) return 0; 24 | return minLen; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/SlidingWindow/PermutationInString/PermutationInString.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public boolean checkInclusion(String t, String s) { 3 | int[] map = new int[128]; 4 | char[] arr = s.toCharArray(); 5 | //Set up the table 6 | for(char cur : t.toCharArray()){ 7 | map[cur]++; 8 | } 9 | 10 | int countAllCharInT = 0; 11 | int left = 0, n = arr.length, right = 0; 12 | 13 | while(right < n){ 14 | //Expand the window 15 | map[arr[right]]--; 16 | if(0 <= map[arr[right]]){ 17 | countAllCharInT++; 18 | } 19 | 20 | //Shrink the window if current window contains all the char in t 21 | while(countAllCharInT == t.length()){ 22 | //Update the minLen 23 | if(right - left + 1 == t.length()){ 24 | return true; 25 | } 26 | 27 | //Shrink the window 28 | map[arr[left]]++; 29 | if(0 < map[arr[left]]){ 30 | countAllCharInT--; 31 | } 32 | left++; 33 | } 34 | 35 | right++; 36 | } 37 | 38 | return false; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Sort/FindMedianfromDataStream/FindMedianfromDataStream.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class MedianFinder { 4 | Queue maxHeap = new PriorityQueue<>((a,b)-> b - a); 5 | Queue minHeap = new PriorityQueue<>(); 6 | int size = 0; 7 | 8 | /** initialize your data structure here. */ 9 | public MedianFinder() { 10 | 11 | } 12 | 13 | public void addNum(int num) { 14 | size++; 15 | // Add element onto the correct heap 16 | if(maxHeap.isEmpty() || num <= maxHeap.peek()){ 17 | maxHeap.add(num); 18 | }else{ 19 | minHeap.add(num); 20 | } 21 | 22 | // balance the heaps 23 | if (minHeap.size() + 1 < maxHeap.size()) { 24 | Integer element = maxHeap.poll(); 25 | minHeap.add(element); 26 | }else if(maxHeap.size() < minHeap.size()){ 27 | Integer element = minHeap.poll(); 28 | maxHeap.add(element); 29 | } 30 | } 31 | 32 | public double findMedian() { 33 | //Odd size 34 | if(size % 2 != 0) return (double) maxHeap.peek(); 35 | //Even size 36 | return (maxHeap.peek() + minHeap.peek()) / 2.0; 37 | } 38 | } 39 | 40 | /** 41 | * Your MedianFinder object will be instantiated and called as such: 42 | * MedianFinder obj = new MedianFinder(); obj.addNum(num); double param_2 = 43 | * obj.findMedian(); 44 | */ 45 | -------------------------------------------------------------------------------- /src/Sort/KClosestPointsToOrigin/KClosestPointsToOrigin.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int[][] kClosest(int[][] points, int k) { 3 | //define a max heap 4 | Queue maxHeap = new PriorityQueue<>((a,b)-> dist(b) - dist(a)); 5 | 6 | //add each points onto the heap 7 | for(int[] point : points){ 8 | maxHeap.add(point); 9 | if(maxHeap.size() > k){ 10 | maxHeap.poll(); 11 | } 12 | } 13 | //add each points from heap onto a array 14 | int[][] res = new int[k][2]; 15 | int i = 0; 16 | while(maxHeap.isEmpty() == false){ 17 | res[i++] = maxHeap.poll(); 18 | } 19 | //return array 20 | return res; 21 | } 22 | private int dist(int[] points){ 23 | int x = points[0]; 24 | int y = points[1]; 25 | return x * x + y * y; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/Sort/KClosestPointsToOrigin/KClosestPointsToOrigin.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | 3 | class Solution: 4 | def kClosest(self, points: List[List[int]], K: int) -> List[List[int]]: 5 | 6 | heap = [] 7 | 8 | for (x, y) in points: 9 | dist = -(x*x + y*y) 10 | if len(heap) == K: 11 | heapq.heappushpop(heap, (dist, x, y)) 12 | else: 13 | heapq.heappush(heap, (dist, x, y)) 14 | 15 | return [(x,y) for (dist,x, y) in heap] 16 | -------------------------------------------------------------------------------- /src/Sort/MeetingRooms/MeetingRooms1.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public boolean canAttendMeetings(int[][] intervals) { 3 | //base case 4 | int n = intervals.length; 5 | if(n == 0) return true; 6 | 7 | //Sort array by start time 8 | Arrays.sort(intervals, (a,b) -> a[0] - b[0]); 9 | 10 | //return false if there is overlapping 11 | for(int i = 0; i < n - 1; i++){ 12 | int[] meeting1 = intervals[i]; 13 | int[] meeting2 = intervals[i + 1]; 14 | if(meeting1[1] > meeting2[0]){ 15 | return false; 16 | } 17 | } 18 | return true; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Sort/MeetingRooms/MeetingRooms2.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int minMeetingRooms(int[][] intervals) { 3 | //sort array by the start time 4 | Arrays.sort(intervals, (a,b)-> a[0] - b[0]); 5 | 6 | //min heap to keep track of the end time 7 | PriorityQueue minHeap = new PriorityQueue<>(); 8 | 9 | //find min rooms 10 | minHeap.add(intervals[0][1]); 11 | for(int i = 1; i < intervals.length; i++){ 12 | int[] cur = intervals[i]; 13 | if(minHeap.peek() <= cur[0]){ 14 | minHeap.poll(); 15 | } 16 | minHeap.add(cur[1]); 17 | } 18 | //return min rooms 19 | return minHeap.size(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Sort/MergeIntervals/MergeIntervals.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int[][] merge(int[][] intervals) { 3 | Arrays.sort(intervals, (a,b) -> a[0] - b[0]); 4 | 5 | Stack stack = new Stack<>(); 6 | 7 | stack.add(intervals[0]); 8 | 9 | for(int i = 1; i < intervals.length; i++){ 10 | int[] preInterval = stack.peek(); 11 | 12 | //Merge the interval if in conflict 13 | if(intervals[i][0] <= preInterval[1]){ 14 | preInterval[1] = Math.max(intervals[i][1], preInterval[1]); 15 | }else{ 16 | //Add the interval onto the stack if not 17 | stack.add(new int[]{intervals[i][0], intervals[i][1]}); 18 | } 19 | } 20 | 21 | return stack.toArray(new int[stack.size()][2]); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Sort/Non-overlappingIntervals/Non-overlappingIntervals.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int eraseOverlapIntervals(int[][] intervals) { 3 | //Sort the array 4 | Arrays.sort(intervals, (a,b)->a[0] - b[0]); 5 | 6 | int[] pre = intervals[0]; 7 | int erase = 0; 8 | 9 | for(int i = 1; i < intervals.length; i++){ 10 | //Check if there is overlapping with the pre interval 11 | if(intervals[i][0] < pre[1]){ 12 | if(intervals[i][1] < pre[1]){ 13 | pre = intervals[i]; 14 | } 15 | erase++; 16 | }else if(pre[1] <= intervals[i][0]){ 17 | //No overlapping 18 | pre = intervals[i]; 19 | } 20 | } 21 | return erase; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Sort/SortCharactersByFrequency/SortCharactersByFrequency.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public String frequencySort(String s) { 3 | // Save each character freq 4 | Map bucket1 = new HashMap<>(); 5 | for (char cur : s.toCharArray()) { 6 | bucket1.put(cur, bucket1.getOrDefault(cur, 0) + 1); 7 | } 8 | // create bucket 2 with freq as the key 9 | Map> bucket2 = new HashMap<>(); 10 | for (Character cur : bucket1.keySet()) { 11 | Integer freq = bucket1.get(cur); 12 | if (!bucket2.containsKey(freq)) { 13 | bucket2.put(freq, new ArrayList<>()); 14 | } 15 | bucket2.get(freq).add(cur); 16 | } 17 | 18 | // Sort by freq 19 | StringBuilder sb = new StringBuilder(); 20 | for (int n = s.length(); n >= 1; n--) { 21 | if (bucket2.containsKey(n)) { 22 | List list = bucket2.get(n); 23 | for (Character character : list) { 24 | for (int i = 0; i < n; i++) { 25 | sb.append(character); 26 | } 27 | } 28 | } 29 | } 30 | return sb.toString(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Sort/SortCharactersByFrequency/SortCharactersByFrequency.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def frequencySort(self, s: str) -> str: 3 | # 1. store each character's frequency 4 | freq_by_char = dict() 5 | for cur_char in s: 6 | if cur_char not in freq_by_char: 7 | freq_by_char[cur_char] = 0 8 | freq_by_char[cur_char] += 1 9 | 10 | # 2. store frequency with list of characters 11 | chars_by_freq = dict() 12 | max_freq = 0 13 | for cur_char in freq_by_char: 14 | cur_freq = freq_by_char[cur_char] 15 | max_freq = max(max_freq, cur_freq) 16 | if cur_freq not in chars_by_freq: 17 | chars_by_freq[cur_freq] = [] 18 | chars_by_freq[cur_freq].append(cur_char) 19 | 20 | # 3. Iterate from the max freq to least freq 21 | result = [] 22 | for cur_freq in range(max_freq, 0, -1): 23 | if cur_freq in chars_by_freq: 24 | for cur_char in chars_by_freq[cur_freq]: 25 | result.append(cur_char * cur_freq) 26 | return "".join(result) 27 | -------------------------------------------------------------------------------- /src/Sort/TopKFrequentElements/TopKFrequentElements.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int[] topKFrequent(int[] nums, int k) { 3 | // save each element's appearance in a table 4 | Map bucket1 = new HashMap<>(); 5 | for (int num : nums) { 6 | bucket1.put(num, bucket1.getOrDefault(num, 0) + 1); 7 | } 8 | 9 | // Store each element's frequence as the key 10 | Map> bucket2 = new HashMap<>(); 11 | for (Integer num : bucket1.keySet()) { 12 | Integer elementFreq = bucket1.get(num); 13 | if (!bucket2.containsKey(elementFreq)) { 14 | bucket2.put(elementFreq, new ArrayList<>()); 15 | } 16 | bucket2.get(elementFreq).add(num); 17 | } 18 | // Get Top K elements 19 | int[] res = new int[k]; 20 | for (int n = nums.length; n > 0; n--) { 21 | if (bucket2.containsKey(n)) { 22 | List list = bucket2.get(n); 23 | for (Integer integer : list) { 24 | res[--k] = integer; 25 | if (k == 0) 26 | return res; 27 | } 28 | } 29 | } 30 | return res; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Sort/TopKFrequentElements/TopKFrequentElements.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def topKFrequent(self, nums: List[int], k: int) -> List[int]: 3 | # Store each element's frequency 4 | freq_by_num = dict() 5 | max_freq = 0 6 | for num in nums: 7 | if num not in freq_by_num: 8 | freq_by_num[num] = 0 9 | freq_by_num[num] += 1 10 | max_freq = max(max_freq, freq_by_num[num]) 11 | 12 | num_by_freq = dict() 13 | for num in freq_by_num: 14 | freq = freq_by_num[num] 15 | if freq not in num_by_freq: 16 | num_by_freq[freq] = [] 17 | num_by_freq[freq].append(num) 18 | 19 | # Find the top k frequent element 20 | result = [] 21 | 22 | for cur_freq in range(max_freq, -1, -1): 23 | if cur_freq in num_by_freq: 24 | cur_nums = num_by_freq[cur_freq] 25 | for num in cur_nums: 26 | result.append(num) 27 | k -= 1 28 | if k == 0: 29 | return result 30 | -------------------------------------------------------------------------------- /src/Stack&Queue/BasicCalculator/BasicCalculator.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class Solution { 4 | char[] arr; 5 | int index = 0; 6 | 7 | public int calculate(String s) { 8 | arr = s.toCharArray(); 9 | return dfs(); 10 | } 11 | 12 | private int dfs() { 13 | // Define variables 14 | int sum = 0, operator = 1; 15 | // Get the sum within current brackets 16 | while (index < arr.length) { 17 | if (arr[index] == ')') { 18 | break; 19 | } else if (arr[index] == '(') { 20 | index++; 21 | sum += operator * dfs(); 22 | } else if (arr[index] == '-') { 23 | operator = -1; 24 | } else if (arr[index] == '+') { 25 | operator = 1; 26 | } else if (Character.isDigit(arr[index])) { 27 | // Form the number 28 | StringBuilder buildNum = new StringBuilder(); 29 | while (index < arr.length && Character.isDigit(arr[index])) { 30 | buildNum.append(arr[index++]); 31 | } 32 | index--; 33 | // Convert to number 34 | sum += Integer.parseInt(buildNum.toString()) * operator; 35 | } 36 | index++; 37 | } 38 | return sum; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Stack&Queue/BasicCalculatorII/BasicCalculatorII.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int calculate(String s) { 3 | char[] arr = s.toCharArray(); 4 | Stack stack = new Stack<>(); 5 | char operator = '+'; 6 | 7 | // Get rid of * and / 8 | for (int i = 0; i < arr.length; i++) { 9 | if (arr[i] == ' ') 10 | continue; 11 | if (Character.isDigit(arr[i])) { 12 | // build the number 13 | StringBuilder buildNum = new StringBuilder(); 14 | while (i < arr.length && Character.isDigit(arr[i])) { 15 | buildNum.append(arr[i++]); 16 | } 17 | i--; 18 | 19 | int curNum = Integer.parseInt(buildNum.toString()); 20 | if (operator == '-') { 21 | curNum *= -1; 22 | } else if (operator == '*') { 23 | curNum *= stack.pop(); 24 | } else if (operator == '/') { 25 | curNum = stack.pop() / curNum; 26 | } 27 | stack.push(curNum); 28 | } else { 29 | operator = arr[i]; 30 | } 31 | } 32 | 33 | int total = 0; 34 | while (!stack.isEmpty()) { 35 | total += stack.pop(); 36 | } 37 | return total; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Stack&Queue/DailyTemperatures/DailyTemperatures.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int[] dailyTemperatures(int[] temperatures) { 3 | Stack stack = new Stack<>(); 4 | int n = temperatures.length; 5 | int[] res = new int[n]; 6 | for (int i = 0; i < n; i++) { 7 | // Add how many days need to wait 8 | while (!stack.isEmpty() && temperatures[stack.peek()] < temperatures[i]) { 9 | int topIdx = stack.pop(); 10 | // where topIdx < i to calculate how many days to wait 11 | res[topIdx] = i - topIdx; 12 | } 13 | stack.add(i); 14 | } 15 | return res; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Stack&Queue/ImplementQueueUsingStacks/ImplementQueueUsingStacks.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class MyQueue { 4 | Stack pushStack = new Stack<>(); 5 | Stack popStack = new Stack<>(); 6 | 7 | /** Initialize your data structure here. */ 8 | public MyQueue() { 9 | 10 | } 11 | 12 | /** Push element x to the back of queue. */ 13 | public void push(int x) { 14 | pushStack.add(x); 15 | } 16 | 17 | /** Removes the element from in front of queue and returns that element. */ 18 | public int pop() { 19 | transferItems(); 20 | return popStack.pop(); 21 | } 22 | 23 | private void transferItems() { 24 | if (popStack.isEmpty()) { 25 | // Transfer elements onto the pop stack 26 | while (!pushStack.isEmpty()) { 27 | popStack.add(pushStack.pop()); 28 | } 29 | } 30 | } 31 | 32 | /** Get the front element. */ 33 | public int peek() { 34 | transferItems(); 35 | return popStack.peek(); 36 | } 37 | 38 | /** Returns whether the queue is empty. */ 39 | public boolean empty() { 40 | return pushStack.isEmpty() && popStack.isEmpty(); 41 | } 42 | } 43 | 44 | /** 45 | * Your MyQueue object will be instantiated and called as such: MyQueue obj = 46 | * new MyQueue(); obj.push(x); int param_2 = obj.pop(); int param_3 = 47 | * obj.peek(); boolean param_4 = obj.empty(); 48 | */ 49 | -------------------------------------------------------------------------------- /src/Stack&Queue/ImplementStackUsingQueues/ImplementStackUsingQueues.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class MyStack { 4 | Queue queue = new LinkedList<>(); 5 | 6 | /** Initialize your data structure here. */ 7 | public MyStack() { 8 | 9 | } 10 | 11 | /** Push element x onto stack. */ 12 | public void push(int x) { 13 | queue.add(x); 14 | // Rotate n - 1 times 15 | for (int i = 0; i < queue.size() - 1; i++) { 16 | queue.add(queue.remove()); 17 | } 18 | } 19 | 20 | /** Removes the element on top of the stack and returns that element. */ 21 | public int pop() { 22 | return queue.remove(); 23 | } 24 | 25 | /** Get the top element. */ 26 | public int top() { 27 | return queue.peek(); 28 | } 29 | 30 | /** Returns whether the stack is empty. */ 31 | public boolean empty() { 32 | return queue.isEmpty(); 33 | } 34 | } 35 | 36 | /** 37 | * Your MyStack object will be instantiated and called as such: MyStack obj = 38 | * new MyStack(); obj.push(x); int param_2 = obj.pop(); int param_3 = obj.top(); 39 | * boolean param_4 = obj.empty(); 40 | */ 41 | -------------------------------------------------------------------------------- /src/Stack&Queue/MinStack/MinStack.java: -------------------------------------------------------------------------------- 1 | class MinStack { 2 | Stack stack = new Stack<>(); //Store all values 3 | Stack minStack = new Stack<>(); //Min value for each insertion 4 | /** initialize your data structure here. */ 5 | public MinStack() { 6 | 7 | } 8 | 9 | public void push(int val) { 10 | if(minStack.isEmpty() || val < minStack.peek()){ 11 | minStack.add(val); 12 | }else{ 13 | minStack.add(minStack.peek()); 14 | } 15 | stack.add(val); 16 | } 17 | 18 | public void pop() { 19 | stack.pop(); 20 | minStack.pop(); 21 | } 22 | 23 | public int top() { 24 | return stack.peek(); 25 | } 26 | 27 | public int getMin() { 28 | return minStack.peek(); 29 | } 30 | } 31 | 32 | /** 33 | * Your MinStack object will be instantiated and called as such: 34 | * MinStack obj = new MinStack(); 35 | * obj.push(val); 36 | * obj.pop(); 37 | * int param_3 = obj.top(); 38 | * int param_4 = obj.getMin(); 39 | */ 40 | -------------------------------------------------------------------------------- /src/Stack&Queue/NextGreaterElement/NextGreaterElement.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int[] nextGreaterElement(int[] nums1, int[] nums2) { 3 | Stack stack = new Stack<>(); 4 | Map map = new HashMap<>(); 5 | 6 | // Add each element's in nums2 next greater element onto the table 7 | for(Integer num : nums2){ 8 | while(!stack.isEmpty() && stack.peek() < num){ 9 | map.put(stack.pop(), num); 10 | } 11 | if(stack.isEmpty() || num <= stack.peek()){ 12 | stack.add(num); 13 | } 14 | } 15 | //Add remaining elements onto the table 16 | while(!stack.isEmpty()){ 17 | map.put(stack.pop(), -1); 18 | } 19 | // Add each element's in nums1 next greater element onto the result arr 20 | int[] res = new int[nums1.length]; 21 | int i = 0; 22 | for(Integer num : nums1){ 23 | res[i++] = map.get(num); 24 | } 25 | return res; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Stack&Queue/NextGreaterElementII/NextGreaterElementII.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int[] nextGreaterElements(int[] nums) { 3 | Stack stack = new Stack<>(); 4 | int[] res = new int[nums.length]; 5 | Arrays.fill(res, -1); 6 | //Add all next greater element for each element onto res 7 | for(int i = 0; i < nums.length; i++){ 8 | while(!stack.isEmpty() && nums[stack.peek()] < nums[i]){ 9 | res[stack.pop()] = nums[i]; 10 | } 11 | //Stack is in decreasing order 12 | stack.add(i); 13 | } 14 | //circle back one more loop 15 | for(int num : nums){ 16 | while(!stack.isEmpty() && nums[stack.peek()] < num){ 17 | int curIdx = stack.pop(); 18 | res[curIdx] = num; // cur num is the next greater element 19 | } 20 | if(stack.isEmpty()) break; 21 | } 22 | return res; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Stack&Queue/ValidParentheses/ValidParentheses.java: -------------------------------------------------------------------------------- 1 | 2 | class Solution { 3 | public boolean isValid(String s) { 4 | // Table set up 5 | Map map = new HashMap<>(); 6 | map.put(')', '('); 7 | map.put('}', '{'); 8 | map.put(']', '['); 9 | 10 | // Validate the string 11 | Stack stack = new Stack<>(); 12 | for (Character curChar : s.toCharArray()) { 13 | // open parenthese 14 | if (!map.containsKey(curChar)) { 15 | stack.add(curChar); 16 | } else { 17 | if (!stack.isEmpty() && stack.peek() == map.get(curChar)) { 18 | stack.pop(); 19 | } else { 20 | return false; 21 | } 22 | } 23 | } 24 | return stack.isEmpty(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Tree/BalancedBinaryTree/BalancedBinaryTree.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | final int UNBALANCED = -1; 3 | public boolean isBalanced(TreeNode root) { 4 | if(root == null) return true; 5 | return dfs(root) != UNBALANCED; 6 | } 7 | private int dfs(TreeNode root){ 8 | //Base case: leaf node 9 | if(root.left == null && root.right == null) return 1; 10 | 11 | //Left Subtree DFS 12 | int leftH = 0; 13 | if(root.left != null){ 14 | leftH = dfs(root.left); 15 | } 16 | if(leftH == UNBALANCED) return UNBALANCED; 17 | 18 | //Right Subtree DFS 19 | int rightH = 0; 20 | if(root.right != null){ 21 | rightH = dfs(root.right); 22 | } 23 | if(rightH == UNBALANCED) return UNBALANCED; 24 | 25 | //Check current tree 26 | if(Math.abs(rightH - leftH) <= 1) return Math.max(rightH, leftH) + 1; 27 | return UNBALANCED; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Tree/BalancedBinaryTree/BalancedBinaryTree.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, val=0, left=None, right=None): 4 | # self.val = val 5 | # self.left = left 6 | # self.right = right 7 | class Solution: 8 | UNBALANCE = -1 9 | def isBalanced(self, root: Optional[TreeNode]) -> bool: 10 | 11 | def dfs(root): 12 | if root is None: 13 | return 0 14 | 15 | left_height = dfs(root.left) 16 | 17 | right_height = dfs(root.right) 18 | 19 | if left_height == self.UNBALANCE or right_height == self.UNBALANCE: 20 | return self.UNBALANCE 21 | 22 | if 1 < abs(left_height - right_height): 23 | return self.UNBALANCE 24 | 25 | return max(left_height, right_height) + 1 26 | 27 | return dfs(root) != self.UNBALANCE 28 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreeBFSGuide/AverageofLevelsinBinaryTree/AverageofLevelsinBinaryTree.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public List averageOfLevels(TreeNode root) { 3 | List res = new LinkedList<>(); 4 | 5 | if(root == null) return res; 6 | 7 | Queue q = new LinkedList<>(); 8 | q.add(root); 9 | 10 | while(!q.isEmpty()){ 11 | //Traverse level by level 12 | int size = q.size(); 13 | double sum = 0; 14 | for(int i = 0; i < size; i++){ 15 | TreeNode first = q.poll(); 16 | 17 | sum += (double) first.val; 18 | 19 | if(first.left != null){ 20 | q.add(first.left); 21 | } 22 | 23 | if(first.right != null){ 24 | q.add(first.right); 25 | } 26 | } 27 | double avg = sum / size; 28 | res.add(avg); 29 | } 30 | return res; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreeBFSGuide/AverageofLevelsinBinaryTree/AverageofLevelsinBinaryTree.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | class Solution: 3 | def averageOfLevels(self, root: Optional[TreeNode]) -> List[float]: 4 | res = [] 5 | 6 | if root is None: 7 | return res 8 | 9 | queue = deque([root]) 10 | 11 | while len(queue) != 0: 12 | size = len(queue) 13 | 14 | total = 0 15 | 16 | for idx in range(size): 17 | cur_node = queue.popleft() 18 | 19 | total += cur_node.val 20 | 21 | if cur_node.left is not None: 22 | queue.append(cur_node.left) 23 | 24 | if cur_node.right is not None: 25 | queue.append(cur_node.right) 26 | 27 | res.append(float(total / float(size * 1.0))) 28 | 29 | return res 30 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreeBFSGuide/BinaryTreeLevelOrderTraversal/BinaryTreeLevelOrderTraversal.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public List> levelOrder(TreeNode root) { 3 | List> res = new LinkedList<>(); 4 | //Base case 5 | if(root == null) return res; 6 | 7 | Queue queue = new LinkedList<>(); 8 | 9 | queue.add(root); 10 | 11 | while(!queue.isEmpty()){ 12 | //Traverse current level ONLY 13 | int size = queue.size(); 14 | List level = new LinkedList<>(); 15 | for(int i = 0; i < size; i++){ 16 | TreeNode top = queue.poll(); 17 | level.add(top.val); 18 | if(top.left != null){ 19 | queue.add(top.left); 20 | } 21 | if(top.right != null){ 22 | queue.add(top.right); 23 | } 24 | } 25 | //Add current level list onto the list 26 | res.add(level); 27 | } 28 | return res; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreeBFSGuide/BinaryTreeLevelOrderTraversal/BinaryTreeLevelOrderTraversal.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | class Solution: 4 | def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: 5 | res = [] 6 | 7 | if root is None: 8 | return res 9 | 10 | queue = deque([root]) 11 | 12 | while len(queue) != 0: 13 | 14 | level_size = len(queue) 15 | 16 | level_list = [] 17 | 18 | for idx in range(level_size): 19 | cur_node = queue.popleft() 20 | 21 | level_list.append(cur_node.val) 22 | 23 | if cur_node.left is not None: 24 | queue.append(cur_node.left) 25 | 26 | if cur_node.right is not None: 27 | queue.append(cur_node.right) 28 | 29 | res.append(level_list) 30 | 31 | return res 32 | 33 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreeBFSGuide/BinaryTreeZigzagLevelOrderTraversal/BinaryTreeZigzagLevelOrderTraversal.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public List> zigzagLevelOrder(TreeNode root) { 3 | List> res = new LinkedList<>(); 4 | 5 | if(root == null) return res; 6 | 7 | Queue q = new LinkedList<>(); 8 | q.add(root); 9 | 10 | boolean FL = true; 11 | 12 | while(!q.isEmpty()){ 13 | int size = q.size(); 14 | List sub = new LinkedList<>(); 15 | 16 | for(int i = 0; i < size; i++){ 17 | TreeNode first = q.poll(); 18 | if(FL){ 19 | sub.add(first.val); 20 | }else{ 21 | sub.add(0, first.val); 22 | } 23 | if(first.left != null){ 24 | q.add(first.left); 25 | } 26 | 27 | if(first.right != null){ 28 | q.add(first.right); 29 | } 30 | } 31 | res.add(sub); 32 | FL = !FL; 33 | } 34 | return res; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreeBFSGuide/BinaryTreeZigzagLevelOrderTraversal/BinaryTreeZigzagLevelOrderTraversal.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | class Solution: 3 | def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: 4 | res = [] 5 | 6 | if root is None: 7 | return res 8 | 9 | queue = deque([root]) 10 | 11 | is_left_to_right = True 12 | 13 | while len(queue) != 0: 14 | size = len(queue) 15 | 16 | level_list = [] 17 | 18 | for idx in range(size): 19 | cur_node = queue.popleft() 20 | 21 | if is_left_to_right: 22 | level_list.append(cur_node.val) 23 | else: 24 | level_list.insert(0, cur_node.val) 25 | 26 | if cur_node.left is not None: 27 | queue.append(cur_node.left) 28 | 29 | if cur_node.right is not None: 30 | queue.append(cur_node.right) 31 | 32 | is_left_to_right = not is_left_to_right 33 | 34 | res.append(level_list) 35 | 36 | return res 37 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreeBFSGuide/PopulatingNextRightPointersinEachNode/PopulatingNextRightPointersinEachNode.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public Node connect(Node root) { 3 | if(root == null) return root; 4 | 5 | Queue q = new LinkedList<>(); 6 | q.add(root); 7 | 8 | 9 | while(!q.isEmpty()){ 10 | int size = q.size(); 11 | //Create a dummy node 12 | Node pre = new Node(); 13 | for(int i = 0; i < size; i++){ 14 | Node top = q.poll(); 15 | pre.next = top; 16 | pre = top; 17 | //Add the next level nodes onto the queue 18 | if(top.left != null){ 19 | q.add(top.left); 20 | } 21 | if(top.right != null){ 22 | q.add(top.right); 23 | } 24 | } 25 | } 26 | return root; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreeBFSGuide/PopulatingNextRightPointersinEachNode/PopulatingNextRightPointersinEachNode.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | class Solution: 4 | def connect(self, root: 'Node') -> 'Node': 5 | 6 | if root is None: 7 | return root 8 | 9 | queue = deque([root]) 10 | 11 | while len(queue) != 0: 12 | size = len(queue) 13 | 14 | dummy = Node() 15 | pre = dummy 16 | 17 | for idx in range(size): 18 | cur = queue.popleft() 19 | pre.next = cur 20 | pre = cur 21 | 22 | if cur.left is not None: 23 | queue.append(cur.left) 24 | if cur.right is not None: 25 | queue.append(cur.right) 26 | 27 | return root 28 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreeInorderTraversal/BinaryTreeInorderTraversal_Iterative.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public List inorderTraversal(TreeNode root) { 3 | List res = new LinkedList<>(); 4 | //Base case 5 | if(root == null) return res; 6 | 7 | Stack stack = new Stack<>(); 8 | TreeNode cur = root; 9 | 10 | while(cur != null || !stack.isEmpty()){ 11 | if(cur == null){ 12 | TreeNode top = stack.pop(); 13 | res.add(top.val); 14 | cur = top.right; 15 | }else{ 16 | stack.add(cur); 17 | cur = cur.left; 18 | } 19 | } 20 | return res; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreeInorderTraversal/BinaryTreeInorderTraversal_Iterative.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]: 3 | res = [] 4 | if root is None: 5 | return res 6 | 7 | cur_node = root 8 | stack = [] 9 | 10 | while True: 11 | while cur_node is not None: 12 | stack.append(cur_node) 13 | cur_node = cur_node.left 14 | 15 | if len(stack) == 0: 16 | break 17 | 18 | cur_node = stack.pop() 19 | 20 | res.append(cur_node.val) 21 | 22 | cur_node = cur_node.right 23 | 24 | 25 | return res 26 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreeInorderTraversal/BinaryTreeInorderTraversal_Recursive.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | List res = new LinkedList<>(); 3 | 4 | public List inorderTraversal(TreeNode root) { 5 | dfs(root); 6 | return res; 7 | } 8 | private void dfs(TreeNode root){ 9 | //base case 10 | if(root == null) return; 11 | 12 | //traverse the left side 13 | dfs(root.left); 14 | 15 | //take the current node val 16 | res.add(root.val); 17 | 18 | //traverse the right side 19 | dfs(root.right); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreeInorderTraversal/BinaryTreeInorderTraversal_Recursive.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, val=0, left=None, right=None): 4 | # self.val = val 5 | # self.left = left 6 | # self.right = right 7 | class Solution: 8 | def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]: 9 | res = [] 10 | 11 | def dfs(root: Optional[TreeNode]): 12 | if root is None: 13 | return 14 | 15 | dfs(root.left) 16 | 17 | res.append(root.val) 18 | 19 | dfs(root.right) 20 | 21 | dfs(root) 22 | 23 | return res 24 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreeMaximumPathSum/BinaryTreeMaximumPathSum.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | int max = Integer.MIN_VALUE; 3 | public int maxPathSum(TreeNode root) { 4 | dfs(root); 5 | return max; 6 | } 7 | private int dfs(TreeNode root){ 8 | //Base case 9 | if(root == null) return 0; 10 | 11 | //Left 12 | int leftMax = Math.max(dfs(root.left), 0); 13 | 14 | //Right 15 | int rightMax = Math.max(dfs(root.right), 0); 16 | 17 | //Update the max 18 | 19 | max = Math.max(max, leftMax + rightMax + root.val); 20 | 21 | return Math.max(leftMax, rightMax) + root.val; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreeMaximumPathSum/BinaryTreeMaximumPathSum.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, val=0, left=None, right=None): 4 | # self.val = val 5 | # self.left = left 6 | # self.right = right 7 | class Solution: 8 | def maxPathSum(self, root: Optional[TreeNode]) -> int: 9 | max_path_sum = -1001 10 | 11 | def dfs(root): 12 | if root is None: 13 | return 0 14 | 15 | left_path = dfs(root.left) 16 | right_path = dfs(root.right) 17 | 18 | cur_max_path_sum = root.val 19 | 20 | if 0 < left_path: 21 | cur_max_path_sum += left_path 22 | 23 | if 0 < right_path: 24 | cur_max_path_sum += right_path 25 | 26 | nonlocal max_path_sum 27 | max_path_sum = max(max_path_sum, cur_max_path_sum) 28 | 29 | return max(left_path + root.val, right_path + root.val, root.val) 30 | 31 | dfs(root) 32 | 33 | return max_path_sum 34 | 35 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreePostorderTraversal/BinaryTreePostorderTraversal_Recursive.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | List res = new LinkedList<>(); 3 | 4 | public List postorderTraversal(TreeNode root) { 5 | dfs(root); 6 | return res; 7 | } 8 | private void dfs(TreeNode root){ 9 | if(root == null) return; 10 | 11 | //Traverse the left 12 | dfs(root.left); 13 | //Traverse the right 14 | dfs(root.right); 15 | //Take the current root 16 | res.add(root.val); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreePostorderTraversal/BinaryTreePostorderTraversal_Recursive.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]: 3 | res = [] 4 | 5 | def dfs(node): 6 | if node is None: 7 | return 8 | 9 | dfs(node.left) 10 | 11 | dfs(node.right) 12 | 13 | res.append(node.val) 14 | 15 | dfs(root) 16 | 17 | return res 18 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreePostorderTraversal/BinaryTreePostorderTraversal_iterative.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public List postorderTraversal(TreeNode root) { 3 | List res = new LinkedList<>(); 4 | //Base case 5 | if(root == null) return res; 6 | 7 | Stack stack = new Stack<>(); 8 | TreeNode cur = root, pre = null; 9 | 10 | while(cur != null || !stack.isEmpty()){ 11 | if(cur != null){ 12 | stack.add(cur); 13 | cur = cur.left; 14 | }else{ 15 | TreeNode top = stack.peek(); 16 | if(top.right == null || top.right == pre){ 17 | res.add(top.val); 18 | stack.pop(); 19 | pre = top; 20 | cur = null; //Don't traverse the left again 21 | }else{ 22 | cur = top.right; 23 | } 24 | } 25 | } 26 | return res; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreePostorderTraversal/BinaryTreePostorderTraversal_iterative.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]: 3 | res = [] 4 | 5 | if root is None: 6 | return res 7 | 8 | stack = [] 9 | 10 | cur = root 11 | pre = None 12 | 13 | while cur is not None or len(stack) != 0: 14 | if cur is not None: 15 | stack.append(cur) 16 | cur = cur.left 17 | else: 18 | top = stack[-1] # peek the last element 19 | if top.right is None or top.right is pre: 20 | res.append(top.val) 21 | stack.pop() 22 | pre = top 23 | cur = None # Don't traverse the left again 24 | else: 25 | cur = top.right #Ready to traverse the right subtree 26 | 27 | return res 28 | 29 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreePreorderTraversal/BinaryTreePreorderTraversal_Iterative.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public List preorderTraversal(TreeNode root) { 3 | List res = new LinkedList<>(); 4 | if(root == null) return res; 5 | Stack stack = new Stack<>(); 6 | 7 | stack.add(root); 8 | 9 | while(stack.isEmpty() == false){ 10 | TreeNode top = stack.pop(); 11 | //add the current node 12 | res.add(top.val); 13 | if(top.right != null){ 14 | //ensure that right is at the bottom of the left 15 | stack.add(top.right); 16 | } 17 | if(top.left != null){ 18 | //ensure that left is on the top 19 | stack.add(top.left); 20 | } 21 | } 22 | return res; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreePreorderTraversal/BinaryTreePreorderTraversal_Iterative.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]: 3 | res: List[int] = [] 4 | if root is None: 5 | return res 6 | stack = [] 7 | 8 | stack.append(root) 9 | 10 | while len(stack) != 0: 11 | node: TreeNode = stack.pop() 12 | res.append(node.val) 13 | 14 | if node.right is not None: 15 | stack.append(node.right) 16 | 17 | if node.left is not None: 18 | stack.append(node.left) 19 | 20 | return res 21 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreePreorderTraversal/BinaryTreePreorderTraversal_Recursive.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | List res = new LinkedList<>(); 3 | public List preorderTraversal(TreeNode root) { 4 | dfs(root); 5 | return res; 6 | } 7 | private void dfs(TreeNode root){ 8 | if(root == null) return; 9 | //First add current element 10 | res.add(root.val); 11 | //traverse left side 12 | dfs(root.left); 13 | //traverse right side 14 | dfs(root.right); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Tree/BinaryTreePreorderTraversal/BinaryTreePreorderTraversal_Recursive.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]: 3 | list: List[int] = [] 4 | 5 | def dfs(node: Optional[TreeNode]): 6 | if node is None: 7 | return 8 | list.append(node.val) 9 | dfs(node.left) 10 | dfs(node.right) 11 | 12 | dfs(root) 13 | 14 | return list 15 | -------------------------------------------------------------------------------- /src/Tree/ConstructBinaryTreefromInorderandPostorderTraversal/ConstructBinaryTreefromInorderandPostorderTraversal.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | Map map = new HashMap<>(); 3 | int index; 4 | int[] postorder_arr; 5 | int[] inorder_arr; 6 | public TreeNode buildTree(int[] inorder, int[] postorder) { 7 | //Define variables 8 | postorder_arr = postorder; 9 | inorder_arr = inorder; 10 | 11 | int n = postorder.length; 12 | //Define the table 13 | for(int i = 0; i < n; i++){ 14 | map.put(inorder[i], i); 15 | } 16 | index = n - 1; 17 | //Pass the boundaries 18 | return dfs(0, n - 1); 19 | } 20 | private TreeNode dfs(int left, int right){ 21 | int curVal = postorder_arr[index--]; 22 | int curIdx = map.get(curVal); 23 | //Build current node 24 | TreeNode root = new TreeNode(curVal); 25 | 26 | //Build right subtree 27 | if(curIdx < right){ 28 | root.right = dfs(curIdx + 1, right); 29 | } 30 | //Build left subtree 31 | if(left < curIdx){ 32 | root.left = dfs(left, curIdx - 1); 33 | } 34 | //Return current root node 35 | return root; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Tree/ConstructBinaryTreefromInorderandPostorderTraversal/ConstructBinaryTreefromInorderandPostorderTraversal.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, val=0, left=None, right=None): 4 | # self.val = val 5 | # self.left = left 6 | # self.right = right 7 | class Solution: 8 | def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]: 9 | #1. Store all the value by index on to map to achieve O(1) in time when retrive inorder element's index 10 | map = dict() 11 | for i in range(len(inorder)): 12 | map[inorder[i]] = i 13 | 14 | #2. perform dfs to find build the tree 15 | index = len(postorder) - 1 16 | 17 | def dfs(start: int, end: int): 18 | if end < start: 19 | return None 20 | 21 | nonlocal index 22 | root_val = postorder[index] 23 | index -= 1 24 | 25 | inorder_index = map[root_val] 26 | 27 | right_node = dfs(inorder_index + 1, end) 28 | left_node = dfs(start, inorder_index - 1) 29 | 30 | 31 | return TreeNode(val=root_val, left=left_node, right=right_node) 32 | 33 | return dfs(0, len(inorder) - 1) 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/Tree/ConstructBinaryTreefromPreorderandInorderTraversal/ConstructBinaryTreefromPreorderandInorderTraversal.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | Map map = new HashMap<>(); 3 | int index = 0; 4 | int[] preorder_arr; 5 | int[] inorder_arr; 6 | public TreeNode buildTree(int[] preorder, int[] inorder) { 7 | //Define variables 8 | preorder_arr = preorder; 9 | inorder_arr = inorder; 10 | //Define the table 11 | for(int i = 0; i < inorder.length; i++){ 12 | map.put(inorder[i], i); 13 | } 14 | //Pass the boundaries 15 | return dfs(0, inorder.length - 1); 16 | } 17 | private TreeNode dfs(int left, int right){ 18 | int curVal = preorder_arr[index++]; 19 | int curIdx = map.get(curVal); 20 | //Build current node 21 | TreeNode root = new TreeNode(curVal); 22 | 23 | //Build left subtree 24 | if(left < curIdx){ 25 | root.left = dfs(left, curIdx - 1); 26 | } 27 | //Build right subtree 28 | if(curIdx < right){ 29 | root.right = dfs(curIdx + 1, right); 30 | } 31 | //Return current root node 32 | return root; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Tree/ConstructBinaryTreefromPreorderandInorderTraversal/ConstructBinaryTreefromPreorderandInorderTraversal.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: 3 | # 1. Save each inorder element's value and index onto map 4 | map = dict() 5 | 6 | for i in range(len(inorder)): 7 | map[inorder[i]] = i 8 | 9 | # 2. perform dfs to build tree 10 | idx = 0 11 | 12 | def dfs(start: int, end: int): 13 | # base check 14 | if end < start: 15 | return None 16 | 17 | nonlocal idx 18 | root_val = preorder[idx] 19 | idx += 1 20 | 21 | inorder_index = map[root_val] 22 | 23 | left_node = dfs(start, inorder_index - 1) 24 | right_node = dfs(inorder_index + 1, end) 25 | 26 | root = TreeNode(val=root_val, left=left_node, right=right_node) 27 | 28 | return root 29 | 30 | return dfs(0, len(inorder) - 1) 31 | -------------------------------------------------------------------------------- /src/Tree/ConstructBinaryTreefromPreorderandPostorderTraversal/ConstructBinaryTreefromPreorderandPostorderTraversal.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * public class TreeNode { 4 | * int val; 5 | * TreeNode left; 6 | * TreeNode right; 7 | * TreeNode() {} 8 | * TreeNode(int val) { this.val = val; } 9 | * TreeNode(int val, TreeNode left, TreeNode right) { 10 | * this.val = val; 11 | * this.left = left; 12 | * this.right = right; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | int[] pre_arr; 18 | int[] post_arr; 19 | Map map = new HashMap<>(); 20 | int index = 0; 21 | public TreeNode constructFromPrePost(int[] pre, int[] post) { 22 | //Build the table 23 | pre_arr = pre; 24 | post_arr = post; 25 | for(int i = 0; i < post.length; i++){ 26 | map.put(post[i], i); 27 | } 28 | return dfs(pre.length); 29 | } 30 | private TreeNode dfs(int preIdx){ 31 | if(index >= pre_arr.length) return null; 32 | int curVal = pre_arr[index]; 33 | int curIdx = map.get(curVal); 34 | if(preIdx < curIdx) return null; 35 | index++; 36 | TreeNode root = new TreeNode(curVal); 37 | root.left = dfs(curIdx); 38 | root.right = dfs(curIdx); 39 | return root; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Tree/ConstructBinaryTreefromPreorderandPostorderTraversal/ConstructBinaryTreefromPreorderandPostorderTraversal.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, val=0, left=None, right=None): 4 | # self.val = val 5 | # self.left = left 6 | # self.right = right 7 | class Solution: 8 | def constructFromPrePost(self, preorder: List[int], postorder: List[int]) -> Optional[TreeNode]: 9 | map = dict() 10 | for i in range(len(postorder)): 11 | map[postorder[i]] = i 12 | 13 | index = 0 # point to the index in preorder array 14 | 15 | def dfs(preIndex: int): 16 | nonlocal index 17 | if index == len(preorder): 18 | return None 19 | 20 | root_val = preorder[index] 21 | 22 | cur_postorder_index = map[root_val] 23 | 24 | if preIndex < cur_postorder_index: 25 | return None 26 | 27 | index += 1 28 | 29 | left = dfs(cur_postorder_index) 30 | right = dfs(cur_postorder_index) 31 | 32 | root = TreeNode(val=root_val, left=left, right=right) 33 | 34 | return root 35 | 36 | 37 | return dfs(len(postorder)) 38 | -------------------------------------------------------------------------------- /src/Tree/ConvertBinarySearchTreeToSortedDoublyLinkedList/ConvertBinarySearchTreeToSortedDoublyLinkedList.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | Node head = null; 3 | Node pre = null; 4 | public Node treeToDoublyList(Node root) { 5 | dfs(root); 6 | if(head == null) return null; 7 | head.left = pre; 8 | pre.right = head; 9 | return head; 10 | } 11 | private void dfs(Node root){ 12 | if(root == null) return; 13 | //Traverse the left side 14 | dfs(root.left); 15 | 16 | //Visited current node 17 | if(head == null){ 18 | head = root; 19 | }else{ 20 | pre.right = root; 21 | root.left = pre; 22 | } 23 | pre = root; 24 | 25 | //Traverse the right side 26 | dfs(root.right); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Tree/DiameterOfBinaryTree/DiameterOfBinaryTree.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * public class TreeNode { 4 | * int val; 5 | * TreeNode left; 6 | * TreeNode right; 7 | * TreeNode() {} 8 | * TreeNode(int val) { this.val = val; } 9 | * TreeNode(int val, TreeNode left, TreeNode right) { 10 | * this.val = val; 11 | * this.left = left; 12 | * this.right = right; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | int max = Integer.MIN_VALUE; 18 | public int diameterOfBinaryTree(TreeNode root) { 19 | dfs(root); 20 | return max; 21 | } 22 | private int dfs(TreeNode node){ 23 | int left = 0, right = 0; 24 | 25 | if(node.left != null){ 26 | left = dfs(node.left); 27 | } 28 | 29 | if(node.right != null){ 30 | right = dfs(node.right); 31 | } 32 | max = Math.max(max, left + right); 33 | 34 | return Math.max(left, right) + 1; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Tree/DiameterOfBinaryTree/DiameterOfBinaryTree.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, val=0, left=None, right=None): 4 | # self.val = val 5 | # self.left = left 6 | # self.right = right 7 | class Solution: 8 | def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int: 9 | #Base case 10 | if root is None: 11 | return 0 12 | 13 | diameter = 0 14 | 15 | def dfs(root): 16 | left_height = 0 17 | right_height = 0 18 | 19 | if root.left is not None: 20 | left_height = dfs(root.left) + 1 21 | 22 | if root.right is not None: 23 | right_height = dfs(root.right) + 1 24 | 25 | 26 | nonlocal diameter 27 | diameter = max(left_height + right_height, diameter) 28 | 29 | return max(left_height, right_height) 30 | 31 | dfs(root) 32 | 33 | return diameter 34 | 35 | -------------------------------------------------------------------------------- /src/Tree/FindDuplicateSubtrees/FindDuplicateSubtrees.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, val=0, left=None, right=None): 4 | # self.val = val 5 | # self.left = left 6 | # self.right = right 7 | class Solution: 8 | def findDuplicateSubtrees(self, root: Optional[TreeNode]) -> List[Optional[TreeNode]]: 9 | map = dict() 10 | unique_keys = set() 11 | list = [] 12 | 13 | def dfs(root): 14 | if root is None: 15 | return ["X"] 16 | 17 | left_sub = dfs(root.left) 18 | right_sub = dfs(root.right) 19 | 20 | root_tree: List[str] = [str(root.val)] 21 | root_tree += left_sub + right_sub #combine 2 lists to serialize the current subtree 22 | 23 | key = ",".join(root_tree) 24 | 25 | if key in map and key not in unique_keys: 26 | list.append(root) 27 | unique_keys.add(key) 28 | 29 | map[key] = root 30 | 31 | return root_tree 32 | 33 | dfs(root) 34 | 35 | return list 36 | -------------------------------------------------------------------------------- /src/Tree/LowestCommonAncestorofaBinarySearchTree/LowestCommonAncestorofaBinarySearchTree.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { 3 | int min = Math.min(p.val, q.val), max = Math.max(p.val, q.val); 4 | while(root != null){ 5 | int cur = root.val; 6 | if(min < cur && max < cur) { 7 | root = root.left; 8 | }else if(min > cur && max > cur){ 9 | root = root.right; 10 | }else{ 11 | break; 12 | } 13 | } 14 | return root; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Tree/LowestCommonAncestorofaBinaryTree/LowestCommonAncestorofaBinaryTree.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { 3 | //Base case 4 | if(root == null) return null; 5 | 6 | if(root == p || root == q) return root; 7 | 8 | TreeNode left = lowestCommonAncestor(root.left, p, q); 9 | TreeNode right = lowestCommonAncestor(root.right, p, q); 10 | 11 | //We found p and q in left and right 12 | if(left != null && right != null) return root; 13 | 14 | if(left != null) return left; 15 | 16 | return right; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Tree/LowestCommonAncestorofaBinaryTree/LowestCommonAncestorofaBinaryTree.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution: 9 | def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode': 10 | if root == p or root == q: 11 | return root 12 | 13 | if root is None: 14 | return None 15 | 16 | left_lca = self.lowestCommonAncestor(root.left, p, q) 17 | right_lca = self.lowestCommonAncestor(root.right, p, q) 18 | 19 | if left_lca is not None and right_lca is not None: 20 | return root 21 | elif left_lca is not None: 22 | return left_lca 23 | 24 | return right_lca 25 | -------------------------------------------------------------------------------- /src/Tree/PathSum/PathSum1.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public boolean hasPathSum(TreeNode root, int targetSum) { 3 | if(root == null) return false; 4 | return dfs(root, targetSum); 5 | } 6 | private boolean dfs(TreeNode root, int targetSum){ 7 | targetSum -= root.val; 8 | //Base case: leaf node 9 | if(root.left == null && root.right == null){ 10 | return targetSum == 0; 11 | } 12 | boolean left = false, right = false; 13 | if(root.left != null){ 14 | left = dfs(root.left, targetSum); 15 | } 16 | if(root.right != null){ 17 | right = dfs(root.right, targetSum); 18 | } 19 | return left || right; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Tree/PathSum/PathSum1.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool: 3 | # Base case 4 | if root is None: 5 | return False 6 | 7 | targetSum -= root.val 8 | 9 | if root.left is None and root.right is None: 10 | return targetSum == 0 11 | 12 | return self.hasPathSum(root.left, targetSum) or self.hasPathSum(root.right, targetSum) 13 | -------------------------------------------------------------------------------- /src/Tree/PathSum/PathSum2.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | List> res = new LinkedList<>(); 3 | public List> pathSum(TreeNode root, int targetSum) { 4 | if(root == null) return res; 5 | dfs(root, targetSum, new LinkedList<>()); 6 | return res; 7 | } 8 | private void dfs(TreeNode root, int targetSum, List path){ 9 | targetSum -= root.val; 10 | path.add(root.val); 11 | //Base case: leaf node 12 | if(root.left == null && root.right == null && targetSum == 0){ 13 | res.add(new LinkedList<>(path)); 14 | }else{ 15 | if(root.left != null){ 16 | dfs(root.left, targetSum, path); 17 | } 18 | if(root.right != null){ 19 | dfs(root.right, targetSum, path); 20 | } 21 | } 22 | //Backtrack 23 | path.remove(path.size() - 1); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Tree/PathSum/PathSum2.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, val=0, left=None, right=None): 4 | # self.val = val 5 | # self.left = left 6 | # self.right = right 7 | class Solution: 8 | def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]: 9 | res = [] 10 | 11 | def dfs(root, cur_list, cur_sum): 12 | if root is None: 13 | return 14 | 15 | cur_sum += root.val 16 | cur_list.append(root.val) 17 | 18 | if root.left is None and root.right is None and cur_sum == targetSum: 19 | res.append(list(cur_list)) 20 | else: 21 | dfs(root.left, cur_list, cur_sum) 22 | dfs(root.right, cur_list, cur_sum) 23 | 24 | cur_list.pop() 25 | 26 | dfs(root, [], 0) 27 | 28 | return res 29 | 30 | -------------------------------------------------------------------------------- /src/Tree/PopulatingNextRightPointersinEachNodeII/PopulatingNextRightPointersinEachNodeII.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public Node connect(Node root) { 3 | Node head = root; 4 | 5 | while(head != null){ 6 | Node dummy = new Node(); 7 | Node temp = dummy; 8 | 9 | //Build the LinkedList 10 | while(head != null){ 11 | if(head.left != null){ 12 | temp.next = head.left; 13 | temp = temp.next; 14 | } 15 | if(head.right != null){ 16 | temp.next = head.right; 17 | temp = temp.next; 18 | } 19 | head = head.next; 20 | } 21 | //Start from next level 22 | head = dummy.next; 23 | } 24 | return root; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Tree/PopulatingNextRightPointersinEachNodeII/PopulatingNextRightPointersinEachNodeII.py: -------------------------------------------------------------------------------- 1 | """ 2 | # Definition for a Node. 3 | class Node: 4 | def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None): 5 | self.val = val 6 | self.left = left 7 | self.right = right 8 | self.next = next 9 | """ 10 | 11 | class Solution: 12 | def connect(self, root: 'Node') -> 'Node': 13 | cur_node = root 14 | 15 | while cur_node is not None: 16 | dummy = Node() 17 | temp = dummy 18 | 19 | while cur_node is not None: 20 | if cur_node.left is not None: 21 | temp.next = cur_node.left 22 | temp = cur_node.left 23 | 24 | if cur_node.right is not None: 25 | temp.next = cur_node.right 26 | temp = cur_node.right 27 | 28 | cur_node = cur_node.next 29 | 30 | cur_node = dummy.next 31 | 32 | return root 33 | -------------------------------------------------------------------------------- /src/Tree/SerializeandDeserializeBinaryTree/SerializeandDeserializeBinaryTree.java: -------------------------------------------------------------------------------- 1 | public class Codec { 2 | final String X = "X"; 3 | 4 | // Encodes a tree to a single string. 5 | public String serialize(TreeNode root) { 6 | if (root == null) 7 | return X; 8 | String left = serialize(root.left); 9 | String right = serialize(root.right); 10 | return root.val + "," + left + "," + right; 11 | } 12 | 13 | // Decodes your encoded data to tree. 14 | String[] arr; 15 | int index = 0; 16 | 17 | // 1,2,x,x,3,4,5,x,x,x,x 18 | public TreeNode deserialize(String data) { 19 | arr = data.split(","); 20 | return dfs(); 21 | } 22 | 23 | private TreeNode dfs() { 24 | // base case 25 | if (arr[index].equals(X)) { 26 | index++; 27 | return null; 28 | } 29 | // deserialize the current value 30 | TreeNode root = new TreeNode(Integer.parseInt(arr[index++])); 31 | // build our left subtree and return its root 32 | root.left = dfs(); 33 | // build our right subtree and return its root 34 | root.right = dfs(); 35 | return root; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Tree/SymmetricTree/SymmetricTree.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * public class TreeNode { 4 | * int val; 5 | * TreeNode left; 6 | * TreeNode right; 7 | * TreeNode() {} 8 | * TreeNode(int val) { this.val = val; } 9 | * TreeNode(int val, TreeNode left, TreeNode right) { 10 | * this.val = val; 11 | * this.left = left; 12 | * this.right = right; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public boolean isSymmetric(TreeNode root) { 18 | if(root == null) return true; 19 | return dfs(root.left, root.right); 20 | } 21 | private boolean dfs(TreeNode left, TreeNode right){ 22 | if(left == null && right == null) return true; 23 | 24 | if(left == null || right == null) return false; 25 | 26 | if(left.val != right.val) return false; 27 | 28 | return dfs(left.left, right.right) && dfs(left.right, right.left); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Tree/SymmetricTree/SymmetricTree.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isSymmetric(self, root: Optional[TreeNode]) -> bool: 3 | if root is None: 4 | return True 5 | 6 | def dfs(left: Optional[TreeNode], right: Optional[TreeNode]): 7 | if left is None and right is None: 8 | return True 9 | 10 | if left is None or right is None: 11 | return False 12 | 13 | if left.val != right.val: 14 | return False 15 | 16 | return dfs(left.left, right.right) and dfs(left.right, right.left) 17 | 18 | return dfs(root.left, root.right) 19 | -------------------------------------------------------------------------------- /src/TwoPointers/3Sum/3Sum.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public List> threeSum(int[] num) { 3 | Arrays.sort(num); 4 | List> res = new LinkedList<>(); 5 | int n = num.length; 6 | for (int i = 0; i < n-2; i++) { 7 | if (0 < i && num[i] == num[i-1]) continue; 8 | int left = i+1, right = n-1; 9 | while (left < right) { 10 | int sum = num[left] + num[right] + num[i]; 11 | if (sum == 0) { 12 | res.add(Arrays.asList(num[i], num[left], num[right])); 13 | while (left < right && num[left] == num[left+1]) left++; 14 | left++; 15 | while (left < right && num[right] == num[right-1]) right--; 16 | right--; 17 | } else if (sum < 0) { 18 | // improve: skip duplicates 19 | while (left < right && num[left] == num[left+1]) left++; 20 | left++; 21 | } else { 22 | // improve: skip duplicates 23 | while (left < right && num[right] == num[right-1]) right--; 24 | right--; 25 | } 26 | } 27 | } 28 | return res; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/TwoPointers/3Sum/3SumClosest.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int threeSumClosest(int[] nums, int target) { 3 | //Sort array 4 | Arrays.sort(nums); 5 | 6 | //define gap, ans 7 | int gap = Integer.MAX_VALUE, ans = 0, n = nums.length; 8 | 9 | //iterations 10 | for(int i = 0; i < n; i++){ 11 | if(i != 0 && nums[i] == nums[i - 1])continue; 12 | int L = i + 1, R = n - 1; 13 | while(L < R){ 14 | int curSum = nums[L] + nums[R] + nums[i]; 15 | if(curSum == target){ 16 | return target; 17 | }else if(curSum < target){ 18 | L++; 19 | }else{ 20 | R--; 21 | } 22 | int curGap = Math.abs(curSum - target); 23 | if(curGap < gap){ 24 | gap = curGap; 25 | ans = curSum; 26 | } 27 | } 28 | } 29 | //return the sum that has smallest gap between target and the sum 30 | return ans; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/TwoPointers/3Sum/3SumSmaller.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int threeSumSmaller(int[] nums, int target) { 3 | int N = nums.length; 4 | Arrays.sort(nums); 5 | int Counter = 0; 6 | for(int i = 0; i < N; i++){ 7 | // if(i != 0 && nums[i] == nums[i-1]) continue; 8 | int L = i + 1, R = N - 1; 9 | while(L < R){ 10 | int curSum = nums[i] + nums[L] + nums[R]; 11 | if(curSum < target){ 12 | Counter += R - L; 13 | L++; 14 | }else{ 15 | R--; 16 | } 17 | } 18 | } 19 | return Counter; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/TwoPointers/ContainerWithMostWater/ContainerWithMostWater.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int maxArea(int[] height) { 3 | int L = 0, N = height.length, R = N - 1; 4 | int maxArea = 0; 5 | while(L < R){ 6 | int maxHeight = Math.min(height[L], height[R]); 7 | int area = maxHeight * (R - L); 8 | maxArea = Math.max(area, maxArea); 9 | if(height[L] < height[R]){ 10 | L++; 11 | }else{ 12 | R--; 13 | } 14 | } 15 | return maxArea; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/TwoPointers/LinkedListDeletion/RemoveLinkedListElements/RemoveLinkedListElements.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public ListNode removeElements(ListNode head, int val) { 3 | ListNode dummy = new ListNode(); 4 | dummy.next = head; 5 | ListNode pre = dummy, cur = head; 6 | 7 | while(cur != null){ 8 | if(cur.val == val){ 9 | pre.next = cur.next; 10 | }else{ 11 | pre = cur; 12 | } 13 | cur = cur.next; 14 | } 15 | return dummy.next; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/TwoPointers/LinkedListDeletion/RemoveNthFromEndOfList/RemoveNthFromEndOfList.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public ListNode removeNthFromEnd(ListNode head, int n) { 3 | //base case 4 | if(head == null) return null; 5 | 6 | //define slow and fast and pre and dummy 7 | ListNode dummy = new ListNode(); 8 | dummy.next = head; 9 | ListNode slow = dummy, fast = dummy; 10 | ListNode pre = null; 11 | 12 | //move fast pointer n node ahead of the slow 13 | for(int i = 0; i < n; i++){ 14 | fast = fast.next; 15 | } 16 | 17 | //move both slow and fast pointers in the same speed 18 | while(fast != null){ 19 | fast = fast.next; 20 | pre = slow; 21 | slow = slow.next; 22 | } 23 | pre.next = slow.next; 24 | //return head 25 | return dummy.next; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/TwoPointers/MiddleNodeOfList/MiddleNodeOfList.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public ListNode middleNode(ListNode head) { 3 | //base case 4 | if(head.next == null) return head; 5 | 6 | //define slow and fast 7 | ListNode slow = head, fast = head; 8 | 9 | //traverse the list 10 | while(fast != null && fast.next != null){ 11 | fast = fast.next.next; 12 | slow = slow.next; 13 | } 14 | 15 | //return slow 16 | return slow; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/TwoPointers/MoveZeroes/MoveZeroes.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public void moveZeroes(int[] nums) { 3 | //ap: Anchor pointer 4 | int ap = 0; 5 | //ep: Explore pointer 6 | int ep = 0; 7 | //n: length of the arr 8 | int n = nums.length; 9 | 10 | while(ep < n){ 11 | if(nums[ap] != 0){ 12 | //We move both pointers because we need to prevent an example like this [1,0,1] where we could have ep < ap 13 | ap++; 14 | ep = ap; 15 | }else if(nums[ep] == 0){ 16 | ep++; 17 | }else{ 18 | //Current conditions: nums[ap] = 0 and nums[ep] != 0 so we swap 19 | int temp = nums[ap]; 20 | nums[ap] = nums[ep]; 21 | nums[ep] = temp; 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/TwoPointers/PalindromeLinkedList/PalindromeLinkedList.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public boolean isPalindrome(ListNode head) { 3 | //base case 4 | if(head == null || head.next == null) return true; 5 | 6 | //define slow and fast 7 | ListNode slow = head, fast = head; 8 | 9 | //move slow and fast in the right position 10 | while(fast != null && fast.next != null){ 11 | slow = slow.next; 12 | fast = fast.next.next; 13 | } 14 | 15 | //reverse the last half of the list 16 | ListNode L = head, R = reverse(slow); 17 | 18 | //check if is palindrome 19 | while(R != null){ 20 | if(L.val == R.val){ 21 | L = L.next; 22 | R = R.next; 23 | }else{ 24 | return false; 25 | } 26 | } 27 | 28 | return true; 29 | } 30 | private ListNode reverse(ListNode head){ 31 | // base case 32 | if(head == null || head.next == null) return head; 33 | 34 | //reverse 35 | ListNode pre = null, cur = head; 36 | while(cur != null){ 37 | ListNode temp = cur.next; 38 | cur.next = pre; 39 | pre = cur; 40 | cur = temp; 41 | } 42 | return pre; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/TwoPointers/PartitionLabels/PartitionLabels.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public List partitionLabels(String S) { 3 | List res = new LinkedList<>(); 4 | char[] arr = S.toCharArray(); 5 | //1. Last appear character index save onto a table 6 | int[] map = new int[26]; 7 | for(int i = 0; i < arr.length; i++){ 8 | map[arr[i] - 'a'] = i; 9 | } 10 | 11 | //2. Define L and R 12 | int L = 0; 13 | int maxLastAppearIndex = 0; 14 | 15 | for(int R = 0; R < arr.length; R++){ 16 | //Current Character Last appear index 17 | int curLastAppearIndex = map[arr[R] - 'a']; 18 | 19 | //Update the max last appear char index 20 | maxLastAppearIndex = Math.max(maxLastAppearIndex, curLastAppearIndex); 21 | 22 | if(maxLastAppearIndex == R){ 23 | int len = R - L + 1; 24 | res.add(len); 25 | L = R + 1; 26 | } 27 | } 28 | 29 | return res; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/TwoPointers/RemoveDuplicatesfromSortedArray/RemoveDuplicatesfromSortedArray.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int removeDuplicates(int[] nums) { 3 | //cp: current pointer points to current non duplicated item's index 4 | int cp = 0; 5 | //ep: explore pointer explores the next unique item's index 6 | int ep = 1; 7 | 8 | int n = nums.length; 9 | 10 | while(ep < n){ 11 | if(nums[cp] == nums[ep]){ 12 | ep++; 13 | }else{ 14 | nums[++cp] = nums[ep++]; 15 | } 16 | } 17 | return cp + 1; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/TwoPointers/RemoveDuplicatesfromSortedArray/RemoveDuplicatesfromSortedArrayII.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int removeDuplicates(int[] nums) { 3 | boolean seenDup = false; 4 | //cp: current pointer points to current non duplicated item's index 5 | int cp = 0; 6 | //ep: explore pointer explores the next unique item's index 7 | int ep = 1; 8 | int n = nums.length; 9 | 10 | while(ep < n){ 11 | if(nums[cp] == nums[ep]){ 12 | if(seenDup){ 13 | ep++; 14 | }else{ 15 | seenDup = true; 16 | cp++; 17 | nums[cp] = nums[ep]; 18 | ep++; 19 | } 20 | }else{ 21 | nums[++cp] = nums[ep++]; 22 | seenDup = false; 23 | } 24 | } 25 | 26 | return cp + 1; 27 | } 28 | } 29 | 30 | //0,0,1,1,2,3,2,3,3 31 | // ^ ^ 32 | -------------------------------------------------------------------------------- /src/TwoPointers/ReorderList/ReorderList.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public void reorderList(ListNode head) { 3 | //base case 4 | if(head == null || head.next == null) return; 5 | 6 | //define slow and fast 7 | ListNode slow = head, fast = head, pre = null; 8 | 9 | //slow point the middle node in the list 10 | while(fast != null && fast.next != null){ 11 | pre = slow; 12 | slow = slow.next; 13 | fast = fast.next.next; 14 | } 15 | 16 | //break the list 17 | pre.next = null; 18 | 19 | //reverse the last half of the list 20 | ListNode p1 = head, p2 = reverse(slow); 21 | 22 | //reorder the list 23 | while(p1 != null && p2 != null){ 24 | ListNode nex1 = p1.next, nex2 = p2.next; 25 | p1.next = p2; 26 | p2.next = nex1 == null ? nex2 : nex1; 27 | 28 | p1 = nex1; 29 | p2 = nex2; 30 | } 31 | } 32 | private ListNode reverse(ListNode head){ 33 | if(head == null || head.next == null) return head; 34 | 35 | ListNode pre = null, cur = head; 36 | 37 | while(cur != null){ 38 | ListNode temp = cur.next; 39 | cur.next = pre; 40 | pre = cur; 41 | cur = temp; 42 | } 43 | return pre; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/TwoPointers/SortColors/SortColors.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public void sortColors(int[] nums) { 3 | //pz: pointer zero 4 | int pz = 0; 5 | //po: pointer one 6 | int po = 0; 7 | //pt: pointer two 8 | int pt = nums.length - 1; 9 | 10 | while(po <= pt){ 11 | if(nums[po] == 2){ 12 | swap(nums, po, pt); 13 | pt--; 14 | }else if(nums[po] == 0){ 15 | swap(nums, po, pz); 16 | po++; 17 | pz++; 18 | }else{ 19 | po++; 20 | } 21 | } 22 | } 23 | private void swap(int[] nums, int p1, int p2){ 24 | int temp = nums[p1]; 25 | nums[p1] = nums[p2]; 26 | nums[p2] = temp; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/TwoPointers/SquaresOfASortedArray/SquaresOfASortedArray.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int[] sortedSquares(int[] nums) { 3 | int left = 0, n = nums.length, right = n - 1, index = n - 1; 4 | 5 | int[] res = new int[n]; 6 | 7 | while(0 <= index){ 8 | int leftNum = nums[left] * nums[left]; 9 | int rightNum = nums[right] * nums[right]; 10 | if(leftNum < rightNum){ 11 | res[index--] = rightNum; 12 | right--; 13 | }else{ 14 | left++; 15 | res[index--] = leftNum; 16 | } 17 | } 18 | return res; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/TwoPointers/TrappingRainWater/TrappingRainWater.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int trap(int[] height) { 3 | //Define the maps 4 | int N = height.length; 5 | 6 | int[] LeftHighest = new int[N]; 7 | int[] RightHighest = new int[N]; 8 | 9 | int max = 0; 10 | //Find the left max value excluding current element 11 | for(int i = 0; i < N; i++){ 12 | LeftHighest[i] = max; 13 | max = Math.max(height[i], max); 14 | } 15 | max = 0; 16 | 17 | //Find the right max value excluding current element 18 | for(int i = N - 1; i >= 0; i--){ 19 | RightHighest[i] = max; 20 | max = Math.max(height[i], max); 21 | } 22 | 23 | //Find the total water units 24 | int total = 0; 25 | for(int i = 0; i < N; i++){ 26 | int maxLeftHeight = LeftHighest[i]; 27 | int maxRightHeight = RightHighest[i]; 28 | int minHeight = Math.min(maxLeftHeight, maxRightHeight); 29 | int waterUnits = minHeight - height[i]; 30 | if(waterUnits > 0){ 31 | total += waterUnits; 32 | } 33 | } 34 | return total; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/TwoPointers/TwoSum/TwoSum.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int[] twoSum(int[] nums, int target){ 3 | HashMap hm = new HashMap<>(); 4 | for(int i = 0; i< nums.length; i++){ 5 | hm.put(nums[i], i); 6 | } 7 | for(int i = 0; i < nums.length; i++){ 8 | int difference = target - nums[i]; 9 | if(hm.containsKey(difference) && hm.get(difference) != i){ 10 | return new int[]{hm.get(difference), i}; 11 | } 12 | } 13 | return new int[] {-1,-1}; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/TwoPointers/TwoSum/TwoSumII.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int[] twoSum(int[] numbers, int target) { 3 | int n = numbers.length; 4 | int L = 0, R = n - 1; 5 | while(L < R){ 6 | int curSum = numbers[L] + numbers[R]; 7 | if(curSum == target){ 8 | return new int[] { L + 1, R + 1}; 9 | }else if(curSum < target){ 10 | L++; 11 | }else{ 12 | R--; 13 | } 14 | } 15 | return new int[] {-1, -1}; 16 | } 17 | } 18 | --------------------------------------------------------------------------------