├── .gitignore ├── Hello.java ├── 13-SearchingAlgo ├── SA01_LinearSearch.java └── SA02_BinarySearch.java ├── 01-Math ├── Math03_Sqrt.java ├── Math01_Palindrome.java ├── Math02_PlusOne.java └── Math04_Pow.java ├── 16-TwoPointers ├── TP03_ReverseString.java ├── TP01_ValidPalindrome.java ├── TP06_LongestPalindromicSubstring.java ├── TP12_SortColors.java ├── TP05_ContainerWithMostWater.java ├── TP11_RotateArray.java ├── TP04_MiddleOfLinkedList.java └── TP08_TrappingRainWater.java ├── 02-Array ├── Array33_JumpGame.java ├── Array48_PascalTriangle.java ├── Array17_MaximumProductSubarray.java ├── Array02_BestTimeToBuyAndSellStock.java ├── Array35_LongestIncreasingSubsequence.java ├── Array37_MinimumPathSum.java ├── Array36_MedianOfTwoSortedArrays.java ├── Array21_Search2DMatrix.java ├── Array18_Permutation.java ├── Array16_MaximalSquare.java ├── Array15_KthLargestElementInAnArray.java ├── Array11_SpiralMatrix.java ├── Array27_CoinChange.java ├── Array23_Subsets.java ├── Array08_BestTimeToBuyAndSellStockII.java ├── Array41_PlusOne.java ├── Array19_NumberOfIslands.java ├── Array47_SortColors.java ├── Array03_SingleNumber.java ├── Array44_FindMinimumInRotatedSortedArray.java ├── Array45_MaximumSumCircularSubarray.java ├── Array28_CombinationSum.java ├── Array42_RemoveDuplicatesFromSortedArray.java ├── Array13_ContainerWithMostWater.java ├── Array04_MajorityElement.java ├── Array22_SearchInRotatedSortedArray.java ├── Array40_RotateArray.java ├── Array29_TrappingRainWater.java └── Array05_MissingValue.java ├── 03-String ├── String03_ReverseString.java ├── String01_ValidPalindrome.java ├── String11_GenerateParentheses.java ├── String05_LongestSubstringWithoutRepeatingCharacters.java ├── String04_LongestPalindromicSubstring.java ├── String12_BasicCalculator.java └── String09_LetterCombinationPhoneNumber.java ├── CCI └── Chapter-01 │ ├── C01_09_StringRotation.java │ ├── C01_07_RotateImage.java │ ├── C01_03_URLify.java │ ├── C01_06_StringCompression.java │ ├── C01_08_ZeroMatrix.java │ └── C01_02_CheckPermutation.java ├── 04-Recursion-Backtracking ├── RB07_Pow.java ├── RB08_GenerateParentheses.java ├── RB01_Permutation.java ├── RB02_Subsets.java ├── RB06_PathSum.java ├── RB04_CombinationSum.java └── RB05_LetterCombinationPhoneNumber.java ├── 18-DynamicProgramming ├── DP06_LongestIncreasingSubsequence.java ├── DP07_MinimumPathSum.java ├── DP03_CoinChange.java ├── DP02_UniquePaths.java └── DP08_MaximumSumCircularSubarray.java ├── 06-Stack-Queue ├── Stack01_ValidParentheses.java └── Stack03_BasicCalculator.java ├── 17-BitManipulation ├── BW03_BitwiseANDofNumbersRange.java ├── BM01_NumberOf1Bits.java └── BW02_SingleNumber.java ├── 15-SlidingWindow └── SW01_LongestSubstringWithoutRepeatingCharacters.java ├── 08-BinarySearchTrees ├── BST02_ValidateBinarySearchTree.java └── BST04_MinimumDistanceBetweenBSTNodes.java ├── 07-BinaryTrees ├── BT09_SideView.java ├── BT06_FlattenBinaryTreeToLinkedList.java └── BT07_PathSum.java ├── 05-LinkedList ├── LL03_ReverseLinkedList.java └── LL04_MiddleOfLinkedList.java └── 14-SortingAlgo └── SA04_MergeSort.java /.gitignore: -------------------------------------------------------------------------------- 1 | *.class -------------------------------------------------------------------------------- /Hello.java: -------------------------------------------------------------------------------- 1 | public class Hello { 2 | 3 | public static void main(String[] args) { 4 | System.out.println("let's start DSA again!, this time no breaks..........."); 5 | } 6 | } -------------------------------------------------------------------------------- /13-SearchingAlgo/SA01_LinearSearch.java: -------------------------------------------------------------------------------- 1 | public class SA01_LinearSearch { 2 | 3 | public static void linearSearch(int[] data, int target) { // TC => O(n) 4 | 5 | for (int i = 0; i < data.length; i++) { 6 | if (data[i] == target) { 7 | System.out.println(">> " + target + " found at " + i + "th index"); 8 | return; 9 | } 10 | } 11 | 12 | System.out.println(">> " + target + " not found!"); 13 | } 14 | 15 | public static void main(String[] args) { 16 | 17 | System.out.println("--------------------------------------"); 18 | int[] data = { 5, 4, 1, 3, 2, 8, 7, 4, 3 }; 19 | 20 | linearSearch(data, 3); 21 | System.out.println("--------------------------------------"); 22 | 23 | } 24 | } -------------------------------------------------------------------------------- /13-SearchingAlgo/SA02_BinarySearch.java: -------------------------------------------------------------------------------- 1 | public class SA02_BinarySearch { 2 | 3 | public static void binarySearch(int[] data, int target) { // TC -> O(log(n)) 4 | int startIdx = 0, endIdx = data.length - 1; 5 | int midIdx = 0; 6 | 7 | while (startIdx <= endIdx) { 8 | midIdx = startIdx + (endIdx - startIdx) / 2; 9 | 10 | if (data[midIdx] == target) { 11 | System.out.println(">> " + target + " found at " + midIdx + "th index"); 12 | return; 13 | } else if (data[midIdx] < target) { 14 | startIdx = midIdx + 1; 15 | } else { 16 | endIdx = midIdx - 1; 17 | } 18 | } 19 | System.out.println(">> " + target + " not found!"); 20 | } 21 | 22 | public static void main(String[] args) { 23 | System.out.println("--------------------------------------"); 24 | int[] data = { -11, -5, -2, 0, 1, 1, 10, 15, 55, 65, 65, 69, 90 }; // for binary search always need sorted data 25 | 26 | binarySearch(data, 1); 27 | System.out.println("--------------------------------------"); 28 | 29 | } 30 | } -------------------------------------------------------------------------------- /01-Math/Math03_Sqrt.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC69: Sqrt(x) || https://leetcode.com/problems/sqrtx/ 3 | 4 | 5 | Given a non-negative integer x, return the square root of x rounded down to the nearest integer. The returned integer should be non-negative as well. 6 | 7 | You must not use any built-in exponent function or operator. 8 | 9 | For example, do not use pow(x, 0.5) in c++ or x ** 0.5 in python. 10 | 11 | 12 | Example 1: 13 | 14 | Input: x = 4 15 | Output: 2 16 | Explanation: The square root of 4 is 2, so we return 2. 17 | 18 | Example 2: 19 | 20 | Input: x = 8 21 | Output: 2 22 | Explanation: The square root of 8 is 2.82842..., and since we round it down to the nearest integer, 2 is returned. 23 | 24 | 25 | 26 | Constraints: 27 | 28 | 0 <= x <= 231 - 1 29 | */ 30 | class Sqrt { 31 | 32 | //Time complexity: O(log(n)) || Space complexity: O(1) 33 | public int mySqrt(int x) { 34 | if(x == 0 || x == 1) { 35 | return x; 36 | } 37 | 38 | int start = 0, end = x, mid = 0; 39 | 40 | while(start <= end) { 41 | mid = start + (end-start)/2; 42 | 43 | if(mid*mid == x) { 44 | return mid; 45 | } else if((long)mid * mid > x) { 46 | end = mid-1; 47 | } else { 48 | start = mid+1; 49 | } 50 | } 51 | 52 | return end; 53 | } 54 | } 55 | 56 | public class Math03_Sqrt { 57 | public static void main(String[] args) { 58 | Sqrt obj = new Sqrt(); 59 | int x; 60 | 61 | //example 1 62 | System.out.println("----- example 1 ----"); 63 | x = 16; 64 | System.out.println(obj.mySqrt(x)); 65 | 66 | //example 2 67 | System.out.println("----- example 2 ----"); 68 | x = 27; 69 | System.out.println(obj.mySqrt(x)); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /16-TwoPointers/TP03_ReverseString.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC344: Reverse String || https://leetcode.com/problems/reverse-string 3 | 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 | 9 | Example 1: 10 | Input: s = ["h","e","l","l","o"] 11 | Output: ["o","l","l","e","h"] 12 | 13 | Example 2: 14 | Input: s = ["H","a","n","n","a","h"] 15 | Output: ["h","a","n","n","a","H"] 16 | 17 | 18 | Constraints: 19 | 1 <= s.length <= 105 20 | s[i] is a printable ascii character. 21 | */ 22 | 23 | class ReverseString { 24 | 25 | // Time Complexity: o(n) || Space Complexity: O(1) 26 | public void reverseString(char[] s) { 27 | int start = 0, end = s.length - 1; 28 | 29 | while (start <= end) { 30 | // swap 31 | char temp = s[start]; 32 | s[start] = s[end]; 33 | s[end] = temp; 34 | 35 | // update pointers 36 | start++; 37 | end--; 38 | } 39 | 40 | // additional line -> not a part of code 41 | print(s); 42 | } 43 | 44 | private void print(char[] s) { 45 | System.out.print("["); 46 | for (char ch : s) { 47 | System.out.print(" " + ch + " "); 48 | } 49 | System.out.print("]\n"); 50 | } 51 | } 52 | 53 | public class TP03_ReverseString { 54 | public static void main(String[] args) { 55 | ReverseString obj = new ReverseString(); 56 | 57 | // example 1 58 | char[] s1 = { 'h', 'e', 'l', 'l', 'o' }; 59 | obj.reverseString(s1); 60 | 61 | // example 2 62 | char[] s2 = { 'H', 'a', 'n', 'n', 'a', 'h' }; 63 | obj.reverseString(s2); 64 | 65 | // example 3 66 | char[] s3 = { 'a', 'l', 'f', 'a', 'a', 'r', 'g', 'h', 'y', 'a' }; 67 | obj.reverseString(s3); 68 | } 69 | } -------------------------------------------------------------------------------- /02-Array/Array33_JumpGame.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC55: Jump Game || https://leetcode.com/problems/jump-game/ 3 | 4 | You are given an integer array nums. You are initially positioned at the array's first index, and each element in the array represents your maximum jump length at that position. 5 | 6 | Return true if you can reach the last index, or false otherwise. 7 | 8 | 9 | 10 | Example 1: 11 | 12 | Input: nums = [2,3,1,1,4] 13 | Output: true 14 | Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index. 15 | 16 | Example 2: 17 | 18 | Input: nums = [3,2,1,0,4] 19 | Output: false 20 | Explanation: You will always arrive at index 3 no matter what. Its maximum jump length is 0, which makes it impossible to reach the last index. 21 | 22 | 23 | 24 | Constraints: 25 | 26 | 1 <= nums.length <= 10^4 27 | 0 <= nums[i] <= 10^5 28 | 29 | 30 | */ 31 | 32 | class JumpGame { 33 | //Time Complexity => O(n) || Space Complexity => O(1) 34 | public boolean canJump(int[] nums) { 35 | int reach = 0; 36 | for(int i = 0; i < nums.length; i++ ){ 37 | 38 | //when current position is bigger than max jump 39 | if(i > reach) { 40 | return false; 41 | } 42 | 43 | reach = Math.max(reach, nums[i]+i); 44 | } 45 | 46 | return true; 47 | } 48 | } 49 | 50 | public class Array33_JumpGame { 51 | public static void main(String[] args) { 52 | JumpGame obj = new JumpGame(); 53 | int[] nums; 54 | 55 | //example 1 56 | System.out.println("----- example 1 -----"); 57 | nums = new int[] {3,2,1,0,4}; 58 | System.out.println(obj.canJump(nums)); 59 | 60 | //example 2 61 | System.out.println("----- example 2 -----"); 62 | nums = new int[] {2,3,1,1,4}; 63 | System.out.println(obj.canJump(nums)); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /03-String/String03_ReverseString.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC344: Reverse String || https://leetcode.com/problems/reverse-string 3 | 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 | 9 | Example 1: 10 | Input: s = ["h","e","l","l","o"] 11 | Output: ["o","l","l","e","h"] 12 | 13 | Example 2: 14 | Input: s = ["H","a","n","n","a","h"] 15 | Output: ["h","a","n","n","a","H"] 16 | 17 | 18 | Constraints: 19 | 1 <= s.length <= 105 20 | s[i] is a printable ascii character. 21 | */ 22 | 23 | class ReverseString { 24 | 25 | // Time Complexity: o(n) || Space Complexity: O(1) 26 | public void reverseString(char[] s) { 27 | int start = 0, end = s.length - 1; 28 | 29 | while (start <= end) { 30 | // swap 31 | char temp = s[start]; 32 | s[start] = s[end]; 33 | s[end] = temp; 34 | 35 | // update pointers 36 | start++; 37 | end--; 38 | } 39 | 40 | // additional line -> not a part of code 41 | print(s); 42 | } 43 | 44 | private void print(char[] s) { 45 | System.out.print("["); 46 | for (char ch : s) { 47 | System.out.print(" " + ch + " "); 48 | } 49 | System.out.print("]\n"); 50 | } 51 | } 52 | 53 | public class String03_ReverseString { 54 | public static void main(String[] args) { 55 | ReverseString obj = new ReverseString(); 56 | 57 | // example 1 58 | char[] s1 = { 'h', 'e', 'l', 'l', 'o' }; 59 | obj.reverseString(s1); 60 | 61 | // example 2 62 | char[] s2 = { 'H', 'a', 'n', 'n', 'a', 'h' }; 63 | obj.reverseString(s2); 64 | 65 | // example 3 66 | char[] s3 = { 'a', 'l', 'f', 'a', 'a', 'r', 'g', 'h', 'y', 'a' }; 67 | obj.reverseString(s3); 68 | } 69 | } -------------------------------------------------------------------------------- /CCI/Chapter-01/C01_09_StringRotation.java: -------------------------------------------------------------------------------- 1 | /* 2 | String Rotation: Assume you have a method isSubstring which check if one word is a substring of another. 3 | Given two strings, s1 & s2, write code to check if s2 is a rotation s1 using only one call to isSubstring 4 | 5 | Example: "waterbottle" is rotation of "erbottlewat" 6 | */ 7 | 8 | class Solution { 9 | /** ----------- My Solutions ----------- **/ 10 | // TC => O(1) || SC => O(n+n), where n = str1 length 11 | public boolean solution(String str1, String str2) { 12 | if (str1.length() != str2.length()) { 13 | return false; 14 | } 15 | 16 | // example: "waterbottlewaterbottle" 17 | String stringConcat = str1 + str1; 18 | 19 | // example: now "waterbottlewaterbottle" contains "erbottlewat" 20 | return isSubString(stringConcat, str2); 21 | } 22 | 23 | private boolean isSubString(String s1, String s2) { 24 | return s1.contains(s2); 25 | } 26 | 27 | } 28 | 29 | public class C01_09_StringRotation { 30 | 31 | public static void main(String[] args) { 32 | Solution obj = new Solution(); 33 | String str1, str2; 34 | 35 | // example 1 36 | System.out.println("---- Example 1 ----"); 37 | str1 = "waterbottle"; 38 | str2 = "erbottlewat"; 39 | System.out.println(obj.solution(str1, str2)); 40 | 41 | // example 2 42 | System.out.println("---- Example 2 ----"); 43 | str1 = "alfaarghya"; 44 | str2 = "alfa--devs"; 45 | System.out.println(obj.solution(str1, str2)); 46 | 47 | // example 3 48 | System.out.println("---- Example 3 ----"); 49 | str1 = "abcxyz"; 50 | str2 = "zxabcy"; 51 | System.out.println(obj.solution(str1, str2)); 52 | 53 | } 54 | } -------------------------------------------------------------------------------- /04-Recursion-Backtracking/RB07_Pow.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC50: Pow(x, n) || https://leetcode.com/problems/powx-n/ 3 | 4 | Implement pow(x, n), which calculates x raised to the power n (i.e., xn). 5 | 6 | 7 | 8 | Example 1: 9 | 10 | Input: x = 2.00000, n = 10 11 | Output: 1024.00000 12 | 13 | Example 2: 14 | 15 | Input: x = 2.10000, n = 3 16 | Output: 9.26100 17 | 18 | Example 3: 19 | 20 | Input: x = 2.00000, n = -2 21 | Output: 0.25000 22 | Explanation: 2-2 = 1/22 = 1/4 = 0.25 23 | 24 | 25 | 26 | Constraints: 27 | 28 | -100.0 < x < 100.0 29 | -2^31 <= n <= 2^31-1 30 | n is an integer. 31 | Either x is not zero or n > 0. 32 | -10^4 <= x^n <= 10^4 33 | 34 | */ 35 | 36 | class Pow { 37 | //Time complexity: O(log n) || Space complexity: O(log n) 38 | public double myPow(double x, int n) { 39 | return n < 0 ? 1 / pow(x, -n) : pow(x, n); 40 | } 41 | 42 | public double pow(double x, long n) { 43 | // base class 44 | if (n == 0) { 45 | return 1; 46 | } 47 | /* Logic */ 48 | double val = pow(x, n / 2); 49 | val = val * val; 50 | 51 | return n % 2 == 0 ? val : x * val; 52 | } 53 | } 54 | 55 | public class RB07_Pow { 56 | public static void main(String[] args) { 57 | Pow obj = new Pow(); 58 | double x; 59 | int n; 60 | 61 | //example 1 62 | System.out.println("----- example 1 -----"); 63 | x = 1; 64 | n = 10; 65 | System.out.println(obj.myPow(x, n)); 66 | 67 | //example 2 68 | System.out.println("----- example 2 -----"); 69 | x = -2; 70 | n = 5; 71 | System.out.println(obj.myPow(x, n)); 72 | 73 | //example 3 74 | System.out.println("----- example 3 -----"); 75 | x = 2; 76 | n = -5; 77 | System.out.println(obj.myPow(x, n)); 78 | 79 | //example 4 80 | System.out.println("----- example 3 -----"); 81 | x = 2; 82 | n = -254697; 83 | System.out.println(obj.myPow(x, n)); 84 | } 85 | } -------------------------------------------------------------------------------- /02-Array/Array48_PascalTriangle.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC118: Pascal's Triangle || https://leetcode.com/problems/pascals-triangle/ 3 | 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 | 8 | 9 | Example 1: 10 | 11 | Input: numRows = 5 12 | Output: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 13 | 14 | Example 2: 15 | 16 | Input: numRows = 1 17 | Output: [[1]] 18 | 19 | 20 | Constraints: 21 | 1 <= numRows <= 30 22 | */ 23 | 24 | import java.util.List; 25 | import java.util.ArrayList; 26 | 27 | class PascalTriangle { 28 | // Time Complexity: O(n^2) || Space Complexity: O(n) 29 | public List> generate(int numRows) { 30 | List> list = new ArrayList<>(); 31 | 32 | // calculate values of each row 33 | for (int i = 0; i < numRows; i++) { 34 | 35 | // calculate values 36 | List row = new ArrayList<>(); // temprary store 37 | int val = 1; // first value is always 1 38 | row.add(val); // store first val 39 | 40 | for (int j = 1; j <= i; j++) { 41 | val = ((i + 1 - j) * val) / j; 42 | row.add(val); 43 | } 44 | 45 | // build pascal triangle 46 | list.add(row); 47 | } 48 | 49 | return list; 50 | } 51 | } 52 | 53 | public class Array48_PascalTriangle { 54 | public static void main(String[] args) { 55 | PascalTriangle obj = new PascalTriangle(); 56 | int numRows; 57 | 58 | // example 1 59 | System.out.println("---- example 1 ----"); 60 | numRows = 3; 61 | System.out.println(obj.generate(numRows)); 62 | 63 | // example 2 64 | System.out.println("---- example 2 ----"); 65 | numRows = 5; 66 | System.out.println(obj.generate(numRows)); 67 | 68 | // example 3 69 | System.out.println("---- example 3 ----"); 70 | numRows = 11; 71 | System.out.println(obj.generate(numRows)); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /02-Array/Array17_MaximumProductSubarray.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC152: Maximum Product Subarray || https://leetcode.com/problems/maximum-product-subarray/ 3 | 4 | Given an integer array nums, find a subarray that has the largest product, and return the product. 5 | 6 | The test cases are generated so that the answer will fit in a 32-bit integer. 7 | 8 | 9 | Example 1: 10 | Input: nums = [2,3,-2,4] 11 | Output: 6 12 | Explanation: [2,3] has the largest product 6. 13 | 14 | Example 2: 15 | Input: nums = [-2,0,-1] 16 | Output: 0 17 | Explanation: The result cannot be 2, because [-2,-1] is not a subarray. 18 | 19 | 20 | 21 | Constraints: 22 | 1 <= nums.length <= 2 * 104 23 | -10 <= nums[i] <= 10 24 | The product of any subarray of nums is guaranteed to fit in a 32-bit integer. 25 | */ 26 | 27 | class MaximumProductSubarray { 28 | // TC => O(n) || SC => O(1) 29 | public int maxProduct(int[] nums) { 30 | int max = nums[0], min = nums[0], ans = nums[0]; 31 | 32 | for (int i = 1; i < nums.length; i++) { 33 | int temp = max; 34 | int currentVal = nums[i]; 35 | 36 | // calculate maximum product till this point or element 37 | max = Math.max(currentVal, Math.max(max * currentVal, min * currentVal)); 38 | 39 | // calculate minimum product till this point or element 40 | min = Math.min(currentVal, Math.min(temp * currentVal, min * currentVal)); 41 | 42 | // whenever max is bigger update ans 43 | if (max > ans) { 44 | ans = max; 45 | } 46 | 47 | } 48 | 49 | return ans; 50 | } 51 | } 52 | 53 | public class Array17_MaximumProductSubarray { 54 | public static void main(String[] args) { 55 | MaximumProductSubarray obj = new MaximumProductSubarray(); 56 | 57 | // example 1 58 | System.out.println("---- example 1 ----"); 59 | int[] nums1 = { 3, 2, -2, 1, 2, 5, 0 }; 60 | System.out.println(obj.maxProduct(nums1)); 61 | 62 | // example 2 63 | System.out.println("---- example 2 ----"); 64 | int[] nums2 = { 3, 2, -2, -2, 3, -4, 0, 1, 2 }; 65 | System.out.println(obj.maxProduct(nums2)); 66 | } 67 | } -------------------------------------------------------------------------------- /02-Array/Array02_BestTimeToBuyAndSellStock.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC121: Best Time to Buy and Sell Stock || https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ 3 | 4 | You are given an array prices where prices[i] is the price of a given stock on the ith day. 5 | 6 | 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. 7 | 8 | Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return 0. 9 | 10 | 11 | Example 1: 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 | 17 | Example 2: 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 | 22 | Constraints: 23 | 1 <= prices.length <= 105 24 | 0 <= prices[i] <= 104 25 | */ 26 | 27 | class BestTimeToBuyAndSellStock { 28 | public int approach1(int[] prices) { 29 | int buy = prices[0]; // buy at first day 30 | int profit = 0; // profit on a day 31 | int maxProfit = 0; // maximum profit we can make 32 | 33 | // calculate the maximum profit 34 | for (int i = 1; i < prices.length; i++) { 35 | if (prices[i] < buy) { // for now we can't sell stock, but can buy stock 36 | buy = prices[i]; 37 | } else { // now we can sell stock & earn profit 38 | profit = prices[i] - buy; 39 | maxProfit = Math.max(profit, maxProfit); // find max profit 40 | } 41 | } 42 | 43 | return maxProfit; 44 | } 45 | } 46 | 47 | public class Array02_BestTimeToBuyAndSellStock { 48 | public static void main(String[] args) { 49 | BestTimeToBuyAndSellStock obj = new BestTimeToBuyAndSellStock(); 50 | 51 | // example 1 52 | int[] prices1 = { 7, 1, 5, 3, 6, 4 }; 53 | System.out.println(obj.approach1(prices1)); 54 | 55 | // example 2 56 | int[] prices2 = { 7, 6, 4, 3, 1 }; 57 | System.out.println(obj.approach1(prices2)); 58 | } 59 | } -------------------------------------------------------------------------------- /02-Array/Array35_LongestIncreasingSubsequence.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC300: Longest Increasing Subsequence || https://leetcode.com/problems/longest-increasing-subsequence 3 | 4 | Given an integer array nums, return the length of the longest strictly increasing 5 | 6 | Example 1: 7 | Input: nums = [10,9,2,5,3,7,101,18] 8 | Output: 4 9 | Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4. 10 | 11 | Example 2: 12 | Input: nums = [0,1,0,3,2,3] 13 | Output: 4 14 | 15 | Example 3: 16 | Input: nums = [7,7,7,7,7,7,7] 17 | Output: 1 18 | 19 | 20 | Constraints: 21 | 1 <= nums.length <= 2500 22 | -10^4 <= nums[i] <= 10^4 23 | 24 | 25 | Follow up: Can you come up with an algorithm that runs in O(n log(n)) time complexity? 26 | */ 27 | 28 | import java.util.Arrays; 29 | 30 | class LongestIncreasingSubsequence { 31 | 32 | // Time complexity: O(n^2) || Space Complexity: O(n) 33 | public int lengthOfLIS(int[] nums) { 34 | int n = nums.length; 35 | if (n == 0 || n == 1) { 36 | return n; 37 | } 38 | 39 | int[] dp = new int[n]; 40 | 41 | // fill up dp with 1 42 | Arrays.fill(dp, 1); 43 | 44 | for (int i = 1; i < n; i++) { 45 | for (int j = 0; j < i; j++) { 46 | if (nums[i] > nums[j]) { 47 | dp[i] = Math.max(dp[i], dp[j] + 1); 48 | } 49 | } 50 | } 51 | 52 | // find max Length from dp 53 | int maxLength = 0; 54 | for (int val : dp) { 55 | maxLength = Math.max(maxLength, val); 56 | } 57 | 58 | return maxLength; 59 | } 60 | } 61 | 62 | public class Array35_LongestIncreasingSubsequence { 63 | public static void main(String[] args) { 64 | LongestIncreasingSubsequence obj = new LongestIncreasingSubsequence(); 65 | int[] nums; 66 | 67 | // example 1 68 | System.out.println("----- example 1 -----"); 69 | nums = new int[] { 0, 1, 0, 3, 2, 3, 4 }; 70 | System.out.println(obj.lengthOfLIS(nums)); 71 | 72 | // example 2 73 | System.out.println("----- example 2 -----"); 74 | nums = new int[] { 1, 3, 6, 7, 9, 4, 10, 4, 6 }; 75 | System.out.println(obj.lengthOfLIS(nums)); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /18-DynamicProgramming/DP06_LongestIncreasingSubsequence.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC300: Longest Increasing Subsequence || https://leetcode.com/problems/longest-increasing-subsequence 3 | 4 | Given an integer array nums, return the length of the longest strictly increasing 5 | 6 | Example 1: 7 | Input: nums = [10,9,2,5,3,7,101,18] 8 | Output: 4 9 | Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4. 10 | 11 | Example 2: 12 | Input: nums = [0,1,0,3,2,3] 13 | Output: 4 14 | 15 | Example 3: 16 | Input: nums = [7,7,7,7,7,7,7] 17 | Output: 1 18 | 19 | 20 | Constraints: 21 | 1 <= nums.length <= 2500 22 | -10^4 <= nums[i] <= 10^4 23 | 24 | 25 | Follow up: Can you come up with an algorithm that runs in O(n log(n)) time complexity? 26 | */ 27 | 28 | import java.util.Arrays; 29 | 30 | class LongestIncreasingSubsequence { 31 | 32 | // Time complexity: O(n^2) || Space Complexity: O(n) 33 | public int lengthOfLIS(int[] nums) { 34 | int n = nums.length; 35 | if (n == 0 || n == 1) { 36 | return n; 37 | } 38 | 39 | int[] dp = new int[n]; 40 | 41 | // fill up dp with 1 42 | Arrays.fill(dp, 1); 43 | 44 | for (int i = 1; i < n; i++) { 45 | for (int j = 0; j < i; j++) { 46 | if (nums[i] > nums[j]) { 47 | dp[i] = Math.max(dp[i], dp[j] + 1); 48 | } 49 | } 50 | } 51 | 52 | // find max Length from dp 53 | int maxLength = 0; 54 | for (int val : dp) { 55 | maxLength = Math.max(maxLength, val); 56 | } 57 | 58 | return maxLength; 59 | } 60 | } 61 | 62 | public class DP06_LongestIncreasingSubsequence { 63 | public static void main(String[] args) { 64 | LongestIncreasingSubsequence obj = new LongestIncreasingSubsequence(); 65 | int[] nums; 66 | 67 | // example 1 68 | System.out.println("----- example 1 -----"); 69 | nums = new int[] { 0, 1, 0, 3, 2, 3, 4 }; 70 | System.out.println(obj.lengthOfLIS(nums)); 71 | 72 | // example 2 73 | System.out.println("----- example 2 -----"); 74 | nums = new int[] { 1, 3, 6, 7, 9, 4, 10, 4, 6 }; 75 | System.out.println(obj.lengthOfLIS(nums)); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /02-Array/Array37_MinimumPathSum.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC64: Minimum Path Sum ||https://leetcode.com/problems/minimum-path-sum 3 | 4 | Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right, which minimizes the sum of all numbers along its path. 5 | 6 | Note: You can only move either down or right at any point in time. 7 | 8 | 9 | 10 | Example 1: 11 | 12 | Input: grid = [[1,3,1],[1,5,1],[4,2,1]] 13 | Output: 7 14 | Explanation: Because the path 1 → 3 → 1 → 1 → 1 minimizes the sum. 15 | 16 | Example 2: 17 | 18 | Input: grid = [[1,2,3],[4,5,6]] 19 | Output: 12 20 | 21 | 22 | 23 | Constraints: 24 | 25 | m == grid.length 26 | n == grid[i].length 27 | 1 <= m, n <= 200 28 | 0 <= grid[i][j] <= 200 29 | */ 30 | 31 | class MinimumPathSum { 32 | // Time Complexity: O(m*n) || Space Complexity: O(m*n) 33 | public int minPathSum(int[][] grid) { 34 | // create dp 35 | int m = grid.length, n = grid[0].length; 36 | int[][] dp = new int[m][n]; 37 | 38 | // put grid(0,0) value into dp(0,0) 39 | dp[0][0] = grid[0][0]; 40 | 41 | // fill up first row 42 | for (int j = 1; j < n; j++) { 43 | dp[0][j] = grid[0][j] + dp[0][j - 1]; 44 | } 45 | 46 | // fill up first col 47 | for (int i = 1; i < m; i++) { 48 | dp[i][0] = grid[i][0] + dp[i - 1][0]; 49 | } 50 | 51 | // calculate minimum path 52 | for (int i = 1; i < m; i++) { 53 | for (int j = 1; j < n; j++) { 54 | dp[i][j] = grid[i][j] + Math.min(dp[i - 1][j], dp[i][j - 1]); 55 | } 56 | } 57 | 58 | // final answer 59 | return dp[m - 1][n - 1]; 60 | } 61 | } 62 | 63 | public class Array37_MinimumPathSum { 64 | public static void main(String[] args) { 65 | MinimumPathSum obj = new MinimumPathSum(); 66 | int[][] grid; 67 | 68 | //example 1 69 | System.out.println("----- example 1 -----"); 70 | grid = new int[][] {{1,3,1},{1,5,1},{4,2,1}}; 71 | System.out.println(obj.minPathSum(grid)); 72 | 73 | //example 2 74 | System.out.println("----- example 2 -----"); 75 | grid = new int[][] {{5,4,1},{3,6,2},{5,2,5},{4,7,3},{1,2,10}}; 76 | System.out.println(obj.minPathSum(grid)); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /18-DynamicProgramming/DP07_MinimumPathSum.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC64: Minimum Path Sum ||https://leetcode.com/problems/minimum-path-sum 3 | 4 | Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right, which minimizes the sum of all numbers along its path. 5 | 6 | Note: You can only move either down or right at any point in time. 7 | 8 | 9 | 10 | Example 1: 11 | 12 | Input: grid = [[1,3,1],[1,5,1],[4,2,1]] 13 | Output: 7 14 | Explanation: Because the path 1 → 3 → 1 → 1 → 1 minimizes the sum. 15 | 16 | Example 2: 17 | 18 | Input: grid = [[1,2,3],[4,5,6]] 19 | Output: 12 20 | 21 | 22 | 23 | Constraints: 24 | 25 | m == grid.length 26 | n == grid[i].length 27 | 1 <= m, n <= 200 28 | 0 <= grid[i][j] <= 200 29 | */ 30 | 31 | class MinimumPathSum { 32 | // Time Complexity: O(m*n) || Space Complexity: O(m*n) 33 | public int minPathSum(int[][] grid) { 34 | // create dp 35 | int m = grid.length, n = grid[0].length; 36 | int[][] dp = new int[m][n]; 37 | 38 | // put grid(0,0) value into dp(0,0) 39 | dp[0][0] = grid[0][0]; 40 | 41 | // fill up first row 42 | for (int j = 1; j < n; j++) { 43 | dp[0][j] = grid[0][j] + dp[0][j - 1]; 44 | } 45 | 46 | // fill up first col 47 | for (int i = 1; i < m; i++) { 48 | dp[i][0] = grid[i][0] + dp[i - 1][0]; 49 | } 50 | 51 | // calculate minimum path 52 | for (int i = 1; i < m; i++) { 53 | for (int j = 1; j < n; j++) { 54 | dp[i][j] = grid[i][j] + Math.min(dp[i - 1][j], dp[i][j - 1]); 55 | } 56 | } 57 | 58 | // final answer 59 | return dp[m - 1][n - 1]; 60 | } 61 | } 62 | 63 | public class DP07_MinimumPathSum { 64 | public static void main(String[] args) { 65 | MinimumPathSum obj = new MinimumPathSum(); 66 | int[][] grid; 67 | 68 | //example 1 69 | System.out.println("----- example 1 -----"); 70 | grid = new int[][] {{1,3,1},{1,5,1},{4,2,1}}; 71 | System.out.println(obj.minPathSum(grid)); 72 | 73 | //example 2 74 | System.out.println("----- example 2 -----"); 75 | grid = new int[][] {{5,4,1},{3,6,2},{5,2,5},{4,7,3},{1,2,10}}; 76 | System.out.println(obj.minPathSum(grid)); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /03-String/String01_ValidPalindrome.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC125: Valid Palindrome || https://leetcode.com/problems/valid-palindrome/ 3 | 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 | 8 | 9 | Example 1: 10 | Input: s = "A man, a plan, a canal: Panama" 11 | Output: true 12 | Explanation: "amanaplanacanalpanama" is a palindrome. 13 | 14 | Example 2: 15 | Input: s = "race a car" 16 | Output: false 17 | Explanation: "raceacar" is not a palindrome. 18 | 19 | Example 3: 20 | Input: s = " " 21 | Output: true 22 | Explanation: s is an empty string "" after removing non-alphanumeric characters. 23 | Since an empty string reads the same forward and backward, it is a palindrome. 24 | 25 | 26 | Constraints: 27 | 1 <= s.length <= 2 * 105 28 | s consists only of printable ASCII characters. 29 | */ 30 | 31 | class ValidPalindrome { 32 | public boolean approach1(String s) { 33 | if (s == " ") { // when it is empty string 34 | return false; 35 | } 36 | 37 | int startIndex = 0, endIndex = s.length() - 1; 38 | 39 | while (startIndex <= endIndex) { 40 | char char1 = s.charAt(startIndex), char2 = s.charAt(endIndex); 41 | if (!Character.isLetterOrDigit(char1)) { 42 | startIndex++; 43 | } else if (!Character.isLetterOrDigit(char2)) { 44 | endIndex--; 45 | } else { 46 | if (Character.toLowerCase(char1) != Character.toLowerCase(char2)) { 47 | return false; 48 | } 49 | startIndex++; 50 | endIndex--; 51 | } 52 | } 53 | 54 | return true; 55 | } 56 | } 57 | 58 | public class String01_ValidPalindrome { 59 | public static void main(String[] args) { 60 | ValidPalindrome obj = new ValidPalindrome(); 61 | 62 | // example 1 63 | String s1 = "race a car"; 64 | System.out.println(obj.approach1(s1)); 65 | 66 | // example 2 67 | String s2 = "ab1d23ba5"; 68 | System.out.println(obj.approach1(s2)); 69 | 70 | // example 3 71 | String s3 = "rAcE caR"; 72 | System.out.println(obj.approach1(s3)); 73 | } 74 | } -------------------------------------------------------------------------------- /16-TwoPointers/TP01_ValidPalindrome.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC125: Valid Palindrome || https://leetcode.com/problems/valid-palindrome/ 3 | 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 | 8 | 9 | Example 1: 10 | Input: s = "A man, a plan, a canal: Panama" 11 | Output: true 12 | Explanation: "amanaplanacanalpanama" is a palindrome. 13 | 14 | Example 2: 15 | Input: s = "race a car" 16 | Output: false 17 | Explanation: "raceacar" is not a palindrome. 18 | 19 | Example 3: 20 | Input: s = " " 21 | Output: true 22 | Explanation: s is an empty string "" after removing non-alphanumeric characters. 23 | Since an empty string reads the same forward and backward, it is a palindrome. 24 | 25 | 26 | Constraints: 27 | 1 <= s.length <= 2 * 105 28 | s consists only of printable ASCII characters. 29 | */ 30 | 31 | class ValidPalindrome { 32 | public boolean approach1(String s) { 33 | if (s == " ") { // when it is empty string 34 | return false; 35 | } 36 | 37 | int startIndex = 0, endIndex = s.length() - 1; 38 | 39 | while (startIndex <= endIndex) { 40 | char char1 = s.charAt(startIndex), char2 = s.charAt(endIndex); 41 | if (!Character.isLetterOrDigit(char1)) { 42 | startIndex++; 43 | } else if (!Character.isLetterOrDigit(char2)) { 44 | endIndex--; 45 | } else { 46 | if (Character.toLowerCase(char1) != Character.toLowerCase(char2)) { 47 | return false; 48 | } 49 | startIndex++; 50 | endIndex--; 51 | } 52 | } 53 | 54 | return true; 55 | } 56 | } 57 | 58 | public class TP01_ValidPalindrome { 59 | public static void main(String[] args) { 60 | ValidPalindrome obj = new ValidPalindrome(); 61 | 62 | // example 1 63 | String s1 = "race a car"; 64 | System.out.println(obj.approach1(s1)); 65 | 66 | // example 2 67 | String s2 = "ab1d23ba5"; 68 | System.out.println(obj.approach1(s2)); 69 | 70 | // example 3 71 | String s3 = "rAcE caR"; 72 | System.out.println(obj.approach1(s3)); 73 | } 74 | } -------------------------------------------------------------------------------- /02-Array/Array36_MedianOfTwoSortedArrays.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC04: Median of Two Sorted Arrays || https://leetcode.com/problems/median-of-two-sorted-arrays 3 | 4 | 5 | Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays. 6 | 7 | The overall run time complexity should be O(log (m+n)). 8 | 9 | 10 | 11 | Example 1: 12 | 13 | Input: nums1 = [1,3], nums2 = [2] 14 | Output: 2.00000 15 | Explanation: merged array = [1,2,3] and median is 2. 16 | 17 | Example 2: 18 | 19 | Input: nums1 = [1,2], nums2 = [3,4] 20 | Output: 2.50000 21 | Explanation: merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5. 22 | 23 | 24 | 25 | Constraints: 26 | 27 | nums1.length == m 28 | nums2.length == n 29 | 0 <= m <= 1000 30 | 0 <= n <= 1000 31 | 1 <= m + n <= 2000 32 | -10^6 <= nums1[i], nums2[i] <= 10^6 33 | */ 34 | 35 | class MedianOfTwoSortedArrays { 36 | //Time Complexity: O(m+n) || Space Complexity => O(m+n) 37 | public double findMedianSortedArrays(int[] nums1, int[] nums2) { 38 | int m = nums1.length, n = nums2.length; 39 | int[] nums = new int[m+n]; 40 | 41 | //merge 2 arrays into nums 42 | int i = 0, j = 0, k = 0; 43 | while(i < m && j < n) { 44 | if(nums1[i] < nums2[j]) { 45 | nums[k++] = nums1[i++]; 46 | } else { 47 | nums[k++] = nums2[j++]; 48 | } 49 | } 50 | 51 | while(i < m) { 52 | nums[k++] = nums1[i++]; 53 | } 54 | while(j < n) { 55 | nums[k++] = nums2[j++]; 56 | } 57 | 58 | //find the median 59 | double median = 0.0; 60 | 61 | if((m+n) % 2 == 1) { //odd 62 | median = (double) nums[(m+n)/2]; 63 | } else {//even 64 | median = (double) (nums[(m+n)/2]+nums[(m+n)/2 - 1])/2.0d; 65 | } 66 | 67 | return median; 68 | } 69 | } 70 | 71 | public class Array36_MedianOfTwoSortedArrays { 72 | public static void main(String[] args) { 73 | MedianOfTwoSortedArrays obj = new MedianOfTwoSortedArrays(); 74 | int[] nums1, nums2; 75 | 76 | //example 1 77 | System.out.println("----- example 1 -----"); 78 | nums1 = new int[] {2,4,5,7,9}; 79 | nums2 = new int[] {1,3,5,6,8,8,10}; 80 | System.out.println(obj.findMedianSortedArrays(nums1, nums2)); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /02-Array/Array21_Search2DMatrix.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC74: Search a 2D Matrix || https://leetcode.com/problems/search-a-2d-matrix 3 | 4 | 5 | You are given an m x n integer matrix matrix with the following two properties: 6 | 7 | + Each row is sorted in non-decreasing order. 8 | + The first integer of each row is greater than the last integer of the previous row. 9 | 10 | Given an integer target, return true if target is in matrix or false otherwise. 11 | 12 | You must write a solution in O(log(m * n)) time complexity. 13 | 14 | 15 | 16 | Example 1: 17 | 18 | Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3 19 | Output: true 20 | 21 | Example 2: 22 | 23 | Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13 24 | Output: false 25 | 26 | 27 | 28 | Constraints: 29 | m == matrix.length 30 | n == matrix[i].length 31 | 1 <= m, n <= 100 32 | -104 <= matrix[i][j], target <= 104 33 | */ 34 | 35 | class Search2DMatrix { 36 | // Binary Search on 2D matrix 37 | // TC => O(log(m*n)) || SC => O(1) 38 | public boolean searchMatrix(int[][] matrix, int target) { 39 | int m = matrix.length, n = matrix[0].length; 40 | 41 | // two pointers 42 | int start = 0, end = m * n - 1; 43 | int mid = 0; 44 | 45 | while (start <= end) { 46 | mid = start + (end - start) / 2; 47 | int midValue = matrix[mid / n][mid % n]; 48 | 49 | if (target == midValue) { 50 | return true; 51 | } else if (target < midValue) { 52 | end = mid - 1; 53 | } else { 54 | start = mid + 1; 55 | } 56 | } 57 | 58 | return false; 59 | } 60 | 61 | } 62 | 63 | public class Array21_Search2DMatrix { 64 | public static void main(String[] args) { 65 | Search2DMatrix obj = new Search2DMatrix(); 66 | 67 | // example 1 68 | System.out.println("---- example 1 ----"); 69 | int[][] matrix1 = { { 1, 3, 5, 7 }, { 10, 11, 16, 20 }, { 23, 30, 34, 60 } }; 70 | int target1 = 3; 71 | System.out.println(obj.searchMatrix(matrix1, target1)); 72 | 73 | // example 2 74 | System.out.println("---- example 2 ----"); 75 | int[][] matrix2 = { { 1, 3, 5, 7 }, { 10, 11, 16, 20 }, { 23, 30, 34, 60 } }; 76 | int target2 = 7; 77 | System.out.println(obj.searchMatrix(matrix2, target2)); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /03-String/String11_GenerateParentheses.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC22: Generate Parentheses || https://leetcode.com/problems/generate-parentheses/ 3 | 4 | Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. 5 | 6 | 7 | 8 | Example 1: 9 | 10 | Input: n = 3 11 | Output: ["((()))","(()())","(())()","()(())","()()()"] 12 | 13 | Example 2: 14 | 15 | Input: n = 1 16 | Output: ["()"] 17 | 18 | 19 | 20 | Constraints: 21 | 22 | 1 <= n <= 8 23 | 24 | */ 25 | 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | 29 | class GenerateParentheses { 30 | 31 | //Time complexity: O(4^n / sqrt(n)) || Space Complexity: O(4^n / sqrt(n) * n) 32 | public List generateParenthesis(int n) { 33 | List list = new ArrayList<>(); 34 | helper(n, 0, 0, new StringBuilder(""), list); 35 | 36 | return list ; 37 | } 38 | 39 | private void helper(int n, int open, int close, StringBuilder sb, List list) { 40 | //base case 41 | if(sb.length() == n*2) { 42 | list.add(sb.toString()); 43 | return; 44 | } 45 | 46 | //put open brackets 47 | if(open < n) { 48 | sb.append('('); 49 | helper(n, open+1, close, sb, list); //recurssive call 50 | sb.deleteCharAt(sb.length()-1); //backtrack step 51 | } 52 | 53 | //put close brackets 54 | if(close < open) { 55 | sb.append(')'); 56 | helper(n, open, close+1, sb, list); //recurssive call 57 | sb.deleteCharAt(sb.length()-1); //backtrack step 58 | } 59 | } 60 | } 61 | 62 | public class String11_GenerateParentheses { 63 | public static void main(String[] args) { 64 | GenerateParentheses obj = new GenerateParentheses(); 65 | int n; 66 | 67 | //example 1 68 | System.out.println("----- example 1 -----"); 69 | n = 3; 70 | System.out.println(obj.generateParenthesis(n)); 71 | System.out.println(obj.generateParenthesis(n).size()); 72 | 73 | //example 2 74 | System.out.println("----- example 2 -----"); 75 | n = 5; 76 | System.out.println(obj.generateParenthesis(n)); 77 | System.out.println(obj.generateParenthesis(n).size()); 78 | 79 | //example 3 80 | // System.out.println("----- example 3 -----"); 81 | // n = 8; 82 | // System.out.println(obj.generateParenthesis(n)); 83 | } 84 | } -------------------------------------------------------------------------------- /06-Stack-Queue/Stack01_ValidParentheses.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC20: Valid Parentheses || https://leetcode.com/problems/valid-parentheses/ 3 | Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. 4 | 5 | An input string is valid if: 6 | - Open brackets must be closed by the same type of brackets. 7 | - Open brackets must be closed in the correct order. 8 | - Every close bracket has a corresponding open bracket of the same type. 9 | 10 | 11 | Example 1: 12 | Input: s = "()" 13 | Output: true 14 | 15 | Example 2: 16 | Input: s = "()[]{}" 17 | Output: true 18 | 19 | Example 3: 20 | Input: s = "(]" 21 | Output: false 22 | 23 | Example 4: 24 | Input: s = "([])" 25 | Output: true 26 | 27 | Constraints: 28 | 1 <= s.length <= 104 29 | s consists of parentheses only '()[]{}'. 30 | */ 31 | 32 | import java.util.Stack; 33 | 34 | class ValidParentheses { 35 | 36 | // TC: O(n) || SC: O(n) 37 | public boolean approach1(String s) { 38 | Stack stk = new Stack<>(); 39 | 40 | for (char ch : s.toCharArray()) { 41 | // if it's open bracket -> push it to stk 42 | if (ch == '(' || ch == '{' || ch == '[') { 43 | stk.push(ch); 44 | } else { 45 | // if stk is empty -> return false 46 | if (stk.isEmpty()) { 47 | return false; 48 | } 49 | 50 | char top = stk.peek(); 51 | // if it's close bracket with same type -> pop it from stk 52 | if (top == '(' && ch == ')' || 53 | top == '{' && ch == '}' || 54 | top == '[' && ch == ']') { 55 | stk.pop(); 56 | } else { 57 | return false; 58 | } 59 | } 60 | } 61 | 62 | // check stk is empty or not 63 | return stk.isEmpty(); 64 | } 65 | } 66 | 67 | public class Stack01_ValidParentheses { 68 | public static void main(String[] args) { 69 | String s1 = "()"; 70 | String s2 = "(){}[]"; 71 | String s3 = "(])"; 72 | String s4 = "())"; 73 | String s5 = "]"; 74 | 75 | ValidParentheses vp = new ValidParentheses(); 76 | 77 | System.out.println(vp.approach1(s1)); 78 | System.out.println(vp.approach1(s2)); 79 | System.out.println(vp.approach1(s3)); 80 | System.out.println(vp.approach1(s4)); 81 | System.out.println(vp.approach1(s5)); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /04-Recursion-Backtracking/RB08_GenerateParentheses.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC22: Generate Parentheses || https://leetcode.com/problems/generate-parentheses/ 3 | 4 | Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. 5 | 6 | 7 | 8 | Example 1: 9 | 10 | Input: n = 3 11 | Output: ["((()))","(()())","(())()","()(())","()()()"] 12 | 13 | Example 2: 14 | 15 | Input: n = 1 16 | Output: ["()"] 17 | 18 | 19 | 20 | Constraints: 21 | 22 | 1 <= n <= 8 23 | 24 | */ 25 | 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | 29 | class GenerateParentheses { 30 | 31 | //Time complexity: O(4^n / sqrt(n)) || Space Complexity: O(4^n / sqrt(n) * n) 32 | public List generateParenthesis(int n) { 33 | List list = new ArrayList<>(); 34 | helper(n, 0, 0, new StringBuilder(""), list); 35 | 36 | return list ; 37 | } 38 | 39 | private void helper(int n, int open, int close, StringBuilder sb, List list) { 40 | //base case 41 | if(sb.length() == n*2) { 42 | list.add(sb.toString()); 43 | return; 44 | } 45 | 46 | //put open brackets 47 | if(open < n) { 48 | sb.append('('); 49 | helper(n, open+1, close, sb, list); //recurssive call 50 | sb.deleteCharAt(sb.length()-1); //backtrack step 51 | } 52 | 53 | //put close brackets 54 | if(close < open) { 55 | sb.append(')'); 56 | helper(n, open, close+1, sb, list); //recurssive call 57 | sb.deleteCharAt(sb.length()-1); //backtrack step 58 | } 59 | } 60 | } 61 | 62 | public class RB08_GenerateParentheses { 63 | public static void main(String[] args) { 64 | GenerateParentheses obj = new GenerateParentheses(); 65 | int n; 66 | 67 | //example 1 68 | System.out.println("----- example 1 -----"); 69 | n = 3; 70 | System.out.println(obj.generateParenthesis(n)); 71 | System.out.println(obj.generateParenthesis(n).size()); 72 | 73 | //example 2 74 | System.out.println("----- example 2 -----"); 75 | n = 5; 76 | System.out.println(obj.generateParenthesis(n)); 77 | System.out.println(obj.generateParenthesis(n).size()); 78 | 79 | //example 3 80 | // System.out.println("----- example 3 -----"); 81 | // n = 8; 82 | // System.out.println(obj.generateParenthesis(n)); 83 | } 84 | } -------------------------------------------------------------------------------- /17-BitManipulation/BW03_BitwiseANDofNumbersRange.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC201: Bitwise AND of Numbers Range || https://leetcode.com/problems/bitwise-and-of-numbers-range 3 | 4 | Given two integers left and right that represent the range [left, right], return the bitwise AND of all numbers in this range, inclusive. 5 | 6 | 7 | 8 | Example 1: 9 | 10 | Input: left = 5, right = 7 11 | Output: 4 12 | 13 | Example 2: 14 | 15 | Input: left = 0, right = 0 16 | Output: 0 17 | 18 | Example 3: 19 | 20 | Input: left = 1, right = 2147483647 21 | Output: 0 22 | 23 | 24 | 25 | Constraints: 26 | 27 | 0 <= left <= right <= 231 - 1 28 | 29 | */ 30 | 31 | class Solution { 32 | //Brute force 33 | // Time complexity: O(n) || Space complexity: O(1) 34 | public int approach1(int left, int right) { 35 | int ans = left; 36 | int range = left + 1; 37 | 38 | while (range <= right) { 39 | ans &= range; 40 | range++; 41 | } 42 | 43 | return ans; 44 | } 45 | 46 | //time optimal 47 | // Time complexity: O(log(n)) || Space complexity: O(1) 48 | public int approach2(int left, int right) { 49 | int count = 0; 50 | 51 | while (left != right) { 52 | left >>= 1; 53 | right >>= 1; 54 | 55 | count++; 56 | } 57 | 58 | return left << count; 59 | } 60 | } 61 | 62 | public class BW03_BitwiseANDofNumbersRange { 63 | public static void main(String[] args) { 64 | Solution obj = new Solution(); 65 | int left, right; 66 | 67 | //example 1 68 | System.out.println("----- example 1 -----"); 69 | left = 5; right = 5; 70 | // System.out.println(obj.approach1(left, right)); 71 | System.out.println(obj.approach2(left, right)); 72 | 73 | //example 2 74 | System.out.println("----- example 2 -----"); 75 | left = 5; right = 10; 76 | // System.out.println(obj.approach1(left, right)); 77 | System.out.println(obj.approach2(left, right)); 78 | 79 | //example 3 80 | System.out.println("----- example 3 -----"); 81 | left = 5; right = 7; 82 | // System.out.println(obj.approach1(left, right)); 83 | System.out.println(obj.approach2(left, right)); 84 | 85 | //example 4 86 | System.out.println("----- example 4 -----"); 87 | left = 1; right = 2147483647; 88 | // System.out.println(obj.approach1(left, right)); 89 | System.out.println(obj.approach2(left, right)); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /02-Array/Array18_Permutation.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC46: Permutations || https://leetcode.com/problems/permutations 3 | 4 | Given an array nums of distinct integers, return all the possible. You can return the answer in any order. 5 | 6 | 7 | Example 1: 8 | Input: nums = [1,2,3] 9 | Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 10 | 11 | Example 2: 12 | Input: nums = [0,1] 13 | Output: [[0,1],[1,0]] 14 | 15 | Example 3: 16 | Input: nums = [1] 17 | Output: [[1]] 18 | 19 | 20 | Constraints: 21 | 1 <= nums.length <= 6 22 | -10 <= nums[i] <= 10 23 | All the integers of nums are unique. 24 | */ 25 | 26 | import java.util.List; 27 | import java.util.ArrayList; 28 | 29 | class Permutation { 30 | // Time Complexity: O(n!) || Space Complexity: O(n) 31 | public List> permute(int[] nums) { 32 | List> ans = new ArrayList<>(); 33 | backtrack(nums, ans, new ArrayList<>()); 34 | return ans; 35 | } 36 | 37 | private void backtrack(int[] nums, List> ans, List curr) { 38 | // base case 39 | if (nums.length == curr.size()) { 40 | ans.add(new ArrayList<>(curr)); 41 | return; 42 | } 43 | 44 | // permutations 45 | for (int i = 0; i < nums.length; i++) { 46 | if (!curr.contains(nums[i])) { 47 | // add current value in permutation 48 | curr.add(nums[i]); 49 | // recursive call 50 | backtrack(nums, ans, curr); 51 | // backtrack call -> remove last element from curr 52 | curr.remove(curr.size() - 1); 53 | } 54 | } 55 | } 56 | } 57 | 58 | public class Array18_Permutation { 59 | public static void main(String[] args) { 60 | Permutation obj = new Permutation(); 61 | 62 | // example 1 63 | System.out.println("---- example 1 ----"); 64 | System.out.println(obj.permute(new int[] { 1 })); 65 | 66 | // example 2 67 | System.out.println("---- example 2 ----"); 68 | System.out.println(obj.permute(new int[] { 1, 2 })); 69 | 70 | // example 3 71 | System.out.println("---- example 3 ----"); 72 | System.out.println(obj.permute(new int[] { 1, 2, 3 })); 73 | 74 | // example 4 75 | System.out.println("---- example 4 ----"); 76 | System.out.println(obj.permute(new int[] { 4, 2, 1, 3 })); 77 | 78 | // example 5 79 | System.out.println("---- example 5 ----"); 80 | System.out.println(obj.permute(new int[] { 2, 1, 5, 3, 4 })); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /04-Recursion-Backtracking/RB01_Permutation.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC46: Permutations || https://leetcode.com/problems/permutations 3 | 4 | Given an array nums of distinct integers, return all the possible. You can return the answer in any order. 5 | 6 | 7 | Example 1: 8 | Input: nums = [1,2,3] 9 | Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 10 | 11 | Example 2: 12 | Input: nums = [0,1] 13 | Output: [[0,1],[1,0]] 14 | 15 | Example 3: 16 | Input: nums = [1] 17 | Output: [[1]] 18 | 19 | 20 | Constraints: 21 | 1 <= nums.length <= 6 22 | -10 <= nums[i] <= 10 23 | All the integers of nums are unique. 24 | */ 25 | 26 | import java.util.List; 27 | import java.util.ArrayList; 28 | 29 | class Permutation { 30 | // Time Complexity: O(n!) || Space Complexity: O(n) 31 | public List> permute(int[] nums) { 32 | List> ans = new ArrayList<>(); 33 | backtrack(nums, ans, new ArrayList<>()); 34 | return ans; 35 | } 36 | 37 | private void backtrack(int[] nums, List> ans, List curr) { 38 | // base case 39 | if (nums.length == curr.size()) { 40 | ans.add(new ArrayList<>(curr)); 41 | return; 42 | } 43 | 44 | // permutations 45 | for (int i = 0; i < nums.length; i++) { 46 | if (!curr.contains(nums[i])) { 47 | // add current value in permutation 48 | curr.add(nums[i]); 49 | // recursive call 50 | backtrack(nums, ans, curr); 51 | // backtrack call -> remove last element from curr 52 | curr.remove(curr.size() - 1); 53 | } 54 | } 55 | } 56 | } 57 | 58 | public class RB01_Permutation { 59 | public static void main(String[] args) { 60 | Permutation obj = new Permutation(); 61 | 62 | // example 1 63 | System.out.println("---- example 1 ----"); 64 | System.out.println(obj.permute(new int[] { 1 })); 65 | 66 | // example 2 67 | System.out.println("---- example 2 ----"); 68 | System.out.println(obj.permute(new int[] { 1, 2 })); 69 | 70 | // example 3 71 | System.out.println("---- example 3 ----"); 72 | System.out.println(obj.permute(new int[] { 1, 2, 3 })); 73 | 74 | // example 4 75 | System.out.println("---- example 4 ----"); 76 | System.out.println(obj.permute(new int[] { 4, 2, 1, 3 })); 77 | 78 | // example 5 79 | System.out.println("---- example 5 ----"); 80 | System.out.println(obj.permute(new int[] { 2, 1, 5, 3, 4 })); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /02-Array/Array16_MaximalSquare.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC221: Maximal Square || https://leetcode.com/problems/maximal-square 3 | 4 | Given an m x n binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area. 5 | 6 | 7 | Example 1: 8 | Input: matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]] 9 | Output: 4 10 | 11 | Example 2: 12 | Input: matrix = [["0","1"],["1","0"]] 13 | Output: 1 14 | 15 | Example 3: 16 | Input: matrix = [["0"]] 17 | Output: 0 18 | 19 | 20 | 21 | Constraints: 22 | m == matrix.length 23 | n == matrix[i].length 24 | 1 <= m, n <= 300 25 | matrix[i][j] is '0' or '1'. 26 | */ 27 | 28 | class MaximalSquare { 29 | // TC => O(m * n) || SC => O(m * n) 30 | public int maximalSquare(char[][] matrix) { 31 | int m = matrix.length, n = matrix[0].length; 32 | 33 | // no element 34 | if (m == 0 || n == 0) { 35 | return 0; 36 | } 37 | 38 | // initialize 39 | int[][] dp = new int[m][n]; // store the side of square 40 | int side = 0; // store the maximum side we can get 41 | 42 | for (int i = 0; i < m; i++) { 43 | for (int j = 0; j < n; j++) { 44 | // when it's 1 calculate the side 45 | if (matrix[i][j] == '1') { 46 | // only for first row & column put 1 47 | if (i == 0 || j == 0) { 48 | dp[i][j] = 1; 49 | } else { 50 | // find the minimum value between (i-1,j-1), (i,j-1), (i-1,j) & increase by 1 51 | dp[i][j] = Math.min(Math.min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1; 52 | } 53 | 54 | // keep track of maximum side value 55 | side = Math.max(side, dp[i][j]); 56 | } 57 | } 58 | } 59 | 60 | // calculate the area of square 61 | return side * side; 62 | } 63 | } 64 | 65 | public class Array16_MaximalSquare { 66 | public static void main(String[] args) { 67 | MaximalSquare obj = new MaximalSquare(); 68 | 69 | // example 1 70 | System.out.println("---- example 1 ----"); 71 | char[][] matrix1 = { { '1', '0', '1', '0', '0' }, { '1', '0', '1', '1', '1' }, { '1', '1', '1', '1', '1' }, 72 | { '1', '0', '0', '1', '0' } }; 73 | System.out.println(obj.maximalSquare(matrix1)); 74 | 75 | // example 2 76 | System.out.println("---- example 2 ----"); 77 | char[][] matrix2 = { { '0', '1' }, { '1', '0' } }; 78 | System.out.println(obj.maximalSquare(matrix2)); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /02-Array/Array15_KthLargestElementInAnArray.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC215: Kth Largest Element in an Array || https://leetcode.com/problems/kth-largest-element-in-an-array 3 | 4 | 5 | Given an integer array nums and an integer k, return the kth largest element in the array. 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 | 10 | 11 | 12 | Example 1: 13 | Input: nums = [3,2,1,5,6,4], k = 2 14 | Output: 5 15 | 16 | Example 2: 17 | Input: nums = [3,2,3,1,2,4,5,5,6], k = 4 18 | Output: 4 19 | 20 | 21 | Constraints: 22 | 1 <= k <= nums.length <= 105 23 | -104 <= nums[i] <= 104 24 | */ 25 | 26 | import java.util.Arrays; 27 | import java.util.PriorityQueue; 28 | 29 | class KthLargestElement { 30 | // approach 1 - brute force 31 | // TC => O(n log(n)) || SC => O(1) 32 | public int approach1(int[] arr, int k) { 33 | // sort the array 34 | Arrays.sort(arr); 35 | 36 | // run a loop & find the kth largest element 37 | for (int i = arr.length - 1; i >= 0; i--) { 38 | if (k == 1) { 39 | return arr[i]; 40 | } 41 | k--; 42 | } 43 | 44 | return -1; 45 | } 46 | 47 | // approach 2 - Min Heap 48 | // TC => O(n log(k)) || SC => O(k) 49 | public int approach2(int[] arr, int k) { 50 | // create a min heap -> only k number of items will store 51 | PriorityQueue minHeap = new PriorityQueue<>(); 52 | 53 | for (int x : arr) { 54 | // add data into min-heap 55 | minHeap.add(x); 56 | 57 | // if minHeap size is bigger than k -> remove from min heap 58 | if (minHeap.size() > k) { 59 | minHeap.poll(); 60 | } 61 | } 62 | 63 | // at the top of heap, our kth largest integer 64 | return minHeap.peek(); 65 | } 66 | 67 | } 68 | 69 | public class Array15_KthLargestElementInAnArray { 70 | public static void main(String[] args) { 71 | KthLargestElement obj = new KthLargestElement(); 72 | 73 | // example 1 74 | System.out.println("---- example 1 ----"); 75 | int[] arr1 = { 3, 2, 1, 5, 6, 4 }; 76 | int k1 = 2; 77 | System.out.println(obj.approach1(arr1, k1)); 78 | System.out.println(obj.approach2(arr1, k1)); 79 | 80 | // example 2 81 | System.out.println("---- example 2 ----"); 82 | int[] arr2 = { 3, 2, 3, 1, 2, 4, 5, 5, 6 }; 83 | int k2 = 4; 84 | System.out.println(obj.approach1(arr2, k2)); 85 | System.out.println(obj.approach2(arr2, k2)); 86 | 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /03-String/String05_LongestSubstringWithoutRepeatingCharacters.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC03: Longest Substring Without Repeating Characters || https://leetcode.com/problems/longest-substring-without-repeating-characters 3 | 4 | Given a string s, find the length of the longest without duplicate characters. 5 | 6 | 7 | Example 1: 8 | 9 | Input: s = "abcabcbb" 10 | Output: 3 11 | Explanation: The answer is "abc", with the length of 3. 12 | 13 | Example 2: 14 | 15 | Input: s = "bbbbb" 16 | Output: 1 17 | Explanation: The answer is "b", with the length of 1. 18 | 19 | Example 3: 20 | 21 | Input: s = "pwwkew" 22 | Output: 3 23 | Explanation: The answer is "wke", with the length of 3. 24 | Notice that the answer must be a substring, "pwke" is a subsequence and not a substring. 25 | 26 | 27 | Constraints: 28 | 0 <= s.length <= 5 * 104 29 | s consists of English letters, digits, symbols and spaces. 30 | */ 31 | 32 | import java.util.HashSet; 33 | 34 | class LongestSubstring { 35 | 36 | // Time complexity: O(n) || Space complexity: O(1) 37 | public int lengthOfLongestSubstring(String s) { 38 | // empty string 39 | if (s.equals("")) { 40 | return 0; 41 | } 42 | 43 | // initialize 44 | HashSet set = new HashSet<>(); 45 | int maxLen = 0; 46 | int left = 0; 47 | int n = s.length(); 48 | 49 | for (int right = 0; right < n; right++) { 50 | char key = s.charAt(right); 51 | 52 | // remove until we remove the prev duplicate value 53 | while (set.contains(key)) { 54 | set.remove(s.charAt(left)); 55 | left++; 56 | } 57 | 58 | // add current char 59 | set.add(key); 60 | 61 | // calculate max length 62 | maxLen = Math.max(maxLen, right - left + 1); 63 | } 64 | 65 | return maxLen; 66 | } 67 | } 68 | 69 | public class String05_LongestSubstringWithoutRepeatingCharacters { 70 | public static void main(String[] args) { 71 | LongestSubstring obj = new LongestSubstring(); 72 | 73 | // example 1 74 | System.out.println("----- example 1 -----"); 75 | String s1 = "ab11cde2@f234"; 76 | System.out.println(obj.lengthOfLongestSubstring(s1)); 77 | 78 | // example 1 79 | System.out.println("----- example 2 -----"); 80 | String s2 = "ab11cd2e@f234ghi"; 81 | System.out.println(obj.lengthOfLongestSubstring(s2)); 82 | 83 | // example 1 84 | System.out.println("----- example 3 -----"); 85 | String s3 = ""; 86 | System.out.println(obj.lengthOfLongestSubstring(s3)); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /15-SlidingWindow/SW01_LongestSubstringWithoutRepeatingCharacters.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC03: Longest Substring Without Repeating Characters || https://leetcode.com/problems/longest-substring-without-repeating-characters 3 | 4 | Given a string s, find the length of the longest without duplicate characters. 5 | 6 | 7 | Example 1: 8 | 9 | Input: s = "abcabcbb" 10 | Output: 3 11 | Explanation: The answer is "abc", with the length of 3. 12 | 13 | Example 2: 14 | 15 | Input: s = "bbbbb" 16 | Output: 1 17 | Explanation: The answer is "b", with the length of 1. 18 | 19 | Example 3: 20 | 21 | Input: s = "pwwkew" 22 | Output: 3 23 | Explanation: The answer is "wke", with the length of 3. 24 | Notice that the answer must be a substring, "pwke" is a subsequence and not a substring. 25 | 26 | 27 | Constraints: 28 | 0 <= s.length <= 5 * 104 29 | s consists of English letters, digits, symbols and spaces. 30 | */ 31 | 32 | import java.util.HashSet; 33 | 34 | class LongestSubstring { 35 | 36 | // Time complexity: O(n) || Space complexity: O(1) 37 | public int lengthOfLongestSubstring(String s) { 38 | // empty string 39 | if (s.equals("")) { 40 | return 0; 41 | } 42 | 43 | // initialize 44 | HashSet set = new HashSet<>(); 45 | int maxLen = 0; 46 | int left = 0; 47 | int n = s.length(); 48 | 49 | for (int right = 0; right < n; right++) { 50 | char key = s.charAt(right); 51 | 52 | // remove until we remove the prev duplicate value 53 | while (set.contains(key)) { 54 | set.remove(s.charAt(left)); 55 | left++; 56 | } 57 | 58 | // add current char 59 | set.add(key); 60 | 61 | // calculate max length 62 | maxLen = Math.max(maxLen, right - left + 1); 63 | } 64 | 65 | return maxLen; 66 | } 67 | } 68 | 69 | public class SW01_LongestSubstringWithoutRepeatingCharacters { 70 | public static void main(String[] args) { 71 | LongestSubstring obj = new LongestSubstring(); 72 | 73 | // example 1 74 | System.out.println("----- example 1 -----"); 75 | String s1 = "ab11cde2@f234"; 76 | System.out.println(obj.lengthOfLongestSubstring(s1)); 77 | 78 | // example 1 79 | System.out.println("----- example 2 -----"); 80 | String s2 = "ab11cd2e@f234ghi"; 81 | System.out.println(obj.lengthOfLongestSubstring(s2)); 82 | 83 | // example 1 84 | System.out.println("----- example 3 -----"); 85 | String s3 = ""; 86 | System.out.println(obj.lengthOfLongestSubstring(s3)); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /CCI/Chapter-01/C01_07_RotateImage.java: -------------------------------------------------------------------------------- 1 | /* 2 | Rotate Image: Given an image represented by an NxN matrix, where each pixel 3 | in the image is 4 bytes, write a method to rotate the image by 90 degrees. 4 | Can you do it in place? 5 | */ 6 | 7 | import java.util.Arrays; 8 | 9 | class Solution { 10 | /** ----------- My Solutions ----------- **/ 11 | // TC => O(n*n) || SC => O(1), where n = size of matrix[0] 12 | public int[][] solution1(int[][] matrix) { 13 | int n = matrix.length; 14 | 15 | for (int i = 0; i < n; i++) { 16 | for (int j = i; j < n - i - 1; j++) { 17 | int temp = matrix[n - 1 - j][i]; 18 | 19 | // bottom right -> bottom left 20 | matrix[n - 1 - j][i] = matrix[n - 1 - i][n - 1 - j]; 21 | // top right -> bottom right 22 | matrix[n - 1 - i][n - 1 - j] = matrix[j][n - 1 - i]; 23 | // top left -> top right 24 | matrix[j][n - 1 - i] = matrix[i][j]; 25 | // bottom left -> top right 26 | matrix[i][j] = temp; 27 | } 28 | } 29 | 30 | return matrix; 31 | } 32 | 33 | public void printMatrix(int[][] matrix) { 34 | System.out.print("["); 35 | for (int[] row : matrix) { 36 | System.out.print("["); 37 | for (int cell : row) { 38 | System.out.print(" " + cell + " "); 39 | } 40 | System.out.print("]\n"); 41 | } 42 | System.out.print("]\n"); 43 | } 44 | /** ----------- Book Solutions ----------- **/ 45 | 46 | } 47 | 48 | public class C01_07_RotateImage { 49 | 50 | public static void main(String[] args) { 51 | Solution obj = new Solution(); 52 | int[][] matrix; 53 | 54 | // example 1 55 | System.out.println("---- Example 1 ----"); 56 | matrix = new int[][] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; 57 | obj.printMatrix(obj.solution1(matrix)); 58 | 59 | // example 2 60 | System.out.println("---- Example 2 ----"); 61 | matrix = new int[][] { { 5, 1, 9, 11 }, { 2, 4, 8, 10 }, { 13, 3, 6, 7 }, { 15, 14, 12, 16 } }; 62 | ; 63 | obj.printMatrix(obj.solution1(matrix)); 64 | 65 | // example 3 66 | System.out.println("---- Example 3 ----"); 67 | matrix = new int[][] { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 }, { 13, 14, 15, 16 } }; 68 | obj.printMatrix(obj.solution1(matrix)); 69 | 70 | } 71 | } -------------------------------------------------------------------------------- /02-Array/Array11_SpiralMatrix.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC54: Spiral Matrix || https://leetcode.com/problems/spiral-matrix 3 | 4 | Given an m x n matrix, return all elements of the matrix in spiral order. 5 | 6 | Example 1: 7 | Input: matrix = [[1,2,3],[4,5,6],[7,8,9]] 8 | Output: [1,2,3,6,9,8,7,4,5] 9 | 10 | Example 2: 11 | Input: matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]] 12 | Output: [1,2,3,4,8,12,11,10,9,5,6,7] 13 | 14 | Constraints: 15 | 16 | m == matrix.length 17 | n == matrix[i].length 18 | 1 <= m, n <= 10 19 | -100 <= matrix[i][j] <= 100 20 | 21 | 22 | */ 23 | 24 | import java.util.ArrayList; 25 | import java.util.List; 26 | 27 | class SpiralMatrix { 28 | 29 | // Time Complexity: O(m*n) || Space Complexity: O(m+n) 30 | public List spiralOrder(int[][] matrix) { 31 | List list = new ArrayList<>(); 32 | 33 | int startRow = 0, endRow = matrix.length - 1; 34 | int startColumn = 0, endColumn = matrix[0].length - 1; 35 | 36 | while (startRow <= endRow && startColumn <= endColumn) { 37 | // travel top boundary 38 | for (int j = startColumn; j <= endColumn; j++) { 39 | list.add(matrix[startRow][j]); 40 | } 41 | 42 | // travel right boundary 43 | for (int i = startRow + 1; i <= endRow; i++) { 44 | list.add(matrix[i][endColumn]); 45 | } 46 | 47 | // travel bottom boundary 48 | for (int j = endColumn - 1; j >= startColumn; j--) { 49 | if (startRow == endRow) { 50 | break; 51 | } 52 | list.add(matrix[endRow][j]); 53 | } 54 | 55 | // travel left boundary 56 | for (int i = endRow - 1; i >= startRow + 1; i--) { 57 | if (startColumn == endColumn) { 58 | break; 59 | } 60 | list.add(matrix[i][startColumn]); 61 | } 62 | 63 | // update rows & columns 64 | startRow++; 65 | endRow--; 66 | startColumn++; 67 | endColumn--; 68 | } 69 | 70 | return list; 71 | } 72 | } 73 | 74 | public class Array11_SpiralMatrix { 75 | public static void main(String[] args) { 76 | SpiralMatrix obj = new SpiralMatrix(); 77 | 78 | // example 1 79 | System.out.println("---- example 1 ----"); 80 | int[][] data1 = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; 81 | System.out.println(obj.spiralOrder(data1)); 82 | 83 | // example 2 84 | System.out.println("---- example 2 ----"); 85 | int[][] data2 = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } }; 86 | System.out.println(obj.spiralOrder(data2)); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /CCI/Chapter-01/C01_03_URLify.java: -------------------------------------------------------------------------------- 1 | /* 2 | URLify: Write a method to replace all white-spaces in a string with %20. 3 | You may assumed that every string have sufficient spaces at the end to hold the characters 4 | and that you are given the "true" length of the string. 5 | 6 | Examples: 7 | 8 | input: "Mr John Smith ", 13 9 | output: "Mr%20John%20Smith" 10 | 11 | */ 12 | 13 | import java.util.Arrays; 14 | 15 | class Solution { 16 | /** ----------- My Solutions ----------- **/ 17 | // TC => O(n) || SC => O(n), where n is size of str 18 | public String solution1(String str) { 19 | StringBuilder newStr = new StringBuilder(""); 20 | 21 | // trim white-spaces at the beginning and end 22 | str = str.trim(); 23 | 24 | // iterate over the string 25 | for (char ch : str.toCharArray()) { 26 | // found space 27 | if (ch == ' ') { 28 | newStr.append("%20"); 29 | } else { 30 | newStr.append(ch); 31 | } 32 | } 33 | 34 | return newStr.toString(); 35 | } 36 | 37 | /** ----------- Book Solutions ----------- **/ 38 | // TC => O(m) || SC => O(1), where m = trueLength 39 | public String solution2(char[] str, int trueLength) { 40 | int spaceCount = 0; 41 | // count white spaces 42 | for (int i = 0; i < trueLength; i++) { 43 | if (str[i] == ' ') { 44 | spaceCount++; 45 | } 46 | } 47 | 48 | int index = trueLength + spaceCount * 2; 49 | if (trueLength < str.length) 50 | str[trueLength] = '\0'; // end array 51 | 52 | for (int i = trueLength - 1; i >= 0; i--) { 53 | if (str[i] == ' ') { 54 | str[index - 1] = '0'; 55 | str[index - 2] = '2'; 56 | str[index - 3] = '%'; 57 | 58 | index -= 3; 59 | } else { 60 | str[index - 1] = str[i]; 61 | index--; 62 | } 63 | } 64 | 65 | return Arrays.toString(str); 66 | } 67 | 68 | } 69 | 70 | public class C01_03_URLify { 71 | public static void main(String[] args) { 72 | Solution obj = new Solution(); 73 | String str1; 74 | 75 | // example 1 76 | System.out.println("---- Example 1 ----"); 77 | str1 = "Mr John Smith "; 78 | System.out.println(obj.solution1(str1)); 79 | System.out.println(obj.solution2(str1.toCharArray(), 13)); 80 | 81 | } 82 | } -------------------------------------------------------------------------------- /CCI/Chapter-01/C01_06_StringCompression.java: -------------------------------------------------------------------------------- 1 | /* 2 | String Compression: Implement a method to perform basic String compression using the counts 3 | of repeated characters. For example, the string aabcccccaaa would become a2b1c5a3. If the 4 | 'compressed' string would not become smaller than original string should return the 5 | original string. you can assume string has only uppercase and lowercase letters(a-Z). 6 | 7 | */ 8 | 9 | class Solution { 10 | /** ----------- My Solutions ----------- **/ 11 | //TC => O(n) || SC => O(N), where n = size of String, N = size of String builder(ans) 12 | public String solution1(String str) { 13 | int n = str.length(); 14 | if(n == 0 || n == 1) { 15 | return str; 16 | } 17 | 18 | StringBuilder ans = new StringBuilder(); 19 | int[] freq = new int[128]; // to count the frequency 20 | freq[str.charAt(0)-'a']++; // count the first char 21 | 22 | for(int i = 1; i < n; i++) { 23 | char currCh = str.charAt(i); 24 | char prevCh = str.charAt(i-1); 25 | 26 | //when current & previous character does not match 27 | if(currCh != prevCh) { 28 | ans.append(prevCh); //put the prev char into StringBuilder 29 | ans.append(freq[prevCh-'A']); //put the count/freq of the prev char 30 | 31 | freq[prevCh -'A'] = 0; //freq go back to 0 32 | } 33 | 34 | freq[currCh -'A']++;//increase current freq 35 | } 36 | 37 | //put the last character and it's count 38 | ans.append(str.charAt(n-1)); 39 | ans.append(freq[str.charAt(n-1) - 'A']); 40 | 41 | return ans.length() > str.length() ? str : ans.toString(); 42 | } 43 | 44 | /** ----------- Book Solutions ----------- **/ 45 | 46 | } 47 | 48 | public class C01_06_StringCompression { 49 | public static void main(String[] args) { 50 | Solution obj = new Solution(); 51 | String str1; 52 | 53 | // example 1 54 | System.out.println("---- Example 1 ----"); 55 | str1 = "aabcccccaaa"; 56 | System.out.println(obj.solution1(str1)); 57 | 58 | // example 2 59 | System.out.println("---- Example 2 ----"); 60 | str1 = "aBcdEfgHhIj"; 61 | System.out.println(obj.solution1(str1)); 62 | 63 | // example 3 64 | System.out.println("---- Example 3 ----"); 65 | str1 = "alfaarghya"; 66 | System.out.println(obj.solution1(str1)); 67 | 68 | } 69 | } -------------------------------------------------------------------------------- /16-TwoPointers/TP06_LongestPalindromicSubstring.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC5: Longest Palindromic Substring || https://leetcode.com/problems/longest-palindromic-substring 3 | 4 | Given a string s, return the longest in s. 5 | 6 | 7 | Example 1: 8 | 9 | Input: s = "babad" 10 | Output: "bab" 11 | Explanation: "aba" is also a valid answer. 12 | 13 | Example 2: 14 | 15 | Input: s = "cbbd" 16 | Output: "bb" 17 | 18 | 19 | Constraints: 20 | 21 | 1 <= s.length <= 1000 22 | s consist of only digits and English letters. 23 | */ 24 | 25 | class LongestPalindrome { 26 | // approach 1 27 | // TC => O(n^3) || SC => O(1) 28 | public String approach1(String s) { 29 | int n = s.length(); 30 | 31 | for (int length = n; length > 0; length--) { 32 | for (int i = 0; i <= n - length; i++) { 33 | // System.out.println(i + "," + length); 34 | if (isPalindrome(s, i, i + length)) { 35 | return s.substring(i, i + length); 36 | } 37 | } 38 | // System.out.println("-----------"); 39 | } 40 | return ""; 41 | } 42 | private boolean isPalindrome(String s, int i, int j) { 43 | // System.out.println(i + ",," + j); 44 | int left = i, right = j - 1; 45 | 46 | while (left < right) { 47 | if (s.charAt(left) != s.charAt(right)) { 48 | return false; 49 | } 50 | 51 | left++; 52 | right--; 53 | } 54 | 55 | return true; 56 | } 57 | 58 | // approach 2 59 | // TC => O(n^2) || SC => O(1) 60 | public String approach2(String s) { 61 | int start = 0, end = 0; 62 | 63 | for(int i = 0; i < s.length(); i++) { 64 | int oddLen = expandFromCenter(i, i, s); 65 | int evenLen = expandFromCenter(i, i+1, s); 66 | 67 | int maxLen = Math.max(oddLen, evenLen); 68 | 69 | if(maxLen > end - start) { 70 | start = i - (maxLen-1) / 2; 71 | end = i + maxLen/2; 72 | } 73 | } 74 | 75 | return s.substring(start, end+1); 76 | } 77 | private int expandFromCenter(int left, int right, String str) { 78 | while(left >= 0 && right < str.length() && str.charAt(left) == str.charAt(right)) { 79 | left--; 80 | right++; 81 | } 82 | 83 | return right - left - 1; 84 | } 85 | } 86 | 87 | public class TP06_LongestPalindromicSubstring { 88 | public static void main(String[] args) { 89 | LongestPalindrome obj = new LongestPalindrome(); 90 | 91 | // example 1 92 | System.out.println("---- example 1 ----"); 93 | String s1 = "abz12521cdege"; 94 | System.out.println(obj.approach1(s1)); 95 | System.out.println(obj.approach2(s1)); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /03-String/String04_LongestPalindromicSubstring.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC5: Longest Palindromic Substring || https://leetcode.com/problems/longest-palindromic-substring 3 | 4 | Given a string s, return the longest in s. 5 | 6 | 7 | Example 1: 8 | 9 | Input: s = "babad" 10 | Output: "bab" 11 | Explanation: "aba" is also a valid answer. 12 | 13 | Example 2: 14 | 15 | Input: s = "cbbd" 16 | Output: "bb" 17 | 18 | 19 | Constraints: 20 | 21 | 1 <= s.length <= 1000 22 | s consist of only digits and English letters. 23 | */ 24 | 25 | class LongestPalindrome { 26 | // approach 1 27 | // TC => O(n^3) || SC => O(1) 28 | public String approach1(String s) { 29 | int n = s.length(); 30 | 31 | for (int length = n; length > 0; length--) { 32 | for (int i = 0; i <= n - length; i++) { 33 | // System.out.println(i + "," + length); 34 | if (isPalindrome(s, i, i + length)) { 35 | return s.substring(i, i + length); 36 | } 37 | } 38 | // System.out.println("-----------"); 39 | } 40 | return ""; 41 | } 42 | private boolean isPalindrome(String s, int i, int j) { 43 | // System.out.println(i + ",," + j); 44 | int left = i, right = j - 1; 45 | 46 | while (left < right) { 47 | if (s.charAt(left) != s.charAt(right)) { 48 | return false; 49 | } 50 | 51 | left++; 52 | right--; 53 | } 54 | 55 | return true; 56 | } 57 | 58 | // approach 2 59 | // TC => O(n^2) || SC => O(1) 60 | public String approach2(String s) { 61 | int start = 0, end = 0; 62 | 63 | for(int i = 0; i < s.length(); i++) { 64 | int oddLen = expandFromCenter(i, i, s); 65 | int evenLen = expandFromCenter(i, i+1, s); 66 | 67 | int maxLen = Math.max(oddLen, evenLen); 68 | 69 | if(maxLen > end - start) { 70 | start = i - (maxLen-1) / 2; 71 | end = i + maxLen/2; 72 | } 73 | } 74 | 75 | return s.substring(start, end+1); 76 | } 77 | private int expandFromCenter(int left, int right, String str) { 78 | while(left >= 0 && right < str.length() && str.charAt(left) == str.charAt(right)) { 79 | left--; 80 | right++; 81 | } 82 | 83 | return right - left - 1; 84 | } 85 | } 86 | 87 | public class String04_LongestPalindromicSubstring { 88 | public static void main(String[] args) { 89 | LongestPalindrome obj = new LongestPalindrome(); 90 | 91 | // example 1 92 | System.out.println("---- example 1 ----"); 93 | String s1 = "abz12521cdege"; 94 | System.out.println(obj.approach1(s1)); 95 | System.out.println(obj.approach2(s1)); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /02-Array/Array27_CoinChange.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC322: Coin Change || https://leetcode.com/problems/coin-change/ 3 | 4 | 5 | You are given an integer array coins representing coins of different denominations and an integer amount 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 up by any combination of the coins, return -1. 8 | 9 | You may assume that you have an infinite number of each kind of coin. 10 | 11 | 12 | 13 | Example 1: 14 | 15 | Input: coins = [1,2,5], amount = 11 16 | Output: 3 17 | Explanation: 11 = 5 + 5 + 1 18 | 19 | Example 2: 20 | 21 | Input: coins = [2], amount = 3 22 | Output: -1 23 | 24 | Example 3: 25 | 26 | Input: coins = [1], amount = 0 27 | Output: 0 28 | 29 | 30 | 31 | Constraints: 32 | 33 | 1 <= coins.length <= 12 34 | 1 <= coins[i] <= 231 - 1 35 | 0 <= amount <= 104 36 | 37 | */ 38 | 39 | import java.util.Arrays; 40 | 41 | class CoinChange { 42 | 43 | // time complexity: O(c*a) || Space complexity: O(a) 44 | public int coinChange(int[] coins, int amount) { 45 | // store minimum coins for each amount 46 | int[] dp = new int[amount + 1]; 47 | // fill db with values 48 | Arrays.fill(dp, amount + 1); 49 | 50 | // no minimum coin at oth index 51 | dp[0] = 0; 52 | 53 | for (int coin : coins) { 54 | for (int i = coin; i <= amount; i++) { 55 | // find the minimum coins required 56 | dp[i] = Math.min(dp[i], dp[i - coin] + 1); 57 | } 58 | } 59 | 60 | //return minimum coin count or -1 61 | return dp[amount] > amount ? -1 : dp[amount]; 62 | } 63 | } 64 | 65 | public class Array27_CoinChange { 66 | public static void main(String[] args) { 67 | CoinChange obj = new CoinChange(); 68 | int[] coins; 69 | int amount; 70 | 71 | //example 1 72 | System.out.println("---- example 1 ----"); 73 | coins = new int[] {5,1,2}; 74 | amount = 14; 75 | System.out.println(obj.coinChange(coins, amount)); 76 | 77 | //example 2 78 | System.out.println("---- example 2 ----"); 79 | coins = new int[] {2}; 80 | amount = 3; 81 | System.out.println(obj.coinChange(coins, amount)); 82 | 83 | //example 3 84 | System.out.println("---- example 3 ----"); 85 | coins = new int[] {186,419,83,408}; 86 | amount = 6249; 87 | System.out.println(obj.coinChange(coins, amount)); 88 | 89 | //example 4 90 | System.out.println("---- example 4 ----"); 91 | coins = new int[] {1}; 92 | amount = 0; 93 | System.out.println(obj.coinChange(coins, amount)); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /18-DynamicProgramming/DP03_CoinChange.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC322: Coin Change || https://leetcode.com/problems/coin-change/ 3 | 4 | 5 | You are given an integer array coins representing coins of different denominations and an integer amount 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 up by any combination of the coins, return -1. 8 | 9 | You may assume that you have an infinite number of each kind of coin. 10 | 11 | 12 | 13 | Example 1: 14 | 15 | Input: coins = [1,2,5], amount = 11 16 | Output: 3 17 | Explanation: 11 = 5 + 5 + 1 18 | 19 | Example 2: 20 | 21 | Input: coins = [2], amount = 3 22 | Output: -1 23 | 24 | Example 3: 25 | 26 | Input: coins = [1], amount = 0 27 | Output: 0 28 | 29 | 30 | 31 | Constraints: 32 | 33 | 1 <= coins.length <= 12 34 | 1 <= coins[i] <= 231 - 1 35 | 0 <= amount <= 104 36 | 37 | */ 38 | 39 | import java.util.Arrays; 40 | 41 | class CoinChange { 42 | 43 | // time complexity: O(c*a) || Space complexity: O(a) 44 | public int coinChange(int[] coins, int amount) { 45 | // store minimum coins for each amount 46 | int[] dp = new int[amount + 1]; 47 | // fill db with values 48 | Arrays.fill(dp, amount + 1); 49 | 50 | // no minimum coin at oth index 51 | dp[0] = 0; 52 | 53 | for (int coin : coins) { 54 | for (int i = coin; i <= amount; i++) { 55 | // find the minimum coins required 56 | dp[i] = Math.min(dp[i], dp[i - coin] + 1); 57 | } 58 | } 59 | 60 | //return minimum coin count or -1 61 | return dp[amount] > amount ? -1 : dp[amount]; 62 | } 63 | } 64 | 65 | public class DP03_CoinChange { 66 | public static void main(String[] args) { 67 | CoinChange obj = new CoinChange(); 68 | int[] coins; 69 | int amount; 70 | 71 | //example 1 72 | System.out.println("---- example 1 ----"); 73 | coins = new int[] {5,1,2}; 74 | amount = 14; 75 | System.out.println(obj.coinChange(coins, amount)); 76 | 77 | //example 2 78 | System.out.println("---- example 2 ----"); 79 | coins = new int[] {2}; 80 | amount = 3; 81 | System.out.println(obj.coinChange(coins, amount)); 82 | 83 | //example 3 84 | System.out.println("---- example 3 ----"); 85 | coins = new int[] {186,419,83,408}; 86 | amount = 6249; 87 | System.out.println(obj.coinChange(coins, amount)); 88 | 89 | //example 4 90 | System.out.println("---- example 4 ----"); 91 | coins = new int[] {1}; 92 | amount = 0; 93 | System.out.println(obj.coinChange(coins, amount)); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /02-Array/Array23_Subsets.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC78: Subsets || https://leetcode.com/problems/subsets/ 3 | 4 | Given an integer array nums of unique elements, return all possible(the power set). 5 | 6 | The solution set must not contain duplicate subsets. Return the solution in any order. 7 | 8 | 9 | Example 1: 10 | Input: nums = [1,2,3] 11 | Output: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]] 12 | 13 | Example 2: 14 | Input: nums = [0] 15 | Output: [[],[0]] 16 | 17 | 18 | Constraints: 19 | 1 <= nums.length <= 10 20 | -10 <= nums[i] <= 10 21 | All the numbers of nums are unique. 22 | */ 23 | 24 | import java.util.List; 25 | import java.util.ArrayList; 26 | 27 | class Subsets { 28 | 29 | // approach 1 - iterative 30 | public List> approach1(int[] nums) { 31 | List> ans = new ArrayList<>(); 32 | List subset = new ArrayList<>(); 33 | // add empty subset into ans 34 | ans.add(subset); 35 | 36 | // find the subsets 37 | for (int x : nums) { 38 | int n = ans.size(); 39 | for (int i = 0; i < n; i++) { 40 | subset = new ArrayList<>(ans.get(i)); 41 | subset.add(x); 42 | ans.add(new ArrayList<>(subset)); 43 | } 44 | } 45 | 46 | return ans; 47 | } 48 | 49 | // approach 2 - backtracking 50 | // Time complexity: O(2^n) || Space Complexity: O(n) 51 | public List> approach2(int[] nums) { 52 | List> ans = new ArrayList<>(); 53 | backtrack(0, new ArrayList<>(), ans, nums); 54 | return ans; 55 | } 56 | 57 | private void backtrack(int start, List subset, List> ans, int[] nums) { 58 | ans.add(new ArrayList<>(subset)); 59 | 60 | for (int i = start; i < nums.length; i++) { 61 | subset.add(nums[i]); 62 | backtrack(i + 1, subset, ans, nums); 63 | subset.remove(subset.size() - 1); 64 | } 65 | } 66 | } 67 | 68 | public class Array23_Subsets { 69 | public static void main(String[] args) { 70 | Subsets obj = new Subsets(); 71 | 72 | // example 1 73 | System.out.println("---- example 1 ----"); 74 | int[] nums1 = { 0 }; 75 | System.out.println(obj.approach1(nums1)); 76 | System.out.println(obj.approach2(nums1)); 77 | 78 | // example 2 79 | System.out.println("---- example 2 ----"); 80 | int[] nums2 = { 1, 2, 3 }; 81 | System.out.println(obj.approach1(nums2)); 82 | System.out.println(obj.approach2(nums2)); 83 | 84 | // example 3 85 | System.out.println("---- example 3 ----"); 86 | int[] nums3 = { 1, 2, 3, 4, 5 }; 87 | System.out.println(obj.approach1(nums3)); 88 | System.out.println(obj.approach2(nums3)); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /04-Recursion-Backtracking/RB02_Subsets.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC78: Subsets || https://leetcode.com/problems/subsets/ 3 | 4 | Given an integer array nums of unique elements, return all possible(the power set). 5 | 6 | The solution set must not contain duplicate subsets. Return the solution in any order. 7 | 8 | 9 | Example 1: 10 | Input: nums = [1,2,3] 11 | Output: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]] 12 | 13 | Example 2: 14 | Input: nums = [0] 15 | Output: [[],[0]] 16 | 17 | 18 | Constraints: 19 | 1 <= nums.length <= 10 20 | -10 <= nums[i] <= 10 21 | All the numbers of nums are unique. 22 | */ 23 | 24 | import java.util.List; 25 | import java.util.ArrayList; 26 | 27 | class Subsets { 28 | 29 | // approach 1 - iterative 30 | public List> approach1(int[] nums) { 31 | List> ans = new ArrayList<>(); 32 | List subset = new ArrayList<>(); 33 | // add empty subset into ans 34 | ans.add(subset); 35 | 36 | // find the subsets 37 | for (int x : nums) { 38 | int n = ans.size(); 39 | for (int i = 0; i < n; i++) { 40 | subset = new ArrayList<>(ans.get(i)); 41 | subset.add(x); 42 | ans.add(new ArrayList<>(subset)); 43 | } 44 | } 45 | 46 | return ans; 47 | } 48 | 49 | // approach 2 - backtracking 50 | // Time complexity: O(2^n) || Space Complexity: O(n) 51 | public List> approach2(int[] nums) { 52 | List> ans = new ArrayList<>(); 53 | backtrack(0, new ArrayList<>(), ans, nums); 54 | return ans; 55 | } 56 | 57 | private void backtrack(int start, List subset, List> ans, int[] nums) { 58 | ans.add(new ArrayList<>(subset)); 59 | 60 | for (int i = start; i < nums.length; i++) { 61 | subset.add(nums[i]); 62 | backtrack(i + 1, subset, ans, nums); 63 | subset.remove(subset.size() - 1); 64 | } 65 | } 66 | } 67 | 68 | public class RB02_Subsets { 69 | public static void main(String[] args) { 70 | Subsets obj = new Subsets(); 71 | 72 | // example 1 73 | System.out.println("---- example 1 ----"); 74 | int[] nums1 = { 0 }; 75 | System.out.println(obj.approach1(nums1)); 76 | System.out.println(obj.approach2(nums1)); 77 | 78 | // example 2 79 | System.out.println("---- example 2 ----"); 80 | int[] nums2 = { 1, 2, 3 }; 81 | System.out.println(obj.approach1(nums2)); 82 | System.out.println(obj.approach2(nums2)); 83 | 84 | // example 3 85 | System.out.println("---- example 3 ----"); 86 | int[] nums3 = { 1, 2, 3, 4, 5 }; 87 | System.out.println(obj.approach1(nums3)); 88 | System.out.println(obj.approach2(nums3)); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /02-Array/Array08_BestTimeToBuyAndSellStockII.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC122: Best Time to Buy and Sell Stock II || https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ 3 | 4 | You are given an integer array prices where prices[i] is the price of a given stock on the ith day. 5 | 6 | On each day, you may decide to buy and/or sell the stock. You can only hold at most one share of the stock at any time. However, you can buy it then immediately sell it on the same day. 7 | 8 | Find and return the maximum profit you can achieve. 9 | 10 | 11 | Example 1: 12 | Input: prices = [7,1,5,3,6,4] 13 | Output: 7 14 | Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4. 15 | Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3. 16 | Total profit is 4 + 3 = 7. 17 | 18 | Example 2: 19 | Input: prices = [1,2,3,4,5] 20 | Output: 4 21 | Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4. 22 | Total profit is 4. 23 | 24 | Example 3: 25 | Input: prices = [7,6,4,3,1] 26 | Output: 0 27 | Explanation: There is no way to make a positive profit, so we never buy the stock to achieve the maximum profit of 0. 28 | 29 | 30 | Constraints: 31 | 32 | 1 <= prices.length <= 3 * 104 33 | 0 <= prices[i] <= 104 34 | */ 35 | 36 | class BestTimeToBuyAndSellStockII { 37 | // Time Complexity: O(n) || Space Complexity: O(1) 38 | public int approach(int[] prices) { 39 | int buy = prices[0]; // buy at first day 40 | int profit = 0; // profit 41 | 42 | // calculate the maximum profit 43 | for (int i = 1; i < prices.length; i++) { 44 | if (buy < prices[i]) { // now we can sell stock & earn profit 45 | profit += prices[i] - buy; 46 | } 47 | 48 | buy = prices[i]; 49 | } 50 | 51 | return profit; 52 | } 53 | } 54 | 55 | public class Array08_BestTimeToBuyAndSellStockII { 56 | public static void main(String[] args) { 57 | BestTimeToBuyAndSellStockII obj = new BestTimeToBuyAndSellStockII(); 58 | 59 | // example 1 60 | System.out.println("---- example 1 ----"); 61 | int[] prices1 = { 7, 1, 5, 3, 6, 4 }; 62 | System.out.println(obj.approach(prices1)); 63 | 64 | // example 2 65 | System.out.println("---- example 2 ----"); 66 | int[] prices2 = { 7, 6, 4, 3, 1 }; 67 | System.out.println(obj.approach(prices2)); 68 | 69 | // example 3 70 | System.out.println("---- example 3 ----"); 71 | int[] prices3 = { 8, 9, 10, 5, 1, 4, 6, 7 }; 72 | System.out.println(obj.approach(prices3)); 73 | 74 | // example 4 75 | System.out.println("---- example 4 ----"); 76 | int[] prices4 = { 8, 9, 10, 6, 3, 1, 8, 12, 15 }; 77 | System.out.println(obj.approach(prices4)); 78 | } 79 | } -------------------------------------------------------------------------------- /08-BinarySearchTrees/BST02_ValidateBinarySearchTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC98: Validate Binary Search Tree || https://leetcode.com/problems/validate-binary-search-tree/ 3 | 4 | Given the root of a binary tree, determine if it is a valid binary search tree (BST). 5 | 6 | A valid BST is defined as follows: 7 | 8 | The left subtree of a node contains only nodes with keys less than the node's key. 9 | The right subtree of a node contains only nodes with keys greater than the node's key. 10 | Both the left and right subtrees must also be binary search trees. 11 | 12 | 13 | Example 1: 14 | Input: root = [2,1,3] 15 | Output: true 16 | 17 | Example 2: 18 | Input: root = [5,1,4,null,null,3,6] 19 | Output: false 20 | Explanation: The root node's value is 5 but its right child's value is 4. 21 | 22 | 23 | Constraints: 24 | 25 | The number of nodes in the tree is in the range [1, 104]. 26 | -231 <= Node.val <= 231 - 1 27 | */ 28 | 29 | class Node { 30 | int data; 31 | Node left; 32 | Node right; 33 | 34 | Node(int data) { 35 | this.data = data; 36 | this.left = null; 37 | this.right = null; 38 | } 39 | } 40 | 41 | class ValidateBinarySearchTree { 42 | // Time complexity: O(n) || Space Complexity: O(n) 43 | public boolean isValidBST(Node root, long min, long max) { 44 | // base case => if root is null -> true 45 | if (root == null) { 46 | return true; 47 | } 48 | 49 | // check if BST condition is failing 50 | if (!(min < root.data && root.data < max)) { 51 | return false; 52 | } 53 | 54 | // check if both side valid 55 | return isValidBST(root.left, min, root.data) && isValidBST(root.right, root.data, max); 56 | } 57 | } 58 | 59 | public class BST02_ValidateBinarySearchTree { 60 | public static void main(String[] args) { 61 | // example 1 => [5,1,4,null,null,3,6] 62 | System.out.println("---- example 1 ----"); 63 | Node root1 = new Node(5); 64 | root1.left = new Node(1); 65 | root1.right = new Node(4); 66 | root1.right.left = new Node(3); 67 | root1.right.right = new Node(6); 68 | ValidateBinarySearchTree obj1 = new ValidateBinarySearchTree(); 69 | System.out.println(obj1.isValidBST(root1, Long.MIN_VALUE, Long.MAX_VALUE)); 70 | 71 | // example 2 => [5,4,8,null,null,6,9,null,7,null,null] 72 | System.out.println("---- example 2 ----"); 73 | Node root2 = new Node(5); 74 | root2.left = new Node(4); 75 | root2.right = new Node(8); 76 | root2.right.left = new Node(6); 77 | root2.right.left.right = new Node(7); 78 | root2.right.right = new Node(9); 79 | ValidateBinarySearchTree obj2 = new ValidateBinarySearchTree(); 80 | System.out.println(obj2.isValidBST(root2, Long.MIN_VALUE, Long.MAX_VALUE)); 81 | } 82 | } -------------------------------------------------------------------------------- /01-Math/Math01_Palindrome.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC09: Palindrome Number || https://leetcode.com/problems/palindrome-number 3 | 4 | Given an integer x, return true if x is a 5 | palindrome 6 | , and false otherwise. 7 | 8 | 9 | 10 | Example 1: 11 | 12 | Input: x = 121 13 | Output: true 14 | Explanation: 121 reads as 121 from left to right and from right to left. 15 | Example 2: 16 | 17 | Input: x = -121 18 | Output: false 19 | Explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome. 20 | Example 3: 21 | 22 | Input: x = 10 23 | Output: false 24 | Explanation: Reads 01 from right to left. Therefore it is not a palindrome. 25 | 26 | 27 | Constraints: 28 | 29 | -231 <= x <= 231 - 1 30 | 31 | */ 32 | 33 | class Palindrome{ 34 | 35 | // Time complexity -> O(log n) || Space complexity -> O(1) 36 | public boolean approach1(int x) { 37 | int reverse = 0; //store x in reverse order 38 | int original = x; 39 | 40 | while(original > 0) { 41 | reverse = reverse*10 + original % 10; // put values in reverse 42 | original = original/10; //update original 43 | } 44 | 45 | return reverse == x; //check if palindrome 46 | } 47 | 48 | // Time complexity -> O(n) || Space complexity -> O(n) 49 | public boolean approach2(int x) { 50 | String str = Integer.toString(x); //create string from x 51 | int n = str.length(); 52 | 53 | for (int i = 0; i < n / 2; i++) { 54 | if (str.charAt(i) != str.charAt(n - i - 1)) { //check ith char & (n-i-1)th char for palindrome 55 | return false; 56 | } 57 | } 58 | 59 | return true; //palindrome 60 | } 61 | } 62 | public class Math01_Palindrome { 63 | public static void main(String[] args) { 64 | Palindrome obj = new Palindrome(); 65 | int x; 66 | 67 | //example 1 68 | System.out.println("----- example 1 -----"); 69 | x = 5; 70 | System.out.println(obj.approach1(x)); 71 | System.out.println(obj.approach2(x)); 72 | 73 | //example 2 74 | System.out.println("----- example 2 -----"); 75 | x = 121; 76 | System.out.println(obj.approach1(x)); 77 | System.out.println(obj.approach2(x)); 78 | 79 | //example 3 80 | System.out.println("----- example 3 -----"); 81 | x = -121; 82 | System.out.println(obj.approach1(x)); 83 | System.out.println(obj.approach2(x)); 84 | 85 | //example 4 86 | System.out.println("----- example 4 -----"); 87 | x = 1110; 88 | System.out.println(obj.approach1(x)); 89 | System.out.println(obj.approach2(x)); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /07-BinaryTrees/BT09_SideView.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC199: Binary Tree Right Side View || https://leetcode.com/problems/binary-tree-right-side-view 3 | 4 | Given the root of a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom. 5 | 6 | 7 | 8 | Example 1: 9 | 10 | Input: root = [1,2,3,null,5,null,4] 11 | Output: [1,3,4] 12 | 13 | Example 2: 14 | 15 | Input: root = [1,2,3,4,null,null,null,5] 16 | Output: [1,3,4,5] 17 | 18 | Example 3: 19 | 20 | Input: root = [1,null,3] 21 | Output: [1,3] 22 | 23 | Example 4: 24 | 25 | Input: root = [] 26 | Output: [] 27 | 28 | 29 | Constraints: 30 | The number of nodes in the tree is in the range [0, 100]. 31 | -100 <= Node.val <= 100 32 | */ 33 | 34 | import java.util.ArrayList; 35 | import java.util.LinkedList; 36 | import java.util.List; 37 | import java.util.Queue; 38 | 39 | class Node { 40 | int data; 41 | Node left; 42 | Node right; 43 | 44 | Node(int val) { 45 | this.data = val; 46 | this.left = null; 47 | this.right = null; 48 | } 49 | } 50 | 51 | class SideView { 52 | //Time complexity: O(n) || Space Complexity: O(n) 53 | public List rightSideView(Node root) { 54 | List ans = new ArrayList<>(); 55 | List temp = new ArrayList<>(); 56 | 57 | if(root == null) { 58 | return ans; 59 | } 60 | 61 | Queue q = new LinkedList<>(); 62 | q.add(root); //add first node 63 | q.add(null); //null refers to next line 64 | 65 | while(!q.isEmpty()) { 66 | Node curr = q.remove(); 67 | 68 | if(curr == null) { 69 | ans.add(temp.get(temp.size()-1)); //side view -> last element of current level 70 | temp = new ArrayList<>(); 71 | 72 | if(q.isEmpty()) { 73 | break; 74 | } else { 75 | q.add(null); 76 | } 77 | } else { 78 | temp.add(curr.data); 79 | 80 | if(curr.left != null) { 81 | q.add(curr.left); 82 | } 83 | if(curr.right != null) { 84 | q.add(curr.right); 85 | } 86 | } 87 | } 88 | 89 | return ans; 90 | } 91 | } 92 | 93 | public class BT09_SideView { 94 | public static void main(String[] args) { 95 | SideView obj = new SideView(); 96 | 97 | //example 1 98 | System.out.println("----- example 1 -----"); 99 | Node root = new Node(1); 100 | root.left = new Node(2); 101 | root.left.left = new Node(4); 102 | root.left.left.left = new Node(5); 103 | root.right = new Node(3); 104 | 105 | System.out.println(obj.rightSideView(root)); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /01-Math/Math02_PlusOne.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC66: Plus One || https://leetcode.com/problems/plus-one 3 | 4 | 5 | You are given a large integer represented as an integer array digits, where each digits[i] is the ith digit of the integer. The digits are ordered from most significant to least significant in left-to-right order. The large integer does not contain any leading 0's. 6 | 7 | Increment the large integer by one and return the resulting array of digits. 8 | 9 | 10 | 11 | Example 1: 12 | 13 | Input: digits = [1,2,3] 14 | Output: [1,2,4] 15 | Explanation: The array represents the integer 123. 16 | Incrementing by one gives 123 + 1 = 124. 17 | Thus, the result should be [1,2,4]. 18 | 19 | Example 2: 20 | 21 | Input: digits = [4,3,2,1] 22 | Output: [4,3,2,2] 23 | Explanation: The array represents the integer 4321. 24 | Incrementing by one gives 4321 + 1 = 4322. 25 | Thus, the result should be [4,3,2,2]. 26 | 27 | Example 3: 28 | 29 | Input: digits = [9] 30 | Output: [1,0] 31 | Explanation: The array represents the integer 9. 32 | Incrementing by one gives 9 + 1 = 10. 33 | Thus, the result should be [1,0]. 34 | 35 | 36 | 37 | Constraints: 38 | 39 | 1 <= digits.length <= 100 40 | 0 <= digits[i] <= 9 41 | digits does not contain any leading 0's. 42 | */ 43 | 44 | import java.util.Arrays; 45 | 46 | class PlusOne { 47 | //Time complexity: O(n) || Space complexity: O(n) 48 | public int[] plusOne(int[] digits) { 49 | int carry = 0; 50 | int n = digits.length; 51 | 52 | for(int i = n-1; i >= 0; i--) { 53 | //calculate the new value and carry 54 | int plusOne = digits[i] + 1; 55 | carry = plusOne / 10; 56 | digits[i] = plusOne % 10; 57 | 58 | //carry is not 1 -> so return the digits 59 | if(carry == 0) { 60 | return digits; 61 | } 62 | } 63 | 64 | //handle case like -> 999, 99, 9 etc. 65 | int[] ans = new int[n+1]; 66 | ans[0] = carry; 67 | return ans; 68 | } 69 | } 70 | 71 | public class Math02_PlusOne { 72 | public static void main(String[] args) { 73 | PlusOne obj = new PlusOne(); 74 | int[] digits; 75 | 76 | //example 1 77 | System.out.println("----- example 1 -----"); 78 | digits = new int[] {1,2,1}; 79 | System.out.println(Arrays.toString(obj.plusOne(digits))); 80 | 81 | //example 2 82 | System.out.println("----- example 2 -----"); 83 | digits = new int[] {1,2,9}; 84 | System.out.println(Arrays.toString(obj.plusOne(digits))); 85 | 86 | //example 3 87 | System.out.println("----- example 3 -----"); 88 | digits = new int[] {9}; 89 | System.out.println(Arrays.toString(obj.plusOne(digits))); 90 | 91 | //example 4 92 | System.out.println("----- example 4 -----"); 93 | digits = new int[] {9,9,9,9}; 94 | System.out.println(Arrays.toString(obj.plusOne(digits))); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /02-Array/Array41_PlusOne.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC66: Plus One || https://leetcode.com/problems/plus-one 3 | 4 | 5 | You are given a large integer represented as an integer array digits, where each digits[i] is the ith digit of the integer. The digits are ordered from most significant to least significant in left-to-right order. The large integer does not contain any leading 0's. 6 | 7 | Increment the large integer by one and return the resulting array of digits. 8 | 9 | 10 | 11 | Example 1: 12 | 13 | Input: digits = [1,2,3] 14 | Output: [1,2,4] 15 | Explanation: The array represents the integer 123. 16 | Incrementing by one gives 123 + 1 = 124. 17 | Thus, the result should be [1,2,4]. 18 | 19 | Example 2: 20 | 21 | Input: digits = [4,3,2,1] 22 | Output: [4,3,2,2] 23 | Explanation: The array represents the integer 4321. 24 | Incrementing by one gives 4321 + 1 = 4322. 25 | Thus, the result should be [4,3,2,2]. 26 | 27 | Example 3: 28 | 29 | Input: digits = [9] 30 | Output: [1,0] 31 | Explanation: The array represents the integer 9. 32 | Incrementing by one gives 9 + 1 = 10. 33 | Thus, the result should be [1,0]. 34 | 35 | 36 | 37 | Constraints: 38 | 39 | 1 <= digits.length <= 100 40 | 0 <= digits[i] <= 9 41 | digits does not contain any leading 0's. 42 | */ 43 | 44 | import java.util.Arrays; 45 | 46 | class PlusOne { 47 | //Time complexity: O(n) || Space complexity: O(n) 48 | public int[] plusOne(int[] digits) { 49 | int carry = 0; 50 | int n = digits.length; 51 | 52 | for(int i = n-1; i >= 0; i--) { 53 | //calculate the new value and carry 54 | int plusOne = digits[i] + 1; 55 | carry = plusOne / 10; 56 | digits[i] = plusOne % 10; 57 | 58 | //carry is not 1 -> so return the digits 59 | if(carry == 0) { 60 | return digits; 61 | } 62 | } 63 | 64 | //handle case like -> 999, 99, 9 etc. 65 | int[] ans = new int[n+1]; 66 | ans[0] = carry; 67 | return ans; 68 | } 69 | } 70 | 71 | public class Array41_PlusOne { 72 | public static void main(String[] args) { 73 | PlusOne obj = new PlusOne(); 74 | int[] digits; 75 | 76 | //example 1 77 | System.out.println("----- example 1 -----"); 78 | digits = new int[] {1,2,1}; 79 | System.out.println(Arrays.toString(obj.plusOne(digits))); 80 | 81 | //example 2 82 | System.out.println("----- example 2 -----"); 83 | digits = new int[] {1,2,9}; 84 | System.out.println(Arrays.toString(obj.plusOne(digits))); 85 | 86 | //example 3 87 | System.out.println("----- example 3 -----"); 88 | digits = new int[] {9}; 89 | System.out.println(Arrays.toString(obj.plusOne(digits))); 90 | 91 | //example 4 92 | System.out.println("----- example 4 -----"); 93 | digits = new int[] {9,9,9,9}; 94 | System.out.println(Arrays.toString(obj.plusOne(digits))); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /02-Array/Array19_NumberOfIslands.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC200: Number of Islands || https://leetcode.com/problems/number-of-islands 3 | 4 | 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. 5 | 6 | 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. 7 | 8 | 9 | 10 | Example 1: 11 | 12 | Input: grid = [ 13 | ["1","1","1","1","0"], 14 | ["1","1","0","1","0"], 15 | ["1","1","0","0","0"], 16 | ["0","0","0","0","0"] 17 | ] 18 | Output: 1 19 | 20 | Example 2: 21 | 22 | Input: grid = [ 23 | ["1","1","0","0","0"], 24 | ["1","1","0","0","0"], 25 | ["0","0","1","0","0"], 26 | ["0","0","0","1","1"] 27 | ] 28 | Output: 3 29 | 30 | 31 | 32 | Constraints: 33 | m == grid.length 34 | n == grid[i].length 35 | 1 <= m, n <= 300 36 | grid[i][j] is '0' or '1'. 37 | */ 38 | 39 | class NumberOfIslands { 40 | // Time Complexity => O(m * n) || Space Complexity: O(m * n) 41 | public int numIslands(char[][] grid) { 42 | if (grid.length == 0) { 43 | return 0; 44 | } 45 | 46 | int countIsland = 0; 47 | int m = grid.length, n = grid[0].length; 48 | 49 | for (int i = 0; i < m; i++) { 50 | for (int j = 0; j < n; j++) { 51 | // we found a un visited island 52 | if (grid[i][j] == '1') { 53 | countIsland++; 54 | dfs(i, j, grid); 55 | } 56 | } 57 | } 58 | 59 | return countIsland; 60 | } 61 | 62 | private void dfs(int i, int j, char[][] grid) { 63 | if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] != '1') { 64 | return; 65 | } 66 | 67 | // visit the connected island 68 | grid[i][j] = '-'; 69 | 70 | // go to top 71 | dfs(i - 1, j, grid); 72 | 73 | // go to bottom 74 | dfs(i + 1, j, grid); 75 | 76 | // go to left 77 | dfs(i, j - 1, grid); 78 | 79 | // go to right 80 | dfs(i, j + 1, grid); 81 | } 82 | } 83 | 84 | public class Array19_NumberOfIslands { 85 | public static void main(String[] args) { 86 | NumberOfIslands obj = new NumberOfIslands(); 87 | 88 | // example 1 89 | System.out.println("---- example 1 ----"); 90 | char[][] map1 = { { '1', '1', '1', '1', '0' }, { '1', '1', '0', '1', '0' }, { '1', '1', '0', '0', '0' }, 91 | { '0', '0', '0', '0', '0' } }; 92 | System.out.println(obj.numIslands(map1)); 93 | 94 | // example 2 95 | System.out.println("---- example 2 ----"); 96 | char[][] map2 = { { '1', '1', '0', '0', '0' }, { '1', '1', '0', '0', '0' }, { '0', '0', '1', '0', '0' }, 97 | { '0', '0', '0', '1', '1' } }; 98 | System.out.println(obj.numIslands(map2)); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /05-LinkedList/LL03_ReverseLinkedList.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC206: Reverse Linked List || https://leetcode.com/problems/reverse-linked-list/ 3 | 4 | Given the head of a singly linked list, reverse the list, and return the reversed list. 5 | 6 | Example 1: 7 | Input: head = [1,2,3,4,5] 8 | Output: [5,4,3,2,1] 9 | 10 | Example 2: 11 | Input: head = [1,2] 12 | Output: [2,1] 13 | 14 | Example 3: 15 | Input: head = [] 16 | Output: [] 17 | 18 | 19 | Constraints: 20 | The number of nodes in the list is the range [0, 5000]. 21 | -5000 <= Node.val <= 5000 22 | 23 | Follow up: A linked list can be reversed either iteratively or recursively. Could you implement both? 24 | */ 25 | 26 | class Node { 27 | int data; 28 | Node next; 29 | 30 | Node(int data) { 31 | this.data = data; 32 | this.next = null; 33 | } 34 | 35 | Node(int data, Node next) { 36 | this.data = data; 37 | this.next = next; 38 | } 39 | 40 | Node(int[] arr) { 41 | if (arr.length == 0) { 42 | return; 43 | } 44 | 45 | this.data = arr[0]; 46 | Node temp = this; 47 | for (int i = 1; i < arr.length; i++) { 48 | temp.next = new Node(arr[i]); 49 | temp = temp.next; 50 | } 51 | 52 | } 53 | 54 | public void print() { 55 | if (this == null || (this.data == 0 && this.next == null)) { 56 | System.out.print("[]\n"); 57 | return; 58 | } 59 | 60 | Node temp = this; 61 | 62 | System.out.print("["); 63 | while (temp != null) { 64 | System.out.print(" " + temp.data + " "); 65 | temp = temp.next; 66 | } 67 | System.out.print("]\n"); 68 | } 69 | } 70 | 71 | class ReverseLinkedList { 72 | // Time complexity: O(n) || Space Complexity: O(1) 73 | public Node reverseLinkedList(Node head) { 74 | Node prev = null; // always identify previous Node, need to connect with 75 | Node curr = head; // always identify current Node, 76 | Node nxt = head; // always identify next Node, need to disconnect with 77 | 78 | while (nxt != null) { 79 | nxt = nxt.next; // going to next possible Node 80 | curr.next = prev; // connect to the previous Node 81 | 82 | // change prev & curr for next iteration 83 | prev = curr; 84 | curr = nxt; 85 | } 86 | 87 | return prev; 88 | } 89 | } 90 | 91 | public class LL03_ReverseLinkedList { 92 | public static void main(String[] args) { 93 | ReverseLinkedList obj = new ReverseLinkedList(); 94 | 95 | // example 1 96 | System.out.println("---- example 1 ----"); 97 | Node list1 = new Node(new int[] { 1, 2, 3, 4, 5 }); 98 | obj.reverseLinkedList(list1).print(); 99 | 100 | // example 2 101 | System.out.println("---- example 2 ----"); 102 | Node list2 = new Node(new int[] { 1, 2 }); 103 | obj.reverseLinkedList(list2).print(); 104 | 105 | } 106 | } -------------------------------------------------------------------------------- /07-BinaryTrees/BT06_FlattenBinaryTreeToLinkedList.java: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | LC114: Flatten Binary Tree to Linked List || https://leetcode.com/problems/flatten-binary-tree-to-linked-list 4 | 5 | 6 | Given the root of a binary tree, flatten the tree into a "linked list": 7 | 8 | The "linked list" should use the same TreeNode class where the right child pointer points to the next node in the list and the left child pointer is always null. 9 | The "linked list" should be in the same order as a pre-order traversal of the binary tree. 10 | 11 | 12 | 13 | Example 1: 14 | 15 | Input: root = [1,2,5,3,4,null,6] 16 | Output: [1,null,2,null,3,null,4,null,5,null,6] 17 | 18 | Example 2: 19 | 20 | Input: root = [] 21 | Output: [] 22 | 23 | Example 3: 24 | 25 | Input: root = [0] 26 | Output: [0] 27 | 28 | 29 | Constraints: 30 | The number of nodes in the tree is in the range [0, 2000]. 31 | -100 <= Node.val <= 100 32 | 33 | Follow up: Can you flatten the tree in-place (with O(1) extra space)? 34 | */ 35 | import java.util.ArrayList; 36 | import java.util.List; 37 | 38 | // Definition for a binary tree node. 39 | class TreeNode { 40 | int val; 41 | TreeNode left; 42 | TreeNode right; 43 | 44 | TreeNode() { 45 | } 46 | 47 | TreeNode(int val) { 48 | this.val = val; 49 | } 50 | 51 | TreeNode(int val, TreeNode left, TreeNode right) { 52 | this.val = val; 53 | this.left = left; 54 | this.right = right; 55 | } 56 | } 57 | 58 | class Solution1 { 59 | // Time complexity: O(n) || Space complexity: O(n) 60 | public void flatten(TreeNode root) { 61 | List list = new ArrayList<>(); 62 | preOrderTraversal(root, list); 63 | 64 | TreeNode head = new TreeNode(-1); 65 | TreeNode temp = head; 66 | 67 | for (TreeNode node : list) { 68 | temp.right = node; 69 | temp.left = null; 70 | 71 | temp = temp.right; 72 | } 73 | 74 | head = head.right; 75 | } 76 | 77 | private void preOrderTraversal(TreeNode root, List list) { 78 | if (root == null) { 79 | return; 80 | } 81 | 82 | list.add(root); 83 | preOrderTraversal(root.left, list); 84 | preOrderTraversal(root.right, list); 85 | } 86 | } 87 | 88 | class Solution2 { 89 | // Time complexity: O(n) || Space complexity: O(1) 90 | private TreeNode prev = null; // keep tack what has already flattened 91 | 92 | // reverse the preorder traversal completly 93 | public void flatten(TreeNode root) { 94 | if (root == null) { 95 | return; 96 | } 97 | 98 | flatten(root.right); 99 | flatten(root.left); 100 | root.right = prev; 101 | root.left = null; 102 | 103 | prev = root; 104 | } 105 | } 106 | 107 | public class BT06_FlattenBinaryTreeToLinkedList { 108 | public static void main(String[] args) { 109 | 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /17-BitManipulation/BM01_NumberOf1Bits.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC191: Number of 1 Bits || https://leetcode.com/problems/number-of-1-bits 3 | 4 | Given a positive integer n, write a function that returns the number of set bits in its binary representation (also known as the Hamming weight). 5 | 6 | 7 | Example 1: 8 | Input: n = 11 9 | Output: 3 10 | Explanation: The input binary string 1011 has a total of three set bits. 11 | 12 | Example 2: 13 | Input: n = 128 14 | Output: 1 15 | Explanation: The input binary string 10000000 has a total of one set bit. 16 | 17 | Example 3: 18 | Input: n = 2147483645 19 | Output: 30 20 | Explanation: The input binary string 1111111111111111111111111111101 has a total of thirty set bits. 21 | 22 | 23 | Constraints: 24 | 1 <= n <= 231 - 1 25 | 26 | 27 | Follow up: If this function is called many times, how would you optimize it? 28 | */ 29 | 30 | class NumberOf1Bits { 31 | 32 | // Time Complexity: O(log n) || Space Complexity: O(1) 33 | public int approach1(int n) { 34 | // count the 1 bits 35 | int count = 0; 36 | 37 | while (n != 0) { 38 | // check if bit is 1 39 | if (n % 2 == 1) { 40 | count++; 41 | } 42 | // update n 43 | n /= 2; 44 | } 45 | 46 | return count; 47 | } 48 | 49 | // Time Complexity: O(log n) || Space Complexity: O(1) 50 | public int approach2(int n) { 51 | // count the 1 bits 52 | int count = 0; 53 | 54 | while (n != 0) { 55 | // check if bit is 1 & update count 56 | count += n & 1; 57 | // shift the bits 58 | n >>>= 1; 59 | } 60 | 61 | return count; 62 | } 63 | } 64 | 65 | public class BM01_NumberOf1Bits { 66 | public static void main(String[] args) { 67 | NumberOf1Bits obj = new NumberOf1Bits(); 68 | 69 | // example 1 70 | System.out.println("---- example 1 ----"); 71 | int n1 = 12; 72 | System.out.println(obj.approach1(n1)); 73 | System.out.println(obj.approach2(n1)); 74 | 75 | // example 2 76 | System.out.println("---- example 2 ----"); 77 | int n2 = 13; 78 | System.out.println(obj.approach1(n2)); 79 | System.out.println(obj.approach2(n2)); 80 | 81 | // example 3 82 | System.out.println("---- example 3 ----"); 83 | int n3 = 8; 84 | System.out.println(obj.approach1(n3)); 85 | System.out.println(obj.approach2(n3)); 86 | 87 | // example 4 88 | System.out.println("---- example 4 ----"); 89 | int n4 = 32; 90 | System.out.println(obj.approach1(n4)); 91 | System.out.println(obj.approach2(n4)); 92 | 93 | // example 5 94 | System.out.println("---- example 5 ----"); 95 | int n5 = 128; 96 | System.out.println(obj.approach1(n5)); 97 | System.out.println(obj.approach2(n5)); 98 | 99 | // example 6 100 | System.out.println("---- example 6 ----"); 101 | int n6 = 2147483645; 102 | System.out.println(obj.approach1(n6)); 103 | System.out.println(obj.approach2(n6)); 104 | } 105 | } -------------------------------------------------------------------------------- /02-Array/Array47_SortColors.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC75: Sort Colors || https://leetcode.com/problems/sort-colors 3 | 4 | Given an array nums with n objects colored red, white, or blue, sort them in-place so that objects of the same color are adjacent, with the colors in the order red, white, and blue. 5 | 6 | We will use the integers 0, 1, and 2 to represent the color red, white, and blue, respectively. 7 | 8 | You must solve this problem without using the library's sort function. 9 | 10 | 11 | 12 | Example 1: 13 | 14 | Input: nums = [2,0,2,1,1,0] 15 | Output: [0,0,1,1,2,2] 16 | 17 | Example 2: 18 | 19 | Input: nums = [2,0,1] 20 | Output: [0,1,2] 21 | 22 | 23 | Constraints: 24 | n == nums.length 25 | 1 <= n <= 300 26 | nums[i] is either 0, 1, or 2. 27 | 28 | 29 | Follow up: Could you come up with a one-pass algorithm using only constant extra space? 30 | 31 | */ 32 | 33 | import java.util.Arrays; 34 | 35 | class SortColors { 36 | // Time Complexity: O(n) || Space Complexity: O(1) 37 | public void approach1(int[] nums) { 38 | // pointers 39 | int n0 = 0, n1 = 0, n = nums.length; 40 | 41 | // count 0's and 1's 42 | for (int i = 0; i < n; i++) { 43 | if (nums[i] == 0) { 44 | n0++; 45 | } else if (nums[i] == 1) { 46 | n1++; 47 | } 48 | } 49 | 50 | // put 0's in range of 0 to n0 51 | for (int i = 0; i < n0; i++) { 52 | nums[i] = 0; 53 | } 54 | 55 | // put 1's in range of n0 to (n0+n1) 56 | for (int i = n0; i < n0 + n1; i++) { 57 | nums[i] = 1; 58 | } 59 | 60 | // put 2's in range of (n0+n1) to n 61 | for (int i = n0 + n1; i < n; i++) { 62 | nums[i] = 2; 63 | } 64 | } 65 | 66 | // Time Complexity: O(n) || Space Complexity: O(1) 67 | public void approach2(int[] nums) { 68 | // pointers 69 | int start = 0, end = nums.length - 1; 70 | int ptr = 0; 71 | 72 | // put 0's, 1's & 2's in place 73 | while (ptr <= end) { 74 | if (nums[ptr] == 0) { 75 | swap(nums, ptr++, start++); 76 | } else if (nums[ptr] == 1) { 77 | ptr++; 78 | } else { 79 | swap(nums, ptr, end--); 80 | } 81 | } 82 | } 83 | 84 | private void swap(int[] arr, int i, int j) { 85 | int temp = arr[i]; 86 | arr[i] = arr[j]; 87 | arr[j] = temp; 88 | } 89 | } 90 | 91 | public class Array47_SortColors { 92 | public static void main(String[] args) { 93 | SortColors obj = new SortColors(); 94 | int[] nums; 95 | 96 | // example 1 97 | System.out.println("---- example 1 ----"); 98 | nums = new int[] { 2, 1, 0, 2, 1, 1, 2, 0, 2, 0 }; 99 | // obj.approach1(nums); 100 | obj.approach2(nums); 101 | System.out.println(Arrays.toString(nums)); 102 | 103 | // example 2 104 | System.out.println("---- example 2 ----"); 105 | nums = new int[] { 2, 0, 2, 1, 1, 0 }; 106 | // obj.approach1(nums); 107 | obj.approach2(nums); 108 | System.out.println(Arrays.toString(nums)); 109 | } 110 | } -------------------------------------------------------------------------------- /16-TwoPointers/TP12_SortColors.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC75: Sort Colors || https://leetcode.com/problems/sort-colors 3 | 4 | Given an array nums with n objects colored red, white, or blue, sort them in-place so that objects of the same color are adjacent, with the colors in the order red, white, and blue. 5 | 6 | We will use the integers 0, 1, and 2 to represent the color red, white, and blue, respectively. 7 | 8 | You must solve this problem without using the library's sort function. 9 | 10 | 11 | 12 | Example 1: 13 | 14 | Input: nums = [2,0,2,1,1,0] 15 | Output: [0,0,1,1,2,2] 16 | 17 | Example 2: 18 | 19 | Input: nums = [2,0,1] 20 | Output: [0,1,2] 21 | 22 | 23 | Constraints: 24 | n == nums.length 25 | 1 <= n <= 300 26 | nums[i] is either 0, 1, or 2. 27 | 28 | 29 | Follow up: Could you come up with a one-pass algorithm using only constant extra space? 30 | 31 | */ 32 | 33 | import java.util.Arrays; 34 | 35 | class SortColors { 36 | // Time Complexity: O(n) || Space Complexity: O(1) 37 | public void approach1(int[] nums) { 38 | // pointers 39 | int n0 = 0, n1 = 0, n = nums.length; 40 | 41 | // count 0's and 1's 42 | for (int i = 0; i < n; i++) { 43 | if (nums[i] == 0) { 44 | n0++; 45 | } else if (nums[i] == 1) { 46 | n1++; 47 | } 48 | } 49 | 50 | // put 0's in range of 0 to n0 51 | for (int i = 0; i < n0; i++) { 52 | nums[i] = 0; 53 | } 54 | 55 | // put 1's in range of n0 to (n0+n1) 56 | for (int i = n0; i < n0 + n1; i++) { 57 | nums[i] = 1; 58 | } 59 | 60 | // put 2's in range of (n0+n1) to n 61 | for (int i = n0 + n1; i < n; i++) { 62 | nums[i] = 2; 63 | } 64 | } 65 | 66 | // Time Complexity: O(n) || Space Complexity: O(1) 67 | public void approach2(int[] nums) { 68 | // pointers 69 | int start = 0, end = nums.length - 1; 70 | int ptr = 0; 71 | 72 | // put 0's, 1's & 2's in place 73 | while (ptr <= end) { 74 | if (nums[ptr] == 0) { 75 | swap(nums, ptr++, start++); 76 | } else if (nums[ptr] == 1) { 77 | ptr++; 78 | } else { 79 | swap(nums, ptr, end--); 80 | } 81 | } 82 | } 83 | 84 | private void swap(int[] arr, int i, int j) { 85 | int temp = arr[i]; 86 | arr[i] = arr[j]; 87 | arr[j] = temp; 88 | } 89 | } 90 | 91 | public class TP12_SortColors { 92 | public static void main(String[] args) { 93 | SortColors obj = new SortColors(); 94 | int[] nums; 95 | 96 | // example 1 97 | System.out.println("---- example 1 ----"); 98 | nums = new int[] { 2, 1, 0, 2, 1, 1, 2, 0, 2, 0 }; 99 | // obj.approach1(nums); 100 | obj.approach2(nums); 101 | System.out.println(Arrays.toString(nums)); 102 | 103 | // example 2 104 | System.out.println("---- example 2 ----"); 105 | nums = new int[] { 2, 0, 2, 1, 1, 0 }; 106 | // obj.approach1(nums); 107 | obj.approach2(nums); 108 | System.out.println(Arrays.toString(nums)); 109 | } 110 | } -------------------------------------------------------------------------------- /02-Array/Array03_SingleNumber.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC136: Single Number ||https://leetcode.com/problems/single-number/ 3 | 4 | Given a non-empty array of integers nums, every element appears twice except for one. Find that single one. 5 | 6 | You must implement a solution with a linear runtime complexity and use only constant extra space. 7 | 8 | 9 | Example 1: 10 | Input: nums = [2,2,1] 11 | Output: 1 12 | 13 | Example 2: 14 | Input: nums = [4,1,2,1,2] 15 | Output: 4 16 | 17 | Example 3: 18 | Input: nums = [1] 19 | Output: 1 20 | 21 | 22 | Constraints: 23 | 1 <= nums.length <= 3 * 104 24 | -3 * 104 <= nums[i] <= 3 * 104 25 | Each element in the array appears twice except for one element which appears only once. 26 | */ 27 | 28 | import java.util.HashSet; 29 | 30 | class SingleNumber { 31 | // Brute Force Approach => Time Complexity: O(n^2) || Space Complexity: O(1) 32 | public int approach1(int[] nums) { 33 | 34 | for (int x : nums) { 35 | int count = 0; 36 | for (int y : nums) { 37 | // check for duplicate value 38 | if (x == y) { 39 | count++; 40 | } 41 | } 42 | 43 | // check if there are no duplicate value 44 | if (count == 1) { 45 | return x; 46 | } 47 | } 48 | 49 | return -1; 50 | } 51 | 52 | // HashSet Approach => Time Complexity: O(n) || Space Complexity: O(n) 53 | public int approach2(int[] nums) { 54 | 55 | HashSet set = new HashSet<>(); 56 | 57 | for (int key : nums) { 58 | if (set.contains(key)) { 59 | set.remove(key); 60 | } else { 61 | set.add(key); 62 | } 63 | } 64 | 65 | return set.iterator().next(); 66 | } 67 | 68 | // Bit Manipulation Approach => Time Complexity: O(n) || Space Complexity: O(1) 69 | public int approach3(int[] nums) { 70 | int ans = 0; 71 | 72 | for (int x : nums) { 73 | ans ^= x; 74 | } 75 | 76 | return ans; 77 | } 78 | } 79 | 80 | public class Array03_SingleNumber { 81 | public static void main(String[] args) { 82 | SingleNumber obj = new SingleNumber(); 83 | 84 | // example 1 85 | System.out.println("---- example 1 ----"); 86 | int[] nums1 = { 2, 2, 1 }; 87 | System.out.println("Approach 1: " + obj.approach1(nums1)); 88 | System.out.println("Approach 2: " + obj.approach2(nums1)); 89 | System.out.println("Approach 3: " + obj.approach3(nums1)); 90 | 91 | // example 2 92 | System.out.println("---- example 2 ----"); 93 | int[] nums2 = { 4, 1, 2, 1, 2 }; 94 | System.out.println("Approach 1: " + obj.approach1(nums2)); 95 | System.out.println("Approach 2: " + obj.approach2(nums2)); 96 | System.out.println("Approach 3: " + obj.approach3(nums2)); 97 | 98 | // example 3 99 | System.out.println("---- example 2 ----"); 100 | int[] nums3 = { 1 }; 101 | System.out.println("Approach 1: " + obj.approach1(nums3)); 102 | System.out.println("Approach 2: " + obj.approach2(nums3)); 103 | System.out.println("Approach 3: " + obj.approach3(nums3)); 104 | } 105 | } -------------------------------------------------------------------------------- /17-BitManipulation/BW02_SingleNumber.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC136: Single Number ||https://leetcode.com/problems/single-number/ 3 | 4 | Given a non-empty array of integers nums, every element appears twice except for one. Find that single one. 5 | 6 | You must implement a solution with a linear runtime complexity and use only constant extra space. 7 | 8 | 9 | Example 1: 10 | Input: nums = [2,2,1] 11 | Output: 1 12 | 13 | Example 2: 14 | Input: nums = [4,1,2,1,2] 15 | Output: 4 16 | 17 | Example 3: 18 | Input: nums = [1] 19 | Output: 1 20 | 21 | 22 | Constraints: 23 | 1 <= nums.length <= 3 * 104 24 | -3 * 104 <= nums[i] <= 3 * 104 25 | Each element in the array appears twice except for one element which appears only once. 26 | */ 27 | 28 | import java.util.HashSet; 29 | 30 | class SingleNumber { 31 | // Brute Force Approach => Time Complexity: O(n^2) || Space Complexity: O(1) 32 | public int approach1(int[] nums) { 33 | 34 | for (int x : nums) { 35 | int count = 0; 36 | for (int y : nums) { 37 | // check for duplicate value 38 | if (x == y) { 39 | count++; 40 | } 41 | } 42 | 43 | // check if there are no duplicate value 44 | if (count == 1) { 45 | return x; 46 | } 47 | } 48 | 49 | return -1; 50 | } 51 | 52 | // HashSet Approach => Time Complexity: O(n) || Space Complexity: O(n) 53 | public int approach2(int[] nums) { 54 | 55 | HashSet set = new HashSet<>(); 56 | 57 | for (int key : nums) { 58 | if (set.contains(key)) { 59 | set.remove(key); 60 | } else { 61 | set.add(key); 62 | } 63 | } 64 | 65 | return set.iterator().next(); 66 | } 67 | 68 | // Bit Manipulation Approach => Time Complexity: O(n) || Space Complexity: O(1) 69 | public int approach3(int[] nums) { 70 | int ans = 0; 71 | 72 | for (int x : nums) { 73 | ans ^= x; 74 | } 75 | 76 | return ans; 77 | } 78 | } 79 | 80 | public class BW02_SingleNumber { 81 | public static void main(String[] args) { 82 | SingleNumber obj = new SingleNumber(); 83 | 84 | // example 1 85 | System.out.println("---- example 1 ----"); 86 | int[] nums1 = { 2, 2, 1 }; 87 | System.out.println("Approach 1: " + obj.approach1(nums1)); 88 | System.out.println("Approach 2: " + obj.approach2(nums1)); 89 | System.out.println("Approach 3: " + obj.approach3(nums1)); 90 | 91 | // example 2 92 | System.out.println("---- example 2 ----"); 93 | int[] nums2 = { 4, 1, 2, 1, 2 }; 94 | System.out.println("Approach 1: " + obj.approach1(nums2)); 95 | System.out.println("Approach 2: " + obj.approach2(nums2)); 96 | System.out.println("Approach 3: " + obj.approach3(nums2)); 97 | 98 | // example 3 99 | System.out.println("---- example 2 ----"); 100 | int[] nums3 = { 1 }; 101 | System.out.println("Approach 1: " + obj.approach1(nums3)); 102 | System.out.println("Approach 2: " + obj.approach2(nums3)); 103 | System.out.println("Approach 3: " + obj.approach3(nums3)); 104 | } 105 | } -------------------------------------------------------------------------------- /07-BinaryTrees/BT07_PathSum.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC112: Path Sum || https://leetcode.com/problems/path-sum/ 3 | 4 | 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 | 10 | 11 | Example 1: 12 | 13 | Input: root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22 14 | Output: true 15 | Explanation: The root-to-leaf path with the target sum is shown. 16 | 17 | Example 2: 18 | 19 | Input: root = [1,2,3], targetSum = 5 20 | Output: false 21 | Explanation: There are two root-to-leaf paths in the tree: 22 | (1 --> 2): The sum is 3. 23 | (1 --> 3): The sum is 4. 24 | There is no root-to-leaf path with sum = 5. 25 | 26 | Example 3: 27 | 28 | Input: root = [], targetSum = 0 29 | Output: false 30 | Explanation: Since the tree is empty, there are no root-to-leaf paths. 31 | 32 | 33 | 34 | Constraints: 35 | 36 | The number of nodes in the tree is in the range [0, 5000]. 37 | -1000 <= Node.val <= 1000 38 | -1000 <= targetSum <= 1000 39 | 40 | */ 41 | 42 | class Node { 43 | int data; 44 | Node left; 45 | Node right; 46 | 47 | Node(int val) { 48 | this.data = val; 49 | this.left = null; 50 | this.right = null; 51 | } 52 | } 53 | 54 | class PathSum { 55 | public boolean hasPathSum(Node root, int targetSum) { 56 | int sum = 0; 57 | return helper(root, targetSum, sum); 58 | } 59 | 60 | private boolean helper(Node root, int targetSum, int sum) { 61 | //base case 62 | if(root == null) { 63 | return false; 64 | } 65 | 66 | //leaf node case 67 | if(root.left == null && root.right == null) { 68 | return root.data + sum == targetSum; 69 | } 70 | 71 | //update sum 72 | sum += root.data; 73 | 74 | //recursive call 75 | return helper(root.left, targetSum, sum) || helper(root.right, targetSum, sum); 76 | 77 | } 78 | } 79 | 80 | public class BT07_PathSum { 81 | public static void main(String[] args) { 82 | PathSum obj = new PathSum(); 83 | int targetSum; 84 | 85 | Node root = new Node(5); 86 | root.left = new Node(4); 87 | root.left.left = new Node(11); 88 | root.left.left.left = new Node(7); 89 | root.left.left.right = new Node(2); 90 | root.right = new Node(8); 91 | root.right.left = new Node(13); 92 | root.right.right = new Node(4); 93 | root.right.right.left = new Node(1); 94 | root.right.right.right = new Node(2); 95 | 96 | //example 1 97 | System.out.println("----- example 1 -----"); 98 | targetSum = 18; 99 | System.out.println(obj.hasPathSum(root, targetSum)); 100 | 101 | //example 2 102 | System.out.println("----- example 2 -----"); 103 | targetSum = 20; 104 | System.out.println(obj.hasPathSum(root, targetSum)); 105 | 106 | //example 3 107 | System.out.println("----- example 3 -----"); 108 | targetSum = 22; 109 | System.out.println(obj.hasPathSum(root, targetSum)); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /04-Recursion-Backtracking/RB06_PathSum.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC112: Path Sum || https://leetcode.com/problems/path-sum/ 3 | 4 | 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 | 10 | 11 | Example 1: 12 | 13 | Input: root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22 14 | Output: true 15 | Explanation: The root-to-leaf path with the target sum is shown. 16 | 17 | Example 2: 18 | 19 | Input: root = [1,2,3], targetSum = 5 20 | Output: false 21 | Explanation: There are two root-to-leaf paths in the tree: 22 | (1 --> 2): The sum is 3. 23 | (1 --> 3): The sum is 4. 24 | There is no root-to-leaf path with sum = 5. 25 | 26 | Example 3: 27 | 28 | Input: root = [], targetSum = 0 29 | Output: false 30 | Explanation: Since the tree is empty, there are no root-to-leaf paths. 31 | 32 | 33 | 34 | Constraints: 35 | 36 | The number of nodes in the tree is in the range [0, 5000]. 37 | -1000 <= Node.val <= 1000 38 | -1000 <= targetSum <= 1000 39 | 40 | */ 41 | 42 | class Node { 43 | int data; 44 | Node left; 45 | Node right; 46 | 47 | Node(int val) { 48 | this.data = val; 49 | this.left = null; 50 | this.right = null; 51 | } 52 | } 53 | 54 | class PathSum { 55 | public boolean hasPathSum(Node root, int targetSum) { 56 | int sum = 0; 57 | return helper(root, targetSum, sum); 58 | } 59 | 60 | private boolean helper(Node root, int targetSum, int sum) { 61 | //base case 62 | if(root == null) { 63 | return false; 64 | } 65 | 66 | //leaf node case 67 | if(root.left == null && root.right == null) { 68 | return root.data + sum == targetSum; 69 | } 70 | 71 | //update sum 72 | sum += root.data; 73 | 74 | //recursive call 75 | return helper(root.left, targetSum, sum) || helper(root.right, targetSum, sum); 76 | 77 | } 78 | } 79 | 80 | public class RB06_PathSum { 81 | public static void main(String[] args) { 82 | PathSum obj = new PathSum(); 83 | int targetSum; 84 | 85 | Node root = new Node(5); 86 | root.left = new Node(4); 87 | root.left.left = new Node(11); 88 | root.left.left.left = new Node(7); 89 | root.left.left.right = new Node(2); 90 | root.right = new Node(8); 91 | root.right.left = new Node(13); 92 | root.right.right = new Node(4); 93 | root.right.right.left = new Node(1); 94 | root.right.right.right = new Node(2); 95 | 96 | //example 1 97 | System.out.println("----- example 1 -----"); 98 | targetSum = 18; 99 | System.out.println(obj.hasPathSum(root, targetSum)); 100 | 101 | //example 2 102 | System.out.println("----- example 2 -----"); 103 | targetSum = 20; 104 | System.out.println(obj.hasPathSum(root, targetSum)); 105 | 106 | //example 3 107 | System.out.println("----- example 3 -----"); 108 | targetSum = 22; 109 | System.out.println(obj.hasPathSum(root, targetSum)); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /03-String/String12_BasicCalculator.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC224: Basic Calculator || https://leetcode.com/problems/basic-calculator 3 | 4 | Given a string s representing a valid expression, implement a basic calculator to evaluate it, and return the result of the evaluation. 5 | 6 | Note: You are not allowed to use any built-in function which evaluates strings as mathematical expressions, such as eval(). 7 | 8 | 9 | 10 | Example 1: 11 | 12 | Input: s = "1 + 1" 13 | Output: 2 14 | 15 | Example 2: 16 | 17 | Input: s = " 2-1 + 2 " 18 | Output: 3 19 | 20 | Example 3: 21 | 22 | Input: s = "(1+(4+5+2)-3)+(6+8)" 23 | Output: 23 24 | 25 | 26 | 27 | Constraints: 28 | 29 | 1 <= s.length <= 3 * 10^5 30 | s consists of digits, '+', '-', '(', ')', and ' '. 31 | s represents a valid expression. 32 | '+' is not used as a unary operation (i.e., "+1" and "+(2 + 3)" is invalid). 33 | '-' could be used as a unary operation (i.e., "-1" and "-(2 + 3)" is valid). 34 | There will be no two consecutive operators in the input. 35 | Every number and running calculation will fit in a signed 32-bit integer. 36 | */ 37 | 38 | import java.util.Stack; 39 | 40 | class BasicCalculator { 41 | // Time complexity: O(n) || Space complexity: O(n) 42 | public int calculate(String s) { 43 | Stack stk = new Stack<>(); // store values before brackets 44 | int number = 0; // store current digits 45 | int sign = 1; // + or - sign 46 | int ans = 0; // calculate the result of each operations 47 | 48 | for (char ch : s.toCharArray()) { 49 | if (Character.isDigit(ch)) { // digits 50 | number = 10 * number + (int) (ch - '0'); 51 | } else if (ch == '+') { // add operation 52 | ans += sign * number; 53 | number = 0; 54 | sign = 1; 55 | } else if (ch == '-') { // minus operation 56 | ans += sign * number; 57 | number = 0; 58 | sign = -1; 59 | } else if (ch == '(') { 60 | // store prev ans & sign into stack 61 | stk.push(ans); 62 | stk.push(sign); 63 | 64 | // go back to default 65 | ans = 0; 66 | sign = 1; 67 | } else if (ch == ')') { 68 | ans += sign * number; // first calculate ans inside brackets 69 | 70 | // before brackets 71 | ans *= stk.pop(); // sign 72 | ans += stk.pop(); // ans 73 | 74 | number = 0; 75 | } 76 | } 77 | 78 | // if number still holds value do calculation 79 | if (number != 0) { 80 | ans += sign * number; 81 | } 82 | 83 | return ans; 84 | 85 | } 86 | } 87 | 88 | public class String12_BasicCalculator { 89 | public static void main(String[] args) { 90 | BasicCalculator obj = new BasicCalculator(); 91 | String s; 92 | 93 | //example 1 94 | System.out.println("----- example 1 -----"); 95 | s = "10-2+(3+4-(5+6)+(7+2-1))"; 96 | System.out.println(obj.calculate(s)); 97 | 98 | //example 2 99 | System.out.println("----- example 2 -----"); 100 | s = "(1-(2+3)+(4+5-6)-7+8)"; 101 | System.out.println(obj.calculate(s)); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /06-Stack-Queue/Stack03_BasicCalculator.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC224: Basic Calculator || https://leetcode.com/problems/basic-calculator 3 | 4 | Given a string s representing a valid expression, implement a basic calculator to evaluate it, and return the result of the evaluation. 5 | 6 | Note: You are not allowed to use any built-in function which evaluates strings as mathematical expressions, such as eval(). 7 | 8 | 9 | 10 | Example 1: 11 | 12 | Input: s = "1 + 1" 13 | Output: 2 14 | 15 | Example 2: 16 | 17 | Input: s = " 2-1 + 2 " 18 | Output: 3 19 | 20 | Example 3: 21 | 22 | Input: s = "(1+(4+5+2)-3)+(6+8)" 23 | Output: 23 24 | 25 | 26 | 27 | Constraints: 28 | 29 | 1 <= s.length <= 3 * 10^5 30 | s consists of digits, '+', '-', '(', ')', and ' '. 31 | s represents a valid expression. 32 | '+' is not used as a unary operation (i.e., "+1" and "+(2 + 3)" is invalid). 33 | '-' could be used as a unary operation (i.e., "-1" and "-(2 + 3)" is valid). 34 | There will be no two consecutive operators in the input. 35 | Every number and running calculation will fit in a signed 32-bit integer. 36 | */ 37 | 38 | import java.util.Stack; 39 | 40 | class BasicCalculator { 41 | // Time complexity: O(n) || Space complexity: O(n) 42 | public int calculate(String s) { 43 | Stack stk = new Stack<>(); // store values before brackets 44 | int number = 0; // store current digits 45 | int sign = 1; // + or - sign 46 | int ans = 0; // calculate the result of each operations 47 | 48 | for (char ch : s.toCharArray()) { 49 | if (Character.isDigit(ch)) { // digits 50 | number = 10 * number + (int) (ch - '0'); 51 | } else if (ch == '+') { // add operation 52 | ans += sign * number; 53 | number = 0; 54 | sign = 1; 55 | } else if (ch == '-') { // minus operation 56 | ans += sign * number; 57 | number = 0; 58 | sign = -1; 59 | } else if (ch == '(') { 60 | // store prev ans & sign into stack 61 | stk.push(ans); 62 | stk.push(sign); 63 | 64 | // go back to default 65 | ans = 0; 66 | sign = 1; 67 | } else if (ch == ')') { 68 | ans += sign * number; // first calculate ans inside brackets 69 | 70 | // before brackets 71 | ans *= stk.pop(); // sign 72 | ans += stk.pop(); // ans 73 | 74 | number = 0; 75 | } 76 | } 77 | 78 | // if number still holds value do calculation 79 | if (number != 0) { 80 | ans += sign * number; 81 | } 82 | 83 | return ans; 84 | 85 | } 86 | } 87 | 88 | public class Stack03_BasicCalculator { 89 | public static void main(String[] args) { 90 | BasicCalculator obj = new BasicCalculator(); 91 | String s; 92 | 93 | //example 1 94 | System.out.println("----- example 1 -----"); 95 | s = "10-2+(3+4-(5+6)+(7+2-1))"; 96 | System.out.println(obj.calculate(s)); 97 | 98 | //example 2 99 | System.out.println("----- example 2 -----"); 100 | s = "(1-(2+3)+(4+5-6)-7+8)"; 101 | System.out.println(obj.calculate(s)); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /18-DynamicProgramming/DP02_UniquePaths.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC62: Unique Paths || https://leetcode.com/problems/unique-paths 3 | 4 | 5 | There is a robot on an m x n grid. The robot is initially located at the top-left corner (i.e., grid[0][0]). The robot tries to move to the bottom-right corner (i.e., grid[m - 1][n - 1]). The robot can only move either down or right at any point in time. 6 | 7 | Given the two integers m and n, return the number of possible unique paths that the robot can take to reach the bottom-right corner. 8 | 9 | The test cases are generated so that the answer will be less than or equal to 2 * 109. 10 | 11 | 12 | 13 | Example 1: 14 | Input: m = 3, n = 7 15 | Output: 28 16 | 17 | Example 2: 18 | Input: m = 3, n = 2 19 | Output: 3 20 | Explanation: From the top-left corner, there are a total of 3 ways to reach the bottom-right corner: 21 | 1. Right -> Down -> Down 22 | 2. Down -> Down -> Right 23 | 3. Down -> Right -> Down 24 | 25 | 26 | Constraints: 27 | 1 <= m, n <= 100 28 | */ 29 | 30 | class UniquePaths { 31 | // Time complexity: O(m*n) || Space Complexity: O(m*n) 32 | public int approach1_tabulation(int m, int n) { 33 | int[][] dp = new int[m][n]; 34 | 35 | for (int i = 0; i < m; i++) { 36 | for (int j = 0; j < n; j++) { 37 | if (i == 0 || j == 0) { 38 | dp[i][j] = 1; 39 | } else { 40 | dp[i][j] = dp[i][j - 1] + dp[i - 1][j]; 41 | } 42 | 43 | } 44 | } 45 | 46 | return dp[m - 1][n - 1]; 47 | } 48 | 49 | // Time complexity: O(m*n) || Space Complexity: O(m*n) 50 | public int approach2_memoization(int m, int n) { 51 | int[][] dp = new int[m][n]; 52 | 53 | // fill up with -1 54 | for (int i = 0; i < m; i++) { 55 | for (int j = 0; j < n; j++) { 56 | dp[i][j] = -1; 57 | } 58 | } 59 | 60 | return helper(m - 1, n - 1, dp); 61 | } 62 | 63 | private int helper(int i, int j, int[][] dp) { 64 | // base case -> 1st row or 1st col set it to 1 65 | if (i == 0 || j == 0) { 66 | return 1; 67 | } 68 | 69 | // value already calculated 70 | if (dp[i][j] != -1) { 71 | return dp[i][j]; 72 | } 73 | 74 | dp[i][j] = helper(i, j - 1, dp) + helper(i - 1, j, dp); 75 | return dp[i][j]; 76 | } 77 | } 78 | 79 | public class DP02_UniquePaths { 80 | public static void main(String[] args) { 81 | UniquePaths obj = new UniquePaths(); 82 | 83 | //example 1 84 | System.out.println("---- example 1 ----"); 85 | int m1 = 3, n1 = 4; 86 | System.out.println(obj.approach1_tabulation(m1, n1)); 87 | System.out.println(obj.approach2_memoization(m1, n1)); 88 | 89 | //example 2 90 | System.out.println("---- example 2 ----"); 91 | int m2 = 3, n2 = 2; 92 | System.out.println(obj.approach1_tabulation(m2, n2)); 93 | System.out.println(obj.approach2_memoization(m2, n2)); 94 | 95 | //example 3 96 | System.out.println("---- example 3 ----"); 97 | int m3 = 3, n3 = 7; 98 | System.out.println(obj.approach1_tabulation(m3, n3)); 99 | System.out.println(obj.approach2_memoization(m3, n3)); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /02-Array/Array44_FindMinimumInRotatedSortedArray.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC153 Find Minimum in Rotated Sorted Array || https://leetcode.com/problems/find-minimum-in-rotated-sorted-array 3 | 4 | Suppose an array of length n sorted in ascending order is rotated between 1 and n times. For example, the array nums = [0,1,2,4,5,6,7] might become: 5 | 6 | [4,5,6,7,0,1,2] if it was rotated 4 times. 7 | [0,1,2,4,5,6,7] if it was rotated 7 times. 8 | 9 | Notice that rotating an array [a[0], a[1], a[2], ..., a[n-1]] 1 time results in the array [a[n-1], a[0], a[1], a[2], ..., a[n-2]]. 10 | 11 | Given the sorted rotated array nums of unique elements, return the minimum element of this array. 12 | 13 | You must write an algorithm that runs in O(log n) time. 14 | 15 | 16 | 17 | Example 1: 18 | 19 | Input: nums = [3,4,5,1,2] 20 | Output: 1 21 | Explanation: The original array was [1,2,3,4,5] rotated 3 times. 22 | 23 | Example 2: 24 | 25 | Input: nums = [4,5,6,7,0,1,2] 26 | Output: 0 27 | Explanation: The original array was [0,1,2,4,5,6,7] and it was rotated 4 times. 28 | 29 | Example 3: 30 | 31 | Input: nums = [11,13,15,17] 32 | Output: 11 33 | Explanation: The original array was [11,13,15,17] and it was rotated 4 times. 34 | 35 | 36 | 37 | Constraints: 38 | 39 | n == nums.length 40 | 1 <= n <= 5000 41 | -5000 <= nums[i] <= 5000 42 | All the integers of nums are unique. 43 | nums is sorted and rotated between 1 and n times. 44 | */ 45 | 46 | class FindMinimumInRotatedSortedArray { 47 | //Time complexity: O(log(n)) || Space complexity: O(1) 48 | public int findMin(int[] nums) { 49 | int n = nums.length; 50 | //corner case -> ony 1 element in array 51 | if(n == 1) { 52 | return nums[0]; 53 | } 54 | 55 | //pointers 56 | int start = 0, end = n-1, mid = 0; 57 | 58 | //check -> array is fully rotated or sorted 59 | if(nums[start] < nums[end]) { 60 | return nums[start]; 61 | } 62 | 63 | //find minimum in rotated array 64 | while(start < end) { 65 | mid = start + (end-start)/2; 66 | 67 | //mid is bigger than end -> means, rotated section 68 | if(nums[mid] > nums[end]) { 69 | start = mid+1; 70 | } else { //mid is smaller than end -> means, not in rotated section 71 | end = mid; 72 | } 73 | } 74 | 75 | //final ans 76 | return nums[start]; 77 | } 78 | } 79 | 80 | public class Array44_FindMinimumInRotatedSortedArray { 81 | public static void main(String[] args) { 82 | FindMinimumInRotatedSortedArray obj = new FindMinimumInRotatedSortedArray(); 83 | int[] nums; 84 | 85 | //example 1 86 | System.out.println("----- example 1 -----"); 87 | nums = new int[] {11}; 88 | System.out.println(obj.findMin(nums)); 89 | 90 | //example 2 91 | System.out.println("----- example 2 -----"); 92 | nums = new int[] {6,7,8,9,10,11,12,1,2,3,4,5}; 93 | System.out.println(obj.findMin(nums)); 94 | 95 | //example 3 96 | System.out.println("----- example 3 -----"); 97 | nums = new int[] {3,5,7,10,11,25}; 98 | System.out.println(obj.findMin(nums)); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /02-Array/Array45_MaximumSumCircularSubarray.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC918: Maximum Sum Circular Subarray || https://leetcode.com/problems/maximum-sum-circular-subarray 3 | 4 | Given a circular integer array nums of length n, return the maximum possible sum of a non-empty subarray of nums. 5 | 6 | A circular array means the end of the array connects to the beginning of the array. Formally, the next element of nums[i] is nums[(i + 1) % n] and the previous element of nums[i] is nums[(i - 1 + n) % n]. 7 | 8 | A subarray may only include each element of the fixed buffer nums at most once. Formally, for a subarray nums[i], nums[i + 1], ..., nums[j], there does not exist i <= k1, k2 <= j with k1 % n == k2 % n. 9 | 10 | 11 | 12 | Example 1: 13 | 14 | Input: nums = [1,-2,3,-2] 15 | Output: 3 16 | Explanation: Subarray [3] has maximum sum 3. 17 | 18 | Example 2: 19 | 20 | Input: nums = [5,-3,5] 21 | Output: 10 22 | Explanation: Subarray [5,5] has maximum sum 5 + 5 = 10. 23 | 24 | Example 3: 25 | 26 | Input: nums = [-3,-2,-3] 27 | Output: -2 28 | Explanation: Subarray [-2] has maximum sum -2. 29 | 30 | 31 | 32 | Constraints: 33 | n == nums.length 34 | 1 <= n <= 3 * 10^4 35 | -3 * 10^4 <= nums[i] <= 3 * 10^4 36 | 37 | */ 38 | 39 | class MaximumSumCircularSubarray { 40 | //Time complexity: O(n) || Space Complexity: O(1) 41 | public int maxSubarraySumCircular(int[] nums) { 42 | int maxSum = nums[0], currMax = nums[0]; 43 | int minSum = nums[0], currMin = nums[0]; 44 | int totalSum = nums[0]; 45 | 46 | for (int i = 1; i < nums.length; i++) { 47 | int num = nums[i]; 48 | 49 | // calculate total sum 50 | totalSum += num; 51 | 52 | // Kadane's algorithm for maximum sum 53 | // either extend previos sub-array or start new one 54 | currMax = Math.max(currMax + num, num); 55 | maxSum = Math.max(maxSum, currMax); 56 | 57 | // Kadane's algorithm for minimum sum 58 | // either extend previos sub-array or start new one 59 | currMin = Math.min(currMin + num, num); 60 | minSum = Math.min(minSum, currMin); 61 | } 62 | 63 | int circularSum = totalSum - minSum; 64 | 65 | // corner case -> nums[] contains only negative numbers 66 | if (circularSum == 0) { 67 | return maxSum; 68 | } 69 | 70 | // return either maxSum(when nums[] is strictly increasing order) 71 | // or circularSum for sub-array 72 | return Math.max(maxSum, circularSum); 73 | } 74 | } 75 | 76 | public class Array45_MaximumSumCircularSubarray { 77 | public static void main(String[] args) { 78 | MaximumSumCircularSubarray obj = new MaximumSumCircularSubarray(); 79 | int[] nums; 80 | 81 | //example 1 82 | System.out.println("----- example 1 -----"); 83 | nums = new int[] {3,1,-1,2,0,-4,-1,-2,6,5}; 84 | System.out.println(obj.maxSubarraySumCircular(nums)); 85 | 86 | //example 2 87 | System.out.println("----- example 2 -----"); 88 | nums = new int[] {1,2,3,4,5,6,7}; 89 | System.out.println(obj.maxSubarraySumCircular(nums)); 90 | 91 | //example 3 92 | System.out.println("----- example 3 -----"); 93 | nums = new int[] {-1,-2,-3,-4,-5,-6}; 94 | System.out.println(obj.maxSubarraySumCircular(nums)); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /18-DynamicProgramming/DP08_MaximumSumCircularSubarray.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC918: Maximum Sum Circular Subarray || https://leetcode.com/problems/maximum-sum-circular-subarray 3 | 4 | Given a circular integer array nums of length n, return the maximum possible sum of a non-empty subarray of nums. 5 | 6 | A circular array means the end of the array connects to the beginning of the array. Formally, the next element of nums[i] is nums[(i + 1) % n] and the previous element of nums[i] is nums[(i - 1 + n) % n]. 7 | 8 | A subarray may only include each element of the fixed buffer nums at most once. Formally, for a subarray nums[i], nums[i + 1], ..., nums[j], there does not exist i <= k1, k2 <= j with k1 % n == k2 % n. 9 | 10 | 11 | 12 | Example 1: 13 | 14 | Input: nums = [1,-2,3,-2] 15 | Output: 3 16 | Explanation: Subarray [3] has maximum sum 3. 17 | 18 | Example 2: 19 | 20 | Input: nums = [5,-3,5] 21 | Output: 10 22 | Explanation: Subarray [5,5] has maximum sum 5 + 5 = 10. 23 | 24 | Example 3: 25 | 26 | Input: nums = [-3,-2,-3] 27 | Output: -2 28 | Explanation: Subarray [-2] has maximum sum -2. 29 | 30 | 31 | 32 | Constraints: 33 | n == nums.length 34 | 1 <= n <= 3 * 10^4 35 | -3 * 10^4 <= nums[i] <= 3 * 10^4 36 | 37 | */ 38 | 39 | class MaximumSumCircularSubarray { 40 | //Time complexity: O(n) || Space Complexity: O(1) 41 | public int maxSubarraySumCircular(int[] nums) { 42 | int maxSum = nums[0], currMax = nums[0]; 43 | int minSum = nums[0], currMin = nums[0]; 44 | int totalSum = nums[0]; 45 | 46 | for (int i = 1; i < nums.length; i++) { 47 | int num = nums[i]; 48 | 49 | // calculate total sum 50 | totalSum += num; 51 | 52 | // Kadane's algorithm for maximum sum 53 | // either extend previos sub-array or start new one 54 | currMax = Math.max(currMax + num, num); 55 | maxSum = Math.max(maxSum, currMax); 56 | 57 | // Kadane's algorithm for minimum sum 58 | // either extend previos sub-array or start new one 59 | currMin = Math.min(currMin + num, num); 60 | minSum = Math.min(minSum, currMin); 61 | } 62 | 63 | int circularSum = totalSum - minSum; 64 | 65 | // corner case -> nums[] contains only negative numbers 66 | if (circularSum == 0) { 67 | return maxSum; 68 | } 69 | 70 | // return either maxSum(when nums[] is strictly increasing order) 71 | // or circularSum for sub-array 72 | return Math.max(maxSum, circularSum); 73 | } 74 | } 75 | 76 | public class DP08_MaximumSumCircularSubarray { 77 | public static void main(String[] args) { 78 | MaximumSumCircularSubarray obj = new MaximumSumCircularSubarray(); 79 | int[] nums; 80 | 81 | //example 1 82 | System.out.println("----- example 1 -----"); 83 | nums = new int[] {3,1,-1,2,0,-4,-1,-2,6,5}; 84 | System.out.println(obj.maxSubarraySumCircular(nums)); 85 | 86 | //example 2 87 | System.out.println("----- example 2 -----"); 88 | nums = new int[] {1,2,3,4,5,6,7}; 89 | System.out.println(obj.maxSubarraySumCircular(nums)); 90 | 91 | //example 3 92 | System.out.println("----- example 3 -----"); 93 | nums = new int[] {-1,-2,-3,-4,-5,-6}; 94 | System.out.println(obj.maxSubarraySumCircular(nums)); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /02-Array/Array28_CombinationSum.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC39: Combination Sum || https://leetcode.com/problems/combination-sum/ 3 | 4 | Given an array of distinct integers candidates and a target integer target, return a list of all unique combinations of candidates where the chosen numbers sum to target. You may return the combinations in any order. 5 | 6 | The same number may be chosen from candidates an unlimited number of times. Two combinations are unique if the 7 | 8 | of at least one of the chosen numbers is different. 9 | 10 | The test cases are generated such that the number of unique combinations that sum up to target is less than 150 combinations for the given input. 11 | 12 | 13 | 14 | Example 1: 15 | 16 | Input: candidates = [2,3,6,7], target = 7 17 | Output: [[2,2,3],[7]] 18 | Explanation: 19 | 2 and 3 are candidates, and 2 + 2 + 3 = 7. Note that 2 can be used multiple times. 20 | 7 is a candidate, and 7 = 7. 21 | These are the only two combinations. 22 | 23 | Example 2: 24 | 25 | Input: candidates = [2,3,5], target = 8 26 | Output: [[2,2,2,2],[2,3,3],[3,5]] 27 | 28 | Example 3: 29 | 30 | Input: candidates = [2], target = 1 31 | Output: [] 32 | 33 | 34 | 35 | Constraints: 36 | 37 | 1 <= candidates.length <= 30 38 | 2 <= candidates[i] <= 40 39 | All elements of candidates are distinct. 40 | 1 <= target <= 40 41 | */ 42 | 43 | import java.util.ArrayList; 44 | import java.util.List; 45 | 46 | class CombinationSum { 47 | //Time complexity: O(2^n) 48 | public List> combinationSum(int[] candidates, int target) { 49 | List> list = new ArrayList<>(); 50 | helper(candidates, target, 0, new ArrayList<>(), list); 51 | return list; 52 | } 53 | 54 | private void helper(int[] candidates, int target, int idx, List combination, List> list) { 55 | // base case I 56 | if (target == 0) { 57 | list.add(new ArrayList<>(combination)); 58 | return; 59 | } 60 | 61 | // base case II 62 | if (idx >= candidates.length || target < 0) { 63 | return; 64 | } 65 | 66 | // backtracing 67 | combination.add(candidates[idx]); 68 | helper(candidates, target - candidates[idx], idx, combination, list);// update target 69 | combination.remove(combination.size() - 1); // backtracking step 70 | helper(candidates, target, idx + 1, combination, list);// move forward 71 | } 72 | } 73 | 74 | public class Array28_CombinationSum { 75 | public static void main(String[] args) { 76 | CombinationSum obj = new CombinationSum(); 77 | int[] candidates; 78 | int target; 79 | 80 | // example 1 81 | System.out.println("----- example 1 -----"); 82 | candidates = new int[] { 5, 3, 8, 2 }; 83 | target = 8; 84 | System.out.println(obj.combinationSum(candidates, target)); 85 | 86 | // example 2 87 | System.out.println("----- example 2 -----"); 88 | candidates = new int[] { 2, 3, 6, 7 }; 89 | target = 7; 90 | System.out.println(obj.combinationSum(candidates, target)); 91 | 92 | // example 3 93 | System.out.println("----- example 3 -----"); 94 | candidates = new int[] { 2 }; 95 | target = 1; 96 | System.out.println(obj.combinationSum(candidates, target)); 97 | 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /04-Recursion-Backtracking/RB04_CombinationSum.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC39: Combination Sum || https://leetcode.com/problems/combination-sum/ 3 | 4 | Given an array of distinct integers candidates and a target integer target, return a list of all unique combinations of candidates where the chosen numbers sum to target. You may return the combinations in any order. 5 | 6 | The same number may be chosen from candidates an unlimited number of times. Two combinations are unique if the 7 | 8 | of at least one of the chosen numbers is different. 9 | 10 | The test cases are generated such that the number of unique combinations that sum up to target is less than 150 combinations for the given input. 11 | 12 | 13 | 14 | Example 1: 15 | 16 | Input: candidates = [2,3,6,7], target = 7 17 | Output: [[2,2,3],[7]] 18 | Explanation: 19 | 2 and 3 are candidates, and 2 + 2 + 3 = 7. Note that 2 can be used multiple times. 20 | 7 is a candidate, and 7 = 7. 21 | These are the only two combinations. 22 | 23 | Example 2: 24 | 25 | Input: candidates = [2,3,5], target = 8 26 | Output: [[2,2,2,2],[2,3,3],[3,5]] 27 | 28 | Example 3: 29 | 30 | Input: candidates = [2], target = 1 31 | Output: [] 32 | 33 | 34 | 35 | Constraints: 36 | 37 | 1 <= candidates.length <= 30 38 | 2 <= candidates[i] <= 40 39 | All elements of candidates are distinct. 40 | 1 <= target <= 40 41 | */ 42 | 43 | import java.util.ArrayList; 44 | import java.util.List; 45 | 46 | class CombinationSum { 47 | //Time complexity: O(2^n) 48 | public List> combinationSum(int[] candidates, int target) { 49 | List> list = new ArrayList<>(); 50 | helper(candidates, target, 0, new ArrayList<>(), list); 51 | return list; 52 | } 53 | 54 | private void helper(int[] candidates, int target, int idx, List combination, List> list) { 55 | // base case I 56 | if (target == 0) { 57 | list.add(new ArrayList<>(combination)); 58 | return; 59 | } 60 | 61 | // base case II 62 | if (idx >= candidates.length || target < 0) { 63 | return; 64 | } 65 | 66 | // backtracing 67 | combination.add(candidates[idx]); 68 | helper(candidates, target - candidates[idx], idx, combination, list);// update target 69 | combination.remove(combination.size() - 1); // backtracking step 70 | helper(candidates, target, idx + 1, combination, list);// move forward 71 | } 72 | } 73 | 74 | public class RB04_CombinationSum { 75 | public static void main(String[] args) { 76 | CombinationSum obj = new CombinationSum(); 77 | int[] candidates; 78 | int target; 79 | 80 | // example 1 81 | System.out.println("----- example 1 -----"); 82 | candidates = new int[] { 5, 3, 8, 2 }; 83 | target = 8; 84 | System.out.println(obj.combinationSum(candidates, target)); 85 | 86 | // example 2 87 | System.out.println("----- example 2 -----"); 88 | candidates = new int[] { 2, 3, 6, 7 }; 89 | target = 7; 90 | System.out.println(obj.combinationSum(candidates, target)); 91 | 92 | // example 3 93 | System.out.println("----- example 3 -----"); 94 | candidates = new int[] { 2 }; 95 | target = 1; 96 | System.out.println(obj.combinationSum(candidates, target)); 97 | 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /08-BinarySearchTrees/BST04_MinimumDistanceBetweenBSTNodes.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC530: Minimum Absolute Difference in BST || https://leetcode.com/problems/minimum-absolute-difference-in-bst 3 | LC783: Minimum Distance Between BST Nodes || https://leetcode.com/problems/minimum-distance-between-bst-nodes/ 4 | 5 | 6 | Given the root of a Binary Search Tree (BST), return the minimum absolute difference between the values of any two different nodes in the tree. 7 | 8 | 9 | Example 1: 10 | 11 | Input: root = [4,2,6,1,3] 12 | Output: 1 13 | 14 | Example 2: 15 | 16 | Input: root = [1,0,48,null,null,12,49] 17 | Output: 1 18 | 19 | 20 | 21 | Constraints: 22 | 23 | The number of nodes in the tree is in the range [2, 10^4]. 24 | 0 <= Node.val <= 10^5 25 | 26 | */ 27 | 28 | import java.util.ArrayList; 29 | import java.util.List; 30 | 31 | class Node { 32 | int data; 33 | Node left; 34 | Node right; 35 | 36 | Node(int data) { 37 | this.data = data; 38 | this.left = null; 39 | this.right = null; 40 | } 41 | } 42 | 43 | class MinimumDistanceBetweenBSTNodes { 44 | 45 | // Time complexity: O(n) || Space complexity: O(n) 46 | public int approach1(Node root) { 47 | List list = new ArrayList<>(); 48 | 49 | // inorder traversal 50 | inOrderTraversal(root, list); 51 | 52 | // calculate min difference 53 | int minDiff = Integer.MAX_VALUE; 54 | for (int i = 0; i < list.size() - 1; i++) { 55 | int diff = list.get(i + 1) - list.get(i); 56 | minDiff = Math.min(minDiff, diff); 57 | } 58 | 59 | return minDiff; 60 | } 61 | 62 | private void inOrderTraversal(Node root, List list) { 63 | // base case 64 | if (root == null) { 65 | return; 66 | } 67 | 68 | inOrderTraversal(root.left, list); 69 | list.add(root.data); 70 | inOrderTraversal(root.right, list); 71 | } 72 | 73 | // ------------------------------- 74 | private int minDiff; 75 | private Node prev; 76 | 77 | public int approach2(Node root) { 78 | minDiff = Integer.MAX_VALUE; 79 | prev = null; 80 | 81 | // inorder traversal 82 | inOrderTraversal(root); 83 | 84 | return minDiff; 85 | } 86 | 87 | private void inOrderTraversal(Node root) { 88 | // base case 89 | if (root == null) { 90 | return; 91 | } 92 | 93 | inOrderTraversal(root.left); 94 | 95 | // calculate the minDiff 96 | if (prev != null) { 97 | minDiff = Math.min(minDiff, root.data - prev.data); 98 | } 99 | prev = root; 100 | 101 | inOrderTraversal(root.right); 102 | } 103 | 104 | } 105 | 106 | public class BST04_MinimumDistanceBetweenBSTNodes { 107 | public static void main(String[] args) { 108 | MinimumDistanceBetweenBSTNodes obj = new MinimumDistanceBetweenBSTNodes(); 109 | 110 | //BST 111 | Node root = new Node(20); 112 | root.left = new Node(10); 113 | root.left.left = new Node(7); 114 | root.left.right = new Node(11); 115 | root.right = new Node(25); 116 | root.right.left = new Node(22); 117 | root.right.left.left = new Node(21); 118 | root.right.right = new Node(30); 119 | 120 | //example 1 121 | System.out.println("----- example 1 -----"); 122 | System.out.println(obj.approach1(root)); 123 | System.out.println(obj.approach2(root)); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /01-Math/Math04_Pow.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC50: Pow(x, n) || https://leetcode.com/problems/powx-n/ 3 | 4 | Implement pow(x, n), which calculates x raised to the power n (i.e., xn). 5 | 6 | 7 | 8 | Example 1: 9 | 10 | Input: x = 2.00000, n = 10 11 | Output: 1024.00000 12 | 13 | Example 2: 14 | 15 | Input: x = 2.10000, n = 3 16 | Output: 9.26100 17 | 18 | Example 3: 19 | 20 | Input: x = 2.00000, n = -2 21 | Output: 0.25000 22 | Explanation: 2-2 = 1/22 = 1/4 = 0.25 23 | 24 | 25 | 26 | Constraints: 27 | 28 | -100.0 < x < 100.0 29 | -2^31 <= n <= 2^31-1 30 | n is an integer. 31 | Either x is not zero or n > 0. 32 | -10^4 <= x^n <= 10^4 33 | 34 | */ 35 | 36 | class Pow { 37 | // Time complexity: O(n) || Space complexity: O(1) 38 | public double solution1(double x, int n) { 39 | double ans = 1.0; 40 | 41 | for (int i = 0; i < n; i++) { 42 | ans *= x; 43 | } 44 | 45 | return n < 0 ? 1.0 / ans : ans; 46 | } 47 | 48 | // Time complexity: O(log n) || Space complexity: O(log n) 49 | public double solution2(double x, int n) { 50 | return n < 0 ? 1 / pow(x, -n) : pow(x, n); 51 | } 52 | 53 | private double pow(double x, long n) { 54 | // base class 55 | if (n == 0) { 56 | return 1; 57 | } 58 | /* Logic */ 59 | double val = pow(x, n / 2); 60 | val = val * val; 61 | 62 | return n % 2 == 0 ? val : x * val; 63 | } 64 | 65 | // Time complexity: O(log(n)) || Space complexity: O(1) 66 | public double solution3(double x, int n) { 67 | // corner case 68 | if (n == 0) { 69 | return 1; 70 | } 71 | 72 | // get the positive value 73 | long N = n; 74 | if (N < 0) { 75 | N = -1 * N; 76 | } 77 | double ans = 1.0; 78 | 79 | // calculate the X^n 80 | while (N > 0) { 81 | if (N % 2 == 0) { // even case => X^n = (X^2)^(n/2) 82 | x = x * x; 83 | N = N / 2; 84 | } else { // odd case => X^n = X*X^(n-1) 85 | ans = ans * x; 86 | N = N - 1; 87 | } 88 | } 89 | 90 | return n < 0 ? (double) 1.0 / (double) ans : ans; 91 | } 92 | } 93 | 94 | public class Math04_Pow { 95 | public static void main(String[] args) { 96 | Pow obj = new Pow(); 97 | double x; 98 | int n; 99 | 100 | // example 1 101 | System.out.println("----- example 1 -----"); 102 | x = 1; 103 | n = 10; 104 | System.out.println(obj.solution1(x, n)); 105 | System.out.println(obj.solution2(x, n)); 106 | System.out.println(obj.solution3(x, n)); 107 | 108 | // example 2 109 | System.out.println("----- example 2 -----"); 110 | x = -2; 111 | n = 5; 112 | System.out.println(obj.solution1(x, n)); 113 | System.out.println(obj.solution2(x, n)); 114 | System.out.println(obj.solution3(x, n)); 115 | 116 | // example 3 117 | System.out.println("----- example 3 -----"); 118 | x = 2; 119 | n = -5; 120 | System.out.println(obj.solution1(x, n)); 121 | System.out.println(obj.solution2(x, n)); 122 | System.out.println(obj.solution3(x, n)); 123 | 124 | // example 4 125 | System.out.println("----- example 3 -----"); 126 | x = 2; 127 | n = -254697; 128 | System.out.println(obj.solution1(x, n)); 129 | System.out.println(obj.solution2(x, n)); 130 | System.out.println(obj.solution3(x, n)); 131 | } 132 | } -------------------------------------------------------------------------------- /02-Array/Array42_RemoveDuplicatesFromSortedArray.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC26: Remove Duplicates from Sorted Array || https://leetcode.com/problems/remove-duplicates-from-sorted-array 3 | 4 | Given an integer array nums sorted in non-decreasing order, remove the duplicates in-place such that each unique element appears only once. The relative order of the elements should be kept the same. Then return the number of unique elements in nums. 5 | 6 | Consider the number of unique elements of nums to be k, to get accepted, you need to do the following things: 7 | 8 | + Change the array nums such that the first k elements of nums contain the unique elements in the order they were present in nums initially. The remaining elements of nums are not important as well as the size of nums. 9 | + Return k. 10 | 11 | Custom Judge: 12 | 13 | The judge will test your solution with the following code: 14 | 15 | int[] nums = [...]; // Input array 16 | int[] expectedNums = [...]; // The expected answer with correct length 17 | 18 | int k = removeDuplicates(nums); // Calls your implementation 19 | 20 | assert k == expectedNums.length; 21 | for (int i = 0; i < k; i++) { 22 | assert nums[i] == expectedNums[i]; 23 | } 24 | 25 | If all assertions pass, then your solution will be accepted. 26 | 27 | 28 | 29 | Example 1: 30 | 31 | Input: nums = [1,1,2] 32 | Output: 2, nums = [1,2,_] 33 | Explanation: Your function should return k = 2, with the first two elements of nums being 1 and 2 respectively. 34 | It does not matter what you leave beyond the returned k (hence they are underscores). 35 | 36 | Example 2: 37 | 38 | Input: nums = [0,0,1,1,1,2,2,3,3,4] 39 | Output: 5, nums = [0,1,2,3,4,_,_,_,_,_] 40 | Explanation: Your function should return k = 5, with the first five elements of nums being 0, 1, 2, 3, and 4 respectively. 41 | It does not matter what you leave beyond the returned k (hence they are underscores). 42 | 43 | 44 | 45 | Constraints: 46 | 47 | 1 <= nums.length <= 3 * 10^4 48 | -100 <= nums[i] <= 100 49 | nums is sorted in non-decreasing order. 50 | 51 | 52 | */ 53 | 54 | import java.util.Arrays; 55 | 56 | class RemoveDuplicatesFromSortedArray { 57 | // Time complexity: O(n) || Space complexity: O(1) 58 | public int removeDuplicates(int[] nums) { 59 | int count = 0; 60 | 61 | for (int i = 1; i < nums.length; i++) { 62 | if (nums[count] != nums[i]) { 63 | nums[++count] = nums[i]; 64 | } 65 | } 66 | 67 | return count + 1; 68 | } 69 | } 70 | 71 | public class Array42_RemoveDuplicatesFromSortedArray { 72 | public static void main(String[] args) { 73 | RemoveDuplicatesFromSortedArray obj = new RemoveDuplicatesFromSortedArray(); 74 | int[] nums; 75 | 76 | // example 1 77 | System.out.println("----- example 1 -----"); 78 | nums = new int[] { 1, 1, 3, 3, 3, 3, 6, 7, 8, 8, 9, 9 }; 79 | System.out.println(obj.removeDuplicates(nums)); 80 | System.out.println(Arrays.toString(nums)); 81 | 82 | // example 2 83 | System.out.println("----- example 2 -----"); 84 | nums = new int[] { 1, 1, 2 }; 85 | System.out.println(obj.removeDuplicates(nums)); 86 | System.out.println(Arrays.toString(nums)); 87 | 88 | // example 3 89 | System.out.println("----- example 3 -----"); 90 | nums = new int[] { 0, 0, 1, 1, 1, 2, 2, 3, 3, 4 }; 91 | System.out.println(obj.removeDuplicates(nums)); 92 | System.out.println(Arrays.toString(nums)); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /02-Array/Array13_ContainerWithMostWater.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC11: Container With Most Water || https://leetcode.com/problems/container-with-most-water 3 | 4 | You are given an integer array height of length n. There are n vertical lines drawn such that the two endpoints of the ith line are (i, 0) and (i, height[i]). 5 | 6 | Find two lines that together with the x-axis form a container, such that the container contains the most water. 7 | 8 | Return the maximum amount of water a container can store. 9 | 10 | Notice that you may not slant the container. 11 | 12 | 13 | Example 1: 14 | 15 | Input: height = [1,8,6,2,5,4,8,3,7] 16 | Output: 49 17 | Explanation: The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49. 18 | 19 | Example 2: 20 | 21 | Input: height = [1,1] 22 | Output: 1 23 | 24 | 25 | 26 | Constraints: 27 | n == height.length 28 | 2 <= n <= 105 29 | 0 <= height[i] <= 104 30 | */ 31 | 32 | class ContainerWithMostWater { 33 | // approach 1 - brute force 34 | // Time Complexity: O(n^2) || Space complexity: O(1) 35 | public int approach1(int[] height) { 36 | // variable to store maximum water 37 | int max = 0; 38 | int n = height.length; 39 | 40 | for (int i = 0; i < n - 1; i++) { 41 | for (int j = i + 1; j < n; j++) { 42 | // calculating area = height x width 43 | int area = Math.min(height[i], height[j]) * Math.abs(j - i); 44 | // get or set maximum water 45 | max = Math.max(max, area); 46 | } 47 | } 48 | 49 | return max; 50 | } 51 | 52 | // approach 2 - two pointers (Optimal) 53 | // Time complexity: O(n) || Space complexity: O(1) 54 | public int approach2(int[] height) { 55 | // variable to store maximum water 56 | int max = 0; 57 | // two pointers 58 | int left = 0, right = height.length - 1; 59 | 60 | while (left < right) { 61 | // calculating area 62 | int ht = Math.min(height[left], height[right]); // height will be the minimum one 63 | int width = Math.abs(right - left); 64 | int area = ht * width; 65 | 66 | // get or set maximum water 67 | max = Math.max(max, area); 68 | 69 | // change the pointers -> which one is minimum change that 70 | if (height[left] < height[right]) { 71 | left++; 72 | } else { 73 | right--; 74 | } 75 | } 76 | 77 | return max; 78 | } 79 | } 80 | 81 | public class Array13_ContainerWithMostWater { 82 | public static void main(String[] args) { 83 | ContainerWithMostWater obj = new ContainerWithMostWater(); 84 | 85 | // example 1 86 | System.out.println("---- example 1 ----"); 87 | int[] heights1 = { 2, 6, 7, 1, 4, 5, 3, 8, 8 }; 88 | System.out.println(obj.approach1(heights1)); 89 | System.out.println(obj.approach2(heights1)); 90 | 91 | // example 2 92 | System.out.println("---- example 2 ----"); 93 | int[] heights2 = { 1, 8, 6, 2, 5, 4, 8, 3, 7 }; 94 | System.out.println(obj.approach1(heights2)); 95 | System.out.println(obj.approach2(heights2)); 96 | 97 | // example 3 98 | System.out.println("---- example 3 ----"); 99 | int[] heights3 = { 1, 1 }; 100 | System.out.println(obj.approach1(heights3)); 101 | System.out.println(obj.approach2(heights3)); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /16-TwoPointers/TP05_ContainerWithMostWater.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC11: Container With Most Water || https://leetcode.com/problems/container-with-most-water 3 | 4 | You are given an integer array height of length n. There are n vertical lines drawn such that the two endpoints of the ith line are (i, 0) and (i, height[i]). 5 | 6 | Find two lines that together with the x-axis form a container, such that the container contains the most water. 7 | 8 | Return the maximum amount of water a container can store. 9 | 10 | Notice that you may not slant the container. 11 | 12 | 13 | Example 1: 14 | 15 | Input: height = [1,8,6,2,5,4,8,3,7] 16 | Output: 49 17 | Explanation: The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49. 18 | 19 | Example 2: 20 | 21 | Input: height = [1,1] 22 | Output: 1 23 | 24 | 25 | 26 | Constraints: 27 | n == height.length 28 | 2 <= n <= 105 29 | 0 <= height[i] <= 104 30 | */ 31 | 32 | class ContainerWithMostWater { 33 | // approach 1 - brute force 34 | // Time Complexity: O(n^2) || Space complexity: O(1) 35 | public int approach1(int[] height) { 36 | // variable to store maximum water 37 | int max = 0; 38 | int n = height.length; 39 | 40 | for (int i = 0; i < n - 1; i++) { 41 | for (int j = i + 1; j < n; j++) { 42 | // calculating area = height x width 43 | int area = Math.min(height[i], height[j]) * Math.abs(j - i); 44 | // get or set maximum water 45 | max = Math.max(max, area); 46 | } 47 | } 48 | 49 | return max; 50 | } 51 | 52 | // approach 2 - two pointers (Optimal) 53 | // Time complexity: O(n) || Space complexity: O(1) 54 | public int approach2(int[] height) { 55 | // variable to store maximum water 56 | int max = 0; 57 | // two pointers 58 | int left = 0, right = height.length - 1; 59 | 60 | while (left < right) { 61 | // calculating area 62 | int ht = Math.min(height[left], height[right]); // height will be the minimum one 63 | int width = Math.abs(right - left); 64 | int area = ht * width; 65 | 66 | // get or set maximum water 67 | max = Math.max(max, area); 68 | 69 | // change the pointers -> which one is minimum change that 70 | if (height[left] < height[right]) { 71 | left++; 72 | } else { 73 | right--; 74 | } 75 | } 76 | 77 | return max; 78 | } 79 | } 80 | 81 | public class TP05_ContainerWithMostWater { 82 | public static void main(String[] args) { 83 | ContainerWithMostWater obj = new ContainerWithMostWater(); 84 | 85 | // example 1 86 | System.out.println("---- example 1 ----"); 87 | int[] heights1 = { 2, 6, 7, 1, 4, 5, 3, 8, 8 }; 88 | System.out.println(obj.approach1(heights1)); 89 | System.out.println(obj.approach2(heights1)); 90 | 91 | // example 2 92 | System.out.println("---- example 2 ----"); 93 | int[] heights2 = { 1, 8, 6, 2, 5, 4, 8, 3, 7 }; 94 | System.out.println(obj.approach1(heights2)); 95 | System.out.println(obj.approach2(heights2)); 96 | 97 | // example 3 98 | System.out.println("---- example 3 ----"); 99 | int[] heights3 = { 1, 1 }; 100 | System.out.println(obj.approach1(heights3)); 101 | System.out.println(obj.approach2(heights3)); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /CCI/Chapter-01/C01_08_ZeroMatrix.java: -------------------------------------------------------------------------------- 1 | /* 2 | Zero Matrix: Write an algorithm such that if an element in an MxN matrix is 0, 3 | it's entire row and column are set 0. 4 | 5 | Full Solution: DSA/02-Array/Array12_SetMAtrixZeros.java 6 | */ 7 | 8 | class Solution { 9 | /** ----------- My Solutions ----------- **/ 10 | 11 | // TC => O(m*n) || SC => O(1) 12 | public int[][] solution(int[][] matrix) { 13 | int m = matrix.length, n = matrix[0].length; 14 | boolean isZeroFirstRow = false, isZeroFirstCol = false; 15 | 16 | // check zero in first row 17 | for (int j = 0; j < n; j++) { 18 | if (matrix[0][j] == 0) { 19 | isZeroFirstRow = true; 20 | break; 21 | } 22 | } 23 | 24 | // check zero in first col 25 | for (int i = 0; i < m; i++) { 26 | if (matrix[i][0] == 0) { 27 | isZeroFirstRow = true; 28 | break; 29 | } 30 | } 31 | 32 | // put zeros on first row & col based of current element 33 | for (int i = 1; i < m; i++) { 34 | for (int j = 1; j < n; j++) { 35 | if (matrix[i][j] == 0) { 36 | matrix[0][j] = 0; 37 | matrix[i][0] = 0; 38 | } 39 | } 40 | } 41 | 42 | // put zero based on first row or column 43 | for (int i = 1; i < m; i++) { 44 | for (int j = 1; j < n; j++) { 45 | if (matrix[0][j] == 0 || matrix[i][0] == 0) { 46 | matrix[i][j] = 0; 47 | } 48 | } 49 | } 50 | 51 | // put zeros on first row 52 | if (isZeroFirstRow) { 53 | for (int j = 0; j < n; j++) { 54 | matrix[0][j] = 0; 55 | } 56 | } 57 | 58 | // put zeros on first col 59 | if (isZeroFirstCol) { 60 | for (int i = 0; i < m; i++) { 61 | matrix[i][0] = 0; 62 | } 63 | } 64 | 65 | return matrix; 66 | } 67 | 68 | public void printMatrix(int[][] matrix) { 69 | System.out.print("["); 70 | for (int[] row : matrix) { 71 | System.out.print("["); 72 | for (int cell : row) { 73 | System.out.print(" " + cell + " "); 74 | } 75 | System.out.print("]\n"); 76 | } 77 | System.out.print("]\n"); 78 | } 79 | 80 | /** ----------- Book Solutions ----------- **/ 81 | 82 | } 83 | 84 | public class C01_08_ZeroMatrix { 85 | 86 | public static void main(String[] args) { 87 | Solution obj = new Solution(); 88 | int[][] matrix; 89 | 90 | // example 1 91 | System.out.println("---- Example 1 ----"); 92 | matrix = new int[][] { { 1, 1, 1 }, { 1, 0, 1 }, { 1, 1, 1 } }; 93 | obj.printMatrix(obj.solution(matrix)); 94 | 95 | // example 2 96 | System.out.println("---- Example 2 ----"); 97 | matrix = new int[][] { { 0, 1, 2, 0 }, { 3, 4, 5, 2 }, { 1, 3, 1, 5 } }; 98 | obj.printMatrix(obj.solution(matrix)); 99 | 100 | // example 3 101 | System.out.println("---- Example 3 ----"); 102 | matrix = new int[][] { { 0, 1, 2, 0, 3 }, { 3, 4, 5, 2, 1 }, { 0, 1, 3, 1, 5 } }; 103 | obj.printMatrix(obj.solution(matrix)); 104 | 105 | } 106 | } -------------------------------------------------------------------------------- /03-String/String09_LetterCombinationPhoneNumber.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC17: Letter Combinations of a Phone Number || https://leetcode.com/problems/letter-combinations-of-a-phone-number/ 3 | 4 | Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent. Return the answer in any order. 5 | 6 | A mapping of digits to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters. 7 | 8 | 9 | 10 | Example 1: 11 | 12 | Input: digits = "23" 13 | Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"] 14 | 15 | Example 2: 16 | 17 | Input: digits = "" 18 | Output: [] 19 | 20 | Example 3: 21 | 22 | Input: digits = "2" 23 | Output: ["a","b","c"] 24 | 25 | 26 | 27 | Constraints: 28 | 29 | 0 <= digits.length <= 4 30 | digits[i] is a digit in the range ['2', '9']. 31 | 32 | */ 33 | 34 | import java.util.ArrayList; 35 | import java.util.HashMap; 36 | import java.util.List; 37 | 38 | class LetterCombinationPhoneNumber { 39 | HashMap map; 40 | 41 | LetterCombinationPhoneNumber() { 42 | this.map = new HashMap<>(); 43 | this.map.put('2', "abc"); 44 | this.map.put('3', "def"); 45 | this.map.put('4', "ghi"); 46 | this.map.put('5', "jkl"); 47 | this.map.put('6', "mno"); 48 | this.map.put('7', "pqrs"); 49 | this.map.put('8', "tuv"); 50 | this.map.put('9', "wxyz"); 51 | } 52 | 53 | //Time complexity: O(4^n) OR O(3^n) 54 | public List letterCombinations(String digits) { 55 | // empty digits 56 | if (digits.length() == 0) { 57 | return new ArrayList<>(); 58 | } 59 | 60 | List ans = new ArrayList<>(); // store the combinations 61 | helper(0, digits, ans, new StringBuilder("")); // function call 62 | 63 | return ans; 64 | } 65 | 66 | private void helper(int idx, String digits, List ans, StringBuilder sb) { 67 | // base case, idx is now equal or bigger than digits size 68 | if (idx >= digits.length()) { 69 | ans.add(sb.toString()); // and combination into ans 70 | sb = new StringBuilder(""); // re-initialize sb 71 | return; 72 | } 73 | 74 | String letters = map.get(digits.charAt(idx));// get all letters for current digits 75 | 76 | for (char ch : letters.toCharArray()) { 77 | sb.append(ch); // add character into sb 78 | helper(idx + 1, digits, ans, sb); // recursive call -> increase idx by 1 79 | sb.deleteCharAt(sb.length() - 1); // backtrack 80 | } 81 | } 82 | } 83 | 84 | public class String09_LetterCombinationPhoneNumber { 85 | public static void main(String[] args) { 86 | LetterCombinationPhoneNumber obj = new LetterCombinationPhoneNumber(); 87 | String digits; 88 | 89 | //example 1 90 | System.out.println("----- example 1 -----"); 91 | digits = ""; 92 | System.out.println(obj.letterCombinations(digits)); 93 | 94 | //example 2 95 | System.out.println("----- example 2 -----"); 96 | digits = "77"; 97 | System.out.println(obj.letterCombinations(digits)); 98 | 99 | //example 2 100 | System.out.println("----- example 2 -----"); 101 | digits = "234"; 102 | System.out.println(obj.letterCombinations(digits)); 103 | 104 | //example 3 105 | System.out.println("----- example 3 -----"); 106 | digits = "72"; 107 | System.out.println(obj.letterCombinations(digits)); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /02-Array/Array04_MajorityElement.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC169: Majority Element || https://leetcode.com/problems/majority-element/ 3 | 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 | 9 | Example 1: 10 | Input: nums = [3,2,3] 11 | Output: 3 12 | 13 | Example 2: 14 | Input: nums = [2,2,1,1,1,2,2] 15 | Output: 2 16 | 17 | Constraints: 18 | 19 | n == nums.length 20 | 1 <= n <= 5 * 104 21 | -109 <= nums[i] <= 109 22 | 23 | 24 | Follow-up: Could you solve the problem in linear time and in O(1) space? 25 | */ 26 | 27 | import java.util.Arrays; 28 | import java.util.HashMap; 29 | 30 | class MajorityElement { 31 | 32 | // Brute Force => Time Complexity: O(n log(n)) || Space Complexity: O(1) 33 | public int approach1(int[] arr) { 34 | Arrays.sort(arr); 35 | return arr[arr.length / 2]; 36 | } 37 | 38 | // HashMap => Time Complexity: O(n) || Space Complexity: O(n) 39 | public int approach2(int[] arr) { 40 | // store key -> nums[i] & value -> count of elements 41 | HashMap map = new HashMap<>(); 42 | 43 | for (int key : arr) { 44 | // put or update {key,value} 45 | if (map.containsKey(key)) { 46 | map.put(key, map.get(key) + 1); 47 | } else { 48 | map.put(key, 1); 49 | } 50 | 51 | // check for the majority element 52 | if (map.get(key) > arr.length / 2) { 53 | return key; 54 | } 55 | } 56 | 57 | return -1; 58 | } 59 | 60 | // Optimal approach => Time Complexity: O(n) || Space Complexity: O() 61 | public int approach3(int[] arr) { 62 | int count = 0, ans = 0; 63 | 64 | for (int x : arr) { 65 | if (count == 0) { 66 | ans = x; 67 | } 68 | 69 | if (ans == x) { 70 | count++; 71 | } else { 72 | count--; 73 | } 74 | } 75 | return ans; 76 | } 77 | } 78 | 79 | public class Array04_MajorityElement { 80 | public static void main(String[] args) { 81 | MajorityElement obj = new MajorityElement(); 82 | 83 | // example 1 84 | System.out.println("---- example 1 ----"); 85 | int[] nums1 = { 3, 2, 3 }; 86 | System.out.println("Approach 1: " + obj.approach1(nums1)); 87 | System.out.println("Approach 2: " + obj.approach2(nums1)); 88 | System.out.println("Approach 3: " + obj.approach3(nums1)); 89 | 90 | // example 2 91 | System.out.println("---- example 2 ----"); 92 | int[] nums2 = { 2, 2, 1, 1, 1, 2, 2 }; 93 | System.out.println("Approach 1: " + obj.approach1(nums2)); 94 | System.out.println("Approach 2: " + obj.approach2(nums2)); 95 | System.out.println("Approach 3: " + obj.approach3(nums2)); 96 | 97 | // example 3 98 | System.out.println("---- example 3 ----"); 99 | int[] nums3 = { 1 }; 100 | System.out.println("Approach 1: " + obj.approach1(nums3)); 101 | System.out.println("Approach 2: " + obj.approach2(nums3)); 102 | System.out.println("Approach 3: " + obj.approach3(nums3)); 103 | 104 | // example 3 105 | System.out.println("---- example 4 ----"); 106 | int[] nums4 = { 6, 5, 5 }; 107 | System.out.println("Approach 1: " + obj.approach1(nums4)); 108 | System.out.println("Approach 2: " + obj.approach2(nums4)); 109 | System.out.println("Approach 3: " + obj.approach3(nums4)); 110 | } 111 | } -------------------------------------------------------------------------------- /04-Recursion-Backtracking/RB05_LetterCombinationPhoneNumber.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC17: Letter Combinations of a Phone Number || https://leetcode.com/problems/letter-combinations-of-a-phone-number/ 3 | 4 | Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent. Return the answer in any order. 5 | 6 | A mapping of digits to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters. 7 | 8 | 9 | 10 | Example 1: 11 | 12 | Input: digits = "23" 13 | Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"] 14 | 15 | Example 2: 16 | 17 | Input: digits = "" 18 | Output: [] 19 | 20 | Example 3: 21 | 22 | Input: digits = "2" 23 | Output: ["a","b","c"] 24 | 25 | 26 | 27 | Constraints: 28 | 29 | 0 <= digits.length <= 4 30 | digits[i] is a digit in the range ['2', '9']. 31 | 32 | */ 33 | 34 | import java.util.ArrayList; 35 | import java.util.HashMap; 36 | import java.util.List; 37 | 38 | class LetterCombinationPhoneNumber { 39 | HashMap map; 40 | 41 | LetterCombinationPhoneNumber() { 42 | this.map = new HashMap<>(); 43 | this.map.put('2', "abc"); 44 | this.map.put('3', "def"); 45 | this.map.put('4', "ghi"); 46 | this.map.put('5', "jkl"); 47 | this.map.put('6', "mno"); 48 | this.map.put('7', "pqrs"); 49 | this.map.put('8', "tuv"); 50 | this.map.put('9', "wxyz"); 51 | } 52 | 53 | //Time complexity: O(4^n) OR O(3^n) 54 | public List letterCombinations(String digits) { 55 | // empty digits 56 | if (digits.length() == 0) { 57 | return new ArrayList<>(); 58 | } 59 | 60 | List ans = new ArrayList<>(); // store the combinations 61 | helper(0, digits, ans, new StringBuilder("")); // function call 62 | 63 | return ans; 64 | } 65 | 66 | private void helper(int idx, String digits, List ans, StringBuilder sb) { 67 | // base case, idx is now equal or bigger than digits size 68 | if (idx >= digits.length()) { 69 | ans.add(sb.toString()); // and combination into ans 70 | sb = new StringBuilder(""); // re-initialize sb 71 | return; 72 | } 73 | 74 | String letters = map.get(digits.charAt(idx));// get all letters for current digits 75 | 76 | for (char ch : letters.toCharArray()) { 77 | sb.append(ch); // add character into sb 78 | helper(idx + 1, digits, ans, sb); // recursive call -> increase idx by 1 79 | sb.deleteCharAt(sb.length() - 1); // backtrack 80 | } 81 | } 82 | } 83 | 84 | public class RB05_LetterCombinationPhoneNumber { 85 | public static void main(String[] args) { 86 | LetterCombinationPhoneNumber obj = new LetterCombinationPhoneNumber(); 87 | String digits; 88 | 89 | //example 1 90 | System.out.println("----- example 1 -----"); 91 | digits = ""; 92 | System.out.println(obj.letterCombinations(digits)); 93 | 94 | //example 2 95 | System.out.println("----- example 2 -----"); 96 | digits = "77"; 97 | System.out.println(obj.letterCombinations(digits)); 98 | 99 | //example 2 100 | System.out.println("----- example 2 -----"); 101 | digits = "234"; 102 | System.out.println(obj.letterCombinations(digits)); 103 | 104 | //example 3 105 | System.out.println("----- example 3 -----"); 106 | digits = "72"; 107 | System.out.println(obj.letterCombinations(digits)); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /02-Array/Array22_SearchInRotatedSortedArray.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC33: Search in Rotated Sorted Array || https://leetcode.com/problems/search-in-rotated-sorted-array/ 3 | 4 | There is an integer array nums sorted in ascending order (with distinct values). 5 | 6 | Prior to being passed to your function, nums is possibly rotated at an unknown pivot index k (1 <= k < nums.length) such that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (0-indexed). For example, [0,1,2,4,5,6,7] might be rotated at pivot index 3 and become [4,5,6,7,0,1,2]. 7 | 8 | Given the array nums after the possible rotation and an integer target, return the index of target if it is in nums, or -1 if it is not in nums. 9 | 10 | You must write an algorithm with O(log n) runtime complexity. 11 | 12 | 13 | 14 | Example 1: 15 | Input: nums = [4,5,6,7,0,1,2], target = 0 16 | Output: 4 17 | 18 | Example 2: 19 | Input: nums = [4,5,6,7,0,1,2], target = 3 20 | Output: -1 21 | 22 | Example 3: 23 | Input: nums = [1], target = 0 24 | Output: -1 25 | 26 | 27 | Constraints: 28 | 1 <= nums.length <= 5000 29 | -104 <= nums[i] <= 104 30 | All values of nums are unique. 31 | nums is an ascending array that is possibly rotated. 32 | -104 <= target <= 104 33 | */ 34 | 35 | class SearchInRotatedSortedArray { 36 | // Time complexity: O(log(n)) || Space complexity: O(1) 37 | public int search(int[] nums, int target) { 38 | int start = 0, end = nums.length - 1; 39 | int mid = 0; 40 | 41 | while (start <= end) { 42 | 43 | // calculate mid 44 | mid = start + (end - start) / 2; 45 | 46 | if (nums[mid] == target) { 47 | return mid; 48 | } 49 | 50 | /* 51 | * imagine 2 lines => 52 | * + line 1 -> start from 0th index to before pivot point 53 | * + line 2 -> start from pivot point to nth index 54 | */ 55 | 56 | // case 1 => when mid lies on line 1 57 | if (nums[start] <= nums[mid]) { 58 | // target lies on left side of mid 59 | if (target <= nums[mid] && target >= nums[start]) { 60 | end = mid - 1; 61 | 62 | // target lies on right side of mid 63 | } else { 64 | start = mid + 1; 65 | } 66 | 67 | // case 2 => when mid lies on line 2 68 | } else { 69 | // target lies on tight side of mid 70 | if (target >= nums[mid] && target <= nums[end]) { 71 | start = mid + 1; 72 | 73 | // target lies on left side of mid 74 | } else { 75 | end = mid - 1; 76 | } 77 | } 78 | } 79 | 80 | return -1; 81 | } 82 | } 83 | 84 | public class Array22_SearchInRotatedSortedArray { 85 | public static void main(String[] args) { 86 | SearchInRotatedSortedArray obj = new SearchInRotatedSortedArray(); 87 | 88 | // example 1 89 | System.out.println("---- example 1 ----"); 90 | int[] nums1 = { 4, 5, 6, 7, 0, 1, 2 }; 91 | int target1 = 0; 92 | System.out.println(obj.search(nums1, target1)); 93 | 94 | // example 2 95 | System.out.println("---- example 2 ----"); 96 | int[] nums2 = { 4, 5, 6, 7, 0, 1, 2 }; 97 | int target2 = 3; 98 | System.out.println(obj.search(nums2, target2)); 99 | 100 | // example 3 101 | System.out.println("---- example 3 ----"); 102 | int[] nums3 = { 1 }; 103 | int target3 = 0; 104 | System.out.println(obj.search(nums3, target3)); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /02-Array/Array40_RotateArray.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC189: Rotate Array || https://leetcode.com/problems/rotate-array/ 3 | 4 | Given an integer array nums, rotate the array to the right by k steps, where k is non-negative. 5 | 6 | 7 | Example 1: 8 | 9 | Input: nums = [1,2,3,4,5,6,7], k = 3 10 | Output: [5,6,7,1,2,3,4] 11 | Explanation: 12 | rotate 1 steps to the right: [7,1,2,3,4,5,6] 13 | rotate 2 steps to the right: [6,7,1,2,3,4,5] 14 | rotate 3 steps to the right: [5,6,7,1,2,3,4] 15 | 16 | Example 2: 17 | 18 | Input: nums = [-1,-100,3,99], k = 2 19 | Output: [3,99,-1,-100] 20 | Explanation: 21 | rotate 1 steps to the right: [99,-1,-100,3] 22 | rotate 2 steps to the right: [3,99,-1,-100] 23 | 24 | 25 | 26 | Constraints: 27 | 28 | 1 <= nums.length <= 10^5 29 | -2^31 <= nums[i] <= 2^31 - 1 30 | 0 <= k <= 10^5 31 | 32 | 33 | 34 | Follow up: 35 | 36 | Try to come up with as many solutions as you can. There are at least three different ways to solve this problem. 37 | Could you do it in-place with O(1) extra space? 38 | */ 39 | 40 | import java.util.Arrays; 41 | 42 | class RotateArray { 43 | // Time complexity: O(n) || Space complexity: O(n) 44 | public void approach1(int[] nums, int k) { 45 | int n = nums.length, idx = 0; 46 | k = k % n; 47 | if (k == 0 || n == 0) { 48 | return; 49 | } 50 | 51 | int[] ans = new int[n]; 52 | // store k elements in ans 53 | for (int i = n - k; i < n; i++) { 54 | ans[idx++] = nums[i]; 55 | } 56 | 57 | // store rest of the element 58 | for (int i = 0; i < n - k; i++) { 59 | ans[idx++] = nums[i]; 60 | } 61 | 62 | // copy ans into nums 63 | for (int i = 0; i < n; i++) { 64 | nums[i] = ans[i]; 65 | } 66 | } 67 | 68 | // Time complexity: O(n) || Space complexity: O(1) 69 | public void approach2(int[] nums, int k) { 70 | int n = nums.length; 71 | k = k % n; 72 | 73 | if (k == 0 || n == 0) { 74 | return; 75 | } 76 | 77 | reverse(nums, 0, n - 1); // reverse entire array 78 | reverse(nums, 0, k - 1); // reverse k elements 79 | reverse(nums, k, n - 1); // reverse rest of the elements 80 | } 81 | 82 | private void reverse(int[] nums, int start, int end) { 83 | while (start <= end) { 84 | // swap 85 | int swap = nums[start]; 86 | nums[start] = nums[end]; 87 | nums[end] = swap; 88 | 89 | // update pointer 90 | start++; 91 | end--; 92 | } 93 | } 94 | } 95 | 96 | public class Array40_RotateArray { 97 | public static void main(String[] args) { 98 | RotateArray obj = new RotateArray(); 99 | int[] nums; 100 | int k; 101 | 102 | //example 1 103 | System.out.println("----- example 1 -----"); 104 | nums = new int[] {7,2,1,3,5,4,-11,10,9,8,1}; 105 | k = 5; 106 | // obj.approach1(nums, k); 107 | obj.approach2(nums, k); 108 | System.out.println(Arrays.toString(nums)); 109 | 110 | //example 2 111 | System.out.println("----- example 2 -----"); 112 | nums = new int[] {1,2}; 113 | k = 7; 114 | // obj.approach1(nums, k); 115 | obj.approach2(nums, k); 116 | System.out.println(Arrays.toString(nums)); 117 | 118 | //example 3 119 | System.out.println("----- example 3 -----"); 120 | nums = new int[] {1,2,-11,-10}; 121 | k = 4; 122 | // obj.approach1(nums, k); 123 | obj.approach2(nums, k); 124 | System.out.println(Arrays.toString(nums)); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /16-TwoPointers/TP11_RotateArray.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC189: Rotate Array || https://leetcode.com/problems/rotate-array/ 3 | 4 | Given an integer array nums, rotate the array to the right by k steps, where k is non-negative. 5 | 6 | 7 | Example 1: 8 | 9 | Input: nums = [1,2,3,4,5,6,7], k = 3 10 | Output: [5,6,7,1,2,3,4] 11 | Explanation: 12 | rotate 1 steps to the right: [7,1,2,3,4,5,6] 13 | rotate 2 steps to the right: [6,7,1,2,3,4,5] 14 | rotate 3 steps to the right: [5,6,7,1,2,3,4] 15 | 16 | Example 2: 17 | 18 | Input: nums = [-1,-100,3,99], k = 2 19 | Output: [3,99,-1,-100] 20 | Explanation: 21 | rotate 1 steps to the right: [99,-1,-100,3] 22 | rotate 2 steps to the right: [3,99,-1,-100] 23 | 24 | 25 | 26 | Constraints: 27 | 28 | 1 <= nums.length <= 10^5 29 | -2^31 <= nums[i] <= 2^31 - 1 30 | 0 <= k <= 10^5 31 | 32 | 33 | 34 | Follow up: 35 | 36 | Try to come up with as many solutions as you can. There are at least three different ways to solve this problem. 37 | Could you do it in-place with O(1) extra space? 38 | */ 39 | 40 | import java.util.Arrays; 41 | 42 | class RotateArray { 43 | // Time complexity: O(n) || Space complexity: O(n) 44 | public void approach1(int[] nums, int k) { 45 | int n = nums.length, idx = 0; 46 | k = k % n; 47 | if (k == 0 || n == 0) { 48 | return; 49 | } 50 | 51 | int[] ans = new int[n]; 52 | // store k elements in ans 53 | for (int i = n - k; i < n; i++) { 54 | ans[idx++] = nums[i]; 55 | } 56 | 57 | // store rest of the element 58 | for (int i = 0; i < n - k; i++) { 59 | ans[idx++] = nums[i]; 60 | } 61 | 62 | // copy ans into nums 63 | for (int i = 0; i < n; i++) { 64 | nums[i] = ans[i]; 65 | } 66 | } 67 | 68 | // Time complexity: O(n) || Space complexity: O(1) 69 | public void approach2(int[] nums, int k) { 70 | int n = nums.length; 71 | k = k % n; 72 | 73 | if (k == 0 || n == 0) { 74 | return; 75 | } 76 | 77 | reverse(nums, 0, n - 1); // reverse entire array 78 | reverse(nums, 0, k - 1); // reverse k elements 79 | reverse(nums, k, n - 1); // reverse rest of the elements 80 | } 81 | 82 | private void reverse(int[] nums, int start, int end) { 83 | while (start <= end) { 84 | // swap 85 | int swap = nums[start]; 86 | nums[start] = nums[end]; 87 | nums[end] = swap; 88 | 89 | // update pointer 90 | start++; 91 | end--; 92 | } 93 | } 94 | } 95 | 96 | public class TP11_RotateArray { 97 | public static void main(String[] args) { 98 | RotateArray obj = new RotateArray(); 99 | int[] nums; 100 | int k; 101 | 102 | //example 1 103 | System.out.println("----- example 1 -----"); 104 | nums = new int[] {7,2,1,3,5,4,-11,10,9,8,1}; 105 | k = 5; 106 | // obj.approach1(nums, k); 107 | obj.approach2(nums, k); 108 | System.out.println(Arrays.toString(nums)); 109 | 110 | //example 2 111 | System.out.println("----- example 2 -----"); 112 | nums = new int[] {1,2}; 113 | k = 7; 114 | // obj.approach1(nums, k); 115 | obj.approach2(nums, k); 116 | System.out.println(Arrays.toString(nums)); 117 | 118 | //example 3 119 | System.out.println("----- example 3 -----"); 120 | nums = new int[] {1,2,-11,-10}; 121 | k = 4; 122 | // obj.approach1(nums, k); 123 | obj.approach2(nums, k); 124 | System.out.println(Arrays.toString(nums)); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /05-LinkedList/LL04_MiddleOfLinkedList.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC876: Middle of the Linked List || https://leetcode.com/problems/middle-of-the-linked-list/ 3 | 4 | Given the head of a singly linked list, return the middle node of the linked list. 5 | 6 | If there are two middle nodes, return the second middle node. 7 | 8 | 9 | Example 1: 10 | Input: head = [1,2,3,4,5] 11 | Output: [3,4,5] 12 | Explanation: The middle node of the list is node 3. 13 | 14 | Example 2: 15 | Input: head = [1,2,3,4,5,6] 16 | Output: [4,5,6] 17 | Explanation: Since the list has two middle nodes with values 3 and 4, we return the second one. 18 | 19 | Constraints: 20 | The number of nodes in the list is in the range [1, 100]. 21 | 1 <= Node.val <= 100 22 | */ 23 | 24 | class Node { 25 | int data; 26 | Node next; 27 | 28 | Node() { 29 | this.next = null; 30 | } 31 | 32 | Node(int data) { 33 | this.data = data; 34 | this.next = null; 35 | } 36 | 37 | Node(int data, Node next) { 38 | this.data = data; 39 | this.next = next; 40 | } 41 | 42 | Node(int[] arr) { 43 | if (arr.length == 0) { 44 | return; 45 | } 46 | 47 | this.data = arr[0]; 48 | Node temp = this; 49 | for (int i = 1; i < arr.length; i++) { 50 | temp.next = new Node(arr[i]); 51 | temp = temp.next; 52 | } 53 | 54 | } 55 | 56 | public void print() { 57 | if (this == null || (this.data == 0 && this.next == null)) { 58 | System.out.print("[]\n"); 59 | return; 60 | } 61 | 62 | Node temp = this; 63 | 64 | System.out.print("["); 65 | while (temp != null) { 66 | System.out.print(" " + temp.data + " "); 67 | temp = temp.next; 68 | } 69 | System.out.print("]\n"); 70 | } 71 | } 72 | 73 | class MiddleOfLinkedList { 74 | 75 | // Time Complexity: O(n) || Space Complexity: O(1) 76 | public Node middleOfLinkedList(Node head) { 77 | // there is no Node or only one Node 78 | if (head == null || head.next == null) { 79 | return head; 80 | } 81 | 82 | // two pointers 83 | Node slow = head, fast = head; 84 | 85 | // find out the middle 86 | while (fast != null && fast.next != null) { 87 | slow = slow.next; 88 | fast = fast.next.next; 89 | } 90 | 91 | // answer 92 | return slow; 93 | } 94 | } 95 | 96 | public class LL04_MiddleOfLinkedList { 97 | public static void main(String[] args) { 98 | MiddleOfLinkedList obj = new MiddleOfLinkedList(); 99 | 100 | // example 1 101 | System.out.println("---- example 1 ----"); 102 | Node list1 = new Node(new int[] { 1, 2, 3, 4, 5 }); 103 | System.out.println(obj.middleOfLinkedList(list1).data); 104 | 105 | // example 2 106 | System.out.println("---- example 2 ----"); 107 | Node list2 = new Node(new int[] { 1, 2 }); 108 | System.out.println(obj.middleOfLinkedList(list2).data); 109 | 110 | // example 3 111 | System.out.println("---- example 3 ----"); 112 | Node list3 = new Node(new int[] { 1, 2, 3, 4, 5, 6 }); 113 | System.out.println(obj.middleOfLinkedList(list3).data); 114 | 115 | // example 4 116 | System.out.println("---- example 4 ----"); 117 | Node list4 = new Node(); 118 | System.out.println(obj.middleOfLinkedList(list4).data); 119 | 120 | // example 5 121 | System.out.println("---- example 5 ----"); 122 | Node list5 = new Node(new int[] { 1 }); 123 | System.out.println(obj.middleOfLinkedList(list5).data); 124 | } 125 | } -------------------------------------------------------------------------------- /16-TwoPointers/TP04_MiddleOfLinkedList.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC876: Middle of the Linked List || https://leetcode.com/problems/middle-of-the-linked-list/ 3 | 4 | Given the head of a singly linked list, return the middle node of the linked list. 5 | 6 | If there are two middle nodes, return the second middle node. 7 | 8 | 9 | Example 1: 10 | Input: head = [1,2,3,4,5] 11 | Output: [3,4,5] 12 | Explanation: The middle node of the list is node 3. 13 | 14 | Example 2: 15 | Input: head = [1,2,3,4,5,6] 16 | Output: [4,5,6] 17 | Explanation: Since the list has two middle nodes with values 3 and 4, we return the second one. 18 | 19 | Constraints: 20 | The number of nodes in the list is in the range [1, 100]. 21 | 1 <= Node.val <= 100 22 | */ 23 | 24 | class Node { 25 | int data; 26 | Node next; 27 | 28 | Node() { 29 | this.next = null; 30 | } 31 | 32 | Node(int data) { 33 | this.data = data; 34 | this.next = null; 35 | } 36 | 37 | Node(int data, Node next) { 38 | this.data = data; 39 | this.next = next; 40 | } 41 | 42 | Node(int[] arr) { 43 | if (arr.length == 0) { 44 | return; 45 | } 46 | 47 | this.data = arr[0]; 48 | Node temp = this; 49 | for (int i = 1; i < arr.length; i++) { 50 | temp.next = new Node(arr[i]); 51 | temp = temp.next; 52 | } 53 | 54 | } 55 | 56 | public void print() { 57 | if (this == null || (this.data == 0 && this.next == null)) { 58 | System.out.print("[]\n"); 59 | return; 60 | } 61 | 62 | Node temp = this; 63 | 64 | System.out.print("["); 65 | while (temp != null) { 66 | System.out.print(" " + temp.data + " "); 67 | temp = temp.next; 68 | } 69 | System.out.print("]\n"); 70 | } 71 | } 72 | 73 | class MiddleOfLinkedList { 74 | 75 | // Time Complexity: O(n) || Space Complexity: O(1) 76 | public Node middleOfLinkedList(Node head) { 77 | // there is no Node or only one Node 78 | if (head == null || head.next == null) { 79 | return head; 80 | } 81 | 82 | // two pointers 83 | Node slow = head, fast = head; 84 | 85 | // find out the middle 86 | while (fast != null && fast.next != null) { 87 | slow = slow.next; 88 | fast = fast.next.next; 89 | } 90 | 91 | // answer 92 | return slow; 93 | } 94 | } 95 | 96 | public class TP04_MiddleOfLinkedList { 97 | public static void main(String[] args) { 98 | MiddleOfLinkedList obj = new MiddleOfLinkedList(); 99 | 100 | // example 1 101 | System.out.println("---- example 1 ----"); 102 | Node list1 = new Node(new int[] { 1, 2, 3, 4, 5 }); 103 | System.out.println(obj.middleOfLinkedList(list1).data); 104 | 105 | // example 2 106 | System.out.println("---- example 2 ----"); 107 | Node list2 = new Node(new int[] { 1, 2 }); 108 | System.out.println(obj.middleOfLinkedList(list2).data); 109 | 110 | // example 3 111 | System.out.println("---- example 3 ----"); 112 | Node list3 = new Node(new int[] { 1, 2, 3, 4, 5, 6 }); 113 | System.out.println(obj.middleOfLinkedList(list3).data); 114 | 115 | // example 4 116 | System.out.println("---- example 4 ----"); 117 | Node list4 = new Node(); 118 | System.out.println(obj.middleOfLinkedList(list4).data); 119 | 120 | // example 5 121 | System.out.println("---- example 5 ----"); 122 | Node list5 = new Node(new int[] { 1 }); 123 | System.out.println(obj.middleOfLinkedList(list5).data); 124 | } 125 | } -------------------------------------------------------------------------------- /CCI/Chapter-01/C01_02_CheckPermutation.java: -------------------------------------------------------------------------------- 1 | /* 2 | Check Permutation: Given two string, write a method to decide if one is permutation of the other. 3 | */ 4 | 5 | import java.util.HashMap; 6 | 7 | //This implementation is case sensitive & also we allowed white spaces, 8 | class Solution { 9 | /** ----------- My Solutions ----------- **/ 10 | // This Solution is only work for ASCII 11 | // TC => O(n) || SC => O(1), where n is the size of string 12 | public boolean solution1(String str1, String str2) { 13 | // not the same size 14 | if (str1.length() != str2.length()) { 15 | return false; 16 | } 17 | 18 | // store frequency of each character on string 19 | int[] freq = new int[128]; 20 | 21 | for (int i = 0; i < str1.length(); i++) { 22 | freq[str1.charAt(i) - ' ']++; // increase frequency 23 | freq[str2.charAt(i) - ' ']--; // decrease frequency 24 | } 25 | 26 | // check if all frequency is zero(0) 27 | for (int i : freq) { 28 | if (i != 0) { 29 | return false; 30 | } 31 | } 32 | 33 | return true; 34 | } 35 | 36 | // This Solution is only work for all UNICODE characters 37 | // TC => O(n) || SC => O(n), where n is the size of string 38 | public boolean solution2(String str1, String str2) { 39 | // not the same size 40 | if (str1.length() != str2.length()) { 41 | return false; 42 | } 43 | 44 | HashMap map = new HashMap<>(); 45 | 46 | for (int i = 0; i < str1.length(); i++) { 47 | char key1 = str1.charAt(i); 48 | map.put(key1, map.getOrDefault(key1, 0) + 1);// increase frequency 49 | 50 | char key2 = str2.charAt(i); 51 | map.put(key2, map.getOrDefault(key2, 0) - 1);// decrease frequency 52 | } 53 | 54 | // check if all values in map is zero(0) 55 | for (char key : map.keySet()) { 56 | if (map.get(key) != 0) { 57 | return false; 58 | } 59 | } 60 | 61 | return true; 62 | } 63 | 64 | /** ----------- Book Solutions ----------- **/ 65 | 66 | } 67 | 68 | public class C01_02_CheckPermutation { 69 | public static void main(String[] args) { 70 | Solution obj = new Solution(); 71 | String str1, str2; 72 | 73 | // example 1 74 | System.out.println("---- Example 1 ----"); 75 | str1 = "xzybca"; 76 | str2 = "mzbcaa"; 77 | System.out.println(obj.solution1(str1, str2)); 78 | System.out.println(obj.solution2(str1, str2)); 79 | 80 | // example 2 81 | System.out.println("---- Example 2 ----"); 82 | str1 = "abcezxiyupe"; 83 | str2 = "hii"; 84 | System.out.println(obj.solution1(str1, str2)); 85 | System.out.println(obj.solution2(str1, str2)); 86 | 87 | // example 3 88 | System.out.println("---- Example 3 ----"); 89 | str1 = "ccv125ad"; 90 | str2 = "1d5acv2c"; 91 | System.out.println(obj.solution1(str1, str2)); 92 | System.out.println(obj.solution2(str1, str2)); 93 | 94 | // example 4 95 | System.out.println("---- Example 4 ----"); 96 | str1 = "God"; 97 | str2 = "dog"; 98 | System.out.println(obj.solution1(str1, str2)); 99 | System.out.println(obj.solution2(str1, str2)); 100 | 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /02-Array/Array29_TrappingRainWater.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC42: Trapping Rain Water || https://leetcode.com/problems/trapping-rain-water 3 | 4 | 5 | Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining. 6 | 7 | 8 | 9 | Example 1: 10 | 11 | Input: height = [0,1,0,2,1,0,1,3,2,1,2,1] 12 | Output: 6 13 | Explanation: The above elevation map (black section) is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. 14 | 15 | Example 2: 16 | 17 | Input: height = [4,2,0,3,2,5] 18 | Output: 9 19 | 20 | 21 | 22 | Constraints: 23 | 24 | n == height.length 25 | 1 <= n <= 2 * 104 26 | 0 <= height[i] <= 105 27 | */ 28 | 29 | class TrappingRainWater { 30 | 31 | //Time Complexity: O(n) || Space Complexity: O(n) 32 | public int approach1(int[] height){ 33 | int n = height.length; 34 | 35 | //calculate max left side height boundary for each bar 36 | int[] maxLeft = new int[n]; 37 | maxLeft[0] = height[0]; //0th bar height it self is the max left side height 38 | for(int i = 1; i < n; i++) { 39 | maxLeft[i] = Math.max(height[i], maxLeft[i-1]); 40 | } 41 | 42 | //calculate max right side height boundary for each bar 43 | int[] maxRight = new int[n]; 44 | maxRight[n-1] = height[n-1]; //(n-1)th bar height it self is the max right side height 45 | for(int i = n-2; i >= 0; i--) { 46 | maxRight[i] = Math.max(height[i], maxRight[i+1]); 47 | } 48 | 49 | //calculate trapped rain water on top of each bar 50 | int trappedWater = 0; 51 | for(int i = 0; i < n; i++) { 52 | //trapped water on top of each bar = min height - bar's height 53 | trappedWater += Math.min(maxLeft[i], maxRight[i]) - height[i]; 54 | } 55 | 56 | return trappedWater; 57 | } 58 | 59 | //two pointers 60 | //Time Complexity: O(n) || Space Complexity: O(1) 61 | public int approach2(int[] height){ 62 | int start = 0, end = height.length-1; 63 | int maxLeft = -1; // store left side max height for current bar 64 | int maxRight = -1; //store right side max height for current bar 65 | int trappedWater = 0; 66 | 67 | while(start <= end) { 68 | maxLeft = Math.max(maxLeft, height[start]); 69 | maxRight = Math.max(maxRight, height[end]); 70 | 71 | if(maxLeft < maxRight) { 72 | trappedWater += maxLeft - height[start++]; 73 | } else { 74 | trappedWater += maxRight - height[end--]; 75 | } 76 | } 77 | 78 | return trappedWater; 79 | } 80 | } 81 | 82 | public class Array29_TrappingRainWater { 83 | public static void main(String[] args) { 84 | TrappingRainWater obj = new TrappingRainWater(); 85 | int[] height; 86 | 87 | //example 1 88 | System.out.println("----- example 1 -----"); 89 | height = new int[] {1,2,3,0,0,3,4,5,0,0,10,1}; 90 | System.out.println(obj.approach1(height)); 91 | System.out.println(obj.approach2(height)); 92 | 93 | //example 2 94 | System.out.println("----- example 2 -----"); 95 | height = new int[] {0,1,0,2,1,0,1,3,2,1,2,1}; 96 | System.out.println(obj.approach1(height)); 97 | System.out.println(obj.approach2(height)); 98 | 99 | //example 3 100 | System.out.println("----- example 3 -----"); 101 | height = new int[] {4,2,0,3,2,5}; 102 | System.out.println(obj.approach1(height)); 103 | System.out.println(obj.approach2(height)); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /14-SortingAlgo/SA04_MergeSort.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Scanner; 3 | 4 | class MergeSort { 5 | int[] arr; 6 | int n; 7 | 8 | /*---- constructor ----*/ 9 | MergeSort(int[] data) { 10 | this.arr = data; 11 | this.n = data.length; 12 | } 13 | 14 | MergeSort() { 15 | inputData(); 16 | } 17 | /*---- ----*/ 18 | 19 | /*---- Print the Array ----*/ 20 | public void printData() { 21 | for (int i = 0; i < n; i++) { 22 | System.out.print(arr[i] + " "); 23 | } 24 | System.out.println(); 25 | } 26 | /*---- ----*/ 27 | 28 | /*---- take input from user ----*/ 29 | private void inputData() { 30 | Scanner scn = new Scanner(System.in); 31 | 32 | System.out.print("Enter the size of your array >> "); 33 | n = scn.nextInt(); 34 | arr = new int[n]; 35 | 36 | System.out.println("-------- Enter " + n + " Data --------"); 37 | for (int i = 0; i < n; i++) { 38 | System.out.print("\tarr[" + i + "] = "); 39 | arr[i] = scn.nextInt(); // here we take the input from user 40 | } 41 | System.out.println("\t----- -----"); 42 | 43 | scn.close(); 44 | } 45 | /*---- ----*/ 46 | 47 | public void ascendingOrder() { 48 | int startIdx = 0, endIdx = arr.length - 1; 49 | mergeSort(startIdx, endIdx); 50 | } 51 | 52 | private void mergeSort(int startIdx, int endIdx) { // TC -> O(n log(n)) 53 | if (startIdx >= endIdx) { 54 | return; 55 | } 56 | 57 | int midIdx = startIdx + (endIdx - startIdx) / 2; 58 | mergeSort(startIdx, midIdx); 59 | mergeSort(midIdx + 1, endIdx); 60 | merge(startIdx, midIdx, endIdx); 61 | } 62 | 63 | private void merge(int startIdx, int midIdx, int endIdx) { 64 | ArrayList temp = new ArrayList<>(); // temporary array 65 | 66 | // 2 pointers 67 | int left = startIdx, right = midIdx + 1; 68 | 69 | // sorting 70 | while (left <= midIdx && right <= endIdx) { 71 | if (arr[left] <= arr[right]) { 72 | temp.add(arr[left++]); 73 | } else { 74 | temp.add(arr[right++]); 75 | } 76 | } 77 | 78 | // copy rest of the values 79 | while (left <= midIdx) { 80 | temp.add(arr[left++]); 81 | } 82 | while (right <= endIdx) { 83 | temp.add(arr[right++]); 84 | } 85 | 86 | // re-write the arr with the sorted Data 87 | for (int i = startIdx; i <= endIdx; i++) { 88 | arr[i] = temp.get(i - startIdx); 89 | } 90 | } 91 | 92 | } 93 | 94 | public class SA04_MergeSort { 95 | public static void main(String[] args) { 96 | System.out.println("--------------------------------------"); 97 | int[] data = { 5, 4, 1, 3, 2, 8, 7, 4, 3 }; 98 | 99 | MergeSort ms = new MergeSort(data); // use this when u have pre-defined dataset 100 | System.out.print("Original array > "); 101 | ms.printData(); 102 | ms.ascendingOrder(); 103 | System.out.print("Sorted array(ascending) >> "); 104 | ms.printData(); 105 | System.out.println("--------------------------------------"); 106 | 107 | System.out.println("--------------------------------------"); 108 | MergeSort ms1 = new MergeSort(); // use this when u want to give the data at run time 109 | System.out.print("Original array >> "); 110 | ms1.printData(); 111 | ms1.ascendingOrder(); 112 | System.out.print("Sorted array(ascending)>> "); 113 | ms1.printData(); 114 | System.out.println("--------------------------------------"); 115 | 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /16-TwoPointers/TP08_TrappingRainWater.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC42: Trapping Rain Water || https://leetcode.com/problems/trapping-rain-water 3 | 4 | 5 | Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining. 6 | 7 | 8 | 9 | Example 1: 10 | 11 | Input: height = [0,1,0,2,1,0,1,3,2,1,2,1] 12 | Output: 6 13 | Explanation: The above elevation map (black section) is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. 14 | 15 | Example 2: 16 | 17 | Input: height = [4,2,0,3,2,5] 18 | Output: 9 19 | 20 | 21 | 22 | Constraints: 23 | 24 | n == height.length 25 | 1 <= n <= 2 * 104 26 | 0 <= height[i] <= 105 27 | */ 28 | 29 | class TrappingRainWater { 30 | 31 | //Time Complexity: O(n) || Space Complexity: O(n) 32 | public int approach1(int[] height){ 33 | int n = height.length; 34 | 35 | //calculate max left side height boundary for each bar 36 | int[] maxLeft = new int[n]; 37 | maxLeft[0] = height[0]; //0th bar height it self is the max left side height 38 | for(int i = 1; i < n; i++) { 39 | maxLeft[i] = Math.max(height[i], maxLeft[i-1]); 40 | } 41 | 42 | //calculate max right side height boundary for each bar 43 | int[] maxRight = new int[n]; 44 | maxRight[n-1] = height[n-1]; //(n-1)th bar height it self is the max right side height 45 | for(int i = n-2; i >= 0; i--) { 46 | maxRight[i] = Math.max(height[i], maxRight[i+1]); 47 | } 48 | 49 | //calculate trapped rain water on top of each bar 50 | int trappedWater = 0; 51 | for(int i = 0; i < n; i++) { 52 | //trapped water on top of each bar = min height - bar's height 53 | trappedWater += Math.min(maxLeft[i], maxRight[i]) - height[i]; 54 | } 55 | 56 | return trappedWater; 57 | } 58 | 59 | //two pointers 60 | //Time Complexity: O(n) || Space Complexity: O(1) 61 | public int approach2(int[] height){ 62 | int start = 0, end = height.length-1; 63 | int maxLeft = -1; // store left side max height for current bar 64 | int maxRight = -1; //store right side max height for current bar 65 | int trappedWater = 0; 66 | 67 | while(start <= end) { 68 | maxLeft = Math.max(maxLeft, height[start]); 69 | maxRight = Math.max(maxRight, height[end]); 70 | 71 | if(maxLeft < maxRight) { 72 | trappedWater += maxLeft - height[start++]; 73 | } else { 74 | trappedWater += maxRight - height[end--]; 75 | } 76 | } 77 | 78 | return trappedWater; 79 | } 80 | } 81 | 82 | public class TP08_TrappingRainWater { 83 | public static void main(String[] args) { 84 | TrappingRainWater obj = new TrappingRainWater(); 85 | int[] height; 86 | 87 | //example 1 88 | System.out.println("----- example 1 -----"); 89 | height = new int[] {1,2,3,0,0,3,4,5,0,0,10,1}; 90 | System.out.println(obj.approach1(height)); 91 | System.out.println(obj.approach2(height)); 92 | 93 | //example 2 94 | System.out.println("----- example 2 -----"); 95 | height = new int[] {0,1,0,2,1,0,1,3,2,1,2,1}; 96 | System.out.println(obj.approach1(height)); 97 | System.out.println(obj.approach2(height)); 98 | 99 | //example 3 100 | System.out.println("----- example 3 -----"); 101 | height = new int[] {4,2,0,3,2,5}; 102 | System.out.println(obj.approach1(height)); 103 | System.out.println(obj.approach2(height)); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /02-Array/Array05_MissingValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | LC268: Missing Number || https://leetcode.com/problems/missing-number/ 3 | 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 | 7 | 8 | Example 1: 9 | Input: nums = [3,0,1] 10 | Output: 2 11 | 12 | Explanation: 13 | 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. 14 | 15 | Example 2: 16 | Input: nums = [0,1] 17 | Output: 2 18 | 19 | Explanation: 20 | 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. 21 | 22 | Example 3: 23 | Input: nums = [9,6,4,2,3,5,7,0,1] 24 | Output: 8 25 | 26 | Explanation: 27 | 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. 28 | 29 | 30 | Constraints: 31 | 32 | n == nums.length 33 | 1 <= n <= 104 34 | 0 <= nums[i] <= n 35 | All the numbers of nums are unique. 36 | 37 | 38 | Follow up: Could you implement a solution using only O(1) extra space complexity and O(n) runtime complexity? 39 | */ 40 | 41 | import java.util.Arrays; 42 | 43 | class MissingValue { 44 | 45 | // Brute Force => Time Complexity: O(n log(n)) || Space Complexity: O(1) 46 | public int approach1(int[] arr) { 47 | Arrays.sort(arr); 48 | 49 | for (int i = 0; i < arr.length; i++) { 50 | if (i != arr[i]) { 51 | return i; 52 | } 53 | } 54 | 55 | return arr.length; 56 | } 57 | 58 | // Extra Space => Time Complexity: O(n) || Space Complexity: O(n) 59 | public int approach2(int[] arr) { 60 | int[] temp = new int[arr.length + 1]; 61 | 62 | for (int x : arr) { 63 | temp[x] = 1; 64 | } 65 | 66 | for (int i = 0; i < temp.length; i++) { 67 | if (temp[i] == 0) { 68 | return i; 69 | } 70 | } 71 | 72 | return -1; 73 | } 74 | 75 | // Optimal Approach => Time Complexity: O(n) || Space Complexity: O(1) 76 | public int approach3(int[] arr) { 77 | int n = arr.length; 78 | int expectedSum = n * (n + 1) / 2; 79 | int realSum = 0; 80 | 81 | for (int x : arr) { 82 | realSum += x; 83 | } 84 | 85 | return expectedSum - realSum; 86 | } 87 | 88 | } 89 | 90 | public class Array05_MissingValue { 91 | public static void main(String[] args) { 92 | MissingValue obj = new MissingValue(); 93 | 94 | // example 1 95 | System.out.println("---- example 1 ----"); 96 | int[] nums1 = { 3, 0, 1 }; 97 | System.out.println("Approach 1: " + obj.approach1(nums1)); 98 | System.out.println("Approach 2: " + obj.approach2(nums1)); 99 | System.out.println("Approach 3: " + obj.approach3(nums1)); 100 | 101 | // example 2 102 | System.out.println("---- example 2 ----"); 103 | int[] nums2 = { 0, 1 }; 104 | System.out.println("Approach 1: " + obj.approach1(nums2)); 105 | System.out.println("Approach 2: " + obj.approach2(nums2)); 106 | System.out.println("Approach 3: " + obj.approach3(nums2)); 107 | 108 | // example 3 109 | System.out.println("---- example 3 ----"); 110 | int[] nums3 = { 9, 6, 4, 2, 3, 5, 7, 0, 1 }; 111 | System.out.println("Approach 1: " + obj.approach1(nums3)); 112 | System.out.println("Approach 2: " + obj.approach2(nums3)); 113 | System.out.println("Approach 3: " + obj.approach3(nums3)); 114 | 115 | } 116 | } --------------------------------------------------------------------------------