├── .gitignore ├── README.md └── src └── com └── practice ├── arrayproblems ├── BestTimeToBuyAndSellStock.java ├── CanPlaceFlowers.java ├── ConcatenationOfArray.java ├── CountPrimes.java ├── DefuseTheBomb.java ├── MatrixDiagonalSum.java ├── MergeIntervals.java ├── ReshapeTheMatrix.java ├── ReverseString.java ├── ShuffleTheArray.java └── TwoSum.java ├── breadthfirstsearchproblems ├── BinaryTreeLevelOrderTraversal.java └── OpenTheLock.java ├── hashmapproblems ├── ContainsDuplicateII.java ├── MajorityElement.java ├── SumAllElementsInAMap.java └── ValidAnagram.java ├── linkedlists ├── IntersectionOfTwoLinkedLists.java └── ListNode.java ├── miscellaneous ├── BreadthFirstSearch.java ├── ContainsDuplicate.java ├── CousinsInBinaryTree.java ├── ImplementingComparator.java ├── IntersectionOfTwoArraysII.java ├── IterativeBinarySearch.java ├── LevelOrderTraversalOnMap.java ├── MaximumProductOfThreeNumbers.java ├── MissingNumber.java ├── NumberOfArithmeticTriplets.java ├── NumberOfIslands.java ├── PalindromeLinkedList.java ├── PascalsTriangle.java ├── PascalsTriangleII.java ├── PowerOfTwo.java └── ValidSudoku.java ├── priorityqueueproblems ├── KthLargestElementInAnArray.java ├── KthSmallestElementInASortedMatrix.java ├── SortAnArray.java └── TopKFrequentElements.java ├── recursionproblems ├── AllPathsFromSourceToTarget.java ├── BinarySearchRecursively.java ├── BinaryTreeInorderTraversal.java ├── BinaryTreePaths.java ├── BreadthFirstSearchOnAGraph.java ├── CheckIfTwoStringArraysAreEquivalentRecursively.java ├── ClosestBinarySearchTreeValue.java ├── CoinChange.java ├── CountNodesEqualToAverageOfSubtree.java ├── DeepestLeavesSum.java ├── ExtractKthCharacterFromTheRopeTree.java ├── FibonacciNumber.java ├── FirstBadVersion.java ├── FloodFill.java ├── HappyNumber.java ├── IncreaseOrderSearchTree.java ├── LeafSimilarTrees.java ├── MaxAreaOfIsland.java ├── MaximumDepthOfBinaryTree.java ├── MergeTwoSortedLists.java ├── MinimumDepthOfBinaryTree.java ├── NaryTreePostorderTraversal.java ├── NaryTreePreorderTraversal.java ├── NumberOfIslands.java ├── PalindromeLinkedListRecursion.java ├── PathSum.java ├── PostOrderTraversal.java ├── PostOrderTraversalWithListAsAParameter.java ├── PowerOfTwo.java ├── PreOrderTraversal.java ├── RangeSumOfBST.java ├── ReverseStringRecursively.java ├── RopeTreeNode.java ├── SameTree.java ├── SearchA2DMatrix.java ├── SumOfLeftLeaves.java ├── SumOfNodesWithEvenValuedGrandparent.java ├── SumOfRootToLeafBinaryNumbers.java ├── SumRootToLeafNumbers.java ├── SumUpArrayRecursively.java ├── SumUpArrayWithHeadRecursion.java ├── SumUpTwoDArrayRecursively.java ├── TwoSumIVInputIsABST.java ├── UnivaluedBinaryTree.java ├── WordSearch.java ├── catDog.java ├── countCode.java ├── countHi.java ├── dynamicprogramming │ ├── CourseSchedule.java │ ├── FindIfPathExistsInGraph.java │ └── MinCostClimbingStairs.java └── sumAllNumbersUsingDFS.java ├── simulationproblems ├── CreateQueueBackedByLinkedList.java └── Solution.java ├── slidingwindowproblems ├── DietPlanPerformance.java ├── FindTheKBeautyOfANumber.java ├── MaxSubArray.java ├── MaximumAverageSubarray.java ├── MinimumDifferenceBetweenHighestAndLowestOfKScores.java ├── MinimumDistanceBetweenBSTNodes.java ├── MinimumRecolorsToGetKConsecutiveBlackBlocks.java ├── NumberOfZeroFilledSubarrays.java └── SubstringsOfSizeThreeWithDistinctCharacters.java ├── sortingalgorithms ├── BubbleSort.java ├── InsertionSort.java ├── MergeSort.java └── SelectionSort.java ├── stackproblems ├── DailyTemperatures.java └── MinimumAddToMakeParenthesesValid.java ├── stringproblems ├── CellsInARangeOnAnExcelSheet.java ├── CheckIfTheSentenceIsAPangram.java ├── CheckIfTwoStringArraysAreEquivalent.java ├── CorrectStringUppercase.java ├── CountAsterisks.java ├── CountItemsMatchingARule.java ├── CountTheNumberOfConsistentStrings.java ├── DecodeTheMessage.java ├── DefangingAnIPAddress.java ├── FinalValueOfVariableAfterPerformingOperations.java ├── FindTheIndexOfTheFirstOccurrenceInAString.java ├── GoalParserInterpretation.java ├── JewelsAndStones.java ├── LongestPalindrome.java ├── LongestSubstringWithoutRepeatingCharacters.java ├── MaximumNumberOfWordsFoundInSentences.java ├── MergeStringsAlternately.java ├── RemoveVowelsFromAString.java ├── ReverseWordsInAStringIII.java ├── ShuffleString.java ├── SplitAStringInBalancedStrings.java ├── String2WordEnds.java ├── SubstringsOfSizeThreeWithDistinctCharacters.java ├── ToLowerCase.java ├── TruncateSentence.java ├── UniqueMorseCodeWords.java └── ValidPalindrome.java └── systemdesign ├── DesignAnOrderedStream.java └── LoggerRateLimiter.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | 5 | 6 | ### IntelliJ IDEA ### 7 | .idea 8 | *.iws 9 | *.iml 10 | *.ipr 11 | out/ 12 | !**/src/main/**/out/ 13 | !**/src/test/**/out/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Data Structures and Algorithms 2 | 3 | I compiled this repo by speaking with countless software engineers who have cracked the coding interview. They helped me narrow down the concepts and types of problems to focus on. 4 | 5 | This repo includes concepts that come up often in technical interviews, such as: 6 | 7 | #### Breadth First Search 8 | #### Depth First Search 9 | #### Binary Search 10 | #### Sorting algorithms 11 | #### Much more! 12 | 13 | 14 | # Helpful resources 15 | A lot of these solutions can be very challenging to wrap your head around at first. So, here are some of my favorite resources that help to explain them in layman’s terms: 16 | 17 | [Back To Back SWE ](https://www.youtube.com/@BackToBackSWE) 18 | 19 | [Coding with John]( https://www.youtube.com/@CodingWithJohn) 20 | 21 | [Lalitha Natraj]( https://www.youtube.com/@LalithaNatraj) 22 | 23 | [Leetcode Solutions with Nick White](https://www.youtube.com/playlist?list=PLU_sdQYzUj2keVENTP0a5rdykRSgg9Wp-) 24 | 25 | # Get Connected 26 | 27 | [ LinkedIn](https://www.linkedin.com/in/averycs) 28 | 29 | [Email](mailto:Averydcs@gmail.com) 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/com/practice/arrayproblems/BestTimeToBuyAndSellStock.java: -------------------------------------------------------------------------------- 1 | package com.practice.arrayproblems; 2 | import java.util.*; 3 | 4 | /**Problem statement: 5 | You are given an array prices where prices[i] is the price of a given stock on the ith day. 6 | 7 | You want to maximize your profit by choosing a single day to buy one stock and choosing a different day in the future to sell that stock. 8 | 9 | Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return 0. 10 | Example 1: 11 | 12 | Input: prices = [7,1,5,3,6,4] 13 | Output: 5 14 | Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5. 15 | Note that buying on day 2 and selling on day 1 is not allowed because you must buy before you sell. 16 | Example 2: 17 | 18 | Input: prices = [7,6,4,3,1] 19 | Output: 0 20 | Explanation: In this case, no transactions are done and the max profit = 0. 21 | Constraints: 22 | 23 | 1 <= prices.length <= 105 24 | 0 <= prices[i] <= 104 25 | 26 | Leetcode link: https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/ 27 | **/ 28 | public class BestTimeToBuyAndSellStock {public int maxProfit(int[] prices) { 29 | int min = Integer.MAX_VALUE; 30 | int maxProfit = 0; 31 | 32 | for (int i = 0; i < prices.length; i++) { 33 | if (prices[i] < min) { 34 | min = prices[i]; 35 | } else { 36 | maxProfit = Math.max(maxProfit, (prices[i] - min)); 37 | } 38 | } 39 | return maxProfit; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/com/practice/arrayproblems/CanPlaceFlowers.java: -------------------------------------------------------------------------------- 1 | package com.practice.arrayproblems; 2 | /**Problem statement: 3 | You have a long flowerbed in which some of the plots are planted, and some are not. However, flowers cannot be planted in adjacent plots. 4 | 5 | Given an integer array flowerbed containing 0's and 1's, where 0 means empty and 1 means not empty, and an integer n, return true if n new flowers can be planted in the flowerbed without violating the no-adjacent-flowers rule and false otherwise. 6 | 7 | Example 1: 8 | Input: flowerbed = [1,0,0,0,1], n = 1 9 | Output: true 10 | 11 | Example 2: 12 | Input: flowerbed = [1,0,0,0,1], n = 2 13 | Output: false 14 | 15 | Constraints: 16 | 1 <= flowerbed.length <= 2 * 104 17 | flowerbed[i] is 0 or 1. 18 | There are no two adjacent flowers in flowerbed. 19 | 0 <= n <= flowerbed.length 20 | Leetcode link: https://leetcode.com/problems/can-place-flowers/description/ 21 | **/ 22 | public class CanPlaceFlowers { 23 | public boolean canPlaceFlowers(int[] flowerbed, int n) { 24 | int availableSlots = 0; 25 | for (int i = 0; i < flowerbed.length; i++) { 26 | if (flowerbed[i] == 0 && leftIsAvailable(flowerbed, i) && rightIsAvailable(flowerbed, i)) { 27 | flowerbed[i] = 1; 28 | availableSlots++; 29 | if (availableSlots == n) { 30 | return true; 31 | } 32 | } 33 | } 34 | return availableSlots >= n; 35 | } 36 | public static boolean leftIsAvailable(int[] flowerbed, int i) { 37 | return i - 1 == -1 || flowerbed[i - 1] == 0; 38 | } 39 | public static boolean rightIsAvailable(int[] flowerbed, int i) { 40 | return i + 1 == flowerbed.length || flowerbed[i + 1] == 0; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/com/practice/arrayproblems/ConcatenationOfArray.java: -------------------------------------------------------------------------------- 1 | package com.practice.arrayproblems; 2 | import java.util.*; 3 | 4 | /**Problem statement: 5 | Given an integer array nums of length n, you want to create an array ans of length 2n where ans[i] == nums[i] and ans[i + n] == nums[i] for 0 <= i < n (0-indexed). 6 | 7 | Specifically, ans is the concatenation of two nums arrays. 8 | 9 | Return the array ans. 10 | Example 1: 11 | 12 | Input: nums = [1,2,1] 13 | Output: [1,2,1,1,2,1] 14 | Explanation: The array ans is formed as follows: 15 | - ans = [nums[0],nums[1],nums[2],nums[0],nums[1],nums[2]] 16 | - ans = [1,2,1,1,2,1] 17 | Example 2: 18 | 19 | Input: nums = [1,3,2,1] 20 | Output: [1,3,2,1,1,3,2,1] 21 | Explanation: The array ans is formed as follows: 22 | - ans = [nums[0],nums[1],nums[2],nums[3],nums[0],nums[1],nums[2],nums[3]] 23 | - ans = [1,3,2,1,1,3,2,1] 24 | 25 | 26 | Constraints: 27 | n == nums.length 28 | 1 <= n <= 1000 29 | 1 <= nums[i] <= 1000 30 | 31 | Leetcode link: https://leetcode.com/problems/concatenation-of-array/description/ 32 | **/ 33 | public class ConcatenationOfArray { 34 | public int[] getConcatenation(int[] nums) { 35 | int[] result = new int[nums.length * 2]; 36 | 37 | for (int i = 0; i < nums.length * 2; i++) { 38 | 39 | result[i] = nums[i % nums.length]; 40 | } 41 | return result; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/com/practice/arrayproblems/CountPrimes.java: -------------------------------------------------------------------------------- 1 | package com.practice.arrayproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given an integer n, return the number of prime numbers that are strictly less than n. 5 | Example 1: 6 | Input: n = 10 7 | Output: 4 8 | Explanation: There are 4 prime numbers less than 10, they are 2, 3, 5, 7. 9 | 10 | Example 2: 11 | Input: n = 0 12 | Output: 0 13 | Example 3: 14 | 15 | Input: n = 1 16 | Output: 0 17 | Constraints: 18 | 19 | 0 <= n <= 5 * 106 20 | 21 | **Helpful hint: Look up Sieves of Eratosthenes 22 | **/ 23 | public class CountPrimes { 24 | public int countPrimes(int n) { 25 | boolean[] isPrime = createFilledOutArray(n); 26 | int count = 0; 27 | for (int i = 2; i < n; i++) { 28 | if (isPrime[i]) { 29 | count++; 30 | } 31 | } 32 | return count; 33 | } 34 | public static boolean[] createFilledOutArray(int number) { 35 | boolean[] isPrime = new boolean[number]; 36 | Arrays.fill(isPrime, true); 37 | for (int i = 2; i <= Math.sqrt(number); i++) { 38 | if (isPrime[i]) { 39 | int j = i + i; 40 | while (j < number) { 41 | isPrime[j] = false; 42 | j += i; 43 | } 44 | } 45 | } 46 | return isPrime; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/com/practice/arrayproblems/DefuseTheBomb.java: -------------------------------------------------------------------------------- 1 | package com.practice.arrayproblems; 2 | 3 | /**Problem statement: 4 | You have a bomb to defuse, and your time is running out! Your informer will provide you with a circular array code of length of n and a key k. 5 | 6 | To decrypt the code, you must replace every number. All the numbers are replaced simultaneously. 7 | 8 | If k > 0, replace the ith number with the sum of the next k numbers. 9 | If k < 0, replace the ith number with the sum of the previous k numbers. 10 | If k == 0, replace the ith number with 0. 11 | As code is circular, the next element of code[n-1] is code[0], and the previous element of code[0] is code[n-1]. 12 | 13 | Given the circular array code and an integer key k, return the decrypted code to defuse the bomb! 14 | 15 | Example 1: 16 | Input: code = [5,7,1,4], k = 3 17 | Output: [12,10,16,13] 18 | Explanation: Each number is replaced by the sum of the next 3 numbers. The decrypted code is [7+1+4, 1+4+5, 4+5+7, 5+7+1]. Notice that the numbers wrap around. 19 | 20 | Example 2: 21 | Input: code = [1,2,3,4], k = 0 22 | Output: [0,0,0,0] 23 | Explanation: When k is zero, the numbers are replaced by 0. 24 | 25 | Example 3: 26 | Input: code = [2,4,9,3], k = -2 27 | Output: [12,5,6,13] 28 | Explanation: The decrypted code is [3+9, 2+3, 4+2, 9+4]. Notice that the numbers wrap around again. If k is negative, the sum is of the previous numbers. 29 | 30 | Constraints: 31 | n == code.length 32 | 1 <= n <= 100 33 | 1 <= code[i] <= 100 34 | -(n - 1) <= k <= n - 1 35 | Leetcode link: https://leetcode.com/problems/defuse-the-bomb/description/ 36 | **/ 37 | public class DefuseTheBomb { 38 | public int[] decrypt(int[] code, int k) { 39 | int[] result = new int[code.length]; 40 | 41 | for (int i = 0; i < code.length; i++) { 42 | result[i] = findSum(code, k, i); 43 | } 44 | return result; 45 | } 46 | public static int findSum(int[] code, int k, int index) { 47 | if (k == 0) { 48 | return 0; 49 | } 50 | int sum = 0; 51 | if (k > 0) { 52 | for (int i = index + 1, count = 0; count < k; i++, count++) { 53 | i = i % code.length; 54 | sum += code[i]; 55 | } 56 | } 57 | if (k < 0) { 58 | for (int i = index - 1, count = 0; count < Math.abs(k); i--, count++) { 59 | i = (i + code.length) % code.length; 60 | sum += code[i]; 61 | } 62 | } 63 | return sum; 64 | } 65 | } 66 | 67 | -------------------------------------------------------------------------------- /src/com/practice/arrayproblems/MatrixDiagonalSum.java: -------------------------------------------------------------------------------- 1 | package com.practice.arrayproblems; 2 | import java.util.*; 3 | 4 | /**Problem statement: 5 | Given a square matrix mat, return the sum of the matrix diagonals. 6 | 7 | Only include the sum of all the elements on the primary diagonal and all the elements on the secondary diagonal that are not part of the primary diagonal. 8 | 9 | Example 1: 10 | Input: mat = [[1,2,3], 11 | [4,5,6], 12 | [7,8,9]] 13 | Output: 25 14 | Explanation: Diagonals sum: 1 + 5 + 9 + 3 + 7 = 25 15 | Notice that element mat[1][1] = 5 is counted only once. 16 | 17 | Example 2: 18 | Input: mat = [[1,1,1,1], 19 | [1,1,1,1], 20 | [1,1,1,1], 21 | [1,1,1,1]] 22 | Output: 8 23 | Example 3: 24 | Input: mat = [[5]] 25 | Output: 5 26 | 27 | Constraints: 28 | n == mat.length == mat[i].length 29 | 1 <= n <= 100 30 | 1 <= mat[i][j] <= 100 31 | Leetcode link: https://leetcode.com/problems/matrix-diagonal-sum/description/ 32 | **/ 33 | public class MatrixDiagonalSum { 34 | public int diagonalSum(int[][] mat) { 35 | 36 | int i = 0; 37 | int j = mat.length - 1; 38 | int sum = 0; 39 | 40 | while (i < mat.length) { 41 | sum += mat[i][i]; 42 | 43 | if (j != i) { 44 | sum += mat[j][i]; 45 | } 46 | j--; 47 | i++; 48 | } 49 | return sum; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/com/practice/arrayproblems/MergeIntervals.java: -------------------------------------------------------------------------------- 1 | package com.practice.arrayproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given an array of intervals where intervals[i] = [starti, endi], merge all overlapping intervals, and return an array of the non-overlapping intervals that cover all the intervals in the input. 5 | 6 | Example 1: 7 | Input: intervals = [[1,3],[2,6],[8,10],[15,18]] 8 | Output: [[1,6],[8,10],[15,18]] 9 | Explanation: Since intervals [1,3] and [2,6] overlap, merge them into [1,6]. 10 | 11 | Example 2: 12 | Input: intervals = [[1,4],[4,5]] 13 | Output: [[1,5]] 14 | Explanation: Intervals [1,4] and [4,5] are considered overlapping. 15 | 16 | Constraints: 17 | 1 <= intervals.length <= 104 18 | intervals[i].length == 2 19 | 0 <= starti <= endi <= 104 20 | Leetcode link: https://leetcode.com/problems/merge-intervals/ 21 | **/ 22 | public class MergeIntervals { 23 | public int[][] merge(int[][] intervals) { 24 | Arrays.sort(intervals, (int[] a, int[] b) -> { 25 | return a[0] - b[0]; 26 | }); 27 | List < List < Integer >> list = new ArrayList < > (); 28 | if (intervals.length <= 1) { 29 | return intervals; 30 | } 31 | int[] currentInterval = intervals[0]; 32 | for (int row = 1; row < intervals.length; row++) { 33 | 34 | if (doesNotOverlap(currentInterval, intervals[row])) { 35 | list.add(List.of(currentInterval[0], currentInterval[1])); 36 | currentInterval = intervals[row]; 37 | } else { 38 | currentInterval = createOverlappingIntervalArray(currentInterval, intervals[row]); 39 | } 40 | } 41 | list.add(List.of(currentInterval[0], currentInterval[1])); 42 | return putElementsInListInAnArray(list); 43 | } 44 | 45 | public static int[][] putElementsInListInAnArray(List < List < Integer >> list) { 46 | int[][] result = new int[list.size()][2]; 47 | int row = 0; 48 | for (List < Integer > singleList: list) { 49 | result[row][0] = singleList.get(0); 50 | result[row][1] = singleList.get(1); 51 | row++; 52 | } 53 | return result; 54 | 55 | } 56 | 57 | public static boolean doesNotOverlap(int[] currentInterval, int[] nextInterval) { 58 | return currentInterval[1] < nextInterval[0]; 59 | } 60 | 61 | public static int[] createOverlappingIntervalArray(int[] currentInterval, int[] nextInterval) { 62 | int lowest = Math.min(currentInterval[0], nextInterval[0]); 63 | int highest = Math.max(currentInterval[1], nextInterval[1]); 64 | return new int[] { 65 | lowest, 66 | highest 67 | }; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/com/practice/arrayproblems/ReshapeTheMatrix.java: -------------------------------------------------------------------------------- 1 | package com.practice.arrayproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | In MATLAB, there is a handy function called reshape which can reshape an m x n matrix into a new one with a different size r x c keeping its original data. 5 | 6 | You are given an m x n matrix mat and two integers r and c representing the number of rows and the number of columns of the wanted reshaped matrix. 7 | 8 | The reshaped matrix should be filled with all the elements of the original matrix in the same row-traversing order as they were. 9 | 10 | If the reshape operation with given parameters is possible and legal, output the new reshaped matrix; Otherwise, output the original matrix. 11 | 12 | Example 1: 13 | Input: mat = [[1,2],[3,4]], r = 1, c = 4 14 | Output: [[1,2,3,4]] 15 | 16 | Example 2: 17 | Input: mat = [[1,2],[3,4]], r = 2, c = 4 18 | Output: [[1,2],[3,4]] 19 | 20 | Constraints: 21 | m == mat.length 22 | n == mat[i].length 23 | 1 <= m, n <= 100 24 | -1000 <= mat[i][j] <= 1000 25 | 1 <= r, c <= 300 26 | Leetcode link: https://leetcode.com/problems/reshape-the-matrix/description/ 27 | **/ 28 | public class ReshapeTheMatrix { 29 | public int[][] matrixReshape(int[][] mat, int r, int c) { 30 | int[][] result = new int[r][c]; 31 | 32 | int resultWidth = result[0].length; 33 | int resultHeight = result.length; 34 | 35 | int matWidth = mat[0].length; 36 | int matHeight = mat.length; 37 | 38 | if (resultWidth * resultHeight != matWidth * matHeight) { 39 | return mat; 40 | } 41 | Queue < Integer > q = new ArrayDeque < > (); 42 | for (int row = 0; row < matHeight; row++) { 43 | for (int col = 0; col < matWidth; col++) { 44 | q.add(mat[row][col]); 45 | } 46 | } 47 | for (int row = 0; row < resultHeight; row++) { 48 | for (int col = 0; col < resultWidth; col++) { 49 | result[row][col] = q.remove(); 50 | } 51 | } 52 | return result; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/com/practice/arrayproblems/ReverseString.java: -------------------------------------------------------------------------------- 1 | package com.practice.arrayproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Write a function that reverses a string. The input string is given as an array of characters s. 5 | 6 | You must do this by modifying the input array in-place with O(1) extra memory. 7 | 8 | Example 1: 9 | Input: s = ["h","e","l","l","o"] 10 | Output: ["o","l","l","e","h"] 11 | Example 2: 12 | 13 | Input: s = ["H","a","n","n","a","h"] 14 | Output: ["h","a","n","n","a","H"] 15 | Leetcode link: https://leetcode.com/problems/reverse-string/description/ 16 | **/ 17 | public class ReverseString { 18 | public void reverseString(char[] s) { 19 | for(int end =s.length-1, begin=0; end>begin; end--, begin++){ 20 | char temp = s[end]; 21 | s[end]= s[begin]; 22 | s[begin]= temp; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/com/practice/arrayproblems/ShuffleTheArray.java: -------------------------------------------------------------------------------- 1 | package com.practice.arrayproblems; 2 | /**Problem statement: 3 | Given the array nums consisting of 2n elements in the form [x1,x2,...,xn,y1,y2,...,yn]. 4 | Return the array in the form [x1,y1,x2,y2,...,xn,yn]. 5 | 6 | Example 1: 7 | Input: nums = [2,5,1,3,4,7], n = 3 8 | Output: [2,3,5,4,1,7] 9 | Explanation: Since x1=2, x2=5, x3=1, y1=3, y2=4, y3=7 then the answer is [2,3,5,4,1,7]. 10 | 11 | Example 2: 12 | Input: nums = [1,2,3,4,4,3,2,1], n = 4 13 | Output: [1,4,2,3,3,2,4,1] 14 | Example 3: 15 | Input: nums = [1,1,2,2], n = 2 16 | Output: [1,2,1,2] 17 | Constraints: 18 | 19 | 1 <= n <= 500 20 | nums.length == 2n 21 | 1 <= nums[i] <= 10^3 22 | Leetcode link: https://leetcode.com/problems/shuffle-the-array/description/ 23 | **/ 24 | public class ShuffleTheArray { 25 | public int[] shuffle(int[] nums, int n) { 26 | int[] result = new int[nums.length]; 27 | int i = 0; 28 | int j = n; 29 | int p1 = 0; 30 | while (j < nums.length) { 31 | result[p1] = nums[i]; 32 | p1++; 33 | i++; 34 | result[p1] = nums[j]; 35 | p1++; 36 | j++; 37 | } 38 | return result; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/com/practice/arrayproblems/TwoSum.java: -------------------------------------------------------------------------------- 1 | package com.practice.arrayproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target. 5 | 6 | You may assume that each input would have exactly one solution, and you may not use the same element twice. 7 | 8 | You can return the answer in any order. 9 | Example 1: 10 | Input: nums = [2,7,11,15], target = 9 11 | Output: [0,1] 12 | Explanation: Because nums[0] + nums[1] == 9, we return [0, 1]. 13 | 14 | Example 2: 15 | Input: nums = [3,2,4], target = 6 16 | Output: [1,2] 17 | 18 | Example 3: 19 | Input: nums = [3,3], target = 6 20 | Output: [0,1] 21 | Constraints: 22 | 2 <= nums.length <= 104 23 | -109 <= nums[i] <= 109 24 | -109 <= target <= 109 25 | 26 | Leetcode link: https://leetcode.com/problems/two-sum/description/ 27 | **/ 28 | public class TwoSum { 29 | public int[] twoSum(int[] nums, int target) { 30 | Map < Integer, Integer > map = new HashMap < > (); 31 | for (int i = 0; i < nums.length; i++) { 32 | int match = target - nums[i]; 33 | if (map.containsKey(match)) { 34 | return new int[] {map.get(match), i}; 35 | } else { 36 | map.put(nums[i], i); 37 | } 38 | } 39 | return new int[] {}; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/com/practice/breadthfirstsearchproblems/BinaryTreeLevelOrderTraversal.java: -------------------------------------------------------------------------------- 1 | package com.practice.breadthfirstsearchproblems; 2 | 3 | import java.util.*; 4 | /**Problem statement: 5 | Given the root of a binary tree, return the level order traversal of its nodes' values. (i.e., from left to right, level by level). 6 | 7 | Example 1: 8 | Input: root = [3,9,20,null,null,15,7] 9 | Output: [[3],[9,20],[15,7]] 10 | 11 | Example 2: 12 | Input: root = [1] 13 | Output: [[1]] 14 | Example 3: 15 | 16 | Input: root = [] 17 | Output: [] 18 | 19 | Constraints: 20 | The number of nodes in the tree is in the range [0, 2000]. 21 | -1000 <= Node.val <= 1000 22 | 23 | Leetcode link: https://leetcode.com/problems/binary-tree-level-order-traversal/description/ 24 | **/ 25 | public class BinaryTreeLevelOrderTraversal { 26 | public List < List < Integer >> levelOrder(TreeNode root) { 27 | 28 | Queue < TreeNode > q = new ArrayDeque < > (); 29 | int size = q.size(); 30 | List < List < Integer >> result = new ArrayList < > (); 31 | if (root == null) { 32 | return result; 33 | } 34 | result.add(List.of(root.val)); 35 | q.add(root); 36 | while (!q.isEmpty()) { 37 | size = q.size(); 38 | List < Integer > neighborList = new ArrayList < > (); 39 | for (int i = 0; i < size; i++) { 40 | for (Integer k: findNeighborsAndAddToQueue(q.peek(), q)) { 41 | neighborList.add(k); 42 | } 43 | q.remove(); 44 | } 45 | if (!neighborList.isEmpty()) { 46 | result.add(neighborList); 47 | } 48 | } 49 | return result; 50 | } 51 | public static List < Integer > findNeighborsAndAddToQueue(TreeNode root, Queue < TreeNode > q) { 52 | List < Integer > neighborList = new ArrayList < > (); 53 | if (root.left != null) { 54 | neighborList.add(root.left.val); 55 | 56 | q.add(root.left); 57 | } 58 | if (root.right != null) { 59 | neighborList.add(root.right.val); 60 | 61 | q.add(root.right); 62 | } 63 | return neighborList; 64 | } 65 | } 66 | class TreeNode { 67 | int val; 68 | TreeNode left; 69 | TreeNode right; 70 | TreeNode() {} 71 | TreeNode(int val) { this.val = val; } 72 | TreeNode(int val, TreeNode left, TreeNode right) { 73 | this.val = val; 74 | this.left = left; 75 | this.right = right; 76 | } 77 | } -------------------------------------------------------------------------------- /src/com/practice/hashmapproblems/ContainsDuplicateII.java: -------------------------------------------------------------------------------- 1 | package com.practice.hashmapproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given an integer array nums and an integer k, return true if there are two distinct indices i and j in the array such that nums[i] == nums[j] and abs(i - j) <= k. 5 | 6 | Example 1: 7 | 8 | Input: nums = [1,2,3,1], k = 3 9 | Output: true 10 | Example 2: 11 | 12 | Input: nums = [1,0,1,1], k = 1 13 | Output: true 14 | Example 3: 15 | 16 | Input: nums = [1,2,3,1,2,3], k = 2 17 | Output: false 18 | 19 | Constraints: 20 | 21 | 1 <= nums.length <= 105 22 | -109 <= nums[i] <= 109 23 | 0 <= k <= 105 24 | 25 | Leetcode link: https://leetcode.com/problems/contains-duplicate-ii/description/ 26 | **/ 27 | public class ContainsDuplicateII { 28 | public boolean containsNearbyDuplicate(int[] nums, int k) { 29 | Map map = new HashMap<>(); 30 | 31 | for(int i =0; i< nums.length; i++){ 32 | if(!map.containsKey(nums[i])){ 33 | map.put(nums[i],i); 34 | } 35 | else { 36 | if(Math.abs(i-map.get(nums[i]))<= k){ 37 | return true; 38 | }else{ 39 | map.put(nums[i],i); 40 | } 41 | } 42 | } 43 | return false; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/com/practice/hashmapproblems/MajorityElement.java: -------------------------------------------------------------------------------- 1 | package com.practice.hashmapproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given an array nums of size n, return the majority element. 5 | 6 | The majority element is the element that appears more than ⌊n / 2⌋ times. You may assume that the majority element always exists in the array. 7 | 8 | Example 1: 9 | 10 | Input: nums = [3,2,3] 11 | Output: 3 12 | Example 2: 13 | 14 | Input: nums = [2,2,1,1,1,2,2] 15 | Output: 2 16 | 17 | Constraints: 18 | n == nums.length 19 | 1 <= n <= 5 * 104 20 | -109 <= nums[i] <= 109 21 | 22 | 23 | Leetcode link: https://leetcode.com/problems/majority-element/description/ 24 | 25 | **Special note: This problem can be solved more efficiently using the Moore's Voting algorithm 26 | **/ 27 | public class MajorityElement { 28 | public int majorityElement(int[] nums) { 29 | int maxCount = Integer.MIN_VALUE; 30 | Map < Integer, Integer > map = new HashMap < > (); 31 | int result = 0; 32 | 33 | for (int i: nums) { 34 | if (!map.containsKey(i)) { 35 | map.put(i, 1); 36 | if (map.get(i) > maxCount) { 37 | maxCount = map.get(i); 38 | result = i; 39 | } 40 | } else { 41 | int tempCount = map.get(i) + 1; 42 | map.put(i, tempCount); 43 | 44 | if (tempCount > maxCount) { 45 | maxCount = tempCount; 46 | result = i; 47 | } 48 | } 49 | } 50 | return result; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/com/practice/hashmapproblems/SumAllElementsInAMap.java: -------------------------------------------------------------------------------- 1 | package com.practice.hashmapproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | * Create a map of Integers and recursively sum up all of its elements 5 | 6 | This is a problem I created for myself, in order to be able to a depth-first search on a map 7 | **/ 8 | public class SumAllElementsInAMap { 9 | public static void main(String[] args) { 10 | 11 | Set set = new HashSet<>(); 12 | Map map = new HashMap<>(); 13 | map.put(1, 3); 14 | map.put(2, 3); 15 | map.put(3, 6); 16 | map.put(6, 5); 17 | map.put(5, 2); 18 | 19 | System.out.println("result: "+ sumMap(map,1,set)); 20 | } 21 | 22 | public static int sumMap(Map map, int number, Set set ){ 23 | 24 | if(set.contains(number)){ 25 | return 0; 26 | } 27 | if(!map.containsKey(number)){ 28 | set.add(number); 29 | return number; 30 | } 31 | set.add(number); 32 | return number +sumMap(map, map.get(number), set); 33 | 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/com/practice/hashmapproblems/ValidAnagram.java: -------------------------------------------------------------------------------- 1 | package com.practice.hashmapproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given two strings s and t, return true if t is an anagram of s, and false otherwise. 5 | 6 | An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once. 7 | 8 | Example 1: 9 | Input: s = "anagram", t = "nagaram" 10 | Output: true 11 | 12 | Example 2: 13 | Input: s = "rat", t = "car" 14 | Output: false 15 | 16 | Constraints: 17 | 1 <= s.length, t.length <= 5 * 104 18 | s and t consist of lowercase English letters. 19 | 20 | Leetcode link: https://leetcode.com/problems/valid-anagram/description/ 21 | **/ 22 | public class ValidAnagram { 23 | public boolean isAnagram(String s, String t) { 24 | Map < Character, Integer > map = new HashMap < > (); 25 | 26 | for (int i = 0; i < s.length(); i++) { 27 | char letter = s.charAt(i); 28 | if (!map.containsKey(letter)) { 29 | map.put(letter, 1); 30 | } else { 31 | map.put(letter, map.get(letter) + 1); 32 | } 33 | } 34 | 35 | for (int i = 0; i < t.length(); i++) { 36 | char letter = t.charAt(i); 37 | if (!map.containsKey(letter)) { 38 | map.put(letter, 1); 39 | } else { 40 | map.put(letter, map.get(letter) - 1); 41 | } 42 | } 43 | 44 | for (Map.Entry < Character, Integer > k: map.entrySet()) { 45 | if (k.getValue() != 0) { 46 | return false; 47 | } 48 | } 49 | return true; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/com/practice/linkedlists/ListNode.java: -------------------------------------------------------------------------------- 1 | package com.practice.linkedlists; 2 | 3 | public class ListNode { 4 | int val; 5 | ListNode next; 6 | ListNode(int x) { 7 | val = x; 8 | next = null; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/com/practice/miscellaneous/BreadthFirstSearch.java: -------------------------------------------------------------------------------- 1 | package com.practice.miscellaneous; 2 | import java.util.*; 3 | 4 | /** 5 | * Implement a level order traversal/breadth first search on 2D matric 6 | **/ 7 | public class BreadthFirstSearch { 8 | public static void main(String[] args) { 9 | int[][] nums = { 10 | {1, 2, 3}, 11 | {4, 5, 6}, 12 | {7, 8, 9} 13 | }; 14 | 15 | bfs(nums); 16 | } 17 | public static void bfs(int[][] nums) { 18 | Queue < List < Integer >> coordinates = new ArrayDeque < > (); 19 | Set < List < Integer >> visitedSet = new HashSet < > (); 20 | coordinates.add(List.of(0, 0)); 21 | visitedSet.add(List.of(0, 0)); 22 | 23 | int size = coordinates.size(); 24 | int row = 0; 25 | int col = 0; 26 | System.out.println(nums[coordinates.peek().get(0)][coordinates.peek().get(1)]); 27 | System.out.println("---------------"); 28 | while (!coordinates.isEmpty()) { 29 | size = coordinates.size(); 30 | for (int i = 0; i < size; i++) { 31 | row = coordinates.peek().get(0); 32 | col = coordinates.peek().get(1); 33 | 34 | addNeighbors(coordinates, visitedSet, row, col, nums); 35 | coordinates.remove(); 36 | } 37 | 38 | for (List < Integer > k: coordinates) { 39 | System.out.println(nums[k.get(0)][k.get(1)]); 40 | } 41 | System.out.println("---------------"); 42 | 43 | } 44 | } 45 | public static void addNeighbors(Queue < List < Integer >> coordinates, Set < List < Integer >> visitedSet, int row, int col, int[][] nums) { 46 | int height = nums.length; 47 | int length = nums[0].length; 48 | //check down 49 | if (row + 1 < height && !visitedSet.contains(List.of(row + 1, col))) { 50 | coordinates.add(List.of(row + 1, col)); 51 | visitedSet.add(List.of(row + 1, col)); 52 | } 53 | //check up 54 | if (row - 1 > -1 && !visitedSet.contains(List.of(row - 1, col))) { 55 | coordinates.add(List.of(row - 1, col)); 56 | visitedSet.add(List.of(row - 1, col)); 57 | } 58 | //check left 59 | if (col - 1 > -1 && !visitedSet.contains(List.of(col - 1, row))) { 60 | coordinates.add(List.of(row, col - 1)); 61 | visitedSet.add(List.of(row, col - 1)); 62 | } 63 | //check right 64 | if (col + 1 < length && !visitedSet.contains(List.of(row, col + 1))) { 65 | coordinates.add(List.of(row, col + 1)); 66 | visitedSet.add(List.of(row, col + 1)); 67 | } 68 | 69 | } 70 | } -------------------------------------------------------------------------------- /src/com/practice/miscellaneous/ContainsDuplicate.java: -------------------------------------------------------------------------------- 1 | package com.practice.miscellaneous; 2 | import java.util.*; 3 | 4 | /** 5 | * Problem statement: Create an array and determine if there are any duplicates. 6 | * */ 7 | public class ContainsDuplicate { 8 | public static void main(String[] args) { 9 | int [] nums = {1,2,2,3,4,5,6,7,8,9,10,11,12,13}; 10 | System.out.println(containsDuplicate(nums)); 11 | } 12 | public static boolean containsDuplicate(int[] nums) { 13 | if (nums == null) { 14 | throw new IllegalArgumentException("The array cannot be null."); 15 | } 16 | Set < Integer > set = new HashSet < > (); 17 | 18 | for (int i: nums) { 19 | if (!set.contains(i)) { 20 | System.out.println("short circuiting"); 21 | return true; 22 | }; 23 | } 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/com/practice/miscellaneous/ImplementingComparator.java: -------------------------------------------------------------------------------- 1 | package com.practice.miscellaneous; 2 | import java.util.*; 3 | 4 | /** 5 | * Create a list of Pets and sort them by name. Then, sort them by age. 6 | **/ 7 | 8 | public class ImplementingComparator { 9 | public static void main(String[] args) { 10 | List list = new ArrayList<>(); 11 | 12 | list.add(new Pet("Fido", 10)); 13 | list.add(new Pet("Arla", 3)); 14 | list.add(new Pet("Jaye",12)); 15 | 16 | Collections.sort(list, (Pet a,Pet b)->{ 17 | return a.name.compareTo(b.name); 18 | }); 19 | 20 | Collections.sort(list, (Pet a, Pet b)->{ 21 | return a.age-b.age; 22 | }); 23 | 24 | for(Pet p: list){ 25 | System.out.println(p.name + " - " + p.age); 26 | } 27 | } 28 | } 29 | class Pet { 30 | String name; 31 | int age; 32 | 33 | Pet(String name, int age) { 34 | this.age = age; 35 | this.name = name; 36 | } 37 | } 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/com/practice/miscellaneous/IntersectionOfTwoArraysII.java: -------------------------------------------------------------------------------- 1 | package com.practice.miscellaneous; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given two integer arrays nums1 and nums2, return an array of their intersection. Each element in the result must appear as many times as it shows in both arrays and you may return the result in any order. 5 | Example 1: 6 | 7 | Input: nums1 = [1,2,2,1], nums2 = [2,2] 8 | Output: [2,2] 9 | Example 2: 10 | 11 | Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4] 12 | Output: [4,9] 13 | Explanation: [9,4] is also accepted. 14 | 15 | Constraints: 16 | 17 | 1 <= nums1.length, nums2.length <= 1000 18 | 0 <= nums1[i], nums2[i] <= 1000 19 | 20 | Leetcode link: https://leetcode.com/problems/intersection-of-two-arrays-ii/description/?envType=study-plan&id=data-structure-i 21 | **/ 22 | public class IntersectionOfTwoArraysII { 23 | public int[] intersect(int[] nums1, int[] nums2) { 24 | Map < Integer, Integer > map = new HashMap < > (); 25 | for (int integer: nums1) { 26 | if (!map.containsKey(integer)) { 27 | map.put(integer, 1); 28 | } else { 29 | map.put(integer, map.get(integer) + 1); 30 | } 31 | } 32 | List < Integer > numberList = new ArrayList < > (); 33 | 34 | for (int integerTwo: nums2) { 35 | if (map.containsKey(integerTwo) && map.get(integerTwo) > 0) { 36 | numberList.add(integerTwo); 37 | map.put(integerTwo, map.get(integerTwo) - 1); 38 | } 39 | } 40 | 41 | int[] result = new int[numberList.size()]; 42 | int index = 0; 43 | for (Integer k: numberList) { 44 | result[index] = k; 45 | index++; 46 | System.out.println("index is:" + index); 47 | } 48 | return result; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/com/practice/miscellaneous/IterativeBinarySearch.java: -------------------------------------------------------------------------------- 1 | package com.practice.miscellaneous; 2 | import java.util.*; 3 | public class IterativeBinarySearch { 4 | public static void main(String[] args) { 5 | int [] nums = {1,3,5,7}; 6 | System.out.println(bSearch(nums,0,nums.length, 3)); 7 | 8 | } 9 | public static int bSearch( int[] nums, int begin, int end, int target){ 10 | int middle = (begin +end)/2; 11 | while( begin!=middle && end!=middle && begin target){ 16 | end = middle-1; 17 | }else if(nums[middle] 9 | * This is a problem I created for myself, in order to be able to do a level order traversal on a map 10 | **/ 11 | public class LevelOrderTraversalOnMap { 12 | public static void main(String[] args) { 13 | Map> map = new HashMap<>(); 14 | map.put(1, List.of(3, 2, 4)); 15 | map.put(2, List.of(7, 5)); 16 | 17 | breadthFirstSearch(map, 1); 18 | } 19 | 20 | public static void breadthFirstSearch(Map> map, int begin) { 21 | Queue q = new ArrayDeque<>(); 22 | Set visited = new HashSet<>(); 23 | 24 | q.add(begin); 25 | visited.add(begin); 26 | 27 | while (!q.isEmpty()) { 28 | int size = q.size(); 29 | 30 | for (int i = 0; i < size; i++) { 31 | System.out.println(q.peek()); 32 | addUnivsitedNeighborsToSetAndQueue(q.peek(), map, visited, q); 33 | q.remove(); 34 | } 35 | System.out.println("----------"); 36 | } 37 | } 38 | 39 | public static void addUnivsitedNeighborsToSetAndQueue(int number, Map> map, Set visited, Queue q) { 40 | if (!map.containsKey(number)) { 41 | return; 42 | } 43 | 44 | for (int i : map.get(number)) { 45 | if (!visited.contains(i)) { 46 | q.add(i); 47 | visited.add(i); 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/com/practice/miscellaneous/MaximumProductOfThreeNumbers.java: -------------------------------------------------------------------------------- 1 | package com.practice.miscellaneous; 2 | 3 | import java.util.*; 4 | /**Problem statement: 5 | Given an integer array nums, find three numbers whose product is maximum and return the maximum product. 6 | 7 | Example 1: 8 | 9 | Input: nums = [1,2,3] 10 | Output: 6 11 | Example 2: 12 | 13 | Input: nums = [1,2,3,4] 14 | Output: 24 15 | Example 3: 16 | 17 | Input: nums = [-1,-2,-3] 18 | Output: -6 19 | 20 | Leetcode link: https://leetcode.com/problems/maximum-product-of-three-numbers/description/ 21 | **/ 22 | public class MaximumProductOfThreeNumbers { 23 | public int maximumProduct(int[] nums) { 24 | Arrays.sort(nums); 25 | int endOfArray = nums[nums.length-1]* nums[nums.length-2]* nums[nums.length-3]; 26 | 27 | int begOfArray = nums[0] * nums[1]* nums[nums.length-1]; 28 | 29 | return Math.max(endOfArray, begOfArray); 30 | 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/com/practice/miscellaneous/MissingNumber.java: -------------------------------------------------------------------------------- 1 | package com.practice.miscellaneous; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given an array nums containing n distinct numbers in the range [0, n], return the only number in the range that is missing from the array. 5 | 6 | Example 1: 7 | Input: nums = [3,0,1] 8 | Output: 2 9 | Explanation: n = 3 since there are 3 numbers, so all numbers are in the range [0,3]. 2 is the missing number in the range since it does not appear in nums. 10 | 11 | Example 2: 12 | Input: nums = [0,1] 13 | Output: 2 14 | Explanation: n = 2 since there are 2 numbers, so all numbers are in the range [0,2]. 2 is the missing number in the range since it does not appear in nums. 15 | Example 3: 16 | 17 | Input: nums = [9,6,4,2,3,5,7,0,1] 18 | Output: 8 19 | Explanation: n = 9 since there are 9 numbers, so all numbers are in the range [0,9]. 8 is the missing number in the range since it does not appear in nums. 20 | 21 | Constraints: 22 | n == nums.length 23 | 1 <= n <= 104 24 | 0 <= nums[i] <= n 25 | All the numbers of nums are unique. 26 | Leetcode link: https://leetcode.com/problems/missing-number/description/ 27 | **/ 28 | public class MissingNumber { 29 | public int missingNumber(int[] nums) { 30 | Queue q = new ArrayDeque<>(); 31 | for(int i =0; i<= nums.length;i++){ 32 | q.add(i); 33 | } 34 | for(int i: nums){ 35 | q.remove(i); 36 | } 37 | return q.remove(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/com/practice/miscellaneous/NumberOfArithmeticTriplets.java: -------------------------------------------------------------------------------- 1 | package com.practice.miscellaneous; 2 | import java.util.*; 3 | /**Problem statement: 4 | Example 1: 5 | 6 | Input: nums = [0,1,4,6,7,10], diff = 3 7 | Output: 2 8 | Explanation: 9 | (1, 2, 4) is an arithmetic triplet because both 7 - 4 == 3 and 4 - 1 == 3. 10 | (2, 4, 5) is an arithmetic triplet because both 10 - 7 == 3 and 7 - 4 == 3. 11 | Example 2: 12 | 13 | Input: nums = [4,5,6,7,8,9], diff = 2 14 | Output: 2 15 | Explanation: 16 | (0, 2, 4) is an arithmetic triplet because both 8 - 6 == 2 and 6 - 4 == 2. 17 | (1, 3, 5) is an arithmetic triplet because both 9 - 7 == 2 and 7 - 5 == 2. 18 | 19 | 20 | Constraints: 21 | 22 | 3 <= nums.length <= 200 23 | 0 <= nums[i] <= 200 24 | 1 <= diff <= 50 25 | nums is strictly increasing. 26 | 27 | Leetcode link: https://leetcode.com/problems/number-of-arithmetic-triplets/description/ 28 | **/ 29 | 30 | public class NumberOfArithmeticTriplets { 31 | public int arithmeticTriplets(int[] nums, int diff) { 32 | 33 | //Brute force solution 34 | int count =0; 35 | 36 | for(int i=0; i< nums.length-2; i++){ 37 | for(int j =1; j> set = new HashSet<>(); 37 | int width = grid[0].length; 38 | int height = grid.length; 39 | int islandCount = 0; 40 | for (int row = 0; row < height; row++) { 41 | for (int col = 0; col < width; col++) { 42 | if (grid[row][col] == '1' && !set.contains(List.of(row, col))) { 43 | // add coordinates to the set 44 | set.add(List.of(row, col)); 45 | // perform BFS 46 | bfs(row, col, grid, set); 47 | islandCount++; 48 | } 49 | } 50 | } 51 | return islandCount; 52 | } 53 | 54 | public static void bfs(int row, int col, char[][] grid, Set> set) { 55 | int width = grid[0].length; 56 | int height = grid.length; 57 | 58 | Queue> q = new ArrayDeque<>(); 59 | q.add(List.of(row, col)); 60 | while (!q.isEmpty()) { 61 | List coordinates = q.remove(); 62 | int tempRow = coordinates.get(0); 63 | int tempCol = coordinates.get(1); 64 | 65 | // check 1 below 66 | if (!set.contains(List.of(tempRow + 1, tempCol)) && tempRow + 1 < height && grid[tempRow + 1][tempCol] == '1') { 67 | set.add(List.of(tempRow + 1, tempCol)); 68 | q.add(List.of(tempRow + 1, tempCol)); 69 | } 70 | // check to the right 71 | if (!set.contains(List.of(tempRow, tempCol + 1)) && tempCol + 1 < width && grid[tempRow][tempCol + 1] == '1') { 72 | set.add(List.of(tempRow, tempCol + 1)); 73 | q.add(List.of(tempRow, tempCol + 1)); 74 | } 75 | // check left 76 | if (!set.contains(List.of(tempRow, tempCol - 1)) && tempCol - 1 > -1 && grid[tempRow][tempCol - 1] == '1') { 77 | set.add(List.of(tempRow, tempCol - 1)); 78 | q.add(List.of(tempRow, tempCol - 1)); 79 | } 80 | // check 1 above 81 | if (!set.contains(List.of(tempRow - 1, tempCol)) && tempRow - 1 > -1 && grid[tempRow - 1][tempCol] == '1') { 82 | set.add(List.of(tempRow - 1, tempCol)); 83 | q.add(List.of(tempRow - 1, tempCol)); 84 | } 85 | } 86 | return; 87 | 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/com/practice/miscellaneous/PalindromeLinkedList.java: -------------------------------------------------------------------------------- 1 | package com.practice.miscellaneous; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given the head of a singly linked list, return true if it is a 5 | palindrome 6 | or false otherwise. 7 | 8 | Example 1: 9 | Input: head = [1,2,2,1] 10 | Output: true 11 | 12 | Constraints: 13 | The number of nodes in the list is in the range [1, 105]. 14 | 0 <= Node.val <= 9 15 | 16 | Leetcode link: https://leetcode.com/problems/palindrome-linked-list/description/ 17 | **/ 18 | public class PalindromeLinkedList { 19 | public boolean isPalindrome(ListNode head) { 20 | ArrayDeque q = new ArrayDeque<>(); 21 | while(head != null){ 22 | q.add(head); 23 | head =head.next; 24 | } 25 | while(!q.isEmpty() && q.size()>1){ 26 | if(q.remove().val != q.removeLast().val){ 27 | return false; 28 | } 29 | } 30 | return true; 31 | } 32 | } 33 | class ListNode { 34 | int val; 35 | ListNode next; 36 | ListNode() {} 37 | ListNode(int val) { this.val = val; } 38 | ListNode(int val, ListNode next) { this.val = val; this.next = next; } 39 | } 40 | -------------------------------------------------------------------------------- /src/com/practice/miscellaneous/PascalsTriangle.java: -------------------------------------------------------------------------------- 1 | package com.practice.miscellaneous; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given an integer numRows, return the first numRows of Pascal's triangle. 5 | 6 | In Pascal's triangle, each number is the sum of the two numbers directly above it as shown: 7 | Example 1: 8 | 9 | Input: numRows = 5 10 | Output: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 11 | Example 2: 12 | 13 | Input: numRows = 1 14 | Output: [[1]] 15 | 16 | Leetcode link: https://leetcode.com/problems/pascals-triangle/description/ 17 | **/ 18 | public class PascalsTriangle { 19 | public List < List < Integer >> generate(int numRows) { 20 | List < List < Integer >> result = new ArrayList < > (); 21 | result.add(List.of(1)); 22 | int prevRow = 0; 23 | 24 | while (numRows > 1) { 25 | List < Integer > currentList = new ArrayList < > (); 26 | List < Integer > previousList = result.get(prevRow); 27 | for (int i = -1, k = i + 1; i < previousList.size(); i++, k++) { 28 | int sum = 0; 29 | if (isOutOfBounds(i, previousList)) { 30 | sum += previousList.get(k);; 31 | } else if (isOutOfBounds(k, previousList)) { 32 | sum += previousList.get(i); 33 | } else { 34 | sum += previousList.get(k) + previousList.get(i); 35 | } 36 | currentList.add(sum); 37 | } 38 | result.add(currentList); 39 | numRows--; 40 | prevRow++; 41 | } 42 | return result; 43 | } 44 | public static boolean isOutOfBounds(int i, List < Integer > previousList) { 45 | return i == -1 || i >= previousList.size(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/com/practice/miscellaneous/PascalsTriangleII.java: -------------------------------------------------------------------------------- 1 | package com.practice.miscellaneous; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given an integer rowIndex, return the rowIndexth (0-indexed) row of the Pascal's triangle. 5 | 6 | In Pascal's triangle, each number is the sum of the two numbers directly above it as shown: 7 | Example 1: 8 | Input: rowIndex = 3 9 | Output: [1,3,3,1] 10 | 11 | Example 2: 12 | Input: rowIndex = 0 13 | Output: [1] 14 | 15 | Example 3: 16 | Input: rowIndex = 1 17 | Output: [1,1] 18 | 19 | Constraints: 20 | 0 <= rowIndex <= 33 21 | Leetcode link: https://leetcode.com/problems/pascals-triangle-ii/description/ 22 | **/ 23 | public class PascalsTriangleII { 24 | public List < Integer > getRow(int rowIndex) { 25 | int prevRowIndex = 0; 26 | List < Integer > prevList = new ArrayList < > (); 27 | prevList.add(1); 28 | if (rowIndex == 0) { 29 | return prevList; 30 | } 31 | int size = prevList.size(); 32 | while (prevRowIndex != rowIndex) { 33 | //create currentList 34 | List < Integer > currentList = createCurrentListFromPreviousList(prevList, size); 35 | size = currentList.size(); 36 | prevList = currentList; 37 | prevRowIndex++; 38 | } 39 | return prevList; 40 | } 41 | public static List < Integer > createCurrentListFromPreviousList(List < Integer > prevList, int size) { 42 | List < Integer > currentList = new ArrayList < > (); 43 | for (int i = -1, k = i + 1; i < size; i++, k++) { 44 | int sum = 0; 45 | if (i == -1) { 46 | sum += prevList.get(k); 47 | } else if (k >= prevList.size()) { 48 | sum += prevList.get(i); 49 | } else { 50 | sum += prevList.get(i) + prevList.get(k); 51 | } 52 | currentList.add(sum); 53 | } 54 | return currentList; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/com/practice/miscellaneous/PowerOfTwo.java: -------------------------------------------------------------------------------- 1 | package com.practice.miscellaneous; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given an integer n, return true if it is a power of two. Otherwise, return false. 5 | 6 | An integer n is a power of two, if there exists an integer x such that n == 2x. 7 | Example 1: 8 | 9 | Input: n = 1 10 | Output: true 11 | Explanation: 20 = 1 12 | Example 2: 13 | 14 | Input: n = 16 15 | Output: true 16 | Explanation: 24 = 16 17 | 18 | Leetcode link: https://leetcode.com/problems/power-of-two/description/ 19 | **/ 20 | public class PowerOfTwo { 21 | public boolean isPowerOfTwo(int n) { 22 | 23 | while (true) { 24 | if (n == 1) { 25 | return true; 26 | } 27 | if (n % 2 != 0 ) { 28 | return false; 29 | } 30 | if (n == 0) { 31 | return false; 32 | } 33 | n /= 2; 34 | } 35 | } 36 | //For loop solution below: 37 | public boolean isPowerOfTwoForLoop(int n) { 38 | if (n == 1) { 39 | return true; 40 | } 41 | for (int i = n; i > 0; i /= 2) { 42 | System.out.println(i); 43 | if (i % 2 != 0 && i != 1) { 44 | return false; 45 | } 46 | if (i == 1) { 47 | return true; 48 | } 49 | } 50 | return false; 51 | 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/com/practice/priorityqueueproblems/KthLargestElementInAnArray.java: -------------------------------------------------------------------------------- 1 | package com.practice.priorityqueueproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given an integer array nums and an integer k, return the kth largest element in the array. 5 | 6 | Note that it is the kth largest element in the sorted order, not the kth distinct element. 7 | 8 | Can you solve it without sorting? 9 | Example 1: 10 | Input: nums = [3,2,1,5,6,4], k = 2 11 | Output: 5 12 | 13 | Example 2: 14 | Input: nums = [3,2,3,1,2,4,5,5,6], k = 4 15 | Output: 4 16 | 17 | Constraints: 18 | 1 <= k <= nums.length <= 105 19 | -104 <= nums[i] <= 104 20 | 21 | Leetcode link: https://leetcode.com/problems/kth-largest-element-in-an-array/ 22 | **/ 23 | public class KthLargestElementInAnArray { 24 | public int findKthLargest(int[] nums, int k) { 25 | 26 | Queue q = new PriorityQueue<>(Collections.reverseOrder()); 27 | 28 | for( int i :nums){ 29 | q.add(i); 30 | } 31 | int result =0; 32 | while(k > 0){ 33 | result = q.remove(); 34 | k--; 35 | } 36 | return result; 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/com/practice/priorityqueueproblems/KthSmallestElementInASortedMatrix.java: -------------------------------------------------------------------------------- 1 | package com.practice.priorityqueueproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given an n x n matrix where each of the rows and columns is sorted in ascending order, return the kth smallest element in the matrix. 5 | Note that it is the kth smallest element in the sorted order, not the kth distinct element. 6 | 7 | You must find a solution with a memory complexity better than O(n2). 8 | 9 | Example 1: 10 | Input: matrix = [[1,5,9],[10,11,13],[12,13,15]], k = 8 11 | Output: 13 12 | Explanation: The elements in the matrix are [1,5,9,10,11,12,13,13,15], and the 8th smallest number is 13 13 | 14 | Example 2: 15 | Input: matrix = [[-5]], k = 1 16 | Output: -5 17 | Constraints: 18 | 19 | n == matrix.length == matrix[i].length 20 | 1 <= n <= 300 21 | -109 <= matrix[i][j] <= 109 22 | All the rows and columns of matrix are guaranteed to be sorted in non-decreasing order. 23 | 1 <= k <= n2 24 | 25 | Leetcode link: https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/description/ 26 | **/ 27 | public class KthSmallestElementInASortedMatrix { 28 | public int kthSmallest(int[][] matrix, int k) { 29 | 30 | Queue < Integer > q = new PriorityQueue < > (); 31 | putElementsInPriorityQueue(q, matrix); 32 | 33 | int result = 0; 34 | int count = 0; 35 | 36 | while (!q.isEmpty() && count < k) { 37 | result = q.remove(); 38 | count++; 39 | } 40 | return result; 41 | } 42 | public static void putElementsInPriorityQueue(Queue < Integer > q, int[][] matrix) { 43 | for (int[] singleArr: matrix) { 44 | for (int number: singleArr) { 45 | q.add(number); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/com/practice/priorityqueueproblems/SortAnArray.java: -------------------------------------------------------------------------------- 1 | package com.practice.priorityqueueproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given an array of integers nums, sort the array in ascending order and return it. 5 | 6 | You must solve the problem without using any built-in functions in O(nlog(n)) time complexity and with the smallest space complexity possible. 7 | Example 1: 8 | 9 | Input: nums = [5,2,3,1] 10 | Output: [1,2,3,5] 11 | Explanation: After sorting the array, the positions of some numbers are not changed (for example, 2 and 3), while the positions of other numbers are changed (for example, 1 and 5). 12 | 13 | Example 2: 14 | Input: nums = [5,1,1,2,0,0] 15 | Output: [0,0,1,1,2,5] 16 | Explanation: Note that the values of nums are not necessairly unique. 17 | 18 | Constraints: 19 | 1 <= nums.length <= 5 * 104 20 | -5 * 104 <= nums[i] <= 5 * 104 21 | 22 | Leetcode link: https://leetcode.com/problems/sort-an-array/description/ 23 | **/ 24 | public class SortAnArray { 25 | public int[] sortArray(int[] nums) { 26 | int[] result = new int[nums.length]; 27 | Queue q = new PriorityQueue < > (); 28 | for (int i: nums) { 29 | q.add(i); 30 | } 31 | int p1 = 0; 32 | while (!q.isEmpty()) { 33 | result[p1] = q.remove(); 34 | p1++; 35 | } 36 | return result; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/com/practice/priorityqueueproblems/TopKFrequentElements.java: -------------------------------------------------------------------------------- 1 | package com.practice.priorityqueueproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given an integer array nums and an integer k, return the k most frequent elements. You may return the answer in any order. 5 | Example 1: 6 | Input: nums = [1,1,1,2,2,3], k = 2 7 | Output: [1,2] 8 | 9 | Example 2: 10 | Input: nums = [1], k = 1 11 | Output: [1] 12 | 13 | Constraints: 14 | 1 <= nums.length <= 105 15 | -104 <= nums[i] <= 104 16 | k is in the range [1, the number of unique elements in the array]. 17 | It is guaranteed that the answer is unique. 18 | Follow up: Your algorithm's time complexity must be better than O(n log n), where n is the array's size. 19 | 20 | Leetcode link: https://leetcode.com/problems/top-k-frequent-elements/ 21 | **/ 22 | public class TopKFrequentElements { 23 | public int[] topKFrequent(int[] nums, int k) { 24 | int[] result = new int[k]; 25 | int pointer = 0; 26 | 27 | Map < Integer, Integer > map = createMap(nums); 28 | List < Integer > frequencyList = findTopFrequencies(map, k); 29 | 30 | for (Map.Entry < Integer, Integer > f: map.entrySet()) { 31 | if (frequencyList.contains(f.getValue())) { 32 | result[pointer] = f.getKey(); 33 | pointer++; 34 | } 35 | } 36 | return result; 37 | } 38 | public static List < Integer > findTopFrequencies(Map < Integer, Integer > map, int k) { 39 | List < Integer > result = new ArrayList < > (); 40 | 41 | Queue < Integer > q = new PriorityQueue < > (Collections.reverseOrder()); 42 | for (Map.Entry < Integer, Integer > l: map.entrySet()) { 43 | q.add(l.getValue()); 44 | } 45 | while (k > 0) { 46 | result.add(q.remove()); 47 | k--; 48 | } 49 | return result; 50 | } 51 | public static Map < Integer, Integer > createMap(int[] nums) { 52 | Map < Integer, Integer > map = new HashMap < > (); 53 | 54 | for (int i: nums) { 55 | if (!map.containsKey(i)) { 56 | map.put(i, 1); 57 | } else { 58 | map.put(i, map.get(i) + 1); 59 | } 60 | } 61 | return map; 62 | 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/AllPathsFromSourceToTarget.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given a directed acyclic graph (DAG) of n nodes labeled from 0 to n - 1, find all possible paths from node 0 to node n - 1 and return them in any order. 5 | 6 | The graph is given as follows: graph[i] is a list of all nodes you can visit from node i (i.e., there is a directed edge from node i to node graph[i][j]). 7 | 8 | Example 1: 9 | Input: graph = [[1,2],[3],[3],[]] 10 | Output: [[0,1,3],[0,2,3]] 11 | Explanation: There are two paths: 0 -> 1 -> 3 and 0 -> 2 -> 3. 12 | 13 | Example 2: 14 | Input: graph = [[4,3,1],[3,2,4],[3],[4],[]] 15 | Output: [[0,4],[0,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,4]] 16 | 17 | Constraints: 18 | n == graph.length 19 | 2 <= n <= 15 20 | 0 <= graph[i][j] < n 21 | graph[i][j] != i (i.e., there will be no self-loops). 22 | All the elements of graph[i] are unique. 23 | The input graph is guaranteed to be a DAG. 24 | 25 | Leetcode link: https://leetcode.com/problems/all-paths-from-source-to-target/description/ 26 | **/ 27 | public class AllPathsFromSourceToTarget { 28 | public List < List < Integer >> allPathsSourceTarget(int[][] graph) { 29 | Map < Integer, List < Integer >> map = createMap(graph); 30 | Map < Integer, List < Integer >> pathMap = new HashMap < > (); 31 | int destination = graph.length - 1; 32 | List < Integer > tempList = new ArrayList < > (); 33 | List < List < Integer >> resultList = new ArrayList < > (); 34 | findPath(map, 0, destination, tempList, resultList); 35 | return resultList; 36 | 37 | } 38 | public static Map < Integer, List < Integer >> createMap(int[][] graph) { 39 | Map < Integer, List < Integer >> result = new HashMap < > (); 40 | 41 | int height = graph.length; 42 | 43 | for (int i = 0; i < height; i++) { 44 | int[] singleArr = graph[i]; 45 | if (singleArr.length > 0) { 46 | List < Integer > tempList = createListFromArray(singleArr); 47 | result.put(i, tempList); 48 | } 49 | } 50 | return result; 51 | } 52 | public static List < Integer > createListFromArray(int[] singleArr) { 53 | List < Integer > result = new ArrayList < > (); 54 | 55 | for (int i: singleArr) { 56 | result.add(i); 57 | } 58 | return result; 59 | } 60 | public static void findPath(Map < Integer, List < Integer >> map, int number, int destination, List < Integer > tempList, List < List < Integer >> resultList) { 61 | 62 | tempList.add(number); 63 | if (number == destination) { 64 | resultList.add(new ArrayList < > (tempList)); 65 | tempList.remove(tempList.size() - 1); 66 | return; 67 | } 68 | if (!map.containsKey(number)) { 69 | tempList.remove(tempList.size() - 1); 70 | return; 71 | } 72 | 73 | for (Integer i: map.get(number)) { 74 | findPath(map, i, destination, tempList, resultList); 75 | } 76 | tempList.remove(tempList.size() - 1); 77 | return; 78 | 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/BinarySearchRecursively.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | 4 | /**Return the position of a target by implementing a binary search. If it does not exist, return a -1. 5 | * */ 6 | 7 | 8 | public class BinarySearchRecursively { 9 | public static void main(String[] args) { 10 | int [] nums ={ -1,2,9,50}; 11 | int target = 9; 12 | System.out.println(bSearch(nums, 0, nums.length, target)); 13 | } 14 | 15 | public static int bSearch(int[] nums, int begin, int end, int target) { 16 | int middle = (begin + end) / 2; 17 | if (middle < nums.length && nums[middle] == target) { 18 | return middle; 19 | } else if (middle == begin || middle == end) { 20 | return -1; 21 | } else if (nums[middle] < target) { 22 | begin = middle + 1; 23 | } else { 24 | end = middle ; 25 | } 26 | return bSearch(nums, begin, end, target); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/BinaryTreeInorderTraversal.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.ArrayList; 3 | import java.util.List; 4 | 5 | /**Problem statement: 6 | Given the root of a binary tree, return the inorder traversal of its nodes' values. 7 | 8 | Leetcode link: https://leetcode.com/problems/binary-tree-inorder-traversal/description/ 9 | **/ 10 | 11 | public class BinaryTreeInorderTraversal { 12 | public List inorderTraversal(TreeNode root) { 13 | 14 | if( root == null){ 15 | //this will return an empty list 16 | return List.of(); 17 | } 18 | List result = new ArrayList<>(); 19 | /**the if statement below is not needed. However, it makes the code more clear, but it can be commented out for 20 | * less time complexity 21 | **/ 22 | if(root.left == null && root.right == null){ 23 | result.add(root.val); 24 | } 25 | result.addAll(inorderTraversal(root.left)); 26 | result.add(root.val); 27 | result.addAll(inorderTraversal(root.right)); 28 | return result; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/BinaryTreePaths.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | 4 | /**Problem statement: 5 | Given the root of a binary tree, return all root-to-leaf paths in any order. 6 | 7 | A leaf is a node with no children. 8 | 9 | Example 1: 10 | Input: root = [1,2,3,null,5] 11 | Output: ["1->2->5","1->3"] 12 | 13 | Example 2: 14 | Input: root = [1] 15 | Output: ["1"] 16 | 17 | Constraints: 18 | The number of nodes in the tree is in the range [1, 100]. 19 | -100 <= Node.val <= 100 20 | -1000 <= targetSum <= 1000 21 | 22 | Leetcode link: https://leetcode.com/problems/binary-tree-paths/description/ 23 | **/ 24 | public class BinaryTreePaths { 25 | public List < String > binaryTreePaths(TreeNode root) { 26 | List result = new ArrayList<>(); 27 | StringBuilder sb = new StringBuilder(); 28 | findPath(result, root, sb); 29 | return result; 30 | 31 | } 32 | public static void findPath(List < String > list, TreeNode root, StringBuilder sb) { 33 | if (root == null) { 34 | return; 35 | } 36 | int end = sb.length(); 37 | 38 | if (sb.isEmpty()|| sb.charAt(sb.length()-1) == '>') { 39 | sb.append(root.val); 40 | } else { 41 | sb.append("->"); 42 | sb.append(root.val); 43 | } 44 | if (root.left == null && root.right == null) { 45 | list.add(String.valueOf(sb)); 46 | sb.delete(end, sb.length()); 47 | return; 48 | } 49 | findPath(list, root.right, sb); 50 | findPath(list, root.left, sb); 51 | sb.delete(end, sb.length()); 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/BreadthFirstSearchOnAGraph.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | 3 | import java.io.*; 4 | import java.util.*; 5 | 6 | /** 7 | *Problem statement: Create a hashmap representing a graph, where the key is an element in the graph, and the value is 8 | * the list of neighbors. 9 | * 10 | * After this, implement a breadth first search 11 | * 12 | * 13 | **/ 14 | 15 | public class BreadthFirstSearchOnAGraph { 16 | public static void main(String[] args) { 17 | 18 | Map> map = new HashMap<>(); 19 | 20 | map.put(2, List.of(3, 0, 9)); 21 | map.put(9, List.of(2)); 22 | map.put(3, List.of(2, 7)); 23 | map.put(0, List.of(2, 7)); 24 | map.put(7, List.of(3, 0)); 25 | } 26 | } -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/CheckIfTwoStringArraysAreEquivalentRecursively.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | /**Problem statement: 3 | * A recursive solution is not optimal. However, in order to practice recursiion, I have decided to solve this problem recursively. 4 | * 5 | Given two string arrays word1 and word2, return true if the two arrays represent the same string, and false otherwise. 6 | 7 | A string is represented by an array if the array elements concatenated in order forms the string. 8 | 9 | Example 1: 10 | 11 | Input: word1 = ["ab", "c"], word2 = ["a", "bc"] 12 | Output: true 13 | Explanation: 14 | word1 represents string "ab" + "c" -> "abc" 15 | word2 represents string "a" + "bc" -> "abc" 16 | The strings are the same, so return true. 17 | Example 2: 18 | 19 | Input: word1 = ["a", "cb"], word2 = ["ab", "c"] 20 | Output: false 21 | Example 3: 22 | 23 | Input: word1 = ["abc", "d", "defg"], word2 = ["abcddefg"] 24 | Output: true 25 | Constraints: 26 | 27 | 1 <= word1.length, word2.length <= 103 28 | 1 <= word1[i].length, word2[i].length <= 103 29 | 1 <= sum(word1[i].length), sum(word2[i].length) <= 103 30 | word1[i] and word2[i] consist of lowercase letters. 31 | 32 | Leetcode link: https://leetcode.com/problems/check-if-two-string-arrays-are-equivalent/description/ 33 | **/ 34 | public class CheckIfTwoStringArraysAreEquivalentRecursively { 35 | public boolean arrayStringsAreEqual(String[] word1, String[] word2) { 36 | String one = createString(word1, 0); 37 | String two = createString(word2, 0); 38 | 39 | return one.equals(two); 40 | } 41 | public static String createString(String[] word, int index) { 42 | StringBuilder result = new StringBuilder(); 43 | 44 | if (index == word.length) { 45 | return result.toString(); 46 | } 47 | return result.append(word[index]) + createString(word, index + 1); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/ClosestBinarySearchTreeValue.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | 4 | /**Problem statement: 5 | Given the root of a binary search tree and a target value, return the value in the BST that is closest to the target. If there are multiple answers, print the smallest. 6 | 7 | Example 1: 8 | Input: root = [4,2,5,1,3], target = 3.714286 9 | Output: 4 10 | 11 | Example 2: 12 | Input: root = [1], target = 4.428571 13 | Output: 1 14 | Constraints: 15 | 16 | The number of nodes in the tree is in the range [1, 104]. 17 | 0 <= Node.val <= 109 18 | -109 <= target <= 109 19 | 20 | 21 | Leetcode link: https://leetcode.com/problems/closest-binary-search-tree-value/description/ 22 | **/ 23 | public class ClosestBinarySearchTreeValue { 24 | public int closestValue(TreeNode root, double target) { 25 | double result = Integer.MAX_VALUE; 26 | int [] finalResult = new int [1]; 27 | findClosest(root,target, result, finalResult); 28 | return finalResult[0]; 29 | } 30 | public static void findClosest(TreeNode root, double target, double result, int [] finalResult){ 31 | if(root == null){ 32 | return; 33 | } 34 | double temp = Math.abs(target - root.val); 35 | if(temp == result){ 36 | int current = finalResult[0]; 37 | finalResult[0] = Math.min(current, root.val); 38 | } 39 | if(temp < result){ 40 | finalResult[0] = root.val; 41 | } 42 | 43 | result = Math.min(result, temp); 44 | 45 | if(root.left == null && root.right == null){ 46 | //evaluate root 47 | return; 48 | } 49 | findClosest(root.right, target, result, finalResult); 50 | findClosest(root.left, target, result, finalResult); 51 | 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/CoinChange.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | You are given an integer array coins representing coins of different denominations and an integer amount 5 | representing a total amount of money. 6 | 7 | Return the fewest number of coins that you need to make up that amount. If that amount of money cannot be made 8 | up by any combination of the coins, return -1. 9 | 10 | You may assume that you have an infinite number of each kind of coin. 11 | 12 | Example 1: 13 | 14 | Input: coins = [1,2,5], amount = 11 15 | Output: 3 16 | Explanation: 11 = 5 + 5 + 1 17 | Example 2: 18 | 19 | Input: coins = [2], amount = 3 20 | Output: -1 21 | Example 3: 22 | 23 | Input: coins = [1], amount = 0 24 | Output: 0 25 | 26 | Leetcode link: https://leetcode.com/problems/coin-change/description/ 27 | **/ 28 | public class CoinChange { 29 | public int coinChange(int[] coins, int amount) { 30 | Map map = new HashMap<>(); 31 | return coinChanger(coins, amount, map); 32 | } 33 | 34 | public static int coinChanger(int[] coins, int amount, Map map) { 35 | int minCoins = Integer.MAX_VALUE; 36 | if (map.containsKey(amount)) { 37 | return map.get(amount); 38 | } else if (amount < 0) { 39 | return -1; 40 | } else if (amount == 0) { 41 | return 0; 42 | } else { 43 | 44 | for (int i = 0; i < coins.length; i++) { 45 | int coinsNeeded = coinChanger(coins, amount - coins[i], map); 46 | if (coinsNeeded != -1 && coinsNeeded < minCoins) { 47 | minCoins = coinsNeeded + 1; 48 | } 49 | } 50 | int result = minCoins == Integer.MAX_VALUE ? -1 : minCoins; 51 | map.put(amount, result); 52 | return result; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/CountNodesEqualToAverageOfSubtree.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given the root of a binary tree, return the number of nodes where the value of the node is equal to the average of the values in its subtree. 5 | 6 | Note: 7 | 8 | The average of n elements is the sum of the n elements divided by n and rounded down to the nearest integer. 9 | A subtree of root is a tree consisting of root and all of its descendants. 10 | 11 | 12 | Example 1: 13 | Input: root = [4,8,5,0,1,null,6] 14 | Output: 5 15 | Explanation: 16 | For the node with value 4: The average of its subtree is (4 + 8 + 5 + 0 + 1 + 6) / 6 = 24 / 6 = 4. 17 | For the node with value 5: The average of its subtree is (5 + 6) / 2 = 11 / 2 = 5. 18 | For the node with value 0: The average of its subtree is 0 / 1 = 0. 19 | For the node with value 1: The average of its subtree is 1 / 1 = 1. 20 | For the node with value 6: The average of its subtree is 6 / 1 = 6. 21 | 22 | Example 2: 23 | Input: root = [1] 24 | Output: 1 25 | Explanation: For the node with value 1: The average of its subtree is 1 / 1 = 1. 26 | 27 | Constraints: 28 | The number of nodes in the tree is in the range [1, 1000]. 29 | 0 <= Node.val <= 1000 30 | 31 | Leetcode link: https://leetcode.com/problems/count-nodes-equal-to-average-of-subtree/ 32 | **/ 33 | 34 | public class CountNodesEqualToAverageOfSubtree { 35 | int count; 36 | int sum; 37 | public int averageOfSubtree(TreeNode root) { 38 | 39 | if (root == null) { 40 | return 0; 41 | } 42 | 43 | int count = findCount(root); 44 | int sum = findSum(root); 45 | int average = (int) Math.floor(sum / count); 46 | int result = averageOfSubtree(root.left) + averageOfSubtree(root.right); 47 | 48 | return average == root.val ? 1 + result : result; 49 | } 50 | public static int findCount(TreeNode root) { 51 | if (root == null) { 52 | return 0; 53 | } 54 | return 1 + findCount(root.left) + findCount(root.right); 55 | } 56 | public static int findSum(TreeNode root) { 57 | if (root == null) { 58 | return 0; 59 | } 60 | 61 | return root.val + findSum(root.left) + findSum(root.right); 62 | 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/DeepestLeavesSum.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | 3 | import java.util.*; 4 | /**Problem statement: 5 | Given the root of a binary tree, return the sum of values of its deepest leaves. 6 | 7 | Example 1: 8 | Input: root = [1,2,3,4,5,null,6,7,null,null,null,null,8] 9 | Output: 15 10 | 11 | Example 2: 12 | Input: root = [6,7,8,2,7,1,3,9,null,1,4,null,null,null,5] 13 | Output: 19 14 | 15 | Constraints: 16 | The number of nodes in the tree is in the range [1, 104]. 17 | 1 <= Node.val <= 100 18 | 19 | Leetcode link: https://leetcode.com/problems/deepest-leaves-sum/description/ 20 | **/ 21 | 22 | 23 | public class DeepestLeavesSum { 24 | public int deepestLeavesSum(TreeNode root) { 25 | return findSum(root); 26 | } 27 | public static int findSum(TreeNode root) { 28 | Queue < TreeNode > q = new ArrayDeque < > (); 29 | q.add(root); 30 | int size = q.size(); 31 | int sum = 0; 32 | 33 | while (!q.isEmpty()) { 34 | size = q.size(); 35 | sum = addUpElementsInQueue(q); 36 | 37 | for (int i = 0; i < size; i++) { 38 | TreeNode current = q.peek(); 39 | addNeighbors(current, q); 40 | q.remove(); 41 | } 42 | } 43 | return sum; 44 | } 45 | public static int addUpElementsInQueue(Queue < TreeNode > q) { 46 | int sum = 0; 47 | for (TreeNode node: q) { 48 | sum += node.val; 49 | } 50 | return sum; 51 | } 52 | public static void addNeighbors(TreeNode current, Queue < TreeNode > q) { 53 | if (current.left != null) { 54 | q.add(current.left); 55 | } 56 | if (current.right != null) { 57 | q.add(current.right); 58 | } 59 | return; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/ExtractKthCharacterFromTheRopeTree.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | You are given the root of a binary tree and an integer k. Besides the left and right children, every node of this tree has two other properties, a string node.val containing only lowercase English letters (possibly empty) and a non-negative integer node.len. There are two types of nodes in this tree: 5 | 6 | Leaf: These nodes have no children, node.len = 0, and node.val is some non-empty string. 7 | Internal: These nodes have at least one child (also at most two children), node.len > 0, and node.val is an empty string. 8 | The tree described above is called a Rope binary tree. Now we define S[node] recursively as follows: 9 | 10 | If node is some leaf node, S[node] = node.val, 11 | Otherwise if node is some internal node, S[node] = concat(S[node.left], S[node.right]) and S[node].length = node.len. 12 | Return k-th character of the string S[root]. 13 | 14 | Note: If s and p are two strings, concat(s, p) is a string obtained by concatenating p to s. For example, concat("ab", "zz") = "abzz". 15 | Example 1: 16 | Input: root = [10,4,"abcpoe","g","rta"], k = 6 17 | Output: "b" 18 | Explanation: In the picture below, we put an integer on internal nodes that represents node.len, and a string on leaf nodes that represents node.val. 19 | You can see that S[root] = concat(concat("g", "rta"), "abcpoe") = "grtaabcpoe". So S[root][5], which represents 6th character of it, is equal to "b". 20 | 21 | Example 3: 22 | Input: root = ["ropetree"], k = 8 23 | Output: "e" 24 | Explanation: In the picture below, we put an integer on internal nodes that represents node.len, and a string on leaf nodes that represents node.val. 25 | You can see that S[root] = "ropetree". So S[root][7], which represents 8th character of it, is equal to "e". 26 | 27 | Constraints: 28 | The number of nodes in the tree is in the range [1, 103] 29 | node.val contains only lowercase English letters 30 | 0 <= node.val.length <= 50 31 | 0 <= node.len <= 104 32 | for leaf nodes, node.len = 0 and node.val is non-empty 33 | for internal nodes, node.len > 0 and node.val is empty 34 | 1 <= k <= S[root].length 35 | 36 | Leetcode link: https://leetcode.com/problems/extract-kth-character-from-the-rope-tree/description/ 37 | **/ 38 | public class ExtractKthCharacterFromTheRopeTree { 39 | public char getKthCharacter(RopeTreeNode root, int k) { 40 | StringBuilder sb = new StringBuilder(); 41 | createSB(root, sb); 42 | return sb.toString().charAt(k - 1); 43 | } 44 | public static void createSB(RopeTreeNode root, StringBuilder result) { 45 | if (root == null) { 46 | return; 47 | } 48 | if (root.left == null && root.right == null) { 49 | result.append(root.val); 50 | } 51 | createSB(root.left, result); 52 | createSB(root.right, result); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/FibonacciNumber.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | The Fibonacci numbers, commonly denoted F(n) form a sequence, called the Fibonacci sequence, such that each number is the sum of the two preceding ones, starting from 0 and 1. That is, 5 | 6 | F(0) = 0, F(1) = 1 7 | F(n) = F(n - 1) + F(n - 2), for n > 1. 8 | Given n, calculate F(n). 9 | 10 | Example 1: 11 | 12 | Input: n = 2 13 | Output: 1 14 | Explanation: F(2) = F(1) + F(0) = 1 + 0 = 1. 15 | 16 | Constraints: 17 | 18 | 0 <= n <= 30 19 | Leetcode link: https://leetcode.com/problems/fibonacci-number/description/ 20 | **/ 21 | public class FibonacciNumber { 22 | public int fib(int n) { 23 | 24 | 25 | if(n == 0 || n==1){ 26 | return n; 27 | } 28 | return fib(n-1) + fib(n-2); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/FirstBadVersion.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | You are a product manager and currently leading a team to develop a new product. Unfortunately, the latest version of your product fails the quality check. Since each version is developed based on the previous version, all the versions after a bad version are also bad. 5 | Suppose you have n versions [1, 2, ..., n] and you want to find out the first bad one, which causes all the following ones to be bad. 6 | 7 | You are given an API bool isBadVersion(version) which returns whether version is bad. Implement a function to find the first bad version. You should minimize the number of calls to the API. 8 | Example 1: 9 | 10 | Input: n = 5, bad = 4 11 | Output: 4 12 | Explanation: 13 | call isBadVersion(3) -> false 14 | call isBadVersion(5) -> true 15 | call isBadVersion(4) -> true 16 | Then 4 is the first bad version. 17 | Example 2: 18 | 19 | Input: n = 1, bad = 1 20 | Output: 1 21 | 22 | Constraints: 23 | 1 <= bad <= n <= 231 - 1 24 | 25 | Leetcode link: https://leetcode.com/problems/first-bad-version/description/ 26 | **/ 27 | public class FirstBadVersion { 28 | public int firstBadVersion(int n) { 29 | 30 | return findBadVersion(0, n); 31 | 32 | } 33 | public int findBadVersion(int begin, int end) { 34 | 35 | int middle = begin + (end - begin) / 2; 36 | if (end == begin) { 37 | return begin + 1; 38 | } 39 | if (isBadVersion(middle + 1)) { 40 | end = middle; 41 | } else if (!isBadVersion(middle + 1)) { 42 | begin = middle + 1; 43 | } 44 | return findBadVersion(begin, end); 45 | } 46 | public static boolean isBadVersion(int version){ 47 | return version >= 4; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/FloodFill.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * Problem statement: 7 | * An image is represented by an m x n integer grid image where image[i][j] represents the pixel value of the image. 8 | *

9 | * You are also given three integers sr, sc, and color. You should perform a flood fill on the image starting from the pixel image[sr][sc]. 10 | *

11 | * To perform a flood fill, consider the starting pixel, plus any pixels connected 4-directionally to the starting pixel of the same color as the starting pixel, plus any pixels connected 4-directionally to those pixels (also with the same color), and so on. Replace the color of all of the aforementioned pixels with color. 12 | *

13 | * Return the modified image after performing the flood fill. 14 | *

15 | * Example 1: 16 | * Input: image = [[1,1,1],[1,1,0],[1,0,1]], sr = 1, sc = 1, color = 2 17 | * Output: [[2,2,2],[2,2,0],[2,0,1]] 18 | * Explanation: From the center of the image with position (sr, sc) = (1, 1) (i.e., the red pixel), all pixels connected by a path of the same color as the starting pixel (i.e., the blue pixels) are colored with the new color. 19 | * Note the bottom corner is not colored 2, because it is not 4-directionally connected to the starting pixel. 20 | * Example 2: 21 | *

22 | * Input: image = [[0,0,0],[0,0,0]], sr = 0, sc = 0, color = 0 23 | * Output: [[0,0,0],[0,0,0]] 24 | * Explanation: The starting pixel is already colored 0, so no changes are made to the image. 25 | *

26 | * Constraints: 27 | * m == image.length 28 | * n == image[i].length 29 | * 1 <= m, n <= 50 30 | * 0 <= image[i][j], color < 216 31 | * 0 <= sr < m 32 | * 0 <= sc < n 33 | *

34 | * Leetcode link: https://leetcode.com/problems/flood-fill/description/ 35 | **/ 36 | public class FloodFill { 37 | public int[][] floodFill(int[][] image, int sr, int sc, int color) { 38 | int width = image[0].length; 39 | int height = image.length; 40 | int[][] result = Arrays.copyOf(image, image.length); 41 | 42 | Set> set = new HashSet<>(); 43 | fill(image, sr, sc, color, image[sr][sc], set); 44 | return image; 45 | } 46 | 47 | public static void fill(int[][] image, int row, int col, int color, int startColor, Set> set) { 48 | if (isOutOfBounds(row, col, image)) { 49 | return; 50 | } 51 | if (set.contains(List.of(row, col))) { 52 | return; 53 | } 54 | set.add(List.of(row, col)); 55 | if (image[row][col] != startColor) { 56 | return; 57 | } else { 58 | image[row][col] = color; 59 | } 60 | //up 61 | fill(image, row - 1, col, color, startColor, set); 62 | 63 | //down 64 | fill(image, row + 1, col, color, startColor, set); 65 | 66 | //left 67 | fill(image, row, col - 1, color, startColor, set); 68 | //right 69 | fill(image, row, col + 1, color, startColor, set); 70 | } 71 | 72 | public static boolean isOutOfBounds(int row, int col, int[][] image) { 73 | int width = image[0].length; 74 | int height = image.length; 75 | 76 | return row < 0 || row >= height || col < 0 || col >= width; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/HappyNumber.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Write an algorithm to determine if a number n is happy. 5 | 6 | A happy number is a number defined by the following process: 7 | 8 | Starting with any positive integer, replace the number by the sum of the squares of its digits. 9 | Repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. 10 | Those numbers for which this process ends in 1 are happy. 11 | Return true if n is a happy number, and false if not. 12 | 13 | Example 1: 14 | Input: n = 19 15 | Output: true 16 | Explanation: 17 | 12 + 92 = 82 18 | 82 + 22 = 68 19 | 62 + 82 = 100 20 | 12 + 02 + 02 = 1 21 | 22 | Example 2: 23 | Input: n = 2 24 | Output: false 25 | 26 | Constraints: 27 | 1 <= n <= 231 - 1 28 | 29 | Leetcode link: https://leetcode.com/problems/happy-number/description/ 30 | **/ 31 | public class HappyNumber { 32 | public boolean isHappy(int n) { 33 | Set < Integer > set = new HashSet < > (); 34 | return isHappyHelper(n, set); 35 | } 36 | public static boolean isHappyHelper(int n, Set < Integer > set) { 37 | if (n == 1) { 38 | return true; 39 | } 40 | if (set.contains(n)) { 41 | return false; 42 | } 43 | set.add(n); 44 | return isHappyHelper(findSum(n), set); 45 | } 46 | public static int findSum(int n) { 47 | int sum = 0; 48 | String numberString = String.valueOf(n); 49 | 50 | for (int i = 0; i < numberString.length(); i++) { 51 | int number = Character.getNumericValue(numberString.charAt(i)); 52 | int squaredNumber = (int) Math.pow(number, 2); 53 | sum += squaredNumber; 54 | } 55 | return sum; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/IncreaseOrderSearchTree.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | 3 | /**Problem statement: 4 | Given the root of a binary search tree, rearrange the tree in in-order so that the leftmost 5 | node in the tree is now the root of the tree, and every node has no left child and only one right child. 6 | 7 | Leetcode link: https://leetcode.com/problems/increasing-order-search-tree/description/ 8 | **/ 9 | public class IncreaseOrderSearchTree { 10 | 11 | public TreeNode increasingBST(TreeNode root) { 12 | if (root == null) { 13 | return root; 14 | } 15 | 16 | if (root.left == null && root.right == null) { 17 | return new TreeNode(root.val); 18 | } 19 | TreeNode head = increasingBST(root.left); 20 | TreeNode tail = new TreeNode(); 21 | if (head != null) { 22 | tail = head; 23 | while (tail.right != null) { 24 | tail = tail.right; 25 | } 26 | tail.right = new TreeNode(root.val); 27 | TreeNode rightHead = increasingBST(root.right); 28 | tail.right.right = rightHead; 29 | } else { 30 | head = new TreeNode(root.val); 31 | head.right = increasingBST(root.right); 32 | } 33 | return head; 34 | } 35 | } 36 | class TreeNode { 37 | int val; 38 | TreeNode left; 39 | TreeNode right; 40 | 41 | TreeNode() { 42 | } 43 | 44 | TreeNode(int val) { 45 | this.val = val; 46 | } 47 | 48 | TreeNode(int val, TreeNode left, TreeNode right) { 49 | this.val = val; 50 | this.left = left; 51 | this.right = right; 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/LeafSimilarTrees.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.io.*; 3 | import java.util.*; 4 | /**Problem statement: 5 | Consider all the leaves of a binary tree, from left to right order, the values of those leaves form a leaf value 6 | sequence. 7 | 8 | For example, in the given tree above, the leaf value sequence is (6, 7, 4, 9, 8). 9 | 10 | Two binary trees are considered leaf-similar if their leaf value sequence is the same. 11 | 12 | Return true if and only if the two given trees with head nodes root1 and root2 are leaf-similar. 13 | 14 | Constraints: 15 | 16 | The number of nodes in each tree will be in the range [1, 200]. 17 | Both of the given trees will have values in the range [0, 200]. 18 | 19 | Leetcode link: https://leetcode.com/problems/leaf-similar-trees/description/ 20 | **/ 21 | 22 | public class LeafSimilarTrees { 23 | 24 | public boolean leafSimilar(TreeNode root1, TreeNode root2) { 25 | return leafSimilar(root2).equals(leafSimilar(root1)); 26 | } 27 | 28 | public static List leafSimilar(TreeNode root) { 29 | List oneList = new ArrayList<>(); 30 | if(root == null ){ 31 | return oneList; 32 | } 33 | if(root.left == null && root.right == null){ 34 | oneList.add(root.val); 35 | return oneList; 36 | } 37 | oneList.addAll(leafSimilar(root.left)); 38 | oneList.addAll(leafSimilar(root.right)); 39 | return oneList; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/MaxAreaOfIsland.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | You are given an m x n binary matrix grid. An island is a group of 1's (representing land) connected 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water. 5 | 6 | The area of an island is the number of cells with a value 1 in the island. 7 | 8 | Return the maximum area of an island in grid. If there is no island, return 0. 9 | 10 | Example 1: 11 | Input: grid = [[0,0,1,0,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,1,1,0,1,0,0,0,0,0,0,0,0],[0,1,0,0,1,1,0,0,1,0,1,0,0],[0,1,0,0,1,1,0,0,1,1,1,0,0],[0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,0,0,0,0,0,0,1,1,0,0,0,0]] 12 | Output: 6 13 | Explanation: The answer is not 11, because the island must be connected 4-directionally. 14 | 15 | Leetcode link: https://leetcode.com/problems/max-area-of-island/ 16 | **/ 17 | public class MaxAreaOfIsland { 18 | public int maxAreaOfIsland(int[][] grid) { 19 | Set < List < Integer >> set = new HashSet < > (); 20 | int width = grid[0].length; 21 | int height = grid.length; 22 | int islandCount = 0; 23 | for (int row = 0; row < height; row++) { 24 | for (int col = 0; col < width; col++) { 25 | if (grid[row][col] == 1 && !set.contains(List.of(row, col))) { 26 | set.add(List.of(row, col)); 27 | islandCount = Math.max(bfs(row, col, grid, set), islandCount); 28 | } 29 | } 30 | } 31 | return islandCount; 32 | } 33 | public static int bfs(int row, int col, int[][] grid, Set < List < Integer >> set) { 34 | int width = grid[0].length; 35 | int height = grid.length; 36 | int count = 1; 37 | 38 | Queue < List < Integer >> q = new ArrayDeque < > (); 39 | q.add(List.of(row, col)); 40 | while (!q.isEmpty()) { 41 | List < Integer > coordinates = q.remove(); 42 | int tempRow = coordinates.get(0); 43 | int tempCol = coordinates.get(1); 44 | 45 | 46 | if (!set.contains(List.of(tempRow + 1, tempCol)) && tempRow + 1 < height && grid[tempRow + 1][tempCol] == 1) { 47 | set.add(List.of(tempRow + 1, tempCol)); 48 | q.add(List.of(tempRow + 1, tempCol)); 49 | count++; 50 | } 51 | 52 | if (!set.contains(List.of(tempRow, tempCol + 1)) && tempCol + 1 < width && grid[tempRow][tempCol + 1] == 1) { 53 | set.add(List.of(tempRow, tempCol + 1)); 54 | q.add(List.of(tempRow, tempCol + 1)); 55 | count++; 56 | } 57 | 58 | if (!set.contains(List.of(tempRow, tempCol - 1)) && tempCol - 1 > -1 && grid[tempRow][tempCol - 1] == 1) { 59 | set.add(List.of(tempRow, tempCol - 1)); 60 | q.add(List.of(tempRow, tempCol - 1)); 61 | count++; 62 | } 63 | 64 | if (!set.contains(List.of(tempRow - 1, tempCol)) && tempRow - 1 > -1 && grid[tempRow - 1][tempCol] == 1) { 65 | set.add(List.of(tempRow - 1, tempCol)); 66 | q.add(List.of(tempRow - 1, tempCol)); 67 | count++; 68 | } 69 | } 70 | return count; 71 | 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/MaximumDepthOfBinaryTree.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /**Problem statement: 7 | Given the root of a binary tree, return its maximum depth. 8 | 9 | A binary tree's maximum depth is the number of nodes along the longest path from the root node down to the farthest 10 | leaf node. 11 | 12 | Leetcode link: https://leetcode.com/problems/maximum-depth-of-binary-tree/description/ 13 | **/ 14 | 15 | public class MaximumDepthOfBinaryTree { 16 | public int maxDepth(TreeNode root) { 17 | if(root == null){ 18 | return 0; 19 | } 20 | if(root.right == null && root.left == null){ 21 | return 1; 22 | } 23 | int left = 1 + maxDepth(root.left); 24 | int right = 1 + maxDepth(root.right); 25 | return Math.max(left, right); 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/MergeTwoSortedLists.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | You are given the heads of two sorted linked lists list1 and list2. 5 | 6 | Merge the two lists in a one sorted list. The list should be made by splicing together the nodes of the first two lists. 7 | 8 | Return the head of the merged linked list. 9 | 10 | Example 1: 11 | Input: list1 = [1,2,4], list2 = [1,3,4] 12 | Output: [1,1,2,3,4,4] 13 | Example 2: 14 | 15 | Input: list1 = [], list2 = [] 16 | Output: [] 17 | Example 3: 18 | 19 | Input: list1 = [], list2 = [0] 20 | Output: [0] 21 | 22 | Constraints: 23 | The number of nodes in both lists is in the range [0, 50]. 24 | -100 <= Node.val <= 100 25 | Both list1 and list2 are sorted in non-decreasing order. 26 | 27 | Leetcode link: https://leetcode.com/problems/merge-two-sorted-lists/ 28 | **/ 29 | public class MergeTwoSortedLists { 30 | public ListNode mergeTwoLists(ListNode list1, ListNode list2) { 31 | return mergeTheTwoLists(list1, list2); 32 | } 33 | public static ListNode mergeTheTwoLists(ListNode list1, ListNode list2) { 34 | if (list1 == null && list2 == null) { 35 | return null; 36 | } 37 | if (list1 != null && list2 == null) { 38 | return list1; 39 | } 40 | if (list2 != null && list1 == null) { 41 | return list2; 42 | } 43 | 44 | if (list1.next == null && list2.next == null) { 45 | if (list1.val < list2.val) { 46 | list1.next = list2; 47 | return list1; 48 | } else { 49 | list2.next = list1; 50 | return list2; 51 | } 52 | } 53 | 54 | if (list1.val < list2.val) { 55 | list1.next = mergeTheTwoLists(list1.next, list2); 56 | return list1; 57 | } else { 58 | list2.next = mergeTheTwoLists(list1, list2.next); 59 | return list2; 60 | } 61 | } 62 | } 63 | 64 | class ListNode { 65 | int val; 66 | ListNode next; 67 | ListNode() {} 68 | ListNode(int val) { this.val = val; } 69 | ListNode(int val, ListNode next) { this.val = val; this.next = next; } 70 | } 71 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/MinimumDepthOfBinaryTree.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | /**Problem statement: 3 | Given a binary tree, find its minimum depth. 4 | 5 | The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. 6 | 7 | Note: A leaf is a node with no children. 8 | 9 | Example 1: 10 | Input: root = [3,9,20,null,null,15,7] 11 | Output: 2 12 | 13 | Example 2: 14 | Input: root = [2,null,3,null,4,null,5,null,6] 15 | Output: 5 16 | 17 | Constraints: 18 | The number of nodes in the tree is in the range [0, 105]. 19 | -1000 <= Node.val <= 1000 20 | 21 | 22 | Leetcode link:https://leetcode.com/problems/minimum-depth-of-binary-tree/description/ 23 | **/ 24 | public class MinimumDepthOfBinaryTree { 25 | public int minDepth(TreeNode root) { 26 | if (root == null) { 27 | return 0; 28 | } 29 | if (root.left == null && root.right == null) { 30 | return 1; 31 | } 32 | int left = Integer.MAX_VALUE; 33 | int right = Integer.MAX_VALUE; 34 | if (root.left != null) { 35 | left = 1 + minDepth(root.left); 36 | } 37 | if (root.right != null) { 38 | right = 1 + minDepth(root.right); 39 | } 40 | return Math.min(left, right); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/NaryTreePostorderTraversal.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /**Problem statement: 7 | Given the root of an n-ary tree, return the postorder traversal of its nodes' values. 8 | 9 | Nary-Tree input serialization is represented in their level order traversal. Each group 10 | of children is separated by the null value. 11 | 12 | Leetcode link: https://leetcode.com/problems/n-ary-tree-postorder-traversal/description/ 13 | **/ 14 | 15 | public class NaryTreePostorderTraversal { 16 | 17 | public List< Integer > postorder(Node root) { 18 | List < Integer > result = new ArrayList< >(); 19 | if (root == null) { 20 | return result; 21 | } 22 | for (Node n: root.children) { 23 | result.addAll(postorder(n)); 24 | } 25 | result.add(root.val); 26 | return result; 27 | 28 | } 29 | } 30 | class Node { 31 | public int val; 32 | public List children; 33 | 34 | public Node() {} 35 | 36 | public Node(int _val) { 37 | val = _val; 38 | } 39 | 40 | public Node(int _val, List _children) { 41 | val = _val; 42 | children = _children; 43 | } 44 | }; -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/NaryTreePreorderTraversal.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.ArrayList; 3 | import java.util.List; 4 | 5 | /**Problem statement: 6 | Given the root of an n-ary tree, return the preorder traversal of its nodes' values. 7 | 8 | Nary-Tree input serialization is represented in their level order traversal. Each group of children is 9 | separated by the null value 10 | 11 | Leetcode link: https://leetcode.com/problems/n-ary-tree-preorder-traversal/description/ 12 | **/ 13 | 14 | 15 | public class NaryTreePreorderTraversal { 16 | 17 | public List preorder(Node root) { 18 | 19 | List result = new ArrayList<>(); 20 | if(root == null){ 21 | return result; 22 | } 23 | result.add(root.val); 24 | //traverse the list of children 25 | for(Node n: root.children){ 26 | result.addAll(preorder(n)); 27 | } 28 | return result; 29 | } 30 | } 31 | 32 | //Definition for Node class can be found in "N-ary Tree Post Order Traversal" -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/NumberOfIslands.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | /**Problem statement: 3 | Given an m x n 2D binary grid grid which represents a map of '1's (land) and '0's (water), return the number of islands. 4 | 5 | An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water. 6 | 7 | Example 1: 8 | Input: grid = [ 9 | ["1","1","1","1","0"], 10 | ["1","1","0","1","0"], 11 | ["1","1","0","0","0"], 12 | ["0","0","0","0","0"] 13 | ] 14 | Output: 1 15 | 16 | Example 2: 17 | Input: grid = [ 18 | ["1","1","0","0","0"], 19 | ["1","1","0","0","0"], 20 | ["0","0","1","0","0"], 21 | ["0","0","0","1","1"] 22 | ] 23 | Output: 3 24 | 25 | Constraints: 26 | m == grid.length 27 | n == grid[i].length 28 | 1 <= m, n <= 300 29 | grid[i][j] is '0' or '1'. 30 | 31 | Leetcode link: https://leetcode.com/problems/number-of-islands/description/ 32 | **/ 33 | public class NumberOfIslands { 34 | public int numIslands(char[][] grid) { 35 | int width = grid[0].length; 36 | int height = grid.length; 37 | int count = 0; 38 | 39 | for (int row = 0; row < height; row++) { 40 | for (int col = 0; col < width; col++) { 41 | if (grid[row][col] == '1') { 42 | count++; 43 | dfs(grid, row, col); 44 | } 45 | } 46 | } 47 | return count; 48 | } 49 | public static void dfs(char[][] grid, int row, int col) { 50 | if (isOutOfBounds(row, col, grid)) { 51 | return; 52 | } 53 | if (grid[row][col] == '0') { 54 | return; 55 | } 56 | grid[row][col] = '0'; 57 | dfs(grid, row + 1, col); 58 | dfs(grid, row - 1, col); 59 | dfs(grid, row, col + 1); 60 | dfs(grid, row, col - 1); 61 | } 62 | public static boolean isOutOfBounds(int row, int col, char[][] grid) { 63 | return row < 0 || col < 0 || row >= grid.length || col >= grid[0].length; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/PalindromeLinkedListRecursion.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given the head of a singly linked list, return true if it is a 5 | palindrome 6 | or false otherwise. 7 | 8 | Example 1: 9 | Input: head = [1,2,2,1] 10 | Output: true 11 | 12 | Example 2: 13 | Input: head = [1,2] 14 | Output: false 15 | 16 | Constraints: 17 | The number of nodes in the list is in the range [1, 105]. 18 | 0 <= Node.val <= 9 19 | 20 | Leetcode link: https://leetcode.com/problems/palindrome-linked-list/description/ 21 | **/ 22 | public class PalindromeLinkedListRecursion { 23 | ListNode node; 24 | 25 | public boolean isPalindrome(ListNode head) { 26 | if (head == null) { 27 | return true; 28 | } 29 | if (node == null) { 30 | node = head; 31 | } 32 | boolean isPal = isPalindrome(head.next); 33 | if (node.val == head.val) { 34 | node = node.next; 35 | } else { 36 | return false; 37 | } 38 | return isPal; 39 | } 40 | } -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/PathSum.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | 4 | /**Problem statement: 5 | Given the root of a binary tree and an integer targetSum, return true if the tree has a root-to-leaf path such that adding up all the values along the path equals targetSum. 6 | 7 | A leaf is a node with no children. 8 | 9 | Example 1: 10 | Input: root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22 11 | Output: true 12 | Explanation: The root-to-leaf path with the target sum is shown. 13 | 14 | Example 2: 15 | Input: root = [1,2,3], targetSum = 5 16 | Output: false 17 | Explanation: There two root-to-leaf paths in the tree: 18 | (1 --> 2): The sum is 3. 19 | (1 --> 3): The sum is 4. 20 | There is no root-to-leaf path with sum = 5. 21 | 22 | Example 3: 23 | Input: root = [], targetSum = 0 24 | Output: false 25 | Explanation: Since the tree is empty, there are no root-to-leaf paths. 26 | Constraints: 27 | 28 | The number of nodes in the tree is in the range [0, 5000]. 29 | -1000 <= Node.val <= 1000 30 | -1000 <= targetSum <= 1000 31 | 32 | Leetcode link: https://leetcode.com/problems/path-sum/description/ 33 | **/ 34 | public class PathSum { 35 | public boolean hasPathSum(TreeNode root, int targetSum) { 36 | return pathSum(root, targetSum); 37 | } 38 | public static boolean pathSum(TreeNode root, int targetSum) { 39 | if (root == null) { 40 | return false; 41 | } 42 | if (root.left == null && root.right == null) { 43 | return targetSum - root.val == 0; 44 | } 45 | boolean left = pathSum(root.right, targetSum - root.val); 46 | boolean right = pathSum(root.left, targetSum - root.val); 47 | return left || right; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/PostOrderTraversal.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.io.*; 3 | import java.util.*; 4 | /**Problem statement: 5 | Given the root of a binary tree, return the postorder traversal of its nodes' values. 6 | 7 | Leetcode link: https://leetcode.com/problems/binary-tree-postorder-traversal/description/ 8 | **/ 9 | public class PostOrderTraversal { 10 | public List postorderTraversal(TreeNode root) { 11 | List result = new ArrayList<>(); 12 | 13 | if(root == null){ 14 | return result; 15 | } 16 | 17 | result.addAll(postorderTraversal(root.left)); 18 | result.addAll(postorderTraversal(root.right)); 19 | result.add(root.val); 20 | 21 | return result; 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/PostOrderTraversalWithListAsAParameter.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given the root of a binary tree, return the postorder traversal of its nodes' values. 5 | 6 | Leetcode link: https://leetcode.com/problems/binary-tree-postorder-traversal/description/ 7 | **/ 8 | 9 | public class PostOrderTraversalWithListAsAParameter { 10 | public List postorderTraversal(TreeNode root) { 11 | List result = new ArrayList<>(); 12 | postorderTraversal(root, result); 13 | return result; 14 | } 15 | 16 | public static void postorderTraversal(TreeNode root, List result ){ 17 | if(root == null){ 18 | return; 19 | } 20 | postorderTraversal(root.left, result); 21 | postorderTraversal(root.right,result); 22 | result.add(root.val); 23 | return; 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/PowerOfTwo.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given an integer n, return true if it is a power of two. Otherwise, return false. 5 | 6 | An integer n is a power of two, if there exists an integer x such that n == 2x. 7 | Example 1: 8 | 9 | Input: n = 1 10 | Output: true 11 | Explanation: 20 = 1 12 | Example 2: 13 | 14 | Input: n = 16 15 | Output: true 16 | Explanation: 24 = 16 17 | 18 | Leetcode link: https://leetcode.com/problems/power-of-two/description/ 19 | **/ 20 | 21 | public class PowerOfTwo { 22 | public boolean isPowerOfTwo(int n) { 23 | if (n == 0) { 24 | return false; 25 | } 26 | if (n == 1) { 27 | return true; 28 | } 29 | if (n % 2 != 0) { 30 | return false; 31 | } 32 | return isPowerOfTwo(n / 2); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/PreOrderTraversal.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | 3 | import java.io.*; 4 | import java.util.*; 5 | /**Problem statement: 6 | Given the root of a binary tree, return the preorder traversal of its nodes' values. 7 | 8 | Leetcode link: https://leetcode.com/problems/binary-tree-preorder-traversal/description/ 9 | **/ 10 | 11 | public class PreOrderTraversal { 12 | public List preorderTraversal(TreeNode root) { 13 | List result = new ArrayList<>(); 14 | if( root == null){ 15 | return result; 16 | } 17 | 18 | result.add(root.val); 19 | result.addAll(preorderTraversal(root.left)); 20 | result.addAll(preorderTraversal(root.right)); 21 | 22 | return result; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/RangeSumOfBST.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | 3 | import java.util.*; 4 | /**Problem statement: 5 | Given the root node of a binary search tree and two integers low and high, return the sum of values of all nodes with a value in the inclusive range [low, high]. 6 | 7 | Example 1: 8 | Input: root = [10,5,15,3,7,null,18], low = 7, high = 15 9 | Output: 32 10 | Explanation: Nodes 7, 10, and 15 are in the range [7, 15]. 7 + 10 + 15 = 32. 11 | 12 | Example 2: 13 | Input: root = [10,5,15,3,7,13,18,1,null,6], low = 6, high = 10 14 | Output: 23 15 | Explanation: Nodes 6, 7, and 10 are in the range [6, 10]. 6 + 7 + 10 = 23. 16 | 17 | Constraints: 18 | The number of nodes in the tree is in the range [1, 2 * 104]. 19 | 1 <= Node.val <= 105 20 | 1 <= low <= high <= 105 21 | All Node.val are unique. 22 | 23 | Leetcode link: https://leetcode.com/problems/range-sum-of-bst/description/ 24 | **/ 25 | public class RangeSumOfBST { 26 | 27 | public int rangeSumBST(TreeNode root, int low, int high) { 28 | if (root == null) { 29 | return 0; 30 | } 31 | int left = rangeSumBST(root.left, low, high); 32 | int right = rangeSumBST(root.right, low, high); 33 | if (isInRange(root.val, low, high)) { 34 | return root.val + left + right; 35 | } else { 36 | return left + right; 37 | } 38 | } 39 | public static boolean isInRange(int n, int low, int high) { 40 | return n >= low && n <= high; 41 | } 42 | } -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/ReverseStringRecursively.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.ArrayList; 3 | import java.util.List; 4 | 5 | /**Problem statement: 6 | Given a String, create a method that reverse the String recursively **/ 7 | public class ReverseStringRecursively { 8 | static public void main( String args[] ) { 9 | String result = reverseString("Avery", 4); 10 | 11 | System.out.print(result); 12 | } 13 | //Solution 1 - using .substring 14 | public static String reverseString( String s){ 15 | String result = ""; 16 | if(s.length() <= 0){ 17 | return result; 18 | } 19 | 20 | result = s.substring(s.length()-1) + reverseString(s.substring(0,s.length()-1) ); 21 | 22 | return result; 23 | } 24 | //Solution 2 - passing in an index 25 | public static String reverseString(String s, int index){ 26 | String result =""; 27 | if( index <0){ 28 | return result; 29 | } 30 | result = s.charAt(index)+ reverseString(s, index-1); 31 | return result; 32 | 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/RopeTreeNode.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | 3 | public class RopeTreeNode { 4 | int len; 5 | String val; 6 | RopeTreeNode left; 7 | RopeTreeNode right; 8 | RopeTreeNode() {} 9 | RopeTreeNode(String val) { 10 | this.len = 0; 11 | this.val = val; 12 | } 13 | RopeTreeNode(int len) { 14 | this.len = len; 15 | this.val = ""; 16 | } 17 | RopeTreeNode(int len, RopeTreeNode left, RopeTreeNode right) { 18 | this.len = len; 19 | this.val = ""; 20 | this.left = left; 21 | this.right = right; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/SameTree.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given the roots of two binary trees p and q, write a function to check if they are the same or not. 5 | 6 | Two binary trees are considered the same if they are structurally identical, and the nodes have the same value. 7 | 8 | Example 1: 9 | Input: p = [1,2,3], q = [1,2,3] 10 | Output: true 11 | 12 | Example 2: 13 | Input: p = [1,2], q = [1,null,2] 14 | Output: false 15 | 16 | Example 3: 17 | Input: p = [1,2,1], q = [1,1,2] 18 | Output: false 19 | 20 | Constraints: 21 | The number of nodes in both trees is in the range [0, 100]. 22 | -104 <= Node.val <= 104 23 | 24 | Leetcode link: https://leetcode.com/problems/same-tree/description/ 25 | **/ 26 | public class SameTree { 27 | public boolean isSameTree(TreeNode p, TreeNode q) { 28 | if (p == null || q == null) { 29 | return p == q; 30 | } 31 | if (p.val != q.val) { 32 | return false; 33 | } 34 | return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/SearchA2DMatrix.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | You are given an m x n integer matrix matrix with the following two properties: 5 | 6 | Each row is sorted in non-decreasing order. 7 | The first integer of each row is greater than the last integer of the previous row. 8 | Given an integer target, return true if target is in matrix or false otherwise. 9 | 10 | You must write a solution in O(log(m * n)) time complexity. 11 | Example 1: 12 | Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3 13 | Output: true 14 | 15 | Leetcode link: https://leetcode.com/problems/search-a-2d-matrix/description/ 16 | **/ 17 | public class SearchA2DMatrix { 18 | public boolean searchMatrix(int[][] matrix, int target) { 19 | for (int row = 0; row < matrix.length; row++) { 20 | if (bSearch(0, matrix[0].length, matrix[row], target) == 1) { 21 | return true; 22 | } 23 | } 24 | return false; 25 | } 26 | public static int bSearch(int begin, int end, int[] row, int target) { 27 | int middle = (begin + end) / 2; 28 | 29 | if (row[middle] == target) { 30 | return 1; 31 | } 32 | if (middle == begin || middle == end) { 33 | return 0; 34 | } else if (row[middle] > target) { 35 | end = middle; 36 | } else if (row[middle] < target) { 37 | begin = middle + 1; 38 | } 39 | if (middle == row.length || begin == row.length) { 40 | return 0; 41 | } 42 | return bSearch(begin, end, row, target); 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/SumOfLeftLeaves.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | /**Problem statement: 3 | Given the root of a binary tree, return the sum of all left leaves. 4 | 5 | A leaf is a node with no children. A left leaf is a leaf that is the left child of another node. 6 | 7 | Example 1: 8 | Input: root = [3,9,20,null,null,15,7] 9 | Output: 24 10 | Explanation: There are two left leaves in the binary tree, with values 9 and 15 respectively. 11 | 12 | Example 2: 13 | Input: root = [1] 14 | Output: 0 15 | Constraints: 16 | 17 | The number of nodes in the tree is in the range [1, 1000]. 18 | -1000 <= Node.val <= 1000 19 | 20 | Leetcode link: https://leetcode.com/problems/sum-of-left-leaves/description/ 21 | **/ 22 | public class SumOfLeftLeaves { 23 | public int sumOfLeftLeaves(TreeNode root) { 24 | return sumLeft(root); 25 | } 26 | 27 | public static int sumLeft(TreeNode root) { 28 | 29 | if (root == null) { 30 | return 0; 31 | } 32 | 33 | if (root.left == null) { 34 | return sumLeft(root.right); 35 | } 36 | 37 | int left = sumLeft(root.left); 38 | int right = sumLeft(root.right); 39 | 40 | if (root.left.left == null && root.left.right == null) { 41 | return root.left.val + right + left; 42 | } else { 43 | return right + left; 44 | } 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/SumOfNodesWithEvenValuedGrandparent.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | 4 | /**Problem statement: 5 | Given the root of a binary tree, return the sum of values of nodes with an even-valued grandparent. If there are no nodes with an even-valued grandparent, return 0. 6 | 7 | A grandparent of a node is the parent of its parent if it exists. 8 | Example 1: 9 | Input: root = [6,7,8,2,7,1,3,9,null,1,4,null,null,null,5] 10 | Output: 18 11 | Explanation: The red nodes are the nodes with even-value grandparent while the blue nodes are the even-value grandparents. 12 | 13 | Example 2: 14 | Input: root = [1] 15 | Output: 0 16 | 17 | Constraints: 18 | The number of nodes in the tree is in the range [1, 104]. 19 | 1 <= Node.val <= 100 20 | 21 | Leetcode link: https://leetcode.com/problems/sum-of-nodes-with-even-valued-grandparent/ 22 | **/ 23 | 24 | 25 | public class SumOfNodesWithEvenValuedGrandparent { 26 | public int sumEvenGrandparent(TreeNode root) { 27 | if (root == null) { 28 | return 0; 29 | } 30 | int sum = 0; 31 | if(root.val % 2 == 0 ){ 32 | if (root.left != null) { 33 | sum += sumAllChildrenOfNode(root.left); 34 | } 35 | if (root.right != null) { 36 | sum += sumAllChildrenOfNode(root.right); 37 | } 38 | } 39 | int result = sumEvenGrandparent(root.left) + sumEvenGrandparent(root.right); 40 | return sum + result ; 41 | } 42 | 43 | public static int sumAllChildrenOfNode(TreeNode root) { 44 | int sum = 0; 45 | if (root.left != null) { 46 | sum += root.left.val; 47 | } 48 | if (root.right != null) { 49 | sum += root.right.val; 50 | } 51 | return sum; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/SumOfRootToLeafBinaryNumbers.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | 4 | /**Problem statement: 5 | Given an integer array nums of length n, you want to create an array ans of length 2n where ans[i] == nums[i] and ans[i + n] == nums[i] for 0 <= i < n (0-indexed). 6 | 7 | Specifically, ans is the concatenation of two nums arrays. 8 | 9 | Return the array ans. 10 | Example 1: 11 | 12 | Input: nums = [1,2,1] 13 | Output: [1,2,1,1,2,1] 14 | Explanation: The array ans is formed as follows: 15 | - ans = [nums[0],nums[1],nums[2],nums[0],nums[1],nums[2]] 16 | - ans = [1,2,1,1,2,1] 17 | Example 2: 18 | 19 | Input: nums = [1,3,2,1] 20 | Output: [1,3,2,1,1,3,2,1] 21 | Explanation: The array ans is formed as follows: 22 | - ans = [nums[0],nums[1],nums[2],nums[3],nums[0],nums[1],nums[2],nums[3]] 23 | - ans = [1,3,2,1,1,3,2,1] 24 | 25 | 26 | Constraints: 27 | n == nums.length 28 | 1 <= n <= 1000 29 | 1 <= nums[i] <= 1000 30 | 31 | Leetcode link: https://leetcode.com/problems/sum-of-root-to-leaf-binary-numbers/description/ 32 | **/ 33 | public class SumOfRootToLeafBinaryNumbers { 34 | List < String > binaryList = new ArrayList < > (); 35 | public int sumRootToLeaf(TreeNode root) { 36 | 37 | addToList(root, ""); 38 | int sum = 0; 39 | for (String s: binaryList) { 40 | int temp = Integer.parseInt(s, 2); 41 | sum += temp; 42 | } 43 | return sum; 44 | } 45 | public void addToList(TreeNode root, String number) { 46 | if (root == null) { 47 | return; 48 | } 49 | if (root.left == null && root.right == null) { 50 | number = number + String.valueOf(root.val); 51 | binaryList.add(number); 52 | return; 53 | } 54 | number = number + String.valueOf(root.val); 55 | addToList(root.left, number); 56 | addToList(root.right, number); 57 | } 58 | } 59 | 60 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/SumRootToLeafNumbers.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | You are given the root of a binary tree containing digits from 0 to 9 only. 5 | 6 | Each root-to-leaf path in the tree represents a number. 7 | 8 | For example, the root-to-leaf path 1 -> 2 -> 3 represents the number 123. 9 | Return the total sum of all root-to-leaf numbers. Test cases are generated so that the answer will fit in a 32-bit integer. 10 | 11 | A leaf node is a node with no children. 12 | Example 1: 13 | 14 | Input: root = [1,2,3] 15 | Output: 25 16 | Explanation: 17 | The root-to-leaf path 1->2 represents the number 12. 18 | The root-to-leaf path 1->3 represents the number 13. 19 | Therefore, sum = 12 + 13 = 25. 20 | 21 | Constraints: 22 | The number of nodes in the tree is in the range [1, 1000]. 23 | 0 <= Node.val <= 9 24 | The depth of the tree will not exceed 10. 25 | 26 | Leetcode link: https://leetcode.com/problems/sum-root-to-leaf-numbers/description/ 27 | **/ 28 | public class SumRootToLeafNumbers { 29 | 30 | public int sumNumbers(TreeNode root) { 31 | int result = sumNumbers(root, 0); 32 | return result; 33 | } 34 | public int sumNumbers(TreeNode A, int sum) { 35 | if (A.left == null && A.right == null) { 36 | return ((sum * 10) + A.val); 37 | } 38 | if (A.left != null && A.right != null) { 39 | int left = sumNumbers(A.left, (sum * 10) + A.val); 40 | int right = sumNumbers(A.right, (sum * 10) + A.val); 41 | return left + right; 42 | } else if (A.left != null) { 43 | return sumNumbers(A.left, (sum * 10) + A.val); 44 | } else { 45 | return sumNumbers(A.right, (sum * 10) + A.val); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/SumUpArrayRecursively.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.ArrayList; 3 | import java.util.List; 4 | 5 | /**Problem statement: 6 | Given an array of ints, sum up the array using tail recursion**/ 7 | 8 | public class SumUpArrayRecursively { 9 | 10 | static public void main( String args[] ) { 11 | int [] nums = new int []{2,7,10,3}; 12 | 13 | System.out.print("The sum of the array is "+ sumArray(nums,0) +"."); 14 | 15 | } 16 | /**The implementation of this method includes tail recursion, meaning that the recursive call is at the tail end/ 17 | * no additional operations are being done after the recursive call. 18 | * 19 | * A helpful way to think about this is that in this call, I'm adding the element that I'm on (nums[index]) and 20 | * trusting the recursive call to sum up the remainder of the array. 21 | * 22 | * */ 23 | public static int sumArray( int[] nums, int index){ 24 | if(index == nums.length){ 25 | return 0; 26 | } 27 | 28 | return nums[index]+ sumArray(nums, index +1); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/SumUpArrayWithHeadRecursion.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | /**Problem statement: 3 | Given an array of ints, sum up the array using head recursion**/ 4 | public class SumUpArrayWithHeadRecursion { 5 | public static void main(String[] args) { 6 | int [] nums = new int []{2,7,10,3}; 7 | 8 | System.out.print("The sum of the array is "+ sumArray(nums,0) +"."); 9 | } 10 | 11 | /**The implementation of this method includes head/non-tail recursion, meaning that the recursive call does not come 12 | * at the end of the method and that there are operations being performed after the recursive call. 13 | * 14 | * In this case, the recursive calls go to the end of the call stack and the sum is calculated on the way back. 15 | * 16 | * */ 17 | public static int sumArray(int [] nums, int index){ 18 | 19 | if( index == nums.length){ 20 | return 0; 21 | } 22 | int temp = nums[index]; 23 | 24 | int total = sumArray(nums, index +1); 25 | return total +temp; 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/SumUpTwoDArrayRecursively.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.io.*; 3 | import java.util.*; 4 | /**Problem statement: 5 | Given a 2D array of ints, sum up the array recursively **/ 6 | 7 | public class SumUpTwoDArrayRecursively { 8 | static public void main( String args[] ) { 9 | int[][] nums = new int[][]{ 10 | {2, 7, 9}, 11 | {3, 0, 1}, 12 | {2, 3, 9} 13 | }; 14 | Set> set = new HashSet<>(); 15 | System.out.print("The sum of the 2D array is " + sumArray(nums, 0, 0, set)); 16 | } 17 | 18 | public static int sumArray( int [][] nums, int row, int col, Set> set){ 19 | int width= nums[0].length; 20 | int height = nums.length; 21 | 22 | if(row>= height || col >= width){ 23 | return 0; 24 | } 25 | if(set.contains(List.of(row,col))){ 26 | return 0; 27 | } 28 | set.add(List.of(row, col)); 29 | return nums [row][col]+ sumArray(nums,row, col+1,set) + sumArray(nums,row+1, col,set); 30 | 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/TwoSumIVInputIsABST.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | 3 | import java.io.*; 4 | import java.util.*; 5 | /**Problem statement: 6 | Given the root of a binary search tree and an integer k, return true if there exist two elements in the BST such that their sum is equal to k, or false otherwise. 7 | 8 | Constraints: 9 | 10 | The number of nodes in the tree is in the range [1, 104]. 11 | -104 <= Node.val <= 104 12 | root is guaranteed to be a valid binary search tree. 13 | -105 <= k <= 105 14 | Leetcode https://leetcode.com/problems/two-sum-iv-input-is-a-bst/description/ 15 | **/ 16 | 17 | public class TwoSumIVInputIsABST { 18 | public boolean findTarget(TreeNode root, int k) { 19 | List result = findTargets(root,k); 20 | for(Integer l: result){ 21 | System.out.println(l); 22 | } 23 | 24 | for( int i = 0, j = result.size()-1 ; i-1 && i k){ 32 | j--; 33 | } 34 | } 35 | return false; 36 | } 37 | public List findTargets(TreeNode root, int k) { 38 | List result = new ArrayList<>(); 39 | 40 | if(root == null){ 41 | return result; 42 | } 43 | result.addAll(findTargets(root.left,k)); 44 | result.add(root.val); 45 | result.addAll( findTargets( root.right, k)); 46 | return result; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/UnivaluedBinaryTree.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.io.*; 3 | import java.util.*; 4 | /**Problem statement: 5 | A binary tree is uni-valued if every node in the tree has the same value. 6 | 7 | Given the root of a binary tree, return true if the given tree is uni-valued, or false otherwise. 8 | 9 | Constraints: 10 | 11 | The number of nodes in the tree is in the range [1, 100]. 12 | 0 <= Node.val < 100 13 | 14 | Leetcode link: https://leetcode.com/problems/univalued-binary-tree/description/ 15 | **/ 16 | public class UnivaluedBinaryTree { 17 | public boolean isUnivalTree(TreeNode root) { 18 | 19 | return isUnivalTree(root, root.val); 20 | } 21 | public boolean isUnivalTree(TreeNode root, int value ) { 22 | 23 | if( root == null){ 24 | return true; 25 | } 26 | 27 | if( root.val != value ){ 28 | return false; 29 | } 30 | boolean left = isUnivalTree(root.left, root.val); 31 | boolean right =isUnivalTree(root.right, root.val); 32 | 33 | return left && right; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/WordSearch.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given an m x n grid of characters board and a string word, return true if word exists in the grid. 5 | 6 | The word can be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once. 7 | 8 | Example 1: 9 | Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED" 10 | Output: true 11 | 12 | Example 2: 13 | Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE" 14 | Output: true 15 | 16 | Example 3: 17 | Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB" 18 | Output: false 19 | 20 | Constraints: 21 | m == board.length 22 | n = board[i].length 23 | 1 <= m, n <= 6 24 | 1 <= word.length <= 15 25 | board and word consists of only lowercase and uppercase English letters. 26 | Leetcode link: https://leetcode.com/problems/find-the-index-of-the-first-occurrence-in-a-string/description/ 27 | **/ 28 | public class WordSearch { 29 | public boolean exist(char[][] board, String word) { 30 | if (word.length() <= 0) { 31 | return false; 32 | } 33 | int[][] tracker = new int[board.length][board[0].length]; 34 | char firstLetter = word.charAt(0); 35 | for (int row = board.length - 1; row > -1; row--) { 36 | for (int col = board[0].length - 1; col > -1; col--) { 37 | if (board[row][col] == firstLetter) { 38 | if (search(board, word, row, col, 0, tracker)) { 39 | return true; 40 | } 41 | } 42 | } 43 | } 44 | return false; 45 | } 46 | public static boolean search(char[][] board, String word, int row, int col, int index, int[][] tracker) { 47 | if (index == word.length()) { 48 | return true; 49 | } 50 | if (isOutOfBounds(row, col, board)) { 51 | return false; 52 | } 53 | if (tracker[row][col] == 1) { 54 | return false; 55 | } 56 | char letterToFind = word.charAt(index); 57 | if (board[row][col] != letterToFind) { 58 | return false; 59 | } 60 | tracker[row][col] = 1; 61 | //means the letter was found 62 | index++; 63 | boolean left = search(board, word, row, col - 1, index, tracker); 64 | boolean right = search(board, word, row, col + 1, index, tracker); 65 | boolean up = search(board, word, row - 1, col, index, tracker); 66 | boolean down = search(board, word, row + 1, col, index, tracker); 67 | 68 | tracker[row][col] = 0; 69 | 70 | return left || right || up || down; 71 | } 72 | public static boolean isOutOfBounds(int row, int col, char[][] board) { 73 | return col >= board[0].length || row >= board.length || col < 0 || row < 0; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/catDog.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | 3 | /** 4 | * 5 | * To practice recursion, I took this simple codingbat problem and implemented it recursively 6 | * Problem statement: 7 | * 8 | Return true if the string "cat" and "dog" appear the same number of times in the given string. 9 | catDog("catdog") → true 10 | catDog("catcat") → false 11 | catDog("1cat1cadodog") → true 12 | * 13 | Codingbat link: https://codingbat.com/prob/p111624 14 | **/ 15 | public class catDog { 16 | public boolean catDog(String str) { 17 | 18 | return findCount(str, 0) == 0; 19 | 20 | } 21 | 22 | public static int findCount(String str, int index) { 23 | 24 | if (index > str.length() - 3) { 25 | return 0; 26 | } 27 | String check = str.substring(index, index + 3); 28 | 29 | if (check.equals("dog")) { 30 | return 1 + findCount(str, index + 1); 31 | } 32 | 33 | if (check.equals("cat")) { 34 | return -1 + findCount(str, index + 1); 35 | } else { 36 | return findCount(str, index + 1); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/countCode.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | /** 3 | * 4 | * To practice recursion, I took this simple codingbat problem and implemented it recursively, using recursion. 5 | * 6 | * Problem statement: 7 | * 8 | Return the number of times that the string "code" appears anywhere in the given string, except we'll accept 9 | any letter for the 'd', so "cope" and "cooe" count. 10 | 11 | countCode("aaacodebbb") → 1 12 | countCode("codexxcode") → 2 13 | countCode("cozexxcope") → 2 14 | Codingbat link:https://codingbat.com/prob/p123614 15 | **/ 16 | public class countCode { 17 | public int countCode(String str) { 18 | 19 | return countCodes(str, 0); 20 | } 21 | 22 | public int countCode(String str, int index) { 23 | if (index > str.length() - 4) { 24 | return 0; 25 | } 26 | int count = countCode(str, index + 1); 27 | 28 | if (str.substring(index, index + 2).equals("co") && str.charAt(index + 3) == 'e') { 29 | return 1 + count; 30 | } else { 31 | return count; 32 | } 33 | } 34 | 35 | public int countCodes(String str, int index) { 36 | if (index > str.length() - 4) { 37 | return 0; 38 | } 39 | 40 | if (str.substring(index, index + 2).equals("co") && str.charAt(index + 3) == 'e') { 41 | return 1 + countCodes(str, index + 1); 42 | } else { 43 | return countCodes(str, index + 1); 44 | } 45 | 46 | } 47 | } -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/countHi.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | /** 3 | * 4 | * To practice recursion, I took this simple codingbat problem and implemented it recursively, using tail recursion. 5 | * 6 | * Problem statement: 7 | * 8 | Return the number of times that the string "hi" appears anywhere in the given string. 9 | countHi("abc hi ho") → 1 10 | countHi("ABChi hi") → 2 11 | countHi("hihi") → 2 12 | * 13 | Codingbat link: https://codingbat.com/prob/p147448 14 | **/ 15 | public class countHi { 16 | public int countHi(String str) { 17 | return totalHi(str, 0); 18 | } 19 | public int totalHi(String str, int index) { 20 | if (index > str.length() - 2) { 21 | return 0; 22 | } 23 | 24 | int count = totalHi(str, index + 1); 25 | 26 | String check = str.substring(index, index + 2); 27 | if (check.equals("hi")) { 28 | return 1 + count; 29 | } else { 30 | return count; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/dynamicprogramming/CourseSchedule.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems.dynamicprogramming; 2 | import java.util.*; 3 | /**Problem statement: 4 | * 5 | * There are a total of numCourses courses you have to take, labeled from 0 to numCourses - 1. You are given an array prerequisites where prerequisites[i] = [ai, bi] indicates that you must take course bi first if you want to take course ai. 6 | * 7 | * For example, the pair [0, 1], indicates that to take course 0 you have to first take course 1. 8 | * Return true if you can finish all courses. Otherwise, return false. 9 | * 10 | *Example 1: 11 | * Input: numCourses = 2, prerequisites = [[1,0]] 12 | * Output: true 13 | * Explanation: There are a total of 2 courses to take. 14 | * To take course 1 you should have finished course 0. So it is possible. 15 | 16 | * Example 2: 17 | * Input: numCourses = 2, prerequisites = [[1,0],[0,1]] 18 | * Output: false 19 | * Explanation: There are a total of 2 courses to take. 20 | * To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible. 21 | * 22 | * 23 | * Constraints: 24 | * 1 <= numCourses <= 2000 25 | * 0 <= prerequisites.length <= 5000 26 | * prerequisites[i].length == 2 27 | * 0 <= ai, bi < numCourses 28 | * All the pairs prerequisites[i] are unique. 29 | 30 | 31 | Leetcode link: https://leetcode.com/problems/course-schedule/description/ 32 | **/ 33 | public class CourseSchedule { 34 | public boolean canFinish(int numCourses, int[][] prerequisites) { 35 | 36 | if (prerequisites.length < 1) { 37 | return true; 38 | } 39 | Map < Integer, List < Integer >> map = createMap(prerequisites); 40 | Map < Integer, Boolean > storedMap = new HashMap < > (); 41 | boolean[] set = new boolean[numCourses]; 42 | for (int i = 0; i < numCourses; i++) { 43 | if (containsCycle(map, i, set, storedMap)) { 44 | return false; 45 | } 46 | Arrays.fill(set, false); 47 | } 48 | return true; 49 | } 50 | 51 | public static boolean containsCycle(Map < Integer, List < Integer >> map, int course, boolean[] set, Map < Integer, Boolean > storedMap) { 52 | if (storedMap.containsKey(course)) { 53 | return storedMap.get(course); 54 | } 55 | if (!map.containsKey(course)) { 56 | return false; 57 | } 58 | 59 | if (set[course]) { 60 | return true; 61 | } 62 | 63 | set[course] = true; 64 | boolean result = false; 65 | 66 | for (int singleCourse: map.get(course)) { 67 | boolean hasCycle = containsCycle(map, singleCourse, set, storedMap); 68 | if (hasCycle) { 69 | storedMap.put(singleCourse, true); 70 | return true; 71 | } 72 | } 73 | storedMap.put(course, false); 74 | return result; 75 | } 76 | 77 | public static Map < Integer, List < Integer >> createMap(int[][] prerequisites) { 78 | Map < Integer, List < Integer >> map = new HashMap < > (); 79 | 80 | for (int[] nums: prerequisites) { 81 | int key = nums[1]; 82 | if (!map.containsKey(key)) { 83 | map.put(key, List.of(nums[0])); 84 | } else { 85 | List < Integer > temp = new ArrayList < > (map.get(key)); 86 | temp.add(nums[0]); 87 | map.put(key, temp); 88 | } 89 | } 90 | return map; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/dynamicprogramming/MinCostClimbingStairs.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems.dynamicprogramming; 2 | import java.util.*; 3 | /**Problem statement: 4 | You are given an integer array cost where cost[i] is the cost of ith step on a staircase. Once you pay the cost, you can either climb one or two steps. 5 | 6 | You can either start from the step with index 0, or the step with index 1. 7 | 8 | Return the minimum cost to reach the top of the floor. 9 | Example 1: 10 | 11 | Input: cost = [10,15,20] 12 | Output: 15 13 | Explanation: You will start at index 1. 14 | - Pay 15 and climb two steps to reach the top. 15 | The total cost is 15. 16 | Example 2: 17 | 18 | Input: cost = [1,100,1,1,1,100,1,1,100,1] 19 | Output: 6 20 | Explanation: You will start at index 0. 21 | - Pay 1 and climb two steps to reach index 2. 22 | - Pay 1 and climb two steps to reach index 4. 23 | - Pay 1 and climb two steps to reach index 6. 24 | - Pay 1 and climb one step to reach index 7. 25 | - Pay 1 and climb two steps to reach index 9. 26 | - Pay 1 and climb one step to reach the top. 27 | The total cost is 6. 28 | 29 | Constraints: 30 | 2 <= cost.length <= 1000 31 | 0 <= cost[i] <= 999 32 | Leetcode link: https://leetcode.com/problems/min-cost-climbing-stairs/description/ 33 | **/ 34 | public class MinCostClimbingStairs {public int minCostClimbingStairs(int[] cost) { 35 | Map < Integer, Integer > map = new HashMap < > (); 36 | return Math.min(getMinCost(cost, 0, map), getMinCost(cost, 1, map)); 37 | } 38 | public static int getMinCost(int[] cost, int index, Map < Integer, Integer > map) { 39 | if (index == cost.length) { 40 | return 0; 41 | } 42 | if (index == cost.length - 1) { 43 | return cost[index]; 44 | } 45 | if (map.containsKey(index)) { 46 | return map.get(index); 47 | } 48 | int one = getMinCost(cost, index + 1, map); 49 | int two = getMinCost(cost, index + 2, map); 50 | int result = Math.min(one, two) + cost[index]; 51 | map.put(index, result); 52 | return result; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/com/practice/recursionproblems/sumAllNumbersUsingDFS.java: -------------------------------------------------------------------------------- 1 | package com.practice.recursionproblems; 2 | import java.util.*; 3 | 4 | /** 5 | * Problem statement: 6 | * Create a 2D array of characcters with periods and numbers. Recursively sum up all of the numbers in the array. 7 | *

8 | * This is a problem I created for myself, in order to practice depth first search. 9 | **/ 10 | public class sumAllNumbersUsingDFS { 11 | public static void main(String[] args) { 12 | char [][] board ={ 13 | {'.','.','2','.'}, 14 | {'.','9','.','.'}, 15 | {'.','.','2','.'} 16 | }; 17 | Set> set = new HashSet<>(); 18 | System.out.println(sumDigits(board, 0,0,set)); 19 | 20 | } 21 | public static int sumDigits( char [][] board, int row, int col, Set> set){ 22 | if(isOutofBounds(row,col, board)){ 23 | return 0; 24 | } 25 | if(set.contains(List.of(row,col))){ 26 | return 0; 27 | } 28 | set.add(List.of(row, col)); 29 | 30 | char current = board[row][col]; 31 | 32 | int right = sumDigits(board,row,col+1, set); 33 | int down = sumDigits(board, row+1, col, set); 34 | 35 | if(Character.isDigit(current)){ 36 | return Character.getNumericValue(current) +right +down ; 37 | }else{ 38 | return right +down; 39 | } 40 | } 41 | public static boolean isOutofBounds(int row, int col, char[][] board){ 42 | int width = board[0].length; 43 | int height = board.length; 44 | return row <0 || row >= height || col<0 || col >= width; 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/com/practice/simulationproblems/Solution.java: -------------------------------------------------------------------------------- 1 | package com.practice.simulationproblems; 2 | /* 3 | * Click `Run` to execute the snippet below! 4 | */ 5 | import java.util.List; 6 | import java.io.*; 7 | import java.util.*; 8 | 9 | /* 10 | * To execute Java, please define "static void main" on a class 11 | * named Solution. 12 | * 13 | * If you need more classes, simply define them inline. 14 | */ 15 | 16 | class Solution { 17 | public static void main(String[] args) { 18 | 19 | HashMap studentMap = new HashMap<>(); 20 | Student ashley= new Student("Ashley",29,87, 4); 21 | Student milly = new Student("Milly",54,17,3.2); 22 | Student jordan = new Student("Jordan", 21,23, 1); 23 | Student rudy= new Student("Rudy",45, 81, 2); 24 | 25 | 26 | // System.out.println("Ashley's age is "+ ashley.getAge()); 27 | 28 | 29 | studentMap.put(ashley.getSSN(), ashley); 30 | studentMap.put(jordan.getSSN(), jordan); 31 | studentMap.put(rudy.getSSN(), rudy); 32 | studentMap.put(milly.getSSN(),milly); 33 | 34 | StudentTracker tracker = new StudentTracker(studentMap); 35 | 36 | double average = tracker.getAverageGPA(); 37 | System.out.println("The average GPA is " + average); 38 | 39 | } 40 | 41 | 42 | } 43 | 44 | 45 | class Student { 46 | 47 | private String name; 48 | private int age; 49 | private int ssn; 50 | private double gpa; 51 | 52 | Student(String name, int age, int ssn, double gpa) { 53 | this.age = age; 54 | this.ssn = ssn; 55 | this.gpa = gpa; 56 | this.name = name; 57 | } 58 | 59 | public int getAge() { 60 | return age; 61 | } 62 | 63 | public int getSSN() { 64 | return ssn; 65 | } 66 | 67 | public double getSingleGPA() { 68 | return gpa; 69 | } 70 | 71 | public String getName() { 72 | return name; 73 | } 74 | 75 | } 76 | 77 | class StudentTracker { 78 | private HashMap ssnMap; 79 | 80 | StudentTracker(HashMap ssnMap) { 81 | this.ssnMap = ssnMap; 82 | } 83 | 84 | public Student getStudent(int ssn) { 85 | return ssnMap.get(ssn); 86 | } 87 | 88 | public double getAverageGPA() { 89 | double allGrades = 0; 90 | int entries = ssnMap.size(); 91 | for (Map.Entry i : ssnMap.entrySet()) { 92 | allGrades += i.getValue().getSingleGPA(); 93 | } 94 | return allGrades / entries; 95 | } 96 | // public ArrayList getStudentsInOrderOfGPA(HashMap ssnMap){ 97 | // //What I need to be able to retrieve: Student, along with their GPA 98 | // //If i pass in the HashMap, I could iterate through it and get the student object. 99 | // //How can it know what an Entry data type is? Is that built in? 100 | // Set> entrySet= ssnMap.entrySet(); 101 | // 102 | // List studentList = new ArrayList<>(); 103 | // for(Map.Entry i: ssnMap.entrySet()){ 104 | // studentList.add(i.getValue() ); 105 | // } 106 | // 107 | // return Collections.sort(studentList); 108 | // 109 | // 110 | // 111 | // } 112 | 113 | 114 | } 115 | -------------------------------------------------------------------------------- /src/com/practice/slidingwindowproblems/DietPlanPerformance.java: -------------------------------------------------------------------------------- 1 | package com.practice.slidingwindowproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | A dieter consumes calories[i] calories on the i-th day. 5 | Given an integer k, for every consecutive sequence of k days (calories[i], calories[i+1], ..., calories[i+k-1] for all 0 <= i <= n-k), they look at T, the total calories consumed during that sequence of k days (calories[i] + calories[i+1] + ... + calories[i+k-1]): 6 | 7 | If T < lower, they performed poorly on their diet and lose 1 point; 8 | If T > upper, they performed well on their diet and gain 1 point; 9 | Otherwise, they performed normally and there is no change in points. 10 | Initially, the dieter has zero points. Return the total number of points the dieter has after dieting for calories.length days. 11 | 12 | Note that the total points can be negative. 13 | 14 | Example 1: 15 | 16 | Input: calories = [1,2,3,4,5], k = 1, lower = 3, upper = 3 17 | Output: 0 18 | Explanation: Since k = 1, we consider each element of the array separately and compare it to lower and upper. 19 | calories[0] and calories[1] are less than lower so 2 points are lost. 20 | calories[3] and calories[4] are greater than upper so 2 points are gained. 21 | 22 | Leetcode link: https://leetcode.com/problems/diet-plan-performance/description/ 23 | **/ 24 | public class DietPlanPerformance { 25 | public int dietPlanPerformance(int[] calories, int k, int lower, int upper) { 26 | int total =0; 27 | int totalPoints =0; 28 | 29 | for(int i=0; i< k; i++){ 30 | total+= calories[i]; 31 | } 32 | if( total< lower){ 33 | totalPoints--; 34 | } 35 | else if(total> upper){ 36 | totalPoints++; 37 | } 38 | for(int p1=1, p2 =p1 +(k-1); p2< calories.length; p1++, p2++){ 39 | 40 | total-= calories[p1-1]; 41 | total+= calories[p2]; 42 | if( total< lower){ 43 | totalPoints--; 44 | } 45 | else if(total> upper){ 46 | totalPoints++; 47 | } 48 | } 49 | return totalPoints; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/com/practice/slidingwindowproblems/FindTheKBeautyOfANumber.java: -------------------------------------------------------------------------------- 1 | package com.practice.slidingwindowproblems; 2 | /**Problem statement: 3 | The k-beauty of an integer num is defined as the number of substrings of num when it is read as a string 4 | that meet the following conditions: 5 | It has a length of k. 6 | It is a divisor of num. 7 | Given integers num and k, return the k-beauty of num. 8 | 9 | Note: 10 | Leading zeros are allowed. 11 | 0 is not a divisor of any value. 12 | A substring is a contiguous sequence of characters in a string. 13 | 14 | Example 1: 15 | Input: num = 240, k = 2 16 | Output: 2 17 | Explanation: The following are the substrings of num of length k: 18 | - "24" from "240": 24 is a divisor of 240. 19 | - "40" from "240": 40 is a divisor of 240. 20 | Therefore, the k-beauty is 2. 21 | 22 | Leetcode link: https://leetcode.com/problems/find-the-k-beauty-of-a-number/description/ 23 | **/ 24 | public class FindTheKBeautyOfANumber { 25 | public int divisorSubstrings(int num, int k) { 26 | int count = 0; 27 | String number = Integer.toString(num); 28 | for (int i = 0; i <= String.valueOf(num).length() - k; i++) { 29 | int check = returnInteger(number,i, num, k); 30 | if (check != 0 && num % check == 0) { 31 | System.out.println(check); 32 | count++; 33 | } 34 | } 35 | return count; 36 | } 37 | 38 | public static int returnInteger(String number, int index, int num, int k) { 39 | return Integer.valueOf(number.substring(index, index+k)); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/com/practice/slidingwindowproblems/MaxSubArray.java: -------------------------------------------------------------------------------- 1 | package com.practice.slidingwindowproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given an array and value k 5 | 6 | Find the maximum sum in a contiguous window of size k that includes the first element or last element of the array 7 | 8 | input [3,4,2,8,1] 9 | k = 3 10 | output: 12 11 | 12 | input: [1,3,3,4] 13 | k = 2 14 | output: 7 15 | 16 | 17 | **/ 18 | public class MaxSubArray { 19 | public static void main(String[] args) { 20 | int[] nums = {1, 3, 3, 4}; 21 | int k = 2; 22 | int sum = 0; 23 | for (int l = 0; l < k; l++) { 24 | sum += nums[l]; 25 | } 26 | int tempSum = sum; 27 | 28 | for (int i = 1, j = i + k - 1; i < nums.length; i++, j++) { 29 | j = j % nums.length; 30 | tempSum -= nums[i - 1]; 31 | tempSum += nums[j]; 32 | if (includesFirstOrLast(nums, i, j)) { 33 | sum = Math.max(tempSum, sum); 34 | } 35 | } 36 | System.out.println(sum); 37 | } 38 | public static boolean includesFirstOrLast ( int[] nums, int begin, int end){ 39 | return end == 0 || begin == 0 || begin == nums.length || end == nums.length - 1; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/com/practice/slidingwindowproblems/MaximumAverageSubarray.java: -------------------------------------------------------------------------------- 1 | package com.practice.slidingwindowproblems; 2 | 3 | import java.util.*; 4 | /**Problem statement: 5 | You are given an integer array nums consisting of n elements, and an integer k. 6 | 7 | Find a contiguous subarray whose length is equal to k that has the maximum average value and return this value. Any answer with a calculation error less than 10-5 will be accepted. 8 | Example 1: 9 | Input: nums = [1,12,-5,-6,50,3], k = 4 10 | Output: 12.75000 11 | Explanation: Maximum average is (12 - 5 - 6 + 50) / 4 = 51 / 4 = 12.75 12 | Example 2: 13 | 14 | Input: nums = [5], k = 1 15 | Output: 5.00000 16 | Constraints: 17 | n == nums.length 18 | 1 <= k <= n <= 105 19 | -104 <= nums[i] <= 104 20 | 21 | Leetcode link: https://leetcode.com/problems/maximum-average-subarray-i/description/ 22 | **/ 23 | 24 | public class MaximumAverageSubarray { 25 | public double findMaxAverage(int[] nums, int k) { 26 | double avg =0; 27 | for(int i =0; i< k; i++){ 28 | avg+= nums[i]; 29 | } 30 | double temp= avg; 31 | for(int p1=1;p1+ (k-1)< nums.length ; p1++){ 32 | temp -= nums[p1-1]; 33 | temp += nums [p1+(k-1)]; 34 | avg = Math.max(temp, avg); 35 | } 36 | return avg/k; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/com/practice/slidingwindowproblems/MinimumDifferenceBetweenHighestAndLowestOfKScores.java: -------------------------------------------------------------------------------- 1 | package com.practice.slidingwindowproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | You are given a 0-indexed integer array nums, where nums[i] represents the score of the ith student. You are also given an integer k. 5 | 6 | Pick the scores of any k students from the array so that the difference between the highest and the lowest of the k scores is minimized. 7 | 8 | Return the minimum possible difference. 9 | Example 1: 10 | 11 | Input: nums = [9,4,1,7], k = 2 12 | Output: 2 13 | Explanation: There are six ways to pick score(s) of two students: 14 | - [9,4,1,7]. The difference between the highest and lowest score is 9 - 4 = 5. 15 | - [9,4,1,7]. The difference between the highest and lowest score is 9 - 1 = 8. 16 | - [9,4,1,7]. The difference between the highest and lowest score is 9 - 7 = 2. 17 | - [9,4,1,7]. The difference between the highest and lowest score is 4 - 1 = 3. 18 | - [9,4,1,7]. The difference between the highest and lowest score is 7 - 4 = 3. 19 | - [9,4,1,7]. The difference between the highest and lowest score is 7 - 1 = 6. 20 | The minimum possible difference is 2. 21 | 22 | Constraints: 23 | 1 <= k <= nums.length <= 1000 24 | 0 <= nums[i] <= 105 25 | Leetcode link: https://leetcode.com/problems/minimum-difference-between-highest-and-lowest-of-k-scores/description/ 26 | **/ 27 | 28 | public class MinimumDifferenceBetweenHighestAndLowestOfKScores { 29 | public int minimumDifference(int[] nums, int k) { 30 | 31 | if(nums.length<2){ 32 | return 0; 33 | } 34 | Arrays.sort(nums); 35 | 36 | int minDiff= Integer.MAX_VALUE; 37 | 38 | for( int p1=0, p2=p1+(k-1); p2< nums.length; p1++, p2++){ 39 | minDiff=Math.min(minDiff, nums[p2]-nums[p1]); 40 | } 41 | return minDiff; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/com/practice/slidingwindowproblems/MinimumDistanceBetweenBSTNodes.java: -------------------------------------------------------------------------------- 1 | package com.practice.slidingwindowproblems; 2 | 3 | import java.util.*; 4 | 5 | /** 6 | * Problem statement: 7 | * Given the root of a Binary Search Tree (BST), return the minimum difference between the values of any two different 8 | * nodes in the tree. 9 | *

10 | * Input: root = [4,2,6,1,3] 11 | * Output: 1 12 | *

13 | * Constraints: 14 | *

15 | * The number of nodes in the tree is in the range [2, 100]. 16 | * 0 <= Node.val <= 105 17 | *

18 | * Leetcode link: https://leetcode.com/problems/minimum-distance-between-bst-nodes/description/ 19 | **/ 20 | public class MinimumDistanceBetweenBSTNodes { 21 | public int minDiffInBST(TreeNode root) { 22 | List list = new ArrayList<>(); 23 | createList(root, list); 24 | 25 | int temp = Math.abs(list.get(0) - list.get(1)); 26 | int result = temp; 27 | for (int i = 1; i < list.size() - 1; i++) { 28 | temp = Math.abs(list.get(i) - list.get(i + 1)); 29 | result = Math.min(temp, result); 30 | } 31 | return result; 32 | } 33 | 34 | public static void createList(TreeNode root, List list) { 35 | if (root == null) { 36 | return; 37 | } 38 | createList(root.left, list); 39 | list.add(root.val); 40 | createList(root.right, list); 41 | return; 42 | } 43 | } 44 | 45 | class TreeNode { 46 | int val; 47 | TreeNode left; 48 | TreeNode right; 49 | 50 | TreeNode() { 51 | } 52 | 53 | TreeNode(int val) { 54 | this.val = val; 55 | } 56 | 57 | TreeNode(int val, TreeNode left, TreeNode right) { 58 | this.val = val; 59 | this.left = left; 60 | this.right = right; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/com/practice/slidingwindowproblems/MinimumRecolorsToGetKConsecutiveBlackBlocks.java: -------------------------------------------------------------------------------- 1 | package com.practice.slidingwindowproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | You are given a 0-indexed string blocks of length n, where blocks[i] is either 'W' or 'B', representing the color of the ith block. The characters 'W' and 'B' denote the colors white and black, respectively. 5 | 6 | You are also given an integer k, which is the desired number of consecutive black blocks. 7 | 8 | In one operation, you can recolor a white block such that it becomes a black block. 9 | 10 | Return the minimum number of operations needed such that there is at least one occurrence of k consecutive black blocks. 11 | 12 | 13 | 14 | Example 1: 15 | 16 | Input: blocks = "WBBWWBBWBW", k = 7 17 | Output: 3 18 | Explanation: 19 | One way to achieve 7 consecutive black blocks is to recolor the 0th, 3rd, and 4th blocks 20 | so that blocks = "BBBBBBBWBW". 21 | It can be shown that there is no way to achieve 7 consecutive black blocks in less than 3 operations. 22 | Therefore, we return 3. 23 | Example 2: 24 | 25 | Input: blocks = "WBWBBBW", k = 2 26 | Output: 0 27 | Explanation: 28 | No changes need to be made, since 2 consecutive black blocks already exist. 29 | Therefore, we return 0. 30 | 31 | Leetcode link: https://leetcode.com/problems/minimum-recolors-to-get-k-consecutive-black-blocks/description/ 32 | **/ 33 | 34 | public class MinimumRecolorsToGetKConsecutiveBlackBlocks { 35 | 36 | public int minimumRecolors(String blocks, int k) { 37 | if (meetsCriteria(blocks, k)) { 38 | return 0; 39 | } else { 40 | char[] arr = blocks.toCharArray(); 41 | int changeCount = Integer.MAX_VALUE; 42 | for (int j = 0; j < arr.length; j++) { 43 | int bCount = 0; 44 | int tempChangeCount = 0; 45 | for (int i = j; i < arr.length; i++) { 46 | if (blocks.charAt(i) == 'W') { 47 | bCount++; 48 | tempChangeCount++; 49 | } else { 50 | bCount++; 51 | } 52 | if (bCount == k) { 53 | changeCount = Math.min(changeCount, tempChangeCount); 54 | } 55 | 56 | } 57 | } 58 | return changeCount; 59 | } 60 | 61 | } 62 | public static boolean meetsCriteria(String blocks, int k) { 63 | int count = 0; 64 | for (int i = 0; i < blocks.length(); i++) { 65 | if (blocks.charAt(i) == 'E') { 66 | count++; 67 | } else if (blocks.charAt(i) == 'W') { 68 | count = 0; 69 | } 70 | if (count >= k) { 71 | return true; 72 | } 73 | } 74 | return false; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/com/practice/slidingwindowproblems/NumberOfZeroFilledSubarrays.java: -------------------------------------------------------------------------------- 1 | package com.practice.slidingwindowproblems; 2 | /**Problem statement: 3 | Given an integer array nums, return the number of subarrays filled with 0. 4 | 5 | A subarray is a contiguous non-empty sequence of elements within an array. 6 | 7 | 8 | 9 | Example 1: 10 | 11 | Input: nums = [1,3,0,0,2,0,0,4] 12 | Output: 6 13 | Explanation: 14 | There are 4 occurrences of [0] as a subarray. 15 | There are 2 occurrences of [0,0] as a subarray. 16 | There is no occurrence of a subarray with a size more than 2 filled with 0. Therefore, we return 6. 17 | Example 2: 18 | 19 | Input: nums = [0,0,0,2,0,0] 20 | Output: 9 21 | Explanation: 22 | There are 5 occurrences of [0] as a subarray. 23 | There are 3 occurrences of [0,0] as a subarray. 24 | There is 1 occurrence of [0,0,0] as a subarray. 25 | There is no occurrence of a subarray with a size more than 3 filled with 0. Therefore, we return 9. 26 | Example 3: 27 | 28 | Input: nums = [2,10,2019] 29 | Output: 0 30 | Explanation: There is no subarray filled with 0. Therefore, we return 0. 31 | 32 | 33 | Constraints: 34 | 35 | 1 <= nums.length <= 105 36 | -109 <= nums[i] <= 109 37 | 38 | Leetcode link: https://leetcode.com/problems/number-of-zero-filled-subarrays/description/ 39 | **/ 40 | public class NumberOfZeroFilledSubarrays { 41 | public long zeroFilledSubarray(int[] nums) { 42 | long count = 0; 43 | long subArrays = 0; 44 | 45 | for (int i = 0; i < nums.length; i++) { 46 | if (nums[i] == 0) { 47 | count++; 48 | subArrays += count; 49 | } else { 50 | count = 0; 51 | } 52 | } 53 | return subArrays; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/com/practice/slidingwindowproblems/SubstringsOfSizeThreeWithDistinctCharacters.java: -------------------------------------------------------------------------------- 1 | package com.practice.slidingwindowproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | A string is good if there are no repeated characters. 5 | 6 | Given a string s​​​​​, return the number of good substrings of length three in s​​​​​​. 7 | 8 | Note that if there are multiple occurrences of the same substring, every occurrence should be counted. 9 | 10 | A substring is a contiguous sequence of characters in a string. 11 | Example 1: 12 | 13 | Input: s = "xyzzaz" 14 | Output: 1 15 | Explanation: There are 4 substrings of size 3: "xyz", "yzz", "zza", and "zaz". 16 | The only good substring of length 3 is "xyz". 17 | Example 2: 18 | 19 | Input: s = "aababcabc" 20 | Output: 4 21 | Explanation: There are 7 substrings of size 3: "aab", "aba", "bab", "abc", "bca", "cab", and "abc". 22 | The good substrings are "abc", "bca", "cab", and "abc". 23 | 24 | Leetcode link: https://leetcode.com/problems/substrings-of-size-three-with-distinct-characters/description/ 25 | **/ 26 | public class SubstringsOfSizeThreeWithDistinctCharacters { 27 | public int countGoodSubstrings(String s) { 28 | int count =0; 29 | char [] arr = s.toCharArray(); 30 | 31 | for( int i=0; i<= arr.length -3; i++){ 32 | if( isGood(i,arr) ){ 33 | count ++; 34 | } 35 | } 36 | return count; 37 | } 38 | public static boolean isGood( int i, char [] arr){ 39 | return arr[i] != arr[i+1] && arr[i+1] != arr[i+2] && arr[i] != arr[i+2]; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/com/practice/sortingalgorithms/BubbleSort.java: -------------------------------------------------------------------------------- 1 | package com.practice.sortingalgorithms; 2 | 3 | public class BubbleSort { 4 | 5 | public static void main(String[] args) { 6 | int[] nums = new int[]{3, 1, 8, 12, -1, 100, 99, 11, 3}; 7 | 8 | int k = nums.length; 9 | for (int i = 0; i < k - 1; k--) { 10 | for (int j = i + 1; j < k; j++) { 11 | if (nums[j] < nums[j - 1]) { 12 | swap(nums, j - 1, j); 13 | } 14 | } 15 | } 16 | for (int l : nums) { 17 | System.out.println(l); 18 | } 19 | } 20 | 21 | public static void swap(int[] array, int p1, int p2) { 22 | int temp = array[p1]; 23 | array[p1] = array[p2]; 24 | array[p2] = temp; 25 | } 26 | } 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/com/practice/sortingalgorithms/InsertionSort.java: -------------------------------------------------------------------------------- 1 | package com.practice.sortingalgorithms; 2 | 3 | public class InsertionSort { 4 | public static void main(String[] args) { 5 | int[] nums = new int[]{3, 2, 1, 8, 0, 9, 6, 1, 13, 100, 101, 7}; 6 | 7 | for (int j = 1; j < nums.length; j++) { 8 | for (int k = j; k > 0; k--) { 9 | if (nums[k] < nums[k - 1]) { 10 | swap(nums, k); 11 | } 12 | } 13 | } 14 | for (int i : nums) { 15 | System.out.println(i); 16 | } 17 | } 18 | 19 | public static void swap(int[] nums, int pointer) { 20 | int temp = nums[pointer]; 21 | nums[pointer] = nums[pointer - 1]; 22 | nums[pointer - 1] = temp; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/com/practice/sortingalgorithms/MergeSort.java: -------------------------------------------------------------------------------- 1 | package com.practice.sortingalgorithms; 2 | import java.util.*; 3 | 4 | public class MergeSort { 5 | 6 | public static void main(String[] args) { 7 | int[] nums = new int[]{-1,8,2,0,7,3,18,9,11}; 8 | mergeSort(nums); 9 | for(int i: nums){ 10 | System.out.println(i); 11 | } 12 | } 13 | 14 | public static int[] mergeSort(int[] k) { 15 | if (k.length < 2) { 16 | return k; 17 | } 18 | int[] leftArr = new int[k.length / 2]; 19 | leftArr = Arrays.copyOfRange(k, 0, k.length / 2); 20 | 21 | int[] rightArr = new int[k.length - (k.length / 2)]; 22 | rightArr = Arrays.copyOfRange(k, (k.length / 2), k.length); 23 | 24 | mergeSort(leftArr); 25 | mergeSort(rightArr); 26 | merge(k, leftArr, rightArr); 27 | return k; 28 | } 29 | 30 | private static void merge(int[] original, int[] left, int[] right) { 31 | 32 | int i = 0; 33 | int j = 0; 34 | int k = 0; 35 | while (i < left.length && j < right.length) { 36 | if (left[i] < right[j]) { 37 | original[k] = left[i]; 38 | i++; 39 | } else { 40 | original[k] = right[j]; 41 | j++; 42 | } 43 | k++; 44 | } 45 | 46 | while (i < left.length) { 47 | original[k] = left[i]; 48 | i++; 49 | k++; 50 | } 51 | 52 | while (j < right.length) { 53 | original[k] = right[j]; 54 | j++; 55 | k++; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/com/practice/sortingalgorithms/SelectionSort.java: -------------------------------------------------------------------------------- 1 | package com.practice.sortingalgorithms; 2 | 3 | public class SelectionSort { 4 | 5 | public static void main(String[] args) { 6 | int[] nums = new int[]{3, 2, 1, 8, 0, 9, 6, 1, 13, 100, 101, 7}; 7 | for (int i = 0; i < nums.length - 1; i++) { 8 | int temp = i; 9 | for (int j = i + 1; j < nums.length; j++) { 10 | if (nums[j] < nums[temp]) { 11 | temp = j; 12 | } 13 | } 14 | if (temp != i) { 15 | swapTempToFront(nums, temp, i); 16 | } 17 | } 18 | for (int i : nums) { 19 | System.out.println(i); 20 | } 21 | } 22 | 23 | public static void swapTempToFront(int[] nums, int temp, int i) { 24 | int swap = nums[temp]; 25 | nums[temp] = nums[i]; 26 | nums[i] = swap; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/com/practice/stackproblems/DailyTemperatures.java: -------------------------------------------------------------------------------- 1 | package com.practice.stackproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given an array of integers temperatures represents the daily temperatures, return an array answer such that answer[i] is the number of days you have to wait after the ith day to get a warmer temperature. If there is no future day for which this is possible, keep answer[i] == 0 instead. 5 | Example 1: 6 | Input: temperatures = [73,74,75,71,69,72,76,73] 7 | Output: [1,1,4,2,1,1,0,0] 8 | Example 2: 9 | Input: temperatures = [30,60,90] 10 | Output: [1,1,0] 11 | Constraints: 12 | 1 <= temperatures.length <= 105 13 | 30 <= temperatures[i] <= 100 14 | 15 | Leetcode link: https://leetcode.com/problems/daily-temperatures/description/ 16 | **/ 17 | 18 | public class DailyTemperatures { 19 | public int[] dailyTemperatures(int[] temperatures) { 20 | Stack < Integer > stack = new Stack < > (); 21 | int[] result = new int[temperatures.length]; 22 | 23 | for (int i = 0; i < temperatures.length; i++) { 24 | 25 | while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]) { 26 | 27 | int index = stack.pop(); 28 | int diff = i - index; 29 | result[index] = diff; 30 | } 31 | stack.push(i); 32 | } 33 | 34 | while (!stack.isEmpty()) { 35 | result[stack.pop()] = 0; 36 | } 37 | return result; 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/com/practice/stackproblems/MinimumAddToMakeParenthesesValid.java: -------------------------------------------------------------------------------- 1 | package com.practice.stackproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | A parentheses string is valid if and only if: 5 | It is the empty string, 6 | It can be written as AB (A concatenated with B), where A and B are valid strings, or 7 | It can be written as (A), where A is a valid string. 8 | You are given a parentheses string s. In one move, you can insert a parenthesis at any position of the string. 9 | 10 | For example, if s = "()))", you can insert an opening parenthesis to be "(()))" or a closing parenthesis to be "())))". 11 | Return the minimum number of moves required to make s valid. 12 | Example 1: 13 | 14 | Input: s = "())" 15 | Output: 1 16 | 17 | Example 2: 18 | 19 | Input: s = "(((" 20 | 21 | Output: 3 22 | Constraints: 23 | 24 | 1 <= s.length <= 1000 25 | s[i] is either '(' or ')'. 26 | 27 | Leetcode link: https://leetcode.com/problems/minimum-add-to-make-parentheses-valid/description/ 28 | **/ 29 | public class MinimumAddToMakeParenthesesValid { 30 | public int minAddToMakeValid(String s) { 31 | 32 | Stack < Character > stack = new Stack < > (); 33 | int count = 0; 34 | for (int i = 0; i < s.length(); i++) { 35 | char check = s.charAt(i); 36 | if (check == '(') { 37 | stack.push(check); 38 | } else if (check == ')' && !stack.isEmpty()) { 39 | stack.pop(); 40 | } else if (check == ')' && stack.isEmpty()) { 41 | count++; 42 | } 43 | } 44 | return count + stack.size(); 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/CellsInARangeOnAnExcelSheet.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | A cell (r, c) of an excel sheet is represented as a string "" where: 5 | 6 | denotes the column number c of the cell. It is represented by alphabetical letters. 7 | For example, the 1st column is denoted by 'A', the 2nd by 'B', the 3rd by 'C', and so on. 8 | is the row number r of the cell. The rth row is represented by the integer r. 9 | You are given a string s in the format ":", where represents the column c1, 10 | represents the row r1, represents the column c2, and represents the row r2, such that r1 <= r2 and c1 11 | <= c2. 12 | 13 | Return the list of cells (x, y) such that r1 <= x <= r2 and c1 <= y <= c2. The cells should be represented as 14 | strings in the format mentioned above and be sorted in non-decreasing order first by columns and then by rows. 15 | 16 | Input: s = "K1:L2" 17 | Output: ["K1","K2","L1","L2"] 18 | Explanation: 19 | The above diagram shows the cells which should be present in the list. 20 | The red arrows denote the order in which the cells should be presented. 21 | 22 | Leetcode link: https://leetcode.com/problems/cells-in-a-range-on-an-excel-sheet/description/ 23 | **/ 24 | public class CellsInARangeOnAnExcelSheet { 25 | public List < String > cellsInRange(String s) { 26 | String[] arr = s.split(":"); 27 | List < String > result = new ArrayList < > (); 28 | List < Character > charList = createCharacterList(arr[0].charAt(0), arr[1].charAt(0)); 29 | List < Integer > numberList = createNumberList(Character.getNumericValue(arr[0].charAt(1)), Character.getNumericValue(arr[1].charAt(1))); 30 | 31 | for (Character c: charList) { 32 | for (Integer i: numberList) { 33 | StringBuilder temp = new StringBuilder(); 34 | result.add(String.valueOf(temp.append(c).append(i))); 35 | } 36 | } 37 | return result; 38 | } 39 | public static List < Character > createCharacterList(char a, char b) { 40 | List < Character > list = new ArrayList < > (); 41 | 42 | for (char i = a; i <= b; i++) { 43 | list.add(i); 44 | } 45 | return list; 46 | } 47 | 48 | public static List < Integer > createNumberList(Integer a, Integer b) { 49 | List < Integer > numberList = new ArrayList < > (); 50 | 51 | for (int i = a; i <= b; i++) { 52 | numberList.add(i); 53 | } 54 | 55 | return numberList; 56 | 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/CheckIfTheSentenceIsAPangram.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | 3 | import java.util.*; 4 | /**Problem statement: 5 | A pangram is a sentence where every letter of the English alphabet appears at least once. 6 | 7 | Given a string sentence containing only lowercase English letters, return true if sentence is a pangram, or false otherwise. 8 | Example 1: 9 | 10 | Input: sentence = "thequickbrownfoxjumpsoverthelazydog" 11 | Output: true 12 | Explanation: sentence contains at least one of every letter of the English alphabet. 13 | 14 | Leetcode link: https://leetcode.com/problems/check-if-the-sentence-is-pangram/ 15 | **/ 16 | 17 | public class CheckIfTheSentenceIsAPangram { 18 | public boolean checkIfPangram(String sentence) { 19 | Set set = new HashSet<>(); 20 | for(char s : sentence.toCharArray()){ 21 | set.add(s); 22 | } 23 | return set.size() == 26; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/CheckIfTwoStringArraysAreEquivalent.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | /**Problem statement: 3 | Given two string arrays word1 and word2, return true if the two arrays represent the same string, and false otherwise. 4 | 5 | A string is represented by an array if the array elements concatenated in order forms the string. 6 | 7 | 8 | 9 | Example 1: 10 | 11 | Input: word1 = ["ab", "c"], word2 = ["a", "bc"] 12 | Output: true 13 | Explanation: 14 | word1 represents string "ab" + "c" -> "abc" 15 | word2 represents string "a" + "bc" -> "abc" 16 | The strings are the same, so return true. 17 | Example 2: 18 | 19 | Input: word1 = ["a", "cb"], word2 = ["ab", "c"] 20 | Output: false 21 | Example 3: 22 | 23 | Input: word1 = ["abc", "d", "defg"], word2 = ["abcddefg"] 24 | Output: true 25 | Constraints: 26 | 27 | 1 <= word1.length, word2.length <= 103 28 | 1 <= word1[i].length, word2[i].length <= 103 29 | 1 <= sum(word1[i].length), sum(word2[i].length) <= 103 30 | word1[i] and word2[i] consist of lowercase letters. 31 | 32 | Leetcode link: https://leetcode.com/problems/check-if-two-string-arrays-are-equivalent/description/ 33 | **/ 34 | public class CheckIfTwoStringArraysAreEquivalent { 35 | public boolean arrayStringsAreEqual(String[] word1, String[] word2) { 36 | 37 | StringBuilder one = new StringBuilder(); 38 | StringBuilder two = new StringBuilder(); 39 | 40 | for (String s: word1) { 41 | one.append(s); 42 | } 43 | 44 | for (String t: word2) { 45 | two.append(t); 46 | } 47 | 48 | return one.toString().equals(two.toString()); 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/CorrectStringUppercase.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | import java.io.*; 3 | import java.util.*; 4 | 5 | 6 | /**Problem statement: 7 | Given a String, return a String with the first letter of each word in uppercase, unless the String has two letters 8 | or less. If a Stirng has two letters or less, the entire String should be lowercase. 9 | Example: CAStLe is the OwnEr should return Castle is The Owner**/ 10 | public class CorrectStringUppercase { 11 | static public void main( String args[] ) { 12 | String str = "CAStLe is the OwnEr "; 13 | System.out.print(correctString(str)); 14 | } 15 | public static String correctString( String s){ 16 | String [] parts = s.split(" "); 17 | StringBuilder result = new StringBuilder (); 18 | for(String k: parts){ 19 | String word = ""; 20 | if(k.length() > 2){ 21 | word = k.substring(0,1).toUpperCase() + k.substring(1).toLowerCase(); 22 | }else{ 23 | word = k.toLowerCase(); 24 | } 25 | result.append(word + " "); 26 | } 27 | return result.toString().trim(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/CountAsterisks.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | import java.util.*; 3 | 4 | /**Problem statement: 5 | You are given a string s, where every two consecutive vertical bars '|' are grouped into a pair. In other words, the 1st and 2nd '|' make a pair, the 3rd and 4th '|' make a pair, and so forth. 6 | 7 | Return the number of '*' in s, excluding the '*' between each pair of '|'. 8 | 9 | Note that each '|' will belong to exactly one pair. 10 | 11 | Example 1: 12 | Input: s = "l|*e*et|c**o|*de|" 13 | Output: 2 14 | Explanation: The considered characters are underlined: "l|*e*et|c**o|*de|". 15 | The characters between the first and second '|' are excluded from the answer. 16 | Also, the characters between the third and fourth '|' are excluded from the answer. 17 | There are 2 asterisks considered. Therefore, we return 2. 18 | 19 | Example 2: 20 | Input: s = "iamprogrammer" 21 | Output: 0 22 | Explanation: In this example, there are no asterisks in s. Therefore, we return 0. 23 | 24 | Example 3: 25 | Input: s = "yo|uar|e**|b|e***au|tifu|l" 26 | Output: 5 27 | Explanation: The considered characters are underlined: "yo|uar|e**|b|e***au|tifu|l". There are 5 asterisks considered. Therefore, we return 5. 28 | Constraints: 29 | 30 | 1 <= s.length <= 1000 31 | s consists of lowercase English letters, vertical bars '|', and asterisks '*'. 32 | s contains an even number of vertical bars '|'. 33 | Leetcode link: https://leetcode.com/problems/count-asterisks/description/ 34 | **/ 35 | public class CountAsterisks { 36 | public int countAsterisks(String s) { 37 | int count =0; 38 | int result =0; 39 | 40 | for(char i : s.toCharArray()){ 41 | if(i =='|'){ 42 | count++; 43 | } 44 | if( count %2 ==0 && i == '*'){ 45 | result++; 46 | } 47 | } 48 | return result; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/CountItemsMatchingARule.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | You are given an array items, where each items[i] = [typei, colori, namei] describes the type, color, and name of the ith item. You are also given a rule represented by two strings, ruleKey and ruleValue. 5 | 6 | The ith item is said to match the rule if one of the following is true: 7 | 8 | ruleKey == "type" and ruleValue == typei. 9 | ruleKey == "color" and ruleValue == colori. 10 | ruleKey == "name" and ruleValue == namei. 11 | Return the number of items that match the given rule. 12 | 13 | 14 | 15 | Example 1: 16 | 17 | Input: items = [["phone","blue","pixel"],["computer","silver","lenovo"],["phone","gold","iphone"]], ruleKey = "color", ruleValue = "silver" 18 | Output: 1 19 | Explanation: There is only one item matching the given rule, which is ["computer","silver","lenovo"]. 20 | Example 2: 21 | 22 | Input: items = [["phone","blue","pixel"],["computer","silver","phone"],["phone","gold","iphone"]], ruleKey = "type", ruleValue = "phone" 23 | Output: 2 24 | Explanation: There are only two items matching the given rule, which are ["phone","blue","pixel"] and ["phone","gold","iphone"]. Note that the item ["computer","silver","phone"] does not match. 25 | 26 | Leetcode link: https://leetcode.com/problems/count-items-matching-a-rule/description/ 27 | **/ 28 | 29 | public class CountItemsMatchingARule { 30 | public int countMatches(List> items, String ruleKey, String ruleValue) { 31 | int check =0; 32 | if(ruleKey.equals("color")){ 33 | check =1; 34 | } 35 | if(ruleKey.equals("name")){ 36 | check =2; 37 | } 38 | int count =0; 39 | for(List list: items){ 40 | if(list.get(check).equals(ruleValue)){ 41 | count++; 42 | } 43 | } 44 | return count; 45 | 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/CountTheNumberOfConsistentStrings.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | * 5 | * You are given a string allowed consisting of distinct characters and an array of strings words. A string is consistent if all characters in the string appear in the string allowed. 6 | * 7 | * Return the number of consistent strings in the array words. 8 | * Example 1: 9 | * Input: allowed = "ab", words = ["ad","bd","aaab","baa","badab"] 10 | * Output: 2 11 | * Explanation: Strings "aaab" and "baa" are consistent since they only contain characters 'a' and 'b'. 12 | * 13 | * Example 2: 14 | * Input: allowed = "abc", words = ["a","b","c","ab","ac","bc","abc"] 15 | * Output: 7 16 | * Explanation: All strings are consistent. 17 | * Constraints: 18 | * 1 <= words.length <= 104 19 | * 1 <= allowed.length <= 26 20 | * 1 <= words[i].length <= 10 21 | * The characters in allowed are distinct. 22 | * words[i] and allowed contain only lowercase English letters. 23 | 24 | Leetcode link: https://leetcode.com/problems/count-the-number-of-consistent-strings/description/ 25 | **/ 26 | public class CountTheNumberOfConsistentStrings { 27 | public int countConsistentStrings(String allowed, String[] words) { 28 | int count = 0; 29 | for (String word: words) { 30 | Set < String > letterSet = new HashSet < > (); 31 | for (int i = 0; i < allowed.length(); i++) { 32 | letterSet.add(String.valueOf(allowed.charAt(i))); 33 | } 34 | if (isConsistent(word, letterSet)) { 35 | count++; 36 | } 37 | } 38 | return count; 39 | } 40 | 41 | public static boolean isConsistent(String singleWord, Set < String > letterSet) { 42 | for (int i = 0; i < singleWord.length(); i++) { 43 | if (!letterSet.contains(String.valueOf(singleWord.charAt(i)))) { 44 | return false; 45 | } 46 | } 47 | return true; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/DecodeTheMessage.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | You are given the strings key and message, which represent a cipher key and a secret message, respectively. The steps to decode message are as follows: 5 | 6 | Use the first appearance of all 26 lowercase English letters in key as the order of the substitution table. 7 | Align the substitution table with the regular English alphabet. 8 | Each letter in message is then substituted using the table. 9 | Spaces ' ' are transformed to themselves. 10 | For example, given key = "happy boy" (actual key would have at least one instance of each letter in the alphabet), we have the partial substitution table of ('h' -> 'a', 'a' -> 'b', 'p' -> 'c', 'y' -> 'd', 'b' -> 'e', 'o' -> 'f'). 11 | Return the decoded message. 12 | 13 | Example 1: 14 | Input: key = "the quick brown fox jumps over the lazy dog", message = "vkbs bs t suepuv" 15 | Output: "this is a secret" 16 | Explanation: The diagram above shows the substitution table. 17 | It is obtained by taking the first appearance of each letter in "the quick brown fox jumps over the lazy dog". 18 | 19 | Leetcode link: https://leetcode.com/problems/decode-the-message/description/ 20 | **/ 21 | public class DecodeTheMessage { 22 | public String decodeMessage(String key, String message) { 23 | 24 | Map < Character, Character > map = new HashMap < > (); 25 | putInMap(map, key); 26 | StringBuilder result = new StringBuilder(); 27 | 28 | for (int j = 0; j < message.length(); j++) { 29 | char check = message.charAt(j); 30 | if (check == ' ') { 31 | result.append(" "); 32 | } else { 33 | result.append(map.get(check)); 34 | } 35 | } 36 | return result.toString(); 37 | } 38 | public static void putInMap(Map < Character, Character > map, String key) { 39 | char alphabet = 'a'; 40 | for (int i = 0; i < key.length(); i++) { 41 | if (key.charAt(i) != ' ' && !map.containsKey(key.charAt(i))) { 42 | map.put(key.charAt(i), alphabet); 43 | alphabet++; 44 | } 45 | } 46 | 47 | } 48 | } -------------------------------------------------------------------------------- /src/com/practice/stringproblems/DefangingAnIPAddress.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | /**Problem statement: 3 | Given a valid (IPv4) IP address, return a defanged version of that IP address. 4 | 5 | A defanged IP address replaces every period "." with "[.]". 6 | 7 | Example 1: 8 | 9 | Input: address = "1.1.1.1" 10 | Output: "1[.]1[.]1[.]1" 11 | 12 | Leetcode link: https://leetcode.com/problems/defanging-an-ip-address/description/ 13 | **/ 14 | 15 | public class DefangingAnIPAddress { 16 | public String defangIPaddr(String address) { 17 | char [] arr = address.toCharArray(); 18 | 19 | 20 | StringBuilder result = new StringBuilder(); 21 | for(char s : arr){ 22 | if( s != '.'){ 23 | result.append(s); 24 | }else{ 25 | result.append("[.]"); 26 | } 27 | } 28 | 29 | return String.valueOf(result); 30 | 31 | } 32 | 33 | } 34 | 35 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/FinalValueOfVariableAfterPerformingOperations.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | There is a programming language with only four operations and one variable X: 5 | 6 | ++X and X++ increments the value of the variable X by 1. 7 | --X and X-- decrements the value of the variable X by 1. 8 | Initially, the value of X is 0. 9 | 10 | Given an array of strings operations containing a list of operations, return the final value of X after performing all the operations. 11 | 12 | 13 | 14 | Example 1: 15 | 16 | Input: operations = ["--X","X++","X++"] 17 | Output: 1 18 | Explanation: The operations are performed as follows: 19 | Initially, X = 0. 20 | --X: X is decremented by 1, X = 0 - 1 = -1. 21 | X++: X is incremented by 1, X = -1 + 1 = 0. 22 | X++: X is incremented by 1, X = 0 + 1 = 1. 23 | 24 | Leetcode link: https://leetcode.com/problems/final-value-of-variable-after-performing-operations/description/ 25 | **/ 26 | 27 | public class FinalValueOfVariableAfterPerformingOperations { 28 | public int finalValueAfterOperations(String[] operations) { 29 | int sum = 0; 30 | 31 | for(String s : operations){ 32 | if(s.contains("-")){ 33 | sum--; 34 | }else{ 35 | sum++; 36 | } 37 | } 38 | return sum; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/FindTheIndexOfTheFirstOccurrenceInAString.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given two strings needle and haystack, return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. 5 | Example 1: 6 | Input: haystack = "sadbutsad", needle = "sad" 7 | Output: 0 8 | Explanation: "sad" occurs at index 0 and 6. 9 | The first occurrence is at index 0, so we return 0. 10 | 11 | Example 2: 12 | Input: haystack = "leetcode", needle = "leeto" 13 | Output: -1 14 | Explanation: "leeto" did not occur in "leetcode", so we return -1. 15 | 16 | 17 | Constraints: 18 | 1 <= haystack.length, needle.length <= 104 19 | haystack and needle consist of only lowercase English characters. 20 | Leetcode link: https://leetcode.com/problems/find-the-index-of-the-first-occurrence-in-a-string/description/ 21 | **/ 22 | public class FindTheIndexOfTheFirstOccurrenceInAString { 23 | public int strStr(String haystack, String needle) { 24 | int stop = haystack.length() - needle.length()+1; 25 | 26 | for(int i = 0; i< stop; i++){ 27 | if(haystack.charAt(i) == needle.charAt(0)){ 28 | if(matches(haystack, needle, i)){ 29 | return i; 30 | } 31 | } 32 | } 33 | return -1; 34 | } 35 | 36 | public static boolean matches( String haystack, String needle, int index){ 37 | for(int i = index, j=0; j< needle.length(); index++, j++){ 38 | if(haystack.charAt(index) != needle.charAt(j)){ 39 | return false; 40 | } 41 | } 42 | return true; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/GoalParserInterpretation.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | 3 | import java.util.*; 4 | /**Problem statement: 5 | You own a Goal Parser that can interpret a string command. The command consists of an alphabet of "G", "()" and/or "(al)" in some order. The Goal Parser will interpret "G" as the string "G", "()" as the string "o", and "(al)" as the string "al". The interpreted strings are then concatenated in the original order. 6 | 7 | Given the string command, return the Goal Parser's interpretation of command. 8 | 9 | 10 | 11 | Example 1: 12 | 13 | Input: command = "G()(al)" 14 | Output: "Goal" 15 | Explanation: The Goal Parser interprets the command as follows: 16 | G -> G 17 | () -> o 18 | (al) -> al 19 | The final concatenated result is "Goal". 20 | Example 2: 21 | 22 | Input: command = "G()()()()(al)" 23 | Output: "Gooooal" 24 | 25 | 26 | Leetcode link: https://leetcode.com/problems/goal-parser-interpretation/description/ 27 | **/ 28 | 29 | public class GoalParserInterpretation { 30 | public String interpret(String command) { 31 | StringBuilder result = new StringBuilder(); 32 | appendToEnd(result, command.toCharArray()); 33 | return String.valueOf(result); 34 | } 35 | 36 | public static void appendToEnd( StringBuilder result, char [] arr ){ 37 | for( int i = 0; i< arr.length; i++ ){ 38 | if( arr[i]=='G'){ 39 | result.append("G"); 40 | } 41 | if(arr[i]== ')' && arr[i-1] =='('){ 42 | result.append("o"); 43 | } 44 | if(arr[i]== 'a'){ 45 | result.append("al"); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/JewelsAndStones.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | import java.util.*; 3 | 4 | /**Problem statement: 5 | You're given strings jewels representing the types of stones that are jewels, and stones representing the stones you have. Each character in stones is a type of stone you have. You want to know how many of the stones you have are also jewels. 6 | Letters are case sensitive, so "a" is considered a different type of stone from "A". 7 | Example 1: 8 | 9 | Input: jewels = "aA", stones = "aAAbbbb" 10 | Output: 3 11 | Example 2: 12 | 13 | Input: jewels = "z", stones = "ZZ" 14 | Output: 0 15 | 16 | Constraints: 17 | 1 <= jewels.length, stones.length <= 50 18 | jewels and stones consist of only English letters. 19 | All the characters of jewels are unique. 20 | 21 | Leetcode link:https://leetcode.com/problems/jewels-and-stones/description/ 22 | **/ 23 | 24 | public class JewelsAndStones { 25 | 26 | public int numJewelsInStones(String jewels, String stones) { 27 | Set < Character > jewelSet = new HashSet < > (); 28 | for (char c: jewels.toCharArray()) { 29 | jewelSet.add(c); 30 | } 31 | int count = 0; 32 | for (char stone: stones.toCharArray()) { 33 | if (jewelSet.contains(stone)) { 34 | count++; 35 | } 36 | } 37 | return count; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/LongestPalindrome.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given a string s which consists of lowercase or uppercase letters, return the length of the longest palindrome that can be built with those letters. 5 | 6 | Letters are case sensitive, for example, "Aa" is not considered a palindrome here. 7 | 8 | Example 1: 9 | Input: s = "abccccdd" 10 | Output: 7 11 | Explanation: One longest palindrome that can be built is "dccaccd", whose length is 7. 12 | 13 | Example 2: 14 | Input: s = "a" 15 | Output: 1 16 | Explanation: The longest palindrome that can be built is "a", whose length is 1. 17 | 18 | Constraints: 19 | 1 <= s.length <= 2000 20 | s consists of lowercase and/or uppercase English letters only. 21 | Leetcode link: https://leetcode.com/problems/longest-palindrome/description/ 22 | **/ 23 | public class LongestPalindrome { 24 | public int longestPalindrome(String s) { 25 | Set < Character > set = new HashSet < > (); 26 | int count = 0; 27 | 28 | for (int i = 0; i < s.length(); i++) { 29 | char c = s.charAt(i); 30 | if (set.contains(c)) { 31 | set.remove(c); 32 | count++; 33 | } else { 34 | set.add(c); 35 | } 36 | } 37 | return set.size() > 0 ? (count * 2) + 1 : count * 2; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/LongestSubstringWithoutRepeatingCharacters.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | import java.util.*; 3 | 4 | /**Problem statement: 5 | Given a string s, find the length of the longest 6 | substring 7 | without repeating characters. 8 | 9 | Example 1: 10 | Input: s = "abcabcbb" 11 | Output: 3 12 | Explanation: The answer is "abc", with the length of 3. 13 | 14 | Example 2: 15 | Input: s = "bbbbb" 16 | Output: 1 17 | Explanation: The answer is "b", with the length of 1. 18 | 19 | Example 3: 20 | Input: s = "pwwkew" 21 | Output: 3 22 | Explanation: The answer is "wke", with the length of 3. 23 | Notice that the answer must be a substring, "pwke" is a subsequence and not a substring. 24 | 25 | Constraints: 26 | 27 | 0 <= s.length <= 5 * 104 28 | s consists of English letters, digits, symbols and spaces. 29 | Leetcode link: https://leetcode.com/problems/longest-substring-without-repeating-characters/ 30 | **/ 31 | public class LongestSubstringWithoutRepeatingCharacters { 32 | public int lengthOfLongestSubstring(String s) { 33 | int result = Integer.MIN_VALUE; 34 | if (s.length() == 0) { 35 | return 0; 36 | } 37 | if (s.length() == 1) { 38 | return 1; 39 | } 40 | //LinkedHashSet maintains order 41 | Set < Character > set = new LinkedHashSet < > (); 42 | for (int i = 0; i < s.length(); i++) { 43 | char letter = s.charAt(i); 44 | if (!set.contains(letter)) { 45 | set.add(letter); 46 | } else { 47 | removeDuplicateLetterAndEverythingBeforeIt(set, letter); 48 | set.add(letter); 49 | } 50 | 51 | } 52 | return result; 53 | } 54 | public static char returnLastCharInSet(Set < Character > set) { 55 | char lastChar = ' '; 56 | for (Character c: set) { 57 | lastChar = c; 58 | } 59 | return lastChar; 60 | } 61 | public static void removeDuplicateLetterAndEverythingBeforeIt(Set < Character > set, char duplicateLetter) { 62 | List < Character > setList = new ArrayList < > (set); 63 | while (setList.get(0) != duplicateLetter) { 64 | setList.remove(0); 65 | } 66 | setList.remove(0); 67 | set.clear(); 68 | for (Character c: setList) { 69 | set.add(c); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/MaximumNumberOfWordsFoundInSentences.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | 3 | import java.util.*; 4 | /**Problem statement: 5 | A sentence is a list of words that are separated by a single space with no leading or trailing spaces. 6 | 7 | You are given an array of strings sentences, where each sentences[i] represents a single sentence. 8 | 9 | Return the maximum number of words that appear in a single sentence. 10 | 11 | 12 | 13 | Example 1: 14 | 15 | Input: sentences = ["alice and bob love leetcode", "i think so too", "this is great thanks very much"] 16 | Output: 6 17 | Explanation: 18 | - The first sentence, "alice and bob love leetcode", has 5 words in total. 19 | - The second sentence, "i think so too", has 4 words in total. 20 | - The third sentence, "this is great thanks very much", has 6 words in total. 21 | Thus, the maximum number of words in a single sentence comes from the third sentence, which has 6 words. 22 | 23 | Leetcode link: https://leetcode.com/problems/maximum-number-of-words-found-in-sentences/description/ 24 | **/ 25 | public class MaximumNumberOfWordsFoundInSentences { 26 | 27 | public int mostWordsFound(String[] sentences) { 28 | int length =0; 29 | 30 | for(String s : sentences){ 31 | length = Math.max(length, s.split(" ").length); 32 | } 33 | 34 | return length; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/MergeStringsAlternately.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | /**Problem statement: 3 | * 4 | * You are given two strings word1 and word2. Merge the strings by adding letters in alternating order, starting with 5 | * word1. If a string is longer than the other, append the additional letters onto the end of the merged string. 6 | * 7 | * Return the merged string. 8 | 9 | * Example 1: 10 | 11 | * Input: word1 = "abc", word2 = "pqr" 12 | * Output: "apbqcr" 13 | * Explanation: The merged string will be merged as so: 14 | * word1: a b c 15 | * word2: p q r 16 | * merged: a p b q c r 17 | * Example 2: 18 | * 19 | * Input: word1 = "ab", word2 = "pqrs" 20 | * Output: "apbqrs" 21 | * Explanation: Notice that as word2 is longer, "rs" is appended to the end. 22 | * word1: a b 23 | * word2: p q r s 24 | * merged: a p b q r s 25 | * 26 | * Constraints: 27 | * 1 <= word1.length, word2.length <= 100 28 | * word1 and word2 consist of lowercase English letters. 29 | 30 | Leetcode link: https://leetcode.com/problems/merge-strings-alternately/description/ 31 | 32 | **/ 33 | 34 | public class MergeStringsAlternately { 35 | public String mergeAlternately(String word1, String word2) { 36 | int p1 = 0; 37 | int p2 = 0; 38 | StringBuilder mergedWord = new StringBuilder(); 39 | 40 | while (p1 < word1.length() && p2 < word2.length()) { 41 | char wordOneLetter = word1.charAt(p1); 42 | mergedWord.append(wordOneLetter); 43 | p1++; 44 | char wordTwoLetter = word2.charAt(p2); 45 | mergedWord.append(wordTwoLetter); 46 | p2++; 47 | } 48 | if (p1 < word1.length()) { 49 | for (int i = p1; p1 < word1.length(); p1++) { 50 | mergedWord.append(word1.charAt(p1)); 51 | } 52 | } 53 | if (p2 < word2.length()) { 54 | for (int i = p2; p2 < word2.length(); p2++) { 55 | mergedWord.append(word2.charAt(p2)); 56 | } 57 | } 58 | return String.valueOf(mergedWord); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/RemoveVowelsFromAString.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | 3 | import java.util.*; 4 | /**Problem statement: 5 | Given a string s, remove the vowels 'a', 'e', 'i', 'o', and 'u' from it, and return the new string. 6 | 7 | Leetcode link: https://leetcode.com/problems/remove-vowels-from-a-string/description/ 8 | **/ 9 | 10 | public class RemoveVowelsFromAString { 11 | public String removeVowels(String s) { 12 | char [] arr = s.toCharArray(); 13 | StringBuilder result = new StringBuilder(); 14 | for( char c : arr){ 15 | if( ! isVowel(c)){ 16 | result.append (c); 17 | } 18 | } 19 | 20 | return String.valueOf(result); 21 | 22 | } 23 | public static boolean isVowel(char c){ 24 | return c =='a' || c =='e'|| c == 'i'|| c == 'o' || c == 'u'; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/ReverseWordsInAStringIII.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | * 5 | Given a string s, reverse the order of characters in each word within a sentence while still preserving whitespace and initial word order. 6 | 7 | Example 1: 8 | Input: s = "Let's take LeetCode contest" 9 | Output: "s'teL ekat edoCteeL tsetnoc" 10 | Example 2: 11 | 12 | Input: s = "God Ding" 13 | Output: "doG gniD" 14 | 15 | Constraints: 16 | 1 <= s.length <= 5 * 104 17 | s contains printable ASCII characters. 18 | s does not contain any leading or trailing spaces. 19 | There is at least one word in s. 20 | All the words in s are separated by a single space. 21 | 22 | Leetcode link: https://leetcode.com/problems/reverse-words-in-a-string-iii/description/ 23 | **/ 24 | public class ReverseWordsInAStringIII { 25 | public String reverseWords(String s) { 26 | StringBuilder sb = new StringBuilder(); 27 | String[] parts = s.split(" "); 28 | for (String word: parts) { 29 | System.out.println(word); 30 | reverseWord(word); 31 | sb.append(reverseWord(word)).append(" "); 32 | } 33 | return String.valueOf(sb).trim(); 34 | } 35 | 36 | public static String reverseWord(String word) { 37 | StringBuilder singleWord = new StringBuilder(); 38 | for (int i = word.length() - 1; i > -1; i--) { 39 | singleWord.append(word.charAt(i)); 40 | } 41 | return String.valueOf(singleWord); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/ShuffleString.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | 3 | import java.util.*; 4 | /**Problem statement: 5 | You are given a string s and an integer array indices of the same length. The string s will be shuffled such that the character at the ith position moves to indices[i] in the shuffled string. 6 | 7 | Return the shuffled string. 8 | 9 | Example 1: 10 | Input: s = "codeleet", indices = [4,5,6,7,0,2,1,3] 11 | Output: "leetcode" 12 | Explanation: As shown, "codeleet" becomes "leetcode" after shuffling. 13 | 14 | Leetcode link:https://leetcode.com/problems/shuffle-string/description/ 15 | **/ 16 | public class ShuffleString { 17 | public String restoreString(String s, int[] indices) { 18 | Map map = new HashMap<>(); 19 | char[] arr = s.toCharArray(); 20 | 21 | for (int i = 0; i < arr.length; i++) { 22 | map.put(indices[i], arr[i]); 23 | } 24 | StringBuilder result = new StringBuilder(); 25 | for (int j = 0; j < arr.length; j++) { 26 | result.append(map.get(j)); 27 | } 28 | return result.toString(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/SplitAStringInBalancedStrings.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Balanced strings are those that have an equal quantity of 'L' and 'R' characters. 5 | 6 | Given a balanced string s, split it into some number of substrings such that: 7 | 8 | Each substring is balanced. 9 | Return the maximum number of balanced strings you can obtain. 10 | 11 | 12 | 13 | Example 1: 14 | 15 | Input: s = "RLRRLLRLRL" 16 | Output: 4 17 | Explanation: s can be split into "RL", "RRLL", "RL", "RL", each substring contains same number of 'L' and 'R'. 18 | Example 2: 19 | 20 | Input: s = "RLRRRLLRLL" 21 | Output: 2 22 | Explanation: s can be split into "RL", "RRRLLRLL", each substring contains same number of 'L' and 'R'. 23 | Note that s cannot be split into "RL", "RR", "RL", "LR", "LL", because the 2nd and 5th substrings are not balanced. 24 | Example 3: 25 | 26 | Input: s = "LLLLRRRR" 27 | Output: 1 28 | Explanation: s can be split into "LLLLRRRR". 29 | 30 | Leetcode link: https://leetcode.com/problems/split-a-string-in-balanced-strings/description/ 31 | **/ 32 | 33 | public class SplitAStringInBalancedStrings { 34 | 35 | public int balancedStringSplit(String s) { 36 | int count =0; 37 | 38 | int rCount =0; 39 | int lCount= 0; 40 | 41 | for( int i =0; i< s.length(); i++){ 42 | if(s.charAt(i) == 'R'){ 43 | rCount ++; 44 | 45 | }if(s.charAt(i)== 'L'){ 46 | lCount++; 47 | } 48 | if( rCount == lCount){ 49 | count++; 50 | lCount =0; 51 | rCount=0; 52 | } 53 | } 54 | return count; 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/String2WordEnds.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | 3 | //Given a string and a non-empty word string, return a string made of each char just before and just after 4 | // every appearance of the word in the string. Ignore cases where there is no char before or after 5 | // the word, and a char may be included twice if it is between two words. 6 | // 7 | // 8 | // wordEnds("abcXY123XYijk", "XY") → "c13i" 9 | // wordEnds("XY123XY", "XY") → "13" 10 | // wordEnds("XY1XY", "XY") → "11" 11 | public class String2WordEnds { 12 | 13 | public static void main(String[] args) { 14 | String str= "abcXY123XYijk"; 15 | String word = "XY"; 16 | String result = wordEnds(str, word); 17 | System.out.println(result); 18 | } 19 | 20 | public static String wordEnds(String str, String word) { 21 | StringBuilder sb = new StringBuilder(); 22 | 23 | for (int i = 0; i <= str.length() - word.length(); i++) { 24 | String check = str.substring(i, i + word.length()); 25 | if (check.equals(word)) { 26 | if (i > 0) { 27 | sb.append(str.charAt(i - 1)); 28 | } 29 | if (i + word.length() < str.length()) { 30 | sb.append(str.charAt(i + word.length())); 31 | } 32 | } 33 | } 34 | return sb.toString(); 35 | } 36 | } -------------------------------------------------------------------------------- /src/com/practice/stringproblems/SubstringsOfSizeThreeWithDistinctCharacters.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | A string is good if there are no repeated characters. 5 | 6 | Given a string s, return the number of good substrings of length three in s. 7 | 8 | Note that if there are multiple occurrences of the same substring, every occurrence should be counted. 9 | 10 | A substring is a contiguous sequence of characters in a string. 11 | 12 | Example 1: 13 | 14 | Input: s = "xyzzaz" 15 | Output: 1 16 | Explanation: There are 4 substrings of size 3: "xyz", "yzz", "zza", and "zaz". 17 | The only good substring of length 3 is "xyz". 18 | 19 | Leetcode link: https://leetcode.com/problems/substrings-of-size-three-with-distinct-characters/description/ 20 | **/ 21 | public class SubstringsOfSizeThreeWithDistinctCharacters { 22 | public int countGoodSubstrings(String s) { 23 | int count =0; 24 | for( int i =0; i< s.length()-2; i++){ 25 | String check = s.substring(i, i+3); 26 | Set set = new HashSet<>(); 27 | for(char c: check.toCharArray()){ 28 | set.add(c); 29 | } 30 | if(set.size() == 3){ 31 | count ++; 32 | } 33 | } 34 | return count; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/ToLowerCase.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | Given a string s, return the string after replacing every uppercase letter with the same lowercase letter. 5 | Example 1: 6 | 7 | Input: s = "Hello" 8 | Output: "hello" 9 | Example 2: 10 | 11 | Input: s = "here" 12 | Output: "here" 13 | Example 3: 14 | 15 | Input: s = "LOVELY" 16 | Output: "lovely" 17 | 18 | Constraints: 19 | 1 <= s.length <= 100 20 | s consists of printable ASCII characters. 21 | Leetcode link: https://leetcode.com/problems/to-lower-case/description/ 22 | **/ 23 | public class ToLowerCase { 24 | public String toLowerCase(String s) { 25 | 26 | StringBuilder result = new StringBuilder(); 27 | char a = 'a'; 28 | for (int i = 0; i < s.length(); i++) { 29 | char letter = s.charAt(i); 30 | if (letter < a) { 31 | result.append(String.valueOf(letter).toLowerCase()); 32 | } else { 33 | result.append(letter); 34 | } 35 | } 36 | 37 | return String.valueOf(result); 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/TruncateSentence.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | 3 | /**Problem statement: 4 | A sentence is a list of words that are separated by a single space with no leading or trailing spaces. Each of the words consists of only uppercase and lowercase English letters (no punctuation). 5 | 6 | For example, "Hello World", "HELLO", and "hello world hello world" are all sentences. 7 | You are given a sentence s​​​​​​ and an integer k​​​​​​. You want to truncate s​​​​​​ such that it contains only the first k​​​​​​ words. Return s​​​​​​ after truncating it. 8 | 9 | Example 1: 10 | Input: s = "Hello how are you Contestant", k = 4 11 | Output: "Hello how are you" 12 | Explanation: 13 | The words in s are ["Hello", "how" "are", "you", "Contestant"]. 14 | The first 4 words are ["Hello", "how", "are", "you"]. 15 | Hence, you should return "Hello how are you". 16 | 17 | Constraints: 18 | 1 <= s.length <= 500 19 | k is in the range [1, the number of words in s]. 20 | s consist of only lowercase and uppercase English letters and spaces. 21 | The words in s are separated by a single space. 22 | There are no leading or trailing spaces. 23 | 24 | Leetcode link: https://leetcode.com/problems/truncate-sentence/description/ 25 | 26 | **/ 27 | 28 | public class TruncateSentence { 29 | 30 | public String truncateSentence(String s, int k) { 31 | StringBuilder result = new StringBuilder(); 32 | 33 | String[] parts = s.split(" "); 34 | 35 | for (int i = 0; i < k; i++) { 36 | result.append(parts[i]).append(" "); 37 | } 38 | return String.valueOf(result).trim(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/UniqueMorseCodeWords.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | 3 | import java.util.*; 4 | /**Problem statement: 5 | International Morse Code defines a standard encoding where each letter is mapped to a series of dots and dashes, as follows: 6 | 7 | 'a' maps to ".-", 8 | 'b' maps to "-...", 9 | 'c' maps to "-.-.", and so on. 10 | For convenience, the full table for the 26 letters of the English alphabet is given below: 11 | 12 | [".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."] 13 | Given an array of strings words where each word can be written as a concatenation of the Morse code of each letter. 14 | 15 | For example, "cab" can be written as "-.-..--...", which is the concatenation of "-.-.", ".-", and "-...". We will call such a concatenation the transformation of a word. 16 | Return the number of different transformations among all words we have. 17 | 18 | Example 1: 19 | Input: words = ["gin","zen","gig","msg"] 20 | Output: 2 21 | Explanation: The transformation of each word is: 22 | "gin" -> "--...-." 23 | "zen" -> "--...-." 24 | "gig" -> "--...--." 25 | "msg" -> "--...--." 26 | There are 2 different transformations: "--...-." and "--...--.". 27 | 28 | Constraints: 29 | 1 <= words.length <= 100 30 | 1 <= words[i].length <= 12 31 | words[i] consists of lowercase English letters. 32 | Leetcode https://leetcode.com/problems/unique-morse-code-words/description/ 33 | **/ 34 | 35 | public class UniqueMorseCodeWords { 36 | static String [] morseArr = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."}; 37 | public int uniqueMorseRepresentations(String[] words) { 38 | Set < String > wordSet = new HashSet < > (); 39 | char a = 'a'; 40 | for (String word: words) { 41 | StringBuilder morseWord = new StringBuilder(); 42 | for (int i = 0; i < word.length(); i++) { 43 | char letter = word.charAt(i); 44 | String morseLetter = morseArr[letter - a]; 45 | morseWord.append(morseLetter); 46 | } 47 | wordSet.add(String.valueOf(morseWord)); 48 | } 49 | return wordSet.size(); 50 | 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/com/practice/stringproblems/ValidPalindrome.java: -------------------------------------------------------------------------------- 1 | package com.practice.stringproblems; 2 | import java.util.*; 3 | /**Problem statement: 4 | A phrase is a palindrome if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers. 5 | 6 | Given a string s, return true if it is a palindrome, or false otherwise. 7 | Example 1: 8 | Input: s = "A man, a plan, a canal: Panama" 9 | Output: true 10 | Explanation: "amanaplanacanalpanama" is a palindrome. 11 | 12 | Example 2: 13 | Input: s = "race a car" 14 | Output: false 15 | Explanation: "raceacar" is not a palindrome. 16 | 17 | Example 3: 18 | Input: s = " " 19 | Output: true 20 | Explanation: s is an empty string "" after removing non-alphanumeric characters. 21 | Since an empty string reads the same forward and backward, it is a palindrome. 22 | 23 | Constraints: 24 | 1 <= s.length <= 2 * 105 25 | s consists only of printable ASCII characters. 26 | Leetcode link: https://leetcode.com/problems/valid-palindrome/description/ 27 | **/ 28 | public class ValidPalindrome { 29 | public boolean isPalindrome(String s) { 30 | int begin = 0; 31 | int end = s.length() - 1; 32 | while (begin < end) { 33 | char front = s.charAt(begin); 34 | char back = s.charAt(end); 35 | if (!isAlphanumeric(front)) { 36 | begin++; 37 | } 38 | if (!isAlphanumeric(back)) { 39 | end--; 40 | } 41 | if (isAlphanumeric(front) && isAlphanumeric(back)) { 42 | if (!String.valueOf(front).toLowerCase().equals(String.valueOf(back).toLowerCase())) { 43 | return false; 44 | } else { 45 | begin++; 46 | end--; 47 | } 48 | } 49 | } 50 | return true; 51 | } 52 | public static boolean isAlphanumeric(char c) { 53 | return Character.isLetterOrDigit(c); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/com/practice/systemdesign/LoggerRateLimiter.java: -------------------------------------------------------------------------------- 1 | package com.practice.systemdesign; 2 | import java.util.*; 3 | /**Problem statement: 4 | Design a logger system that receives a stream of messages along with their timestamps. Each unique 5 | message should only be printed at most every 10 seconds (i.e. a message printed at timestamp t will 6 | prevent other identical messages from being printed until timestamp t + 10). 7 | 8 | All messages will come in chronological order. Several messages may arrive at the same timestamp. 9 | 10 | Implement the Logger class: 11 | 12 | Logger() Initializes the logger object. 13 | bool shouldPrintMessage(int timestamp, string message) Returns true if the message should be printed in the 14 | given timestamp, otherwise returns false. 15 | 16 | Leetcode link: https://leetcode.com/problems/logger-rate-limiter/description/ 17 | **/ 18 | 19 | public class LoggerRateLimiter { 20 | Map < String, Integer > map = new HashMap < > (); 21 | class Logger { 22 | 23 | public Logger() {} 24 | } 25 | public boolean shouldPrintMessage(int timestamp, String message) { 26 | if (!map.containsKey(message)) { 27 | map.put(message, timestamp); 28 | return true; 29 | } else { 30 | int prevTimeStamp = map.get(message); 31 | if (timestamp >= prevTimeStamp + 10) { 32 | map.put(message, timestamp); 33 | return true; 34 | } else { 35 | return false; 36 | } 37 | } 38 | 39 | } 40 | } --------------------------------------------------------------------------------