├── .gitbook └── assets │ ├── image (1).png │ ├── image (10) (1).png │ ├── image (10).png │ ├── image (11).png │ ├── image (12).png │ ├── image (13).png │ ├── image (2).png │ ├── image (3).png │ ├── image (4).png │ ├── image (5) (1).png │ ├── image (5).png │ ├── image (6).png │ ├── image (7) (1).png │ ├── image (7).png │ ├── image (8) (1).png │ ├── image (8).png │ ├── image (9).png │ └── image.png ├── 1.-pattern-sliding-window ├── 1.0-introduction.md ├── 1.1-maximum-sum-subarray-of-size-k-easy.md ├── 1.10-smallest-window-containing-substring-hard.md ├── 1.11-words-concatenation-hard.md ├── 1.2-smallest-subarray-with-a-given-sum-easy.md ├── 1.3-longest-substring-with-k-distinct-characters-medium.md ├── 1.4-fruits-into-baskets-medium.md ├── 1.5-no-repeat-substring-hard.md ├── 1.6-longest-substring-with-same-letters-after-replacement-hard.md ├── 1.7-longest-subarray-with-ones-after-replacement-hard.md ├── 1.8-permutation-in-a-string-hard.md ├── 1.9-string-anagrams-hard.md └── README.md ├── 11.-pattern-modified-binary-search ├── 11.1-introduction.md ├── 11.2-order-agnostic-binary-search-easy.md ├── 11.3.md └── README.md ├── 13.-pattern-top-k-elements ├── 01.Introduction.md ├── 02.top-k-numbers.md └── 13.HeapImplementation.md ├── 16.-pattern-topological-sort-graph ├── 16.1-introduction.md ├── 16.2-topological-sort-medium.md ├── 16.3-tasks-scheduling-medium.md ├── 16.4-tasks-scheduling-order-medium.md └── README.md ├── 2.-pattern-two-pointers ├── 2.0-introduction.md ├── 2.1-pair-with-target-sum-easy.md ├── 2.10-minimum-window-sort-medium.md ├── 2.2-remove-duplicates-easy.md ├── 2.3-squaring-a-sorted-array-easy.md ├── 2.4-triplet-sum-to-zero-medium.md ├── 2.5-triplet-sum-close-to-target-medium.md ├── 2.6-triplets-with-smaller-sum-medium.md ├── 2.7-subarrays-with-product-less-than-a-target-medium.md ├── 2.8-dutch-national-flag-problem-medium.md ├── 2.9-comparing-strings-containing-backspaces-medium.md └── README.md ├── 9.-pattern-two-heaps ├── 01.Introduction.md ├── 02.find-median-from-data-stream.md ├── 04.Maximiza-Capital.md └── 05.Maximum-Sum-Combinations.md ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── SUMMARY.md ├── binary-search ├── BinarySearch.md ├── image-1.png ├── image-2.png └── image.png ├── code_of_conduct.md ├── revision └── Revision.md ├── test-your-knowledge ├── 1.EasyProblems.md ├── 2.MediumProblems.md └── 3.HardProblems.md └── untitled ├── 7.0-introduction.md ├── 7.1-binary-tree-level-order-traversal-easy.md ├── 7.10-problem-challenge-2-right-view-of-a-binary-tree-easy.md ├── 7.2-reverse-level-order-traversal-easy.md ├── 7.3-zigzag-traversal-medium.md ├── 7.4-level-averages-in-a-binary-tree-easy.md ├── 7.5-minimum-depth-of-a-binary-tree-easy.md ├── 7.6-maximum-depth-of-binary-tree-easy.md ├── 7.7-level-order-successor-easy.md ├── 7.8-connect-level-order-siblings-medium.md ├── 7.9-problem-challenge-1-connect-all-level-order-siblings-medium.md └── README.md /.gitbook/assets/image (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/.gitbook/assets/image (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (10) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/.gitbook/assets/image (10) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (10).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/.gitbook/assets/image (10).png -------------------------------------------------------------------------------- /.gitbook/assets/image (11).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/.gitbook/assets/image (11).png -------------------------------------------------------------------------------- /.gitbook/assets/image (12).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/.gitbook/assets/image (12).png -------------------------------------------------------------------------------- /.gitbook/assets/image (13).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/.gitbook/assets/image (13).png -------------------------------------------------------------------------------- /.gitbook/assets/image (2).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/.gitbook/assets/image (2).png -------------------------------------------------------------------------------- /.gitbook/assets/image (3).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/.gitbook/assets/image (3).png -------------------------------------------------------------------------------- /.gitbook/assets/image (4).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/.gitbook/assets/image (4).png -------------------------------------------------------------------------------- /.gitbook/assets/image (5) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/.gitbook/assets/image (5) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (5).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/.gitbook/assets/image (5).png -------------------------------------------------------------------------------- /.gitbook/assets/image (6).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/.gitbook/assets/image (6).png -------------------------------------------------------------------------------- /.gitbook/assets/image (7) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/.gitbook/assets/image (7) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (7).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/.gitbook/assets/image (7).png -------------------------------------------------------------------------------- /.gitbook/assets/image (8) (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/.gitbook/assets/image (8) (1).png -------------------------------------------------------------------------------- /.gitbook/assets/image (8).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/.gitbook/assets/image (8).png -------------------------------------------------------------------------------- /.gitbook/assets/image (9).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/.gitbook/assets/image (9).png -------------------------------------------------------------------------------- /.gitbook/assets/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/.gitbook/assets/image.png -------------------------------------------------------------------------------- /1.-pattern-sliding-window/1.0-introduction.md: -------------------------------------------------------------------------------- 1 | # 1.0 Introduction 2 | 3 | ## Introduction 4 | 5 | In many problems dealing with an array \(or a LinkedList\), we are asked to find or calculate something among all the contiguous subarrays \(or sublists\) of a given size. For example, take a look at this problem: 6 | 7 | > Given an array, find the average of all contiguous subarrays of size ‘K’ in it. 8 | 9 | Let’s understand this problem with a real input: `Array: [1, 3, 2, 6, -1, 4, 1, 8, 2], K=5` Here, we are asked to find the average of all contiguous subarrays of size ‘5’ in the given array. Let’s solve this: 10 | 11 | `For the first 5 numbers (subarray from index 0-4), the average is: (1+3+2+6-1)/5 => 2.2(1+3+2+6−1)/5=>2.2` `The average of next 5 numbers (subarray from index 1-5) is: (3+2+6-1+4)/5 => 2.8(3+2+6−1+4)/5=>2.8` `For the next 5 numbers (subarray from index 2-6), the average is: (2+6-1+4+1)/5 => 2.4(2+6−1+4+1)/5=>2.4` 12 | 13 | Here is the final output containing the averages of all contiguous subarrays of size 5: `Output: [2.2, 2.8, 2.4, 3.6, 2.8]` 14 | 15 | A brute-force algorithm will calculate the sum of every 5-element contiguous subarray of the given array and divide the sum by ‘5’ to find the average. This is what the algorithm will look like: 16 | 17 | ```java 18 | import java.util.Arrays; 19 | 20 | class AverageOfSubarrayOfSizeK { 21 | public static double[] findAverages(int K, int[] arr) { 22 | double[] result = new double[arr.length - K + 1]; 23 | for (int i = 0; i <= arr.length - K; i++) { 24 | // find sum of next 'K' elements 25 | double sum = 0; 26 | for (int j = i; j < i + K; j++) 27 | sum += arr[j]; 28 | result[i] = sum / K; // calculate average 29 | } 30 | 31 | return result; 32 | } 33 | 34 | public static void main(String[] args) { 35 | double[] result = AverageOfSubarrayOfSizeK.findAverages(5, new int[] { 1, 3, 2, 6, -1, 4, 1, 8, 2 }); 36 | System.out.println("Averages of subarrays of size K: " + Arrays.toString(result)); 37 | } 38 | } 39 | ``` 40 | 41 | **Time complexity:** Since for every element of the input array, we are calculating the sum of its next ‘K’ elements, the time complexity of the above algorithm will be O\(N\*K\) where ‘N’ is the number of elements in the input array. 42 | 43 | Can we find a better solution? Do you see any inefficiency in the above approach? 44 | 45 | The inefficiency is that for any two consecutive subarrays of size ‘5’, the overlapping part \(which will contain four elements\) will be evaluated twice. For example, take the above-mentioned input: 46 | 47 | ![image](https://user-images.githubusercontent.com/20329508/113503322-c4ff8580-954e-11eb-8f7e-5fc6da8225ee.png) 48 | 49 | As you can see, there are four overlapping elements between the subarray \(indexed from 0-4\) and the subarray \(indexed from 1-5\). Can we somehow reuse the sum we have calculated for the overlapping elements? 50 | 51 | The efficient way to solve this problem would be to visualize each contiguous subarray as a sliding window of ‘5’ elements. This means that we will slide the window by one element when we move on to the next subarray. To reuse the sum from the previous subarray, we will subtract the element going out of the window and add the element now being included in the sliding window. This will save us from going through the whole subarray to find the sum and, as a result, the algorithm complexity will reduce to O\(N\). 52 | 53 | ![image](https://user-images.githubusercontent.com/20329508/113503352-f2e4ca00-954e-11eb-98a0-f496908131b3.png) 54 | 55 | Here is the algorithm for the Sliding Window approach: 56 | 57 | ```java 58 | import java.util.Arrays; 59 | 60 | class AverageOfSubarrayOfSizeK { 61 | public static double[] findAverages(int K, int[] arr) { 62 | double[] result = new double[arr.length - K + 1]; 63 | double windowSum = 0; 64 | int windowStart = 0; 65 | for (int windowEnd = 0; windowEnd < arr.length; windowEnd++) { 66 | windowSum += arr[windowEnd]; // add the next element 67 | // slide the window, we don't need to slide if we've not hit the required window size of 'k' 68 | if (windowEnd >= K - 1) { 69 | result[windowStart] = windowSum / K; // calculate the average 70 | windowSum -= arr[windowStart]; // subtract the element going out 71 | windowStart++; // slide the window ahead 72 | } 73 | } 74 | 75 | return result; 76 | } 77 | 78 | public static void main(String[] args) { 79 | double[] result = AverageOfSubarrayOfSizeK.findAverages(5, new int[] { 1, 3, 2, 6, -1, 4, 1, 8, 2 }); 80 | System.out.println("Averages of subarrays of size K: " + Arrays.toString(result)); 81 | } 82 | } 83 | ``` 84 | 85 | #### **Template to solve some sliding window problem:** 86 | 87 | ```java 88 | public class Solution { 89 | public List slidingWindowTemplateByHarryChaoyangHe(String s, String t) { 90 | //init a collection or int value to save the result according the question. 91 | List result = new LinkedList<>(); 92 | if(t.length()> s.length()) return result; 93 | 94 | //create a hashmap to save the Characters of the target substring. 95 | //(K, V) = (Character, Frequence of the Characters) 96 | Map map = new HashMap<>(); 97 | for(char c : t.toCharArray()){ 98 | map.put(c, map.getOrDefault(c, 0) + 1); 99 | } 100 | //maintain a counter to check whether match the target string. 101 | int counter = map.size();//must be the map size, NOT the string size because the char may be duplicate. 102 | 103 | //Two Pointers: begin - left pointer of the window; end - right pointer of the window 104 | int begin = 0, end = 0; 105 | 106 | //the length of the substring which match the target string. 107 | int len = Integer.MAX_VALUE; 108 | 109 | //loop at the begining of the source string 110 | while(end < s.length()){ 111 | 112 | char c = s.charAt(end);//get a character 113 | 114 | if( map.containsKey(c) ){ 115 | map.put(c, map.get(c)-1);// plus or minus one 116 | if(map.get(c) == 0) counter--;//modify the counter according the requirement(different condition). 117 | } 118 | end++; 119 | 120 | //increase begin pointer to make it invalid/valid again 121 | while(counter == 0 /* counter condition. different question may have different condition */){ 122 | 123 | char tempc = s.charAt(begin);//***be careful here: choose the char at begin pointer, NOT the end pointer 124 | if(map.containsKey(tempc)){ 125 | map.put(tempc, map.get(tempc) + 1);//plus or minus one 126 | if(map.get(tempc) > 0) counter++;//modify the counter according the requirement(different condition). 127 | } 128 | 129 | /* save / update(min/max) the result if find a target*/ 130 | // result collections or result int value 131 | 132 | begin++; 133 | } 134 | } 135 | return result; 136 | } 137 | } 138 | ``` 139 | 140 | -------------------------------------------------------------------------------- /1.-pattern-sliding-window/1.1-maximum-sum-subarray-of-size-k-easy.md: -------------------------------------------------------------------------------- 1 | # 1.1 Maximum Sum Subarray of Size K \(easy\) 2 | 3 | #### Problem Statement 4 | 5 | **Given an array of positive numbers and a positive number ‘k,’ find the maximum sum of any contiguous subarray of size ‘k’.** 6 | 7 | Example 1: 8 | 9 | ```text 10 | Input: [2, 1, 5, 1, 3, 2], k=3 11 | Output: 9 12 | Explanation: Subarray with maximum sum is [5, 1, 3]. 13 | ``` 14 | 15 | Example 2: 16 | 17 | ```text 18 | Input: [2, 3, 4, 1, 5], k=2 19 | Output: 7 20 | Explanation: Subarray with maximum sum is [3, 4]. 21 | ``` 22 | 23 | How can we solve the question? 24 | 25 | We can think of the 'k' as window size of sliding window in an array. 26 | 27 | 1. With each slide we will remove an element from the left and add an element from the right. 28 | 2. Calculate the sum for that window and compare the sum of that window to prevous max sum of sliding windows. 29 | 3. **Beware:** Until the window size becomes equal to 'k', we have to just add the next element to the right but we shouldn't remove the element to the left. 30 | 31 | So, code for that condition: 32 | 33 | ```java 34 | public int maxSumOfContiguousSubArray(int arr[], int k) { 35 | int maxSum = 0; // It will keep the maximum Sum of the subarrays 36 | // with the size 'k' and it will have the result by the end of the for-loop 37 | 38 | int windowSum = 0; // It will keep the sum of elements of that 39 | // window till the current element 40 | 41 | int windowStart = 0; // Starting index of the window 42 | for(int windowEnd = 0; windowEnd < arr.length; windowEnd++) { 43 | // For each iteration ending of the window would be increase by 1. 44 | 45 | windowSum += arr[windowEnd]; //same as windowSum = windowSum + arr[windowEnd], 46 | // element to the right is added to the window so value of that element added 47 | // with the previous elements within the window 48 | 49 | if(windowEnd >= k - 1) { 50 | // when the window size becomes equal to k(before that the size would less that k) 51 | 52 | maxSum = Math.max(maxSum, windowSum); 53 | // Taking the maximum value out of maxSum and the current window(i.e windowSum) 54 | 55 | windowSum -= arr[windowStart]; 56 | // Removing the element from the left, windowStart is the starting index of the window; 57 | 58 | windowStart++; 59 | // windowStart is updated by 1 as the window slides to the right 60 | } 61 | } 62 | return maxSum; 63 | } 64 | ``` 65 | 66 | #### Time Complexity 67 | 68 | The time complexity of the above algorithm will be O\(N\). 69 | 70 | #### Space Complexity 71 | 72 | The algorithm runs in constant space O\(1\). 73 | 74 | -------------------------------------------------------------------------------- /1.-pattern-sliding-window/1.10-smallest-window-containing-substring-hard.md: -------------------------------------------------------------------------------- 1 | # 1.10 Smallest Window containing Substring (hard) 2 | 3 | **Problem:** 4 | 5 | **** [78. Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/) 6 | 7 | Given two strings `s` and `t` of lengths `m` and `n` respectively, return _the **minimum window substring** of_ `s` _such that every character in_ `t` _(**including duplicates**) is included in the window. If there is no such substring, return the empty string_ `""`_._ 8 | 9 | The testcases will be generated such that the answer is **unique**. 10 | 11 | A **substring** is a contiguous sequence of characters within the string. 12 | 13 | **Example 1:** 14 | 15 | ``` 16 | Input: s = "ADOBECODEBANC", t = "ABC" 17 | Output: "BANC" 18 | Explanation: The minimum window substring "BANC" includes 'A', 'B', and 'C' from string t. 19 | ``` 20 | 21 | **Example 2:** 22 | 23 | ``` 24 | Input: s = "a", t = "a" 25 | Output: "a" 26 | Explanation: The entire string s is the minimum window. 27 | ``` 28 | 29 | **Example 3:** 30 | 31 | ``` 32 | Input: s = "a", t = "aa" 33 | Output: "" 34 | Explanation: Both 'a's from t must be included in the window. 35 | Since the largest window of s only has one 'a', return empty string. 36 | ``` 37 | 38 | **Constraints:** 39 | 40 | * `m == s.length` 41 | * `n == t.length` 42 | * `1 <= m, n <= 105` 43 | * `s` and `t` consist of uppercase and lowercase English letters. 44 | 45 | **Follow up:** Could you find an algorithm that runs in `O(m + n)` time? 46 | 47 | 48 | 49 | ```java 50 | class Solution { 51 | public String minWindow(String s, String t) { 52 | // corner case 53 | if(s == null || t == null || s.length() == 0 || t.length() == 0 || s.length() < t.length()) return ""; 54 | 55 | // construct model 56 | int minLeft = 0; 57 | int minRight = 0; 58 | int min = s.length(); 59 | boolean flag = false; 60 | 61 | Map map = new HashMap<>(); 62 | int count = t.length(); // the number of characters that I need to match 63 | for(char c : t.toCharArray()) map.put(c, map.getOrDefault(c, 0) + 1); 64 | 65 | // unfixed sliding window, 2 pointers 66 | int i = 0; 67 | int j = 0; 68 | while(j < s.length()){ 69 | char c = s.charAt(j); 70 | if(map.containsKey(c)){ 71 | map.put(c, map.get(c) - 1); 72 | if(map.get(c) >= 0) count--; // if still unmatched characters, then count-- 73 | } 74 | 75 | // if found a susbtring 76 | while(count == 0 && i <= j){ 77 | // update global min 78 | flag = true; 79 | int curLen = j + 1 - i; 80 | if(curLen <= min){ 81 | minLeft = i; 82 | minRight = j; 83 | min = curLen; 84 | } 85 | 86 | // shrink left pointer 87 | char leftC = s.charAt(i); 88 | if(map.containsKey(leftC)){ 89 | map.put(leftC, map.get(leftC) + 1); 90 | if(map.get(leftC) >= 1) count++; 91 | } 92 | i++; 93 | } 94 | j++; 95 | } 96 | 97 | return flag == true ? s.substring(minLeft, minRight + 1): ""; 98 | } 99 | } 100 | ``` 101 | -------------------------------------------------------------------------------- /1.-pattern-sliding-window/1.11-words-concatenation-hard.md: -------------------------------------------------------------------------------- 1 | # 1.11 Words Concatenation \(hard\) 2 | 3 | **Problem:** 4 | 5 | [30. Substring with Concatenation of All Words](https://leetcode.com/problems/substring-with-concatenation-of-all-words/) 6 | 7 | 8 | 9 | You are given a string `s` and an array of strings `words` of **the same length**. Return all starting indices of substring\(s\) in `s` that is a concatenation of each word in `words` **exactly once**, **in any order**, and **without any intervening characters**. 10 | 11 | You can return the answer in **any order**. 12 | 13 | **Example 1:** 14 | 15 | ```text 16 | Input: s = "barfoothefoobarman", words = ["foo","bar"] 17 | Output: [0,9] 18 | Explanation: Substrings starting at index 0 and 9 are "barfoo" and "foobar" respectively. 19 | The output order does not matter, returning [9,0] is fine too. 20 | ``` 21 | 22 | **Example 2:** 23 | 24 | ```text 25 | Input: s = "wordgoodgoodgoodbestword", words = ["word","good","best","word"] 26 | Output: [] 27 | ``` 28 | 29 | **Example 3:** 30 | 31 | ```text 32 | Input: s = "barfoofoobarthefoobarman", words = ["bar","foo","the"] 33 | Output: [6,9,12] 34 | ``` 35 | 36 | **Constraints:** 37 | 38 | * `1 <= s.length <= 104` 39 | * `s` consists of lower-case English letters. 40 | * `1 <= words.length <= 5000` 41 | * `1 <= words[i].length <= 30` 42 | * `words[i]` consists of lower-case English letters. 43 | 44 | **Solution:** 45 | 46 | ```java 47 | class Solution { 48 | public List findSubstring(String s, String[] words) { 49 | final Map counts = new HashMap<>(); 50 | for (final String word : words) { 51 | counts.put(word, counts.getOrDefault(word, 0) + 1); 52 | } 53 | final List indexes = new ArrayList<>(); 54 | final int n = s.length(), num = words.length, len = words[0].length(); 55 | for (int i = 0; i < n - num * len + 1; i++) { 56 | final Map seen = new HashMap<>(); 57 | int j = 0; 58 | while (j < num) { 59 | final String word = s.substring(i + j * len, i + (j + 1) * len); 60 | if (counts.containsKey(word)) { 61 | seen.put(word, seen.getOrDefault(word, 0) + 1); 62 | if (seen.get(word) > counts.getOrDefault(word, 0)) { 63 | break; 64 | } 65 | } else { 66 | break; 67 | } 68 | j++; 69 | } 70 | if (j == num) { 71 | indexes.add(i); 72 | } 73 | } 74 | return indexes; 75 | } 76 | } 77 | ``` 78 | 79 | -------------------------------------------------------------------------------- /1.-pattern-sliding-window/1.2-smallest-subarray-with-a-given-sum-easy.md: -------------------------------------------------------------------------------- 1 | # 1.2 Smallest Subarray with a given sum \(easy\) 2 | 3 | ### Problem Statement 4 | 5 | **Given an array of positive numbers and a positive number ‘S,’ find the length of the smallest contiguous subarray whose sum is greater than or equal to ‘S’. Return 0 if no such subarray exists.** 6 | 7 | Example 1: 8 | 9 | ```text 10 | Input: [2, 1, 5, 2, 3, 2], S=7 11 | Output: 2 12 | Explanation: The smallest subarray with a sum greater than 13 | or equal to '7' is [5, 2]. 14 | ``` 15 | 16 | Example 2: 17 | 18 | ```text 19 | Input: [2, 1, 5, 2, 8], S=7 20 | Output: 1 21 | Explanation: The smallest subarray with a sum greater than 22 | or equal to '7' is [8]. 23 | ``` 24 | 25 | Example 3: 26 | 27 | ```text 28 | Input: [3, 4, 1, 1, 6], S=8 29 | Output: 3 30 | Explanation: Smallest subarrays with a sum greater than 31 | or equal to '8' are [3, 4, 1] or [1, 1, 6]. 32 | ``` 33 | 34 | ### Solution 35 | 36 | This problem follows the Sliding Window pattern, and we can use a similar strategy as discussed in Maximum Sum Subarray of Size K. There is one difference though: in this problem, the sliding window size is not fixed. Here is how we will solve this problem: 37 | 38 | 1. First, we will add-up elements from the beginning of the array until their sum becomes greater than or equal to ‘S.’ 39 | 2. These elements will constitute our sliding window. We are asked to find the smallest such window having a sum greater than or equal to ‘S.’ We will remember the length of this window as the smallest window so far. 40 | 3. After this, we will keep adding one element in the sliding window \(i.e., slide the window ahead\) in a stepwise fashion. 41 | 4. In each step, we will also try to shrink the window from the beginning. We will shrink the window until the window’s sum is smaller than ‘S’ again. This is needed as we intend to find the smallest window. This shrinking will also happen in multiple steps; in each step, we will do two things: 42 | * Check if the current window length is the smallest so far, and if so, remember its length. 43 | * Subtract the first element of the window from the running sum to shrink the sliding window. 44 | 45 | ```java 46 | public int smallestSubarrayWithGivenSum(int arr[], int S) { 47 | int minLen = Integer.MAX_VALUE; 48 | // it will hold the size of smallest subarray 49 | // Integer.MAX_VALUE is the greatest number a int can hold 50 | // we need the minimum length/size so we will compare others with it. 51 | int windowSum = 0, windowStart = 0; 52 | // windowSum holds sum of the elements in that window 53 | // windowStart holds the starting position of current window 54 | 55 | for(int windowEnd = 0; windowEnd < arr.length; windowEnd++) { 56 | // iterating through every element using windowEnd 57 | windowSum += arr[windowEnd]; 58 | // element is added to the window 59 | while(windowSum >= S) { 60 | // while windowSum is greater than equal to S 61 | minLen = Math.min(minLen, windowEnd - windowStart + 1); 62 | // compares min len of window with the current window 63 | windowSum -= arr[windowStart]; 64 | // removing the element at the start of the window 65 | windowStart++; 66 | // moving the window start position to the next place 67 | } 68 | } 69 | 70 | return minLen == Integer.MAX_VALUE ? 0 : minLen; 71 | // ternary operator: 72 | // if minLen is equal to Integer.MAX_VALUE means minimun window 73 | // with given sum greater than equal to S is not there. So, it 74 | // return 0 else it return minLen 75 | } 76 | ``` 77 | 78 | #### Time Complexity 79 | 80 | The time complexity of the above algorithm will be O\(N\). The outer for loop runs for all elements, and the inner while loop processes each element only once; therefore, the time complexity of the algorithm will be O\(N+N\), which is asymptotically equivalent to O\(N\). 81 | 82 | #### Space Complexity 83 | 84 | The algorithm runs in constant space O\(1\). 85 | 86 | -------------------------------------------------------------------------------- /1.-pattern-sliding-window/1.3-longest-substring-with-k-distinct-characters-medium.md: -------------------------------------------------------------------------------- 1 | # 1.3 Longest Substring with K Distinct Characters \(medium\) 2 | 3 | #### Problem Statement 4 | 5 | Given a string, find the length of the longest substring in it with no more than K distinct characters. 6 | 7 | Example 1: 8 | 9 | ```text 10 | Input: String="araaci", K=2 11 | Output: 4 12 | Explanation: The longest substring with no more 13 | than '2' distinct characters is "araa". 14 | ``` 15 | 16 | Example 2: 17 | 18 | ```text 19 | Input: String="araaci", K=1 20 | Output: 2 21 | Explanation: The longest substring with no more 22 | than '1' distinct characters is "aa". 23 | ``` 24 | 25 | Example 3: 26 | 27 | ```text 28 | Input: String="cbbebi", K=3 29 | Output: 5 30 | Explanation: The longest substrings with no more 31 | than '3' distinct characters are "cbbeb" & "bbebi". 32 | ``` 33 | 34 | #### Solution 35 | 36 | This problem follows the Sliding Window pattern, and we can use a similar dynamic sliding window strategy as discussed in Smallest Subarray with a given sum. We can use a HashMap to remember the frequency of each character we have processed. Here is how we will solve this problem: 37 | 38 | 1. First, we will insert characters from the beginning of the string until we have ‘K’ distinct characters in the HashMap. 39 | 2. These characters will constitute our sliding window. We are asked to find the longest such window having no more than ‘K’ distinct characters. We will remember the length of this window as the longest window so far. 40 | 3. After this, we will keep adding one character in the sliding window \(i.e., slide the window ahead\) in a stepwise fashion. 41 | 4. In each step, we will try to shrink the window from the beginning if the count of distinct characters in the HashMap is larger than ‘K.’ We will shrink the window until we have no more than ‘K’ distinct characters in the HashMap. This is needed as we intend to find the longest window. 42 | 5. While shrinking, we’ll decrement the character’s frequency going out of the window and remove it from the HashMap if its frequency becomes zero. 43 | 6. At the end of each step, we’ll check if the current window length is the longest so far, and if so, remember its length. 44 | 45 | **Source code** 46 | 47 | ```java 48 | public int longestSubstringWithKDistinctChars(String s, int k) { 49 | 50 | if(s == null || s.length == 0 || k == 0) return 0; 51 | int windowStart - 0; 52 | int maxLen = 0; 53 | Map mp = new HashMap<>(); 54 | 55 | for(int windowEnd = 0; windowEnd < s.length(); windowEnd++) { 56 | char right = s.charAt(windowEnd); 57 | mp.put(right, mp.getOrDefault(right, 0) + 1); 58 | 59 | while(mp.size > k) { 60 | char left = s.chartAt(windowStart); 61 | mp.put(left, mp.get(left) - 1); 62 | if(mp.get(left) == 0) { 63 | mp.remove(left); 64 | } 65 | windowStart++; 66 | } 67 | maxLen = Math.max(maxLen, windowEnd - windowStart + 1); 68 | } 69 | return maxLen; 70 | } 71 | ``` 72 | 73 | #### Time Complexity 74 | 75 | The above algorithm’s time complexity will be O\(N\), where ‘N’ is the number of characters in the input string. The outer for loop runs for all characters, and the inner while loop processes each character only once; therefore, the time complexity of the algorithm will be O\(N+N\)O\(N+N\), which is asymptotically equivalent to O\(N\). 76 | 77 | #### Space Complexity 78 | 79 | The algorithm’s space complexity is O\(K\), as we will be storing a maximum of ‘K+1’ characters in the HashMap. 80 | 81 | -------------------------------------------------------------------------------- /1.-pattern-sliding-window/1.4-fruits-into-baskets-medium.md: -------------------------------------------------------------------------------- 1 | # 1.4 Fruits into Baskets \(medium\) 2 | 3 | 4 | 5 | #### Problem Statement 6 | 7 | Given an array of characters where each character represents a fruit tree, you are given two baskets and your goal is to put maximum number of fruits in each basket. The only restriction is that each basket can have only one type of fruit. 8 | 9 | You can start with any tree, but once you have started you can’t skip a tree. You will pick one fruit from each tree until you cannot, i.e., you will stop when you have to pick from a third fruit type. 10 | 11 | Write a function to return the maximum number of fruits in both the baskets. 12 | 13 | **Example 1:** 14 | 15 | ```text 16 | Input: Fruit=['A', 'B', 'C', 'A', 'C'] 17 | Output: 3 18 | Explanation: We can put 2 'C' in one basket and one 'A' in 19 | the other from the subarray ['C', 'A', 'C'] 20 | ``` 21 | 22 | **Example 2:** 23 | 24 | ```text 25 | Input: Fruit=['A', 'B', 'C', 'B', 'B', 'C'] 26 | Output: 5 27 | Explanation: We can put 3 'B' in one basket and two 'C' in 28 | the other basket. 29 | This can be done if we start with the second letter: 30 | ['B', 'C', 'B', 'B', 'C'] 31 | ``` 32 | 33 | #### Solution 34 | 35 | This problem follows the Sliding Window pattern and is quite similar to Longest Substring with K Distinct Characters. In this problem, we need to find the length of the longest subarray with no more than two distinct characters \(or fruit types!\). This transforms the current problem into Longest Substring with K Distinct Characters where K=2. 36 | 37 | #### Code 38 | 39 | ```java 40 | public int fruitsIntoBaskets(char[] arr) { 41 | int windowStart = 0; 42 | int maxFruits = 0; 43 | Map mp = new HashMap<>(); 44 | 45 | for(int windowEnd = 0; windowEnd < arr.length; windowEnd++) { 46 | mp.put(arr[windowEnd], mp.getOrDefault(arr[windowEnd], 0) + 1); 47 | 48 | while(mp.size() > 2) { 49 | mp.put(arr[windowStart], mp.get(arr[windowStart]) - 1); 50 | if(mp.get(arr[windowStart]) == 0) { 51 | mp.remove(arr[windowStart]); 52 | } 53 | windowStart++; 54 | } 55 | maxFruits = Math.max(maxFruits, windowEnd - windowStart + 1); 56 | } 57 | return maxFruits; 58 | } 59 | ``` 60 | 61 | #### Time Complexity 62 | 63 | The time complexity of the above algorithm will be O\(N\)O\(N\) where ‘N’ is the number of characters in the input array. The outer for loop runs for all characters and the inner while loop processes each character only once, therefore the time complexity of the algorithm will be O\(N+N\)O\(N+N\) which is asymptotically equivalent to O\(N\)O\(N\). 64 | 65 | #### Space Complexity 66 | 67 | The algorithm runs in constant space O\(1\)O\(1\) as there can be a maximum of three types of fruits stored in the frequency map. 68 | 69 | #### Similar Problems 70 | 71 | ```text 72 | Problem 1: Longest Substring with at most 2 distinct characters 73 | 74 | Given a string, find the length of the longest substring in it 75 | with at most two distinct characters. 76 | 77 | Solution: This problem is exactly similar to our parent problem. 78 | ``` 79 | 80 | -------------------------------------------------------------------------------- /1.-pattern-sliding-window/1.5-no-repeat-substring-hard.md: -------------------------------------------------------------------------------- 1 | # 1.5 No-repeat Substring \(hard\) 2 | 3 | #### Problem Statement 4 | 5 | Given a string, find the length of the longest substring which has no repeating characters. 6 | 7 | **Example 1:** 8 | 9 | ```text 10 | Input: String="aabccbb" 11 | Output: 3 12 | Explanation: The longest substring without any repeating 13 | characters is "abc". 14 | ``` 15 | 16 | **Example 2:** 17 | 18 | ```text 19 | Input: String="abbbb" 20 | Output: 2 21 | Explanation: The longest substring without any repeating 22 | characters is "ab". 23 | ``` 24 | 25 | **Example 3:** 26 | 27 | ```text 28 | Input: String="abccde" 29 | Output: 3 30 | Explanation: Longest substrings without any repeating 31 | characters are "abc" & "cde". 32 | ``` 33 | 34 | #### Solution 35 | 36 | This problem follows the Sliding Window pattern and we can use a similar dynamic sliding window strategy as discussed in Longest Substring with K Distinct Characters. We can use a HashMap to remember the last index of each character we have processed. Whenever we get a repeating character we will shrink our sliding window to ensure that we always have distinct characters in the sliding window. 37 | 38 | #### Code 39 | 40 | ```java 41 | public int lengthOfLongestSubstring(String s) { 42 | int windowStart = 0; 43 | int maxLen = 0; 44 | Map mp = new HashMap<>(); 45 | for( int windowEnd = 0; windowEnd < s.length(); windowEnd++) { 46 | char rightChar = s.charAt(windowEnd); 47 | if(mp.containsKey(rightChar)) { 48 | windowStart = Math.max(windowStart, mp.get(rightChar) + 1); 49 | } 50 | mp.put(rightChar, windowEnd); 51 | maxLen = Math.max(maxLen, windowEnd - windowStart + 1); 52 | } 53 | return maxLen; 54 | } 55 | ``` 56 | 57 | #### Time Complexity 58 | 59 | The time complexity of the above algorithm will be O\(N\) where ‘N’ is the number of characters in the input string. 60 | 61 | #### Space Complexity 62 | 63 | The space complexity of the algorithm will be O\(K\) where K is the number of distinct characters in the input string. This also means K<=N, because in the worst case, the whole string might not have any repeating character so the entire string will be added to the HashMap. Having said that, since we can expect a fixed set of characters in the input string \(e.g., 26 for English letters\), we can say that the algorithm runs in fixed space O\(1\); in this case, we can use a fixed-size array instead of the HashMap. 64 | 65 | -------------------------------------------------------------------------------- /1.-pattern-sliding-window/1.6-longest-substring-with-same-letters-after-replacement-hard.md: -------------------------------------------------------------------------------- 1 | # 1.6 Longest Substring with Same Letters after Replacement \(hard\) 2 | 3 | **Problem:** 4 | 5 | You are given a string `s` and an integer `k`. You can choose any character of the string and change it to any other uppercase English character. You can perform this operation at most `k` times. 6 | 7 | Return _the length of the longest substring containing the same letter you can get after performing the above operations_. 8 | 9 | **Example 1:** 10 | 11 | ```text 12 | Input: s = "ABAB", k = 2 13 | Output: 4 14 | Explanation: Replace the two 'A's with two 'B's or vice versa. 15 | ``` 16 | 17 | **Example 2:** 18 | 19 | ```text 20 | Input: s = "AABABBA", k = 1 21 | Output: 4 22 | Explanation: Replace the one 'A' in the middle with 'B' and form "AABBBBA". 23 | The substring "BBBB" has the longest repeating letters, which is 4. 24 | ``` 25 | 26 | **Intution:** 27 | 28 | The question asks to find the longest substring that contains the same characters. It also says that we can change k characters to make a substring longer and valid. 29 | 30 | Ex: 31 | 32 | ```text 33 | "ABAB" k = 1 34 | ``` 35 | 36 | Here we know that we can change 1 character to make a substring that is a valid answer 37 | AKA: a substring with all the same characters. 38 | 39 | So a valid substring answer would be s.substring\(0, 3\) -> "ABA" because with can replace 1 character. 40 | 41 | Another answer could be "BAB". 42 | 43 | Using the sliding window technique, we set up pointers `left = 0` and `right = 0` 44 | We know that a our current window / substring is valid when the number of characters that need to be replaced is <= k. 45 | 46 | Lets take the example below to understand it better: 47 | Ex: 48 | 49 | ```text 50 | "AABABCC" k = 2 51 | left = 0 52 | right = 4 inclusive 53 | ``` 54 | 55 | This is example above shows a valid substring window because we have enough k changes to change the B's to A's and match the rest of the string. 56 | 57 | "AABAB" with 2 changes is valid 58 | 59 | We will need to know how many letters in our substring that we need to replace. 60 | To find out the `lettersToReplace = (end - start + 1) - mostFreqLetter;` 61 | Pretty much you take the size of the window minus the most freq letter that is in the current window. 62 | 63 | Now that we know how many characters that need to be replaced in our window, we can deduce that if `lettersToReplace > k` than the window is invalid and we decrease the window size from the left. 64 | 65 | Pulling the whole algorithm together we get: 66 | 67 | ```java 68 | class Solution { 69 | public int characterReplacement(String s, int k) { 70 | int[] freq = new int[26]; 71 | int mostFreqLetter = 0; 72 | int left = 0; 73 | int max = 0; 74 | 75 | for(int right = 0; right < s.length(); right++){ 76 | freq[s.charAt(right) - 'A']++; 77 | mostFreqLetter = Math.max(mostFreqLetter, freq[s.charAt(right) - 'A']); 78 | 79 | int lettersToChange = (right - left + 1) - mostFreqLetter; 80 | if(lettersToChange > k){ 81 | freq[s.charAt(left) - 'A']--; 82 | left++; 83 | } 84 | 85 | max = Math.max(max, right - left + 1); 86 | } 87 | 88 | return max; 89 | } 90 | } 91 | ``` 92 | 93 | `Time Complexity: O(N)` 94 | `Space Complexity: O(26) = O(1)` 95 | 96 | Credits: [https://leetcode.com/doej4566](https://leetcode.com/doej4566) 97 | 98 | -------------------------------------------------------------------------------- /1.-pattern-sliding-window/1.7-longest-subarray-with-ones-after-replacement-hard.md: -------------------------------------------------------------------------------- 1 | # 1.7 Longest Subarray with Ones after Replacement \(hard\) 2 | 3 | **Problem:** 4 | 5 | [Max Consecutive Ones III](https://leetcode.com/problems/max-consecutive-ones-iii/) 6 | 7 | Given a binary array `nums` and an integer `k`, return _the maximum number of consecutive_ `1`_'s in the array if you can flip at most_ `k` `0`'s. 8 | 9 | **Example 1:** 10 | 11 | ```text 12 | Input: nums = [1,1,1,0,0,0,1,1,1,1,0], k = 2 13 | Output: 6 14 | Explanation: [1,1,1,0,0,1,1,1,1,1,1] 15 | Bolded numbers were flipped from 0 to 1. The longest subarray is underlined. 16 | ``` 17 | 18 | **Example 2:** 19 | 20 | ```text 21 | Input: nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], k = 3 22 | Output: 10 23 | Explanation: [0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1] 24 | Bolded numbers were flipped from 0 to 1. The longest subarray is underlined. 25 | ``` 26 | 27 | **Solution:** 28 | 29 | ```java 30 | public int longestOnes(int[] A, int K) { 31 | int max = 0; 32 | int zeroCount = 0; // zero count in current window 33 | int i = 0; // slow pointer 34 | for(int j = 0; j < A.length; ++j) { 35 | if(A[j] == 0) { // move forward j, if current is 0, increase the zeroCount 36 | zeroCount++; 37 | } 38 | 39 | // when current window has more than K, the window is not valid any more 40 | // we need to loop the slow pointer until the current window is valid 41 | while(zeroCount > K) { 42 | if(A[i] == 0) { 43 | zeroCount--; 44 | } 45 | i++; 46 | } 47 | max = Math.max(max, j-i+1); // everytime we get here, the current window is valid 48 | } 49 | return max; 50 | } 51 | ``` 52 | 53 | -------------------------------------------------------------------------------- /1.-pattern-sliding-window/1.8-permutation-in-a-string-hard.md: -------------------------------------------------------------------------------- 1 | # 1.8 - Permutation in a String \(hard\) 2 | 3 | **Problem:** 4 | 5 | [567. Permutation in String](https://leetcode.com/problems/permutation-in-string/) 6 | 7 | 8 | 9 | Given two strings `s1` and `s2`, return true if `s2` contains the permutation of `s1`. 10 | 11 | In other words, one of `s1`'s permutations is the substring of `s2`. 12 | 13 | **Example 1:** 14 | 15 | ```text 16 | Input: s1 = "ab", s2 = "eidbaooo" 17 | Output: true 18 | Explanation: s2 contains one permutation of s1 ("ba"). 19 | ``` 20 | 21 | **Example 2:** 22 | 23 | ```text 24 | Input: s1 = "ab", s2 = "eidboaoo" 25 | Output: false 26 | ``` 27 | 28 | **Constraints:** 29 | 30 | * `1 <= s1.length, s2.length <= 104` 31 | * `s1` and `s2` consist of lowercase English letters. 32 | 33 | **Solution:** 34 | 35 | **Sliding Window** 36 | 37 | **Algorithm** 38 | 39 | Instead of generating the hashmap afresh for every window considered in s2, we can create the hashmap just once for the first window in s2. Then, later on when we slide the window, we know that we remove one preceding character and add a new succeeding character to the new window considered. Thus, we can update the hashmap by just updating the indices associated with those two characters only. Again, for every updated hashmap, we compare all the elements of the hashmap for equality to get the required result. 40 | 41 | ```java 42 | public class Solution { 43 | public boolean checkInclusion(String s1, String s2) { 44 | if (s1.length() > s2.length()) 45 | return false; 46 | int[] s1map = new int[26]; 47 | int[] s2map = new int[26]; 48 | for (int i = 0; i < s1.length(); i++) { 49 | s1map[s1.charAt(i) - 'a']++; 50 | s2map[s2.charAt(i) - 'a']++; 51 | } 52 | for (int i = 0; i < s2.length() - s1.length(); i++) { 53 | if (matches(s1map, s2map)) 54 | return true; 55 | s2map[s2.charAt(i + s1.length()) - 'a']++; 56 | s2map[s2.charAt(i) - 'a']--; 57 | } 58 | return matches(s1map, s2map); 59 | } 60 | public boolean matches(int[] s1map, int[] s2map) { 61 | for (int i = 0; i < 26; i++) { 62 | if (s1map[i] != s2map[i]) 63 | return false; 64 | } 65 | return true; 66 | } 67 | } 68 | ``` 69 | 70 | **Complexity Analysis** 71 | 72 | * Time complexity : O\(l1+26\*\(l2-l1\)\), where l1​ is the length of string s1​ and l2​ is the length of string s2​. 73 | * Space complexity : O\(1\). Constant space is used. 74 | 75 | **Optimized Sliding Window:** 76 | 77 | **Algorithm** 78 | 79 | The last approach can be optimized, if instead of comparing all the elements of the hashmaps for every updated s2map corresponding to every window of s2 considered, we keep a track of the number of elements which were already matching in the earlier hashmap and update just the count of matching elements when we shift the window towards the right. 80 | 81 | To do so, we maintain a count variable, which stores the number of characters\(out of the 26 alphabets\), which have the same frequency of occurence in s1 and the current window in s2. When we slide the window, if the deduction of the last element and the addition of the new element leads to a new frequency match of any of the characters, we increment the count by 1. If not, we keep the count intact. But, if a character whose frequency was the same earlier\(prior to addition and removal\) is added, it now leads to a frequency mismatch which is taken into account by decrementing the same count variable. If, after the shifting of the window, the count evaluates to 26, it means all the characters match in frequency totally. So, we return a True in that case immediately. 82 | 83 | ```java 84 | public class Solution { 85 | public boolean checkInclusion(String s1, String s2) { 86 | if (s1.length() > s2.length()) 87 | return false; 88 | int[] s1map = new int[26]; 89 | int[] s2map = new int[26]; 90 | for (int i = 0; i < s1.length(); i++) { 91 | s1map[s1.charAt(i) - 'a']++; 92 | s2map[s2.charAt(i) - 'a']++; 93 | } 94 | int count = 0; 95 | for (int i = 0; i < 26; i++) 96 | if (s1map[i] == s2map[i]) 97 | count++; 98 | for (int i = 0; i < s2.length() - s1.length(); i++) { 99 | int r = s2.charAt(i + s1.length()) - 'a', l = s2.charAt(i) - 'a'; 100 | if (count == 26) 101 | return true; 102 | s2map[r]++; 103 | if (s2map[r] == s1map[r]) 104 | count++; 105 | else if (s2map[r] == s1map[r] + 1) 106 | count--; 107 | s2map[l]--; 108 | if (s2map[l] == s1map[l]) 109 | count++; 110 | else if (s2map[l] == s1map[l] - 1) 111 | count--; 112 | } 113 | return count == 26; 114 | } 115 | } 116 | ``` 117 | 118 | **Complexity Analysis** 119 | 120 | * Time complexity : O\(l1​+\(l2​−l1​\)\). where l1​ is the length of string s1​ and l2​ is the length of string s2​. 121 | * Space complexity : O\(1\). Constant space is used. 122 | 123 | -------------------------------------------------------------------------------- /1.-pattern-sliding-window/1.9-string-anagrams-hard.md: -------------------------------------------------------------------------------- 1 | # 1.9 String Anagrams (hard) 2 | 3 | **Problem:** 4 | 5 | **** [438**.** Find All Anagrams in a String](https://leetcode.com/problems/find-all-anagrams-in-a-string/) 6 | 7 | 8 | 9 | Given two strings `s` and `p`, return _an array of all the start indices of_ `p`_'s anagrams in_ `s`. You may return the answer in **any order**. 10 | 11 | **Example 1:** 12 | 13 | ``` 14 | Input: s = "cbaebabacd", p = "abc" 15 | Output: [0,6] 16 | Explanation: 17 | The substring with start index = 0 is "cba", which is an anagram of "abc". 18 | The substring with start index = 6 is "bac", which is an anagram of "abc". 19 | ``` 20 | 21 | **Example 2:** 22 | 23 | ``` 24 | Input: s = "abab", p = "ab" 25 | Output: [0,1,2] 26 | Explanation: 27 | The substring with start index = 0 is "ab", which is an anagram of "ab". 28 | The substring with start index = 1 is "ba", which is an anagram of "ab". 29 | The substring with start index = 2 is "ab", which is an anagram of "ab". 30 | ``` 31 | 32 | **Constraints:** 33 | 34 | * `1 <= s.length, p.length <= 3 * 104` 35 | * `s` and `p` consist of lowercase English letters. 36 | 37 | 38 | 39 | ```java 40 | public class Solution { 41 | public List findAnagrams(String s, String p) { 42 | ///We will use sliding window template 43 | 44 | ArrayList soln = new ArrayList(); 45 | 46 | //Check for bad input 47 | if (s.length() == 0 || p.length() == 0 || s.length() < p.length()){ 48 | return new ArrayList(); 49 | } 50 | 51 | //Set up character hash 52 | //Keep track of how many times each character appears 53 | int[] chars = new int[26]; 54 | for (Character c : p.toCharArray()){ 55 | //Increment to setup hash of all characters currently in the window 56 | //Later on, these get DECREMENTED when a character is found 57 | //A positive count later on means that the character is still "needed" in the anagram 58 | //A negative count means that either the character was found more times than necessary 59 | //Or that it isn't needed at all 60 | chars[c-'a']++; 61 | } 62 | 63 | //Start = start poniter, end = end pointer, 64 | //len = length of anagram to find 65 | //diff = length of currently found anagram. If it equals 66 | //the length of anagram to find, it must have been found 67 | int start = 0, end = 0, len = p.length(), diff = len; 68 | 69 | char temp; 70 | //Before we begin this, the "window" has a length of 0, start and 71 | //end pointers both at 0 72 | for (end = 0; end < len; end++){ 73 | //Process current char 74 | temp = s.charAt(end); 75 | 76 | //As discussed earlier, decrement it 77 | chars[temp-'a']--; 78 | 79 | //If it's still >= 0, the anagram still "needed" it so we count it towards the anagram by 80 | //decrementing diff 81 | if (chars[temp-'a'] >= 0){ 82 | diff--; 83 | } 84 | } 85 | 86 | //This would mean that s began with an anagram of p 87 | if (diff == 0){ 88 | soln.add(0); 89 | } 90 | 91 | //At this point, start remains at 0, end has moved so that the window is the length of the anagram 92 | //from this point on we are going to be moving start AND end on each iteration, to shift the window 93 | //along the string 94 | while (end < s.length()){ 95 | 96 | //Temp represents the current first character of the window. The character that is 97 | //going to be "left behind" as the window moves. 98 | temp = s.charAt(start); 99 | 100 | //If it's not negative, this means that the character WAS part of the anagram. That means we 101 | //are one step "farther away" from completing an anagram. So we must increment diff. 102 | if (chars[temp-'a'] >= 0){ 103 | diff++; 104 | } 105 | 106 | //Increment the hash value for this character, because it is no longer contained in the window 107 | chars[temp-'a']++; 108 | 109 | //Increment start to start shifting the window over by 1 110 | start++; 111 | 112 | //Temp represents the last character of the window, the "new" character from the window shift. 113 | //This character "replaces" the one we removed before so the window stays the same length (p.length()) 114 | temp = s.charAt(end); 115 | 116 | //Decrement hash value for this character, because it is now a part of the window 117 | chars[temp-'a']--; 118 | 119 | //Again, if it's not negative it is part of the anagram. So decrement diff 120 | if (chars[temp-'a'] >= 0){ 121 | diff--; 122 | } 123 | 124 | //If diff has reached zero, that means for the last p.length() iterations, diff was decremented and 125 | //NOT decremented, which means every one of those characters was in the anagram, so it must be an anagram 126 | 127 | //Note: If many windows in a row find anagrams, then each iteration will have diff incremented then decremented again 128 | if (diff == 0){ 129 | soln.add(start); 130 | } 131 | 132 | //Increment for next iteration 133 | end++; 134 | 135 | } 136 | 137 | return soln; 138 | 139 | 140 | } 141 | } 142 | ``` 143 | -------------------------------------------------------------------------------- /1.-pattern-sliding-window/README.md: -------------------------------------------------------------------------------- 1 | # 1. Pattern: Sliding Window 2 | 3 | * **Fixed Window Size:** 4 | 5 | ![](../.gitbook/assets/image.png) 6 | 7 | * **Variable Window Size**: 8 | * Window size can be increase or decrease 9 | 10 | -------------------------------------------------------------------------------- /11.-pattern-modified-binary-search/11.1-introduction.md: -------------------------------------------------------------------------------- 1 | # 11.1 Introduction 2 | 3 | -------------------------------------------------------------------------------- /11.-pattern-modified-binary-search/11.2-order-agnostic-binary-search-easy.md: -------------------------------------------------------------------------------- 1 | # 11.2 Order-agnostic Binary Search (easy) 2 | 3 | 4 | 5 | #### Problem Statement [#](https://www.educative.io/courses/grokking-the-coding-interview/R8LzZQlj8lO#problem-statement) 6 | 7 | Given a sorted array of numbers, find if a given number ‘key’ is present in the array. Though we know that the array is sorted, we don’t know if it’s sorted in ascending or descending order. You should assume that the array can have duplicates. 8 | 9 | Write a function to return the index of the ‘key’ if it is present in the array, otherwise return -1. 10 | 11 | **Example 1:** 12 | 13 | ``` 14 | Input: [4, 6, 10], key = 10 15 | Output: 2 16 | ``` 17 | 18 | **Example 2:** 19 | 20 | ``` 21 | Input: [1, 2, 3, 4, 5, 6, 7], key = 5 22 | Output: 4 23 | ``` 24 | 25 | **Example 3:** 26 | 27 | ``` 28 | Input: [10, 6, 4], key = 10 29 | Output: 0 30 | ``` 31 | 32 | **Example 4:** 33 | 34 | ``` 35 | Input: [10, 6, 4], key = 4 36 | Output: 2 37 | ``` 38 | 39 | ``` 40 | class Solution 41 | { 42 | public static int search(int[] arr, int key) { 43 | if (arr.length < 2) { 44 | return arr[0] == key ? 0 : -1; 45 | } 46 | int start = 0, end = arr.length - 1; 47 | if (arr[start] <= arr[end]) 48 | return binarySearchOnAsc(arr, key); 49 | else 50 | return binarySearchOnDsc(arr, key); 51 | } 52 | 53 | private static int binarySearchOnAsc(int[] arr, int key) { 54 | int start = 0, end = arr.length - 1; 55 | 56 | while (start <= end) { 57 | int mid = start + (end - start) / 2; 58 | 59 | if (arr[mid] == key) 60 | return mid; 61 | else if (arr[mid] < key) 62 | start = mid + 1; 63 | else 64 | end = mid - 1; 65 | } 66 | return -1; 67 | } 68 | 69 | private static int binarySearchOnDsc(int[] arr, int key) { 70 | int start = 0, end = arr.length - 1; 71 | 72 | while (start <= end) { 73 | int mid = start + (end - start) / 2; 74 | 75 | if (arr[mid] == key) 76 | return mid; 77 | else if (arr[mid] < key) 78 | end = mid - 1; 79 | else 80 | start = mid + 1; 81 | } 82 | return -1; 83 | } 84 | 85 | public static void main(String[] args) { 86 | System.out.println(search(new int[] { 4, 6, 10 }, 10)); 87 | System.out.println(search(new int[] { 1, 2, 3, 4, 5, 6, 7 }, 5)); 88 | System.out.println(search(new int[] { 10, 6, 4 }, 10)); 89 | System.out.println(search(new int[] { 10, 6, 4 }, 4)); 90 | } 91 | } 92 | ``` 93 | 94 | **Time complexity** 95 | 96 | Since, we are reducing the search range by half at every step, this means that the time complexity of our algorithm will be O(logN) where ‘N’ is the total elements in the given array. 97 | 98 | **Space complexity** 99 | 100 | The algorithm runs in constant space O(1) 101 | -------------------------------------------------------------------------------- /11.-pattern-modified-binary-search/11.3.md: -------------------------------------------------------------------------------- 1 | # 11.3 2 | 3 | -------------------------------------------------------------------------------- /11.-pattern-modified-binary-search/README.md: -------------------------------------------------------------------------------- 1 | # 11. Pattern: Modified Binary Search 2 | 3 | -------------------------------------------------------------------------------- /13.-pattern-top-k-elements/01.Introduction.md: -------------------------------------------------------------------------------- 1 | # 13. Pattern: Top 'K' Elements 2 | 3 | The **Top 'K' Elements** pattern is a common coding pattern used to solve problems that involve finding the top, smallest, or most/least frequent **k** elements in an unsorted list. This pattern is particularly useful when dealing with large datasets, as it allows us to solve these problems efficiently without having to sort the entire list. 4 | 5 | ## Understanding the Pattern 6 | 7 | The main idea behind this pattern is to maintain a heap of size **k** while iterating through the list of elements. The type of heap (min-heap or max-heap) depends on the problem at hand. For instance, if we want to find the top **k** largest elements, we use a min-heap; for the top **k** smallest elements, we use a max-heap. 8 | 9 | ## PriorityQueue in Java 10 | 11 | In Java, the `PriorityQueue` class is a part of the Java Collections Framework. This class is implemented as a priority heap. A priority heap is a special type of data structure that performs operations based on the priority of the elements. In a `PriorityQueue`, elements are ordered either in natural order or by a `Comparator` provided at queue construction time. 12 | 13 | Here is a simple example of a `PriorityQueue` in Java: 14 | 15 | ```java 16 | import java.util.PriorityQueue; 17 | 18 | public class Main { 19 | public static void main(String[] args) { 20 | PriorityQueue numbers = new PriorityQueue<>(); 21 | 22 | // Add items to a Priority Queue (ENQUEUE) 23 | numbers.add(750); 24 | numbers.add(500); 25 | numbers.add(900); 26 | numbers.add(100); 27 | 28 | // Remove items from the Priority Queue (DEQUEUE) 29 | while (!numbers.isEmpty()) { 30 | System.out.println(numbers.remove()); 31 | } 32 | } 33 | } 34 | ``` 35 | 36 | In this example, although the elements are added in the order 750, 500, 900, 100, they are polled in the order 100, 500, 750, 900 which is the natural ordering of integers. 37 | 38 | ## Heap Complexities 39 | 40 | The time complexity of heap operations is as follows: 41 | 42 | - **Insertion**: The time complexity for inserting an element into a heap is **O(log n)**, where **n** is the number of elements in the heap. 43 | 44 | - **Deletion**: The time complexity for deleting an element from a heap is also **O(log n)**, as the element to be deleted must first be found in **O(log n)** time and then removed. 45 | 46 | - **Peek (or top operation)**: The time complexity for retrieving the top element from a heap is **O(1)**, as the top element is always present at the root of the heap. 47 | 48 | These complexities make heaps an efficient data structure for the **Top 'K' Elements** pattern. They allow us to insert and delete elements in logarithmic time, which is significantly faster than linear time operations. This efficiency is crucial when dealing with large datasets or real-time data streams. 49 | 50 | ## Conclusion 51 | 52 | The **Top 'K' Elements** pattern is a powerful tool for dealing with large datasets and finding the top **k** elements. By using a heap data structure, we can solve these problems efficiently and elegantly. Remember, practice is key to mastering this pattern, so try to solve as many problems as you can using this pattern. Happy coding! 53 | -------------------------------------------------------------------------------- /13.-pattern-top-k-elements/02.top-k-numbers.md: -------------------------------------------------------------------------------- 1 | # 13.1 Top 'K' Numbers (easy) 2 | ## Problem Statement 3 | Given an unsorted array of numbers, find the ‘K’ largest numbers in it. 4 | 5 | > Note: For a detailed discussion about different approaches to solve this problem, take a look at Kth Smallest Number. 6 | 7 | Example 1: 8 | ``` 9 | Input: [3, 1, 5, 12, 2, 11], K = 3 10 | Output: [5, 12, 11] 11 | ``` 12 | Example 2: 13 | ``` 14 | Input: [5, 12, 11, -1, 12], K = 3 15 | Output: [12, 11, 12] 16 | ``` 17 | 18 | ## Approach 19 | The approach is to use a min-heap to keep track of the top 'K' largest numbers in the array. The steps are: 20 | 21 | - Create a min-heap of size 'K' and insert the first 'K' numbers of the array into it. 22 | - Iterate through the remaining numbers of the array, and for each number, do the following: 23 | - If the number is larger than the root of the min-heap, remove the root and insert the number into the min-heap. 24 | - Otherwise, ignore the number as it is not among the top 'K' largest numbers. 25 | - Return the contents of the min-heap as the answer. 26 | 27 | ## Solution 28 | ```java 29 | import java.util.*; 30 | 31 | class Solution { 32 | 33 | public static List findKLargestNumbers(int[] nums, int k) { 34 | PriorityQueue minHeap = new PriorityQueue((n1, n2) -> n1 - n2); 35 | // put first 'K' numbers in the min heap 36 | for (int i = 0; i < k; i++) 37 | minHeap.add(nums[i]); 38 | 39 | // go through the remaining numbers of the array, if the number from the array is bigger than the 40 | // top (smallest) number of the min-heap, remove the top number from heap and add the number from array 41 | for (int i = k; i < nums.length; i++) { 42 | if (nums[i] > minHeap.peek()) { 43 | minHeap.poll(); 44 | minHeap.add(nums[i]); 45 | } 46 | } 47 | 48 | // the heap has the top 'K' numbers, return them in a list 49 | return new ArrayList<>(minHeap); 50 | } 51 | } 52 | ``` 53 | 54 | ## Complexities 55 | The above code is an implementation of the heap sort algorithm in Java. The complexity of the code depends on the following factors: 56 | 57 | - The size of the input array, denoted by N 58 | - The number of largest elements to find, denoted by K 59 | - The operations performed on the min-heap, such as insertion, deletion, and peeking 60 | 61 | The time complexity of the code can be analyzed as follows: 62 | 63 | - The first for loop iterates over the first K elements of the array and inserts them into the min-heap. This takes O(K * log K) time, since each insertion takes O(log K) time, where K is the size of the heap. 64 | - The second for loop iterates over the remaining N - K elements of the array and compares them with the root of the min-heap. If the element is larger than the root, it removes the root and inserts the element into the heap. This takes O((N - K) * log K) time, since each deletion and insertion takes O(log K) time. 65 | - The return statement converts the min-heap into a list, which takes O(K) time. 66 | 67 | Therefore, the total time complexity of the code is O(K * log K + (N - K) * log K + K), which is asymptotically equivalent to O(N * log K). 68 | 69 | The space complexity of the code can be analyzed as follows: 70 | 71 | - The min-heap uses O(K) space to store the top K elements of the array. 72 | - The list uses O(K) space to store the same elements as the heap. 73 | - The rest of the variables use O(1) space. 74 | 75 | Therefore, the total space complexity of the code is O(K + K + 1), which is asymptotically equivalent to O(K). 76 | -------------------------------------------------------------------------------- /13.-pattern-top-k-elements/13.HeapImplementation.md: -------------------------------------------------------------------------------- 1 | # Implementing a Heap in Java: A Comprehensive Guide 2 | 3 | A heap is a specialized tree-based data structure that satisfies the heap property. In a min heap, for any given node `i`, the value of `i` is greater than or equal to the value of its parent. This property holds true across the tree. In a max heap, the value of `i` is less than or equal to the value of its parent. 4 | 5 | In this article, we will discuss the implementation of a min heap in Java using an `ArrayList`. The heap will be able to handle generic types (`E`) that extend the `Comparable` interface. 6 | 7 | ## Class Structure 8 | 9 | ```java 10 | public class Heap> { 11 | private List list; 12 | 13 | public Heap() { 14 | list = new ArrayList<>(); 15 | } 16 | } 17 | ``` 18 | 19 | In the above code, we define a class `Heap` that takes a generic parameter `E` which extends `Comparable`. This means that the elements that we add to the heap must be comparable. We use an `ArrayList` to store the elements of the heap. 20 | 21 | ## Adding Elements to the Heap 22 | ### Step 1: Insert 10 to heap into a Min Heap 23 | ![image](https://github.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/assets/20329508/87a98d8f-ae10-4be1-bcbe-f779a281dc1f) 24 | 25 | 26 | ### Step 2: Insert 40 27 | ![image](https://github.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/assets/20329508/8499c140-b2ae-4851-bb27-1b9a566bb62d) 28 | 29 | 30 | ### Step 3: Insert 50 31 | ![image](https://github.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/assets/20329508/8f595838-eb55-4e98-a858-e69ac4d0d861) 32 | 33 | 34 | ### Step 4: Insert 5 35 | ![image](https://github.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/assets/20329508/baec38fe-c7e3-4935-a9e0-ebc1325f62c1) 36 | 37 | 38 | ### Step 5: Swap 5 with 40 39 | ![image](https://github.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/assets/20329508/c016e48b-b65c-44bd-9455-ea5e825f50a5) 40 | 41 | 42 | ### Step 6: Swap 5 with 10 43 | ![image](https://github.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/assets/20329508/cdbfa67b-77ee-475b-bf9f-52a6e634d7ab) 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | ```java 54 | // Time complexity: O(log n) 55 | public void add(E e) { 56 | list.add(e); 57 | int k = list.size() - 1; 58 | // Sifting up the new element to its correct position 59 | while (k > 0 && list.get(k).compareTo(list.get(getParentIndex(k))) < 0) { 60 | swap(k, getParentIndex(k)); 61 | k = getParentIndex(k); 62 | } 63 | } 64 | ``` 65 | 66 | In the `add` method, we add the element `e` to the end of the list and then sifted up the tree by comparing it to its parent and swapping places if necessary. This ensures that the heap property is maintained, where the root element is always the smallest (or largest) element in the heap. 67 | 68 | ## Removing Elements from the Heap 69 | 70 | ```java 71 | // Time complexity: O(log n) 72 | public E remove() { 73 | if (list.size() == 0) 74 | throw new RuntimeException("Unable to remove from an empty heap!"); 75 | 76 | E e = list.get(0); 77 | list.set(0, list.get(list.size() - 1)); 78 | list.remove(list.size() - 1); 79 | 80 | // Sifting down the element at index 0 to its correct position 81 | int parentIndex = 0; 82 | while (parentIndex < (list.size() / 2)) { 83 | int leftChildIndex = getLeftChildIndex(parentIndex); 84 | int rightChildIndex = getRightChildIndex(parentIndex); 85 | int minIndex = leftChildIndex; 86 | 87 | // Finding the smaller of the two children 88 | if (rightChildIndex < list.size() && list.get(leftChildIndex).compareTo(list.get(rightChildIndex)) > 0) { 89 | minIndex = rightChildIndex; 90 | } 91 | 92 | // Swapping the parent with the smaller child if necessary 93 | if (list.get(parentIndex).compareTo(list.get(minIndex)) > 0) { 94 | swap(parentIndex, minIndex); 95 | parentIndex = minIndex; 96 | } else { 97 | break; 98 | } 99 | } 100 | return e; 101 | } 102 | ``` 103 | 104 | The `remove` method removes and returns the smallest element from the heap. It does this by swapping the first and last elements in the list, removing the last element (which is now the smallest element). The new root element is then sifted down the tree by comparing it to its children and swapping places if necessary. This ensures that the heap property is maintained. 105 | 106 | ## Helper Methods 107 | 108 | The `getLeftChildIndex`, `getRightChildIndex`, and `getParentIndex` methods calculate the indices of a node's left child, right child, and parent, respectively. The `swap` method swaps the elements at two positions in the list. 109 | ```java 110 | private int getLeftChildIndex(int index) { 111 | return 2 * index + 1; 112 | } 113 | 114 | private int getRightChildIndex(int index) { 115 | return 2 * index + 2; 116 | } 117 | 118 | private int getParentIndex(int index) { 119 | return (index - 1) / 2; 120 | } 121 | 122 | private void swap(int first, int second) { 123 | E firstEle = list.get(first); 124 | list.set(first, list.get(second)); 125 | list.set(second, firstEle); 126 | } 127 | ``` 128 | 129 | 130 | 131 | The `isEmpty` method checks if the heap is empty, and the `size` method returns the number of elements in the heap. 132 | ```java 133 | public boolean isEmpty() { 134 | return this.list.size() == 0; 135 | } 136 | 137 | public int size() { 138 | return this.list.size(); 139 | } 140 | ``` 141 | 142 | With these methods, our `Heap` class is complete. We can now add elements to the heap, remove elements from the heap, and check if the heap is empty or not. This implementation of a heap is a fundamental component of many efficient algorithms and data structures. Happy coding! 🚀 143 | -------------------------------------------------------------------------------- /16.-pattern-topological-sort-graph/16.1-introduction.md: -------------------------------------------------------------------------------- 1 | # 16.1 Introduction 2 | 3 | -------------------------------------------------------------------------------- /16.-pattern-topological-sort-graph/16.2-topological-sort-medium.md: -------------------------------------------------------------------------------- 1 | # 16.2 Topological Sort (medium) 2 | 3 | [Topological Sort](https://en.wikipedia.org/wiki/Topological\_sorting) of a directed graph (a graph with unidirectional edges) is a linear ordering of its vertices such that for every directed edge (U, V) from vertex `U` to vertex `V`, `U` comes before `V` in the ordering. 4 | 5 | Given a directed graph, find the topological ordering of its vertices. 6 | 7 | **Example 1:** 8 | 9 | ``` 10 | Input: Vertices=4, Edges=[3, 2], [3, 0], [2, 0], [2, 1] 11 | Output: Following are the two valid topological sorts for the given graph: 12 | 1) 3, 2, 0, 1 13 | 2) 3, 2, 1, 0 14 | ``` 15 | 16 | ![](<../.gitbook/assets/image (10).png>) 17 | 18 | **Example 2:** 19 | 20 | ``` 21 | Input: Vertices=5, Edges=[4, 2], [4, 3], [2, 0], [2, 1], [3, 1] 22 | Output: Following are all valid topological sorts for the given graph: 23 | 1) 4, 2, 3, 0, 1 24 | 2) 4, 3, 2, 0, 1 25 | 3) 4, 3, 2, 1, 0 26 | 4) 4, 2, 3, 1, 0 27 | 5) 4, 2, 0, 3, 1 28 | ``` 29 | 30 | **Example 3:** 31 | 32 | ``` 33 | Input: Vertices=7, 34 | Edges=[6, 4], [6, 2], [5, 3], [5, 4], [3, 0], [3, 1], [3, 2], [4, 1] 35 | Output: Following are all valid topological sorts for the given graph: 36 | 1) 5, 6, 3, 4, 0, 1, 2 37 | 2) 6, 5, 3, 4, 0, 1, 2 38 | 3) 5, 6, 4, 3, 0, 2, 1 39 | 4) 6, 5, 4, 3, 0, 1, 2 40 | 5) 5, 6, 3, 4, 0, 2, 1 41 | 6) 5, 6, 3, 4, 1, 2, 0 42 | There are other valid topological ordering of the graph too. 43 | ``` 44 | 45 | **Algorithm** 46 | 47 | 1. Initialize the graph 48 | 2. Build the graph 49 | 3. Find all the sources(i.e, all the vertices with 0 in-degree 50 | 4. For each source, add it to the result and subtract one from all of its children's in-degree & if in-degree of a child become 0 add it to the source 51 | 52 | ```java 53 | public static List sort(int vertices, int[][] edges) { 54 | List result = new ArrayList<>(); 55 | if (vertices <= 0) 56 | return result; 57 | 58 | // 1. Initialize the graph 59 | HashMap inDegree = new HashMap<>(); // count of incoming edges for every vertex 60 | HashMap> graph = new HashMap<>(); // adjacency list graph 61 | for (int i = 0; i < vertices; i++) { 62 | inDegree.put(i, 0); 63 | graph.put(i, new ArrayList()); 64 | } 65 | 66 | // 2. Build the graph 67 | for (int i = 0; i < edges.length; i++) { 68 | int parent = edges[i][0], child = edges[i][1]; 69 | // put the child into it's parent's list 70 | graph.get(parent).add(child); 71 | // increment child's inDegree 72 | inDegree.put(child, inDegree.get(child) + 1); 73 | } 74 | 75 | // 3. Find all sources i.e., all vertices with 0 in-degrees 76 | Queue sources = new LinkedList<>(); 77 | for (Map.Entry entry : inDegree.entrySet()) { 78 | if (entry.getValue() == 0) 79 | sources.add(entry.getKey()); 80 | } 81 | 82 | // 4. For each source, add it to the result and 83 | // subtract one from all of its children's in-degrees 84 | // if a child's in-degree becomes zero, add it to the sources queue 85 | while (!sources.isEmpty()) { 86 | int vertex = sources.poll(); 87 | result.add(vertex); 88 | // get the node's children to decrement their in-degree 89 | List children = graph.get(vertex); 90 | for (int child : children) { 91 | inDegree.put(child, inDegree.get(child) - 1); 92 | if (inDegree.get(child) == 0) 93 | sources.add(child); 94 | } 95 | } 96 | // topological sort is not possible as the graph has a cycle 97 | if (result.size() != vertices) 98 | return new ArrayList<>(); 99 | 100 | return result; 101 | } 102 | ``` 103 | 104 | **Time Complexity** 105 | 106 | In step ‘d’, each vertex will become a source only once and each edge will be accessed and removed once. Therefore, the time complexity of the above algorithm will be O(V+E), where ‘V’ is the total number of vertices and ‘E’ is the total number of edges in the graph. 107 | 108 | **Space Complexity** 109 | 110 | The space complexity will be O(V+E), since we are storing all of the edges for each vertex in an adjacency list. 111 | -------------------------------------------------------------------------------- /16.-pattern-topological-sort-graph/16.3-tasks-scheduling-medium.md: -------------------------------------------------------------------------------- 1 | # 16.3 Tasks Scheduling (medium) 2 | 3 | #### Problem Statement 4 | 5 | There are ‘N’ tasks, labeled from ‘0’ to ‘N-1’. Each task can have some prerequisite tasks which need to be completed before it can be scheduled. Given the number of tasks and a list of prerequisite pairs, find out if it is possible to schedule all the tasks. 6 | 7 | **Example 1:** 8 | 9 | ``` 10 | Input: 11 | Tasks=3, 12 | Prerequisites=[0, 1], [1, 2] 13 | Output: true 14 | Explanation: To execute task '1', task '0' needs to finish first. 15 | Similarly, task '1' needs to finish before '2' can be scheduled. 16 | A possible sceduling of tasks is: [0, 1, 2] 17 | ``` 18 | 19 | **Example 2:** 20 | 21 | ``` 22 | Input: 23 | Tasks=3, 24 | Prerequisites=[0, 1], [1, 2], [2, 0] 25 | Output: false 26 | Explanation: The tasks have cyclic dependency, 27 | therefore they cannot be sceduled. 28 | ``` 29 | 30 | **Example 3:** 31 | 32 | ``` 33 | Input: 34 | Tasks=6, 35 | Prerequisites=[2, 5], [0, 5], [0, 4], [1, 4], [3, 2], [1, 3] 36 | Output: true 37 | Explanation: A possible sceduling of tasks is: [0 1 4 3 2 5] 38 | ``` 39 | 40 | ### Solution 41 | 42 | ```java 43 | public static boolean isSchedulingPossible(int tasks, int[][] prerequisites) { 44 | List res = new ArrayList<>(); 45 | // 1. Initialize the graph 46 | Map> graph = new HashMap<>(); 47 | Map indegree = new HashMap<>(); 48 | 49 | for (int i = 0; i < tasks; i++) { 50 | graph.put(i, new ArrayList<>()); 51 | indegree.put(i, 0); 52 | } 53 | 54 | // 2. Build the graph 55 | for (int i = 0; i < prerequisites.length; i++) { 56 | int start = prerequisites[i][0], end = prerequisites[i][1]; 57 | graph.get(start).add(end); 58 | indegree.put(end, indegree.get(end) + 1); 59 | } 60 | 61 | // 3. Add all the sources(i.e., vertices with in-degree 0) 62 | Queue sources = new LinkedList<>(); 63 | for (Map.Entry entry : indegree.entrySet()) { 64 | if (entry.getValue() == 0) 65 | sources.offer(entry.getKey()); 66 | } 67 | // 4. Process the sources and add it to the result, decrement the in-degree by 68 | // one of all the children 69 | while (!sources.isEmpty()) { 70 | int vertex = sources.poll(); 71 | res.add(vertex); 72 | for (int child : graph.get(vertex)) { 73 | indegree.put(child, indegree.get(child) - 1); 74 | if (indegree.get(child) == 0) 75 | sources.add(child); 76 | } 77 | } 78 | // if res doesn't contain all tasks, there is a cyclic dependency 79 | // between tasks, therefore, we 80 | // will not be able to schedule all tasks 81 | return res.size() == tasks; 82 | } 83 | 84 | ``` 85 | 86 | **Time complexity** 87 | 88 | In step ‘4’, each task can become a source only once and each edge (prerequisite) will be accessed and removed once. Therefore, the time complexity of the above algorithm will be O(V+E), where ‘V’ is the total number of tasks and ‘E’ is the total number of prerequisites. 89 | 90 | **Space complexity** 91 | 92 | The space complexity will be O(V+E), ), since we are storing all of the prerequisites for each task in an adjacency list. 93 | -------------------------------------------------------------------------------- /16.-pattern-topological-sort-graph/16.4-tasks-scheduling-order-medium.md: -------------------------------------------------------------------------------- 1 | # 16.4 Tasks Scheduling Order (medium) 2 | 3 | #### Problem Statement 4 | 5 | There are ‘N’ tasks, labeled from ‘0’ to ‘N-1’. Each task can have some prerequisite tasks which need to be completed before it can be scheduled. Given the number of tasks and a list of prerequisite pairs, write a method to find the ordering of tasks we should pick to finish all tasks. 6 | 7 | **Example 1:** 8 | 9 | ``` 10 | Input: 11 | Tasks=3, 12 | Prerequisites=[0, 1], [1, 2] 13 | Output: [0, 1, 2] 14 | Explanation: To execute task '1', task '0' needs to finish first. 15 | Similarly, task '1' needs to finish before '2' can be scheduled. 16 | A possible scheduling of tasks is: [0, 1, 2] 17 | ``` 18 | 19 | **Example 2:** 20 | 21 | ``` 22 | Input: 23 | Tasks=3, 24 | Prerequisites=[0, 1], [1, 2], [2, 0] 25 | Output: [] 26 | Explanation: The tasks have cyclic dependency, 27 | therefore they cannot be scheduled. 28 | ``` 29 | 30 | **Example 3:** 31 | 32 | ``` 33 | Input: 34 | Tasks=6, 35 | Prerequisites=[2, 5], [0, 5], [0, 4], [1, 4], [3, 2], [1, 3] 36 | Output: [0 1 4 3 2 5] 37 | Explanation: A possible scheduling of tasks is: [0 1 4 3 2 5] 38 | ``` 39 | 40 | ### Solution 41 | 42 | ```java 43 | public static boolean isSchedulingPossible(int tasks, int[][] prerequisites) { 44 | List res = new ArrayList<>(); 45 | // 1. Initialize the graph 46 | Map> graph = new HashMap<>(); 47 | Map indegree = new HashMap<>(); 48 | 49 | for (int i = 0; i < tasks; i++) { 50 | graph.put(i, new ArrayList<>()); 51 | indegree.put(i, 0); 52 | } 53 | 54 | // 2. Build the graph 55 | for (int i = 0; i < prerequisites.length; i++) { 56 | int start = prerequisites[i][0], end = prerequisites[i][1]; 57 | graph.get(start).add(end); 58 | indegree.put(end, indegree.get(end) + 1); 59 | } 60 | 61 | // 3. Add all the sources(i.e., vertices with in-degree 0) 62 | Queue sources = new LinkedList<>(); 63 | for (Map.Entry entry : indegree.entrySet()) { 64 | if (entry.getValue() == 0) 65 | sources.offer(entry.getKey()); 66 | } 67 | // 4. Process the sources and add it to the result, decrement the in-degree by 68 | // one of all the children 69 | while (!sources.isEmpty()) { 70 | int vertex = sources.poll(); 71 | res.add(vertex); 72 | for (int child : graph.get(vertex)) { 73 | indegree.put(child, indegree.get(child) - 1); 74 | if (indegree.get(child) == 0) 75 | sources.add(child); 76 | } 77 | } 78 | // if res doesn't contain all tasks, there is a cyclic dependency between tasks, therefore, we 79 | // will not be able to schedule all tasks 80 | if (res.size() != tasks) 81 | return new ArrayList<>(); 82 | 83 | return res; 84 | } 85 | 86 | ``` 87 | 88 | **Time complexity** 89 | 90 | In step ‘4’, each task can become a source only once and each edge (prerequisite) will be accessed and removed once. Therefore, the time complexity of the above algorithm will be O(V+E), where ‘V’ is the total number of tasks and ‘E’ is the total number of prerequisites. 91 | 92 | **Space complexity** 93 | 94 | The space complexity will be O(V+E), since we are storing all of the prerequisites for each task in an adjacency list. 95 | -------------------------------------------------------------------------------- /16.-pattern-topological-sort-graph/README.md: -------------------------------------------------------------------------------- 1 | # 16. Pattern: Topological Sort (Graph) 2 | 3 | -------------------------------------------------------------------------------- /2.-pattern-two-pointers/2.0-introduction.md: -------------------------------------------------------------------------------- 1 | # 2.0 Introduction 2 | 3 | Two pointer approach is an essential part of a programmer’s toolkit, especially in technical interviews. The name does justice in this case, it involves using two pointers to save time and space. (Here, pointers are basically array indexes). 4 | 5 | > The idea here is to iterate two different parts of the array simultaneously to get the answer faster. 6 | 7 | **Implementation** 8 | 9 | There are primarily two ways of implementing the two-pointer technique: 10 | 11 | **1. One pointer at each end** 12 | 13 | One pointer starts from beginning and other from the end and they proceed towards each other![](https://s3.ap-south-1.amazonaws.com/afteracademy-server-uploads/what-is-the-two-pointer-technique-type1-0f96379aee2ce0dc.png) 14 | 15 | > **Example : In a sorted array, find if a pair exists with a given sum S** 16 | 17 | * **Brute Force Approach:** We could implement a nested loop finding all possible pairs of elements and adding them. 18 | 19 | ```java 20 | bool pairExists(int arr[], int n, int S) 21 | { 22 | for(i = 0 to n-2) 23 | for(j = i+1 to n-1) 24 | if(arr[i] + arr[j] == S) 25 | return true 26 | return false 27 | } 28 | ``` 29 | 30 | Time complexity: O(n²) 31 | 32 | * **Efficient Approach** 33 | 34 | ```java 35 | bool pairExists(int arr[], int n, int S) 36 | { 37 | i = 0 38 | j = n-1 39 | while( i < j) 40 | { 41 | curr_sum = arr[i] + arr[j] 42 | if ( curr_sum == S) 43 | return true 44 | else if ( curr_sum < X ) 45 | i = i + 1 46 | else if ( curr_sum > X ) 47 | j = j - 1 48 | } 49 | return false 50 | } 51 | ``` 52 | 53 | Time Complexity: O(n) 54 | 55 | **2. Different Paces** 56 | 57 | Both pointers start from the beginning but one pointer moves at a faster pace than the other one.![](https://s3.ap-south-1.amazonaws.com/afteracademy-server-uploads/what-is-the-two-pointer-technique-type2-0ff52ece0ef1829c.png) 58 | 59 | > **Example: Find the middle of a linked list** 60 | 61 | * **Brute Force Approach:** We can find the length of the entire linked list in one complete iteration and then iterate till half-length again. 62 | 63 | ```java 64 | ListNode getMiddle(ListNode head) 65 | { 66 | len = 0 67 | ListNode curr = head 68 | while ( curr != NULL ) 69 | { 70 | curr = curr.next 71 | len = len + 1 72 | } 73 | 74 | curr = head 75 | i = 0 76 | while(i != len / 2) 77 | { 78 | curr = curr.next 79 | i = i + 1 80 | } 81 | return curr 82 | } 83 | ``` 84 | 85 | * **Efficient Approach:** Using a two-pointer technique allows us to get the result in one complete iteration 86 | 87 | ```java 88 | ListNode getMiddle(ListNode head) 89 | { 90 | ListNode slow = head 91 | ListNode fast = head 92 | while(fast && fast.next) 93 | { 94 | slow = slow.next 95 | fast = fast.next.next 96 | } 97 | return slow 98 | } 99 | ``` 100 | 101 | **How does this technique save space?** 102 | 103 | There are several situations when a naive implementation of a problem requires additional space thereby increasing the space complexity of the solution. Two-pointer technique often helps to decrease the required space or remove the need for it altogether 104 | 105 | > **Example: Reverse an array** 106 | 107 | * **Naive Solution:** Using a temporary array and fillings elements in it from the end 108 | 109 | ```java 110 | int[] reverseArray(int arr[], int n) 111 | { 112 | int reverse[n] 113 | for ( i = 0 to n-1 ) 114 | reverse[n-i-1] = arr[i] 115 | 116 | return reverse 117 | } 118 | ``` 119 | 120 | Space Complexity: O(n) 121 | 122 | * **Efficient Solution:** Moving pointers towards each other from both ends and swapping elements at their positions 123 | 124 | ```java 125 | int[] reverseArray(int arr[], int n) 126 | { 127 | i = 0 128 | j = n-1 129 | while ( i < j ) 130 | { 131 | swap(arr[i], arr[j]) 132 | i = i + 1 133 | j = j - 1 134 | } 135 | return arr 136 | } 137 | ``` 138 | 139 | **Some popular examples of two pointer approach** 140 | 141 | > **Pseudo code: Merge two sorted array** 142 | 143 | ```java 144 | void mergeSortedArrays(int A[], int B[], int n1, 145 | int n2, int C[]) 146 | { 147 | int i = 0, j = 0, k = 0 148 | while (i **Pseudo code: Partition function in quick sort** 181 | 182 | ```java 183 | int partition (int A[], int l, int r) 184 | { 185 | int pivot = A[r] 186 | int i = l - 1 187 | for (j = l to r-1) 188 | { 189 | if (A[j] < pivot) 190 | { 191 | i++ 192 | swap(A[i], A[j]) 193 | } 194 | } 195 | swap(A[i + 1], A[r]) 196 | return (i + 1) 197 | } 198 | ``` 199 | 200 | Both **** pointers are moving forward in the same direction with different pace i.e. j is incrementing by 1 after each iteration but i is incrementing if (A\[j] < pivot). Time complexity = O(n) 201 | -------------------------------------------------------------------------------- /2.-pattern-two-pointers/2.1-pair-with-target-sum-easy.md: -------------------------------------------------------------------------------- 1 | # 2.1 Pair with Target Sum (easy) 2 | 3 | Given an array of integers `nums` and an integer `target`, return _indices of the two numbers such that they add up to `target`_. 4 | 5 | You may assume that each input would have _**exactly**_** one solution**, and you may not use the _same_ element twice. 6 | 7 | You can return the answer in any order. 8 | 9 | **Example 1:** 10 | 11 | ``` 12 | Input: nums = [2,7,11,15], target = 9 13 | Output: [0,1] 14 | Output: Because nums[0] + nums[1] == 9, we return [0, 1]. 15 | ``` 16 | 17 | **Example 2:** 18 | 19 | ``` 20 | Input: nums = [3,2,4], target = 6 21 | Output: [1,2] 22 | ``` 23 | 24 | **Example 3:** 25 | 26 | ``` 27 | Input: nums = [3,3], target = 6 28 | Output: [0,1] 29 | ``` 30 | 31 | **Constraints:** 32 | 33 | * `2 <= nums.length <= 104` 34 | * `-109 <= nums[i] <= 109` 35 | * `-109 <= target <= 109` 36 | * **Only one valid answer exists.** 37 | 38 | **Follow-up:** Can you come up with an algorithm that is less than `O(n2)` time complexity? 39 | 40 | **Solution:** 41 | 42 | ### **Method 1:** Brute Force 43 | 44 | This approach is straightforward. We can check for every pair in the array and if their sum is equal to the given target, print their indices. This kind of [Brute Force](https://en.wikipedia.org/wiki/Brute-force\_search) solution needs to check every possible pair and number of possible pairs in the array = **n \* (n – 1) / 2.** So, in the worst-case, this approach can be slow. 45 | 46 | ![](<../.gitbook/assets/image (3).png>) 47 | 48 | 1. Run a loop to maintain the first index of the solution in the array 49 | 2. Run another loop to maintain a second index of the solution for every first integer 50 | 3. If at any point, the sum of values of two indices is equal to the target 51 | * Print its indices 52 | 53 | ```java 54 | class Solution { 55 | public int[] twoSum(int[] nums, int target) { 56 | for(int i = 0 ; i < nums.length - 1 ; i++) 57 | for(int j = i + 1 ; j < nums.length ; j++) { 58 | if(nums[i] + nums[j] == target) 59 | return new int[]{i , j}; 60 | } 61 | return new int[]{-1 , -1}; 62 | } 63 | } 64 | ``` 65 | 66 | #### Complexity Analysis: 67 | 68 | **Time Complexity** 69 | 70 | **O(N \* N),** where N = size of the array. As we check for possible pair, and the total number of pairs are: **N \* (N – 1) / 2.** 71 | 72 | **Space complexity** 73 | 74 | **O(1)**. Only constant space for variables is used. 75 | 76 | ### **Method 2: Using Sorting** 77 | 78 | We can get some advantage if the array is already sorted. An approach to solve the problem would be: 79 | 80 | * Sort the given array. 81 | * Start two pointers. Pointer A starts from the beginning of the array, such that it points to the smallest element. Pointer B starts from the end of the array, pointing at the maximum element of the array. 82 | * Now, start a while loop `while(pointer A < pointer B)` 83 | * Get a sum of the elements at `pointerA` and `pointerB`. 84 | * This is where the magic comes in. If the sum is less than `target`, it simply means that we need to add a bigger number. Hence move the `pointerA` one step ahead. Else, we need a smaller number, and we can move the `pointerB` one step backward. 85 | * Somewhere along this iteration, we will get our desired indices. 86 | 87 | ```java 88 | int[] twoSumSorting(int[] nums, int target) { 89 | int[] copyArray = Arrays.copyOf(nums, nums.length); 90 | Arrays.sort(copyArray); 91 | 92 | int head = 0; 93 | int tail = copyArray.length - 1; 94 | int num1 = 0, num2 = 0; 95 | while (head < tail) { 96 | int sum = copyArray[head] + copyArray[tail]; 97 | if (sum < target) { 98 | head++; 99 | } 100 | else if (sum > target) { 101 | tail--; 102 | } else { 103 | num1 = copyArray[head]; 104 | num2 = copyArray[tail]; 105 | break; 106 | } 107 | } 108 | 109 | // Create the result array with indices 110 | int[] result = new int[2]; 111 | for (int i = 0; i < nums.length; i++) { 112 | if (nums[i] == num1) result[0] = i; 113 | if (nums[i] == num2) result[1] = i; 114 | } 115 | return result; 116 | } 117 | ``` 118 | 119 | ![Image showing solution using sorting](https://i2.wp.com/studyalgorithms.com/wp-content/uploads/2021/01/Screenshot-2021-01-10-040252.png?resize=1024%2C672\&ssl=1) 120 | 121 | The above method works in a time complexity of O(n∗log⁡n) because of the sorting step involved. You can use a [quick sort algorithm](https://studyalgorithms.com/array/quick-sort/) to sort your array. 122 | 123 | ### **Method 3: Use Hashing** 124 | 125 | In the previous method, we did not use extra space and achieved a decent time complexity. But, if you can allow yourself to compromise on some space, you can solve this problem in an even efficient manner. 126 | 127 | Instead of finding two numbers whose sum equal to a `target` value, we can think of the problem in an alternative way: 128 | 129 | _**target\_value − first\_number = second\_number**_ 130 | 131 | So, we can develop an algorithm in the following way: 132 | 133 | * Initialize a hash-table that will store the index and the element. 134 | * Start to traverse the array. 135 | * For each element in the array use the above define formula to find the complementing number. 136 | * Look up the complementing number in the hash table. If found, return the `2` indices. 137 | * Else, add the element along with its index to the hash table and proceed with the other elements. 138 | 139 | ![Image showing solution using a hash-table](https://i2.wp.com/studyalgorithms.com/wp-content/uploads/2021/01/Screenshot-2021-01-10-040039.png?resize=1024%2C675\&ssl=1) 140 | 141 | **Implementation:** 142 | 143 | ```java 144 | int[] twoSumHashing(int[] nums, int target) { 145 | 146 | // Create a HashMap 147 | Map map = new HashMap<>(); 148 | 149 | for (int i = 0; i < nums.length; i++) { 150 | 151 | // Get the complement using the target value 152 | int complement = target - nums[i]; 153 | 154 | // Search the hashmap for complement, if found, we got our pair 155 | if (map.containsKey(complement)) { 156 | return new int[]{map.get(complement), i}; 157 | } 158 | 159 | // Put the element in hashmap for subsequent searches. 160 | map.put(nums[i], i); 161 | } 162 | throw new IllegalArgumentException("No two sum solution"); 163 | } 164 | ``` 165 | 166 | _Time Complexity:_ O(n)\ 167 | _Space Complexity:_ O(n) 168 | -------------------------------------------------------------------------------- /2.-pattern-two-pointers/2.10-minimum-window-sort-medium.md: -------------------------------------------------------------------------------- 1 | # 2.10 Minimum Window Sort \(medium\) 2 | 3 | -------------------------------------------------------------------------------- /2.-pattern-two-pointers/2.2-remove-duplicates-easy.md: -------------------------------------------------------------------------------- 1 | # 2.2 Remove Duplicates \(easy\) 2 | 3 | -------------------------------------------------------------------------------- /2.-pattern-two-pointers/2.3-squaring-a-sorted-array-easy.md: -------------------------------------------------------------------------------- 1 | # 2.3 Squaring a Sorted Array \(easy\) 2 | 3 | -------------------------------------------------------------------------------- /2.-pattern-two-pointers/2.4-triplet-sum-to-zero-medium.md: -------------------------------------------------------------------------------- 1 | # 2.4 Triplet Sum to Zero \(medium\) 2 | 3 | -------------------------------------------------------------------------------- /2.-pattern-two-pointers/2.5-triplet-sum-close-to-target-medium.md: -------------------------------------------------------------------------------- 1 | # 2.5 Triplet Sum Close to Target \(medium\) 2 | 3 | -------------------------------------------------------------------------------- /2.-pattern-two-pointers/2.6-triplets-with-smaller-sum-medium.md: -------------------------------------------------------------------------------- 1 | # 2.6 Triplets with Smaller Sum \(medium\) 2 | 3 | -------------------------------------------------------------------------------- /2.-pattern-two-pointers/2.7-subarrays-with-product-less-than-a-target-medium.md: -------------------------------------------------------------------------------- 1 | # 2.7 Subarrays with Product Less than a Target \(medium\) 2 | 3 | -------------------------------------------------------------------------------- /2.-pattern-two-pointers/2.8-dutch-national-flag-problem-medium.md: -------------------------------------------------------------------------------- 1 | # 2.8 Dutch National Flag Problem \(medium\) 2 | 3 | -------------------------------------------------------------------------------- /2.-pattern-two-pointers/2.9-comparing-strings-containing-backspaces-medium.md: -------------------------------------------------------------------------------- 1 | # 2.9 Comparing Strings containing Backspaces \(medium\) 2 | 3 | -------------------------------------------------------------------------------- /2.-pattern-two-pointers/README.md: -------------------------------------------------------------------------------- 1 | # 2. Pattern: Two Pointers 2 | 3 | 4 | 5 | **1. One pointer at each end** 6 | 7 | One pointer starts from beginning and other from the end and they proceed towards each other![](https://s3.ap-south-1.amazonaws.com/afteracademy-server-uploads/what-is-the-two-pointer-technique-type1-0f96379aee2ce0dc.png) 8 | 9 | **2. Different Paces** 10 | 11 | Both pointers start from the beginning but one pointer moves at a faster pace than the other one.![](https://s3.ap-south-1.amazonaws.com/afteracademy-server-uploads/what-is-the-two-pointer-technique-type2-0ff52ece0ef1829c.png) 12 | 13 | -------------------------------------------------------------------------------- /9.-pattern-two-heaps/01.Introduction.md: -------------------------------------------------------------------------------- 1 | # Pattern : Two Heaps 2 | **Two Heaps Pattern: Notes** 3 | 4 | The **Two Heaps Pattern** is a powerful technique used in solving certain algorithmic problems. It involves using two heaps (data structures) to efficiently manage and process data. Here are the key points about this pattern: 5 | 6 | 1. **What is the Two Heaps Pattern?** 7 | - The Two Heaps Pattern uses two heaps simultaneously to solve specific problems. 8 | - It typically involves a **Min Heap** and a **Max Heap**. 9 | - The Min Heap helps find the smallest element, while the Max Heap helps find the largest element. 10 | 11 | 2. **Common Problems Solved Using Two Heaps:** 12 | - **Median of a Stream**: Maintaining a running median of a stream of numbers. 13 | - **Sliding Window Problems**: Efficiently handling sliding windows in arrays or strings. 14 | - **Top K Elements**: Finding the top K elements in a dataset. 15 | - Other problems where you need to track both minimum and maximum values. 16 | 17 | 3. **How to Use Two Heaps:** 18 | - Initialize a Min Heap and a Max Heap. 19 | - Split the input into two parts: one for maximum elements and the other for minimum elements. 20 | - For example, if we have the numbers 2, 6, 8, 10, 12, and 15, we split them into: 21 | - Max heap: 2, 6, 8 22 | - Min heap: 10, 12, 15 23 | - The median can be calculated based on these heaps (average for even numbers, middle element for odd numbers). 24 | 25 | 4. **When to Use Two Heaps:** 26 | - When you can divide the input into two parts, with one part containing maximum elements and the other containing minimum elements. 27 | - Also applicable when two properties are directly proportional, and you want to minimize one while maximizing the other (e.g., capital and profit). 28 | 29 | [Reference: YT Playlist](https://youtube.com/playlist?list=PLYMuCXiM_KMhKHFvfcdyAPHNoVo-qwpKX&feature=shared) 30 | -------------------------------------------------------------------------------- /9.-pattern-two-heaps/02.find-median-from-data-stream.md: -------------------------------------------------------------------------------- 1 | # 295. Find Median from Data Stream 2 | [Leetcode](https://leetcode.com/problems/find-median-from-data-stream/) 3 | 4 | ## Problem 5 | 6 | The **median** is the middle value in an ordered integer list. If the size of the list is even, there is no middle value, and the median is the mean of the two middle values. 7 | 8 | - For example, for `arr = [2,3,4]`, the median is `3`. 9 | - For example, for `arr = [2,3]`, the median is `(2 + 3) / 2 = 2.5`. 10 | 11 | Implement the `MedianFinder` class: 12 | 13 | - `MedianFinder()` initializes the `MedianFinder` object. 14 | - `void addNum(int num)` adds the integer `num` from the data stream to the data structure. 15 | - `double findMedian()` returns the median of all elements so far. Answers within `105` of the actual answer will be accepted. 16 | 17 | **Example 1:** 18 | 19 | ``` 20 | Input 21 | ["MedianFinder", "addNum", "addNum", "findMedian", "addNum", "findMedian"] 22 | [[], [1], [2], [], [3], []] 23 | Output 24 | [null, null, null, 1.5, null, 2.0] 25 | 26 | Explanation 27 | MedianFinder medianFinder = new MedianFinder(); 28 | medianFinder.addNum(1); // arr = [1] 29 | medianFinder.addNum(2); // arr = [1, 2] 30 | medianFinder.findMedian(); // return 1.5 (i.e., (1 + 2) / 2) 31 | medianFinder.addNum(3); // arr[1, 2, 3] 32 | medianFinder.findMedian(); // return 2.0 33 | 34 | ``` 35 | 36 | **Constraints:** 37 | 38 | - `105 <= num <= 105` 39 | - There will be at least one element in the data structure before calling `findMedian`. 40 | - At most `5 * 104` calls will be made to `addNum` and `findMedian`. 41 | 42 | **Follow up:** 43 | 44 | - If all integer numbers from the stream are in the range `[0, 100]`, how would you optimize your solution? 45 | - If `99%` of all integer numbers from the stream are in the range `[0, 100]`, how would you optimize your solution? 46 | 47 | ## Approach 48 | 49 | The code implements a data structure that supports the following operations: **`addNum`** and **`findMedian`**. It uses two heaps to keep track of the median of a stream of numbers. 50 | 51 | 1. **`addNum(int num)`**: This function adds a number into the data structure. It uses two heaps, **`maxHeap`** and **`minHeap`**. The **`maxHeap`** stores the smaller half of the numbers, and **`minHeap`** stores the larger half. The top of **`maxHeap`** is always less than or equal to the top of **`minHeap`**. This way, the median is always at the top of one of the heaps. 52 | 2. **`findMedian()`**: This function returns the median of all elements added so far. If the sizes of both heaps are equal, the median is the average of the tops of both heaps. Otherwise, the median is the top of the heap that has one extra element. 53 | 54 | ## Solution 55 | 56 | ```java 57 | class MedianFinder { 58 | // minHeap to store the larger half of the input numbers 59 | PriorityQueue minHeap; 60 | // maxHeap to store the smaller half of the input numbers 61 | PriorityQueue maxHeap; 62 | 63 | public MedianFinder() { 64 | // Initialize minHeap as a min heap 65 | minHeap = new PriorityQueue<>(); 66 | // Initialize maxHeap as a max heap 67 | maxHeap = new PriorityQueue<>(Collections.reverseOrder()); 68 | } 69 | 70 | public void addNum(int num) { 71 | // If maxHeap is empty or num is less than or equal to the top of maxHeap, add num to maxHeap 72 | if(maxHeap.isEmpty() || maxHeap.peek() >= num) { 73 | maxHeap.offer(num); 74 | } else { 75 | // Otherwise, add num to minHeap 76 | minHeap.offer(num); 77 | } 78 | 79 | // If the size difference between maxHeap and minHeap is more than 1, balance the heaps 80 | if(Math.abs(maxHeap.size()-minHeap.size()) > 1) { 81 | if(maxHeap.size() > minHeap.size()) 82 | // If maxHeap has more elements, remove the top of maxHeap and add it to minHeap 83 | minHeap.offer(maxHeap.poll()); 84 | else 85 | // If minHeap has more elements, remove the top of minHeap and add it to maxHeap 86 | maxHeap.offer(minHeap.poll()); 87 | } 88 | } 89 | 90 | public double findMedian() { 91 | // If maxHeap has more elements, the median is the top of maxHeap 92 | if(maxHeap.size()>minHeap.size()) 93 | return maxHeap.peek(); 94 | // If minHeap has more elements, the median is the top of minHeap 95 | if(minHeap.size()>maxHeap.size()) 96 | return minHeap.peek(); 97 | // If both heaps have the same number of elements, the median is the average of the tops of both heaps 98 | return (minHeap.peek()+maxHeap.peek())/2.0; 99 | } 100 | } 101 | ``` 102 | 103 | ## Complexities 104 | 105 | - **Time Complexity**: The time complexity for adding a number is O(log n) because we are inserting into a heap, and the time complexity for finding the median is O(1) because we can directly access the top of the heap. 106 | - **Space Complexity:** The space complexity is O(n) because in the worst case, we have to store all the numbers in the heaps. 107 | -------------------------------------------------------------------------------- /9.-pattern-two-heaps/04.Maximiza-Capital.md: -------------------------------------------------------------------------------- 1 | # 502. IPO 2 | [Leetcode](https://leetcode.com/problems/ipo/) 3 | 4 | ## Problem 5 | 6 | Suppose LeetCode will start its **IPO** soon. In order to sell a good price of its shares to Venture Capital, LeetCode would like to work on some projects to increase its capital before the **IPO**. Since it has limited resources, it can only finish at most `k` distinct projects before the **IPO**. Help LeetCode design the best way to maximize its total capital after finishing at most `k` distinct projects. 7 | 8 | You are given `n` projects where the `ith` project has a pure profit `profits[i]` and a minimum capital of `capital[i]` is needed to start it. 9 | 10 | Initially, you have `w` capital. When you finish a project, you will obtain its pure profit and the profit will be added to your total capital. 11 | 12 | Pick a list of **at most** `k` distinct projects from given projects to **maximize your final capital**, and return *the final maximized capital*. 13 | 14 | The answer is guaranteed to fit in a 32-bit signed integer. 15 | 16 | **Example 1:** 17 | 18 | ``` 19 | Input: k = 2, w = 0, profits = [1,2,3], capital = [0,1,1] 20 | Output: 4 21 | Explanation: Since your initial capital is 0, you can only start the project indexed 0. 22 | After finishing it you will obtain profit 1 and your capital becomes 1. 23 | With capital 1, you can either start the project indexed 1 or the project indexed 2. 24 | Since you can choose at most 2 projects, you need to finish the project indexed 2 to get the maximum capital. 25 | Therefore, output the final maximized capital, which is 0 + 1 + 3 = 4. 26 | 27 | ``` 28 | 29 | **Example 2:** 30 | 31 | ``` 32 | Input: k = 3, w = 0, profits = [1,2,3], capital = [0,1,2] 33 | Output: 6 34 | 35 | ``` 36 | 37 | **Constraints:** 38 | 39 | - `1 <= k <= 105` 40 | - `0 <= w <= 109` 41 | - `n == profits.length` 42 | - `n == capital.length` 43 | - `1 <= n <= 105` 44 | - `0 <= profits[i] <= 104` 45 | - `0 <= capital[i] <= 109` 46 | 47 | ## Approach 48 | 49 | To solve this problem, we can use two priority queues (heaps): 50 | 51 | 1. A **min heap** (`minCapitalHeap`) to keep track of projects sorted by their minimum capital requirements. 52 | 2. A **max heap** (`maxProfitHeap`) to store projects sorted by their profits in descending order. 53 | 54 | The algorithm proceeds as follows: 55 | 56 | 1. Initialize `currentCapital`with the initial capital **`w`**. 57 | 2. Add all projects to `minCapitalHeap`. 58 | 3. For each of the **`k`** iterations: 59 | - While `minCapitalHeap`is not empty and the project’s minimum capital requirement is less than or equal to `currentCapital`, move the project from `minCapitalHeap` to `maxProfitHeap`. 60 | - If `maxProfitHeap`is empty, break the loop. 61 | - Otherwise, select the project with the highest profit from `maxProfitHeap`, add its profit to `currentCapital`, and remove it from `maxProfitHeap`. 62 | 63 | ## Solution 64 | 65 | ```java 66 | class Solution { 67 | public int findMaximizedCapital(int k, int w, int[] profits, int[] capital) { 68 | // Min heap to track projects by their minimum capital requirements 69 | PriorityQueue minCapitalHeap= new PriorityQueue<>((i, j) -> capital[i] - capital[j]); 70 | 71 | // Max heap to store projects sorted by their profits in descending order 72 | PriorityQueue maxProfitHeap= new PriorityQueue<>((i, j) -> profits[j] - profits[i]); 73 | 74 | // Initialize current capital with the initial amount 75 | int currentCapital= w; 76 | 77 | // Add all projects to the minCapitalHeap 78 | for (int i = 0; i < capital.length; i++) 79 | minCapitalHeap.offer(i); 80 | 81 | // Select at most k distinct projects 82 | for (int i = 0; i < k; i++) { 83 | // Move projects from minCapitalHeap to maxProfitHeap if their capital requirement is met 84 | while (!minCapHeap.isEmpty() && capital[minCapitalHeap.peek()] <= currentCapital) 85 | maxProfitHeap.offer(minCapitalHeap.poll()); 86 | 87 | // If no profitable projects left, exit the loop 88 | if (maxProHeap.isEmpty()) break; 89 | 90 | // Select the project with the highest profit, update current capital 91 | currentCapital+= profits[maxProfitHeap.poll()]; 92 | } 93 | 94 | return currentCapital; 95 | } 96 | } 97 | ``` 98 | 99 | ## Complexities 100 | 101 | - Time complexity: O(n log n) due to the heap operations. 102 | - Space complexity: O(n) for the heaps. 103 | -------------------------------------------------------------------------------- /9.-pattern-two-heaps/05.Maximum-Sum-Combinations.md: -------------------------------------------------------------------------------- 1 | # Maximum Sum Combinations [Medium] 2 | [InterviewBit](https://www.interviewbit.com/problems/maximum-sum-combinations/) 3 | 4 | ## Problem 5 | 6 | Given two equally sized 1-D arrays **A, B** containing **N** integers each. 7 | 8 | A **sum combination** is made by adding one element from array **A** and another element of array **B**. 9 | 10 | Return the **maximum C valid sum combinations** from all the possible sum combinations. 11 | 12 | **Problem Constraints** 13 | 14 | 1 <= N <= 105 15 | 16 | 1 <= A[i] <= 105 17 | 18 | 1 <= C <= N 19 | 20 | **Input Format** 21 | 22 | First argument is an one-dimensional integer array **A** of size **N**. 23 | 24 | Second argument is an one-dimensional integer array **B** of size **N**. 25 | 26 | Third argument is an integer **C**. 27 | 28 | **Output Format** 29 | 30 | Return a one-dimensional integer array of size **C** denoting the top C maximum sum combinations. 31 | 32 | **NOTE:** 33 | 34 | The returned array must be sorted in non-increasing order. 35 | 36 | **Example Input** 37 | 38 | Input 1: 39 | 40 | ``` 41 | A = [3, 2] 42 | B = [1, 4] 43 | C = 2 44 | 45 | ``` 46 | 47 | Input 2: 48 | 49 | ``` 50 | A = [1, 4, 2, 3] 51 | B = [2, 5, 1, 6] 52 | C = 4 53 | 54 | ``` 55 | 56 | **Example Output** 57 | 58 | Output 1: 59 | 60 | ``` 61 | [7, 6] 62 | 63 | ``` 64 | 65 | Output 1: 66 | 67 | ``` 68 | [10, 9, 9, 8] 69 | 70 | ``` 71 | 72 | **Example Explanation** 73 | 74 | Explanation 1: 75 | 76 | ``` 77 | 7 (A : 3) + (B : 4) 78 | 6 (A : 2) + (B : 4) 79 | 80 | ``` 81 | 82 | Explanation 2: 83 | 84 | ``` 85 | 10 (A : 4) + (B : 6) 86 | 9 (A : 4) + (B : 5) 87 | 9 (A : 3) + (B : 6) 88 | 8 (A : 3) + (B : 5) 89 | ``` 90 | 91 | ## Approach 92 | 93 | The approach is to use a max heap to store the sum of pairs along with the indices of the elements from both arrays A and B which make up the sum. The max heap is ordered by the sum. We insert only the pair of indices into the heap along with their sum and also insert the pair into a hash set. Then we pop heap to get the current largest sum, and then insert the next two possible pairs into the max heap but only if the pair is not already present inside the heap. The next two pairs are made by the two possible combinations of indices **`(i+1, j)`** and **`(i, j+1)`** where **`(i, j)`** are the current pair of indices. 94 | 95 | ## Solution 96 | 97 | ```java 98 | public class Solution { 99 | public ArrayList solve(ArrayList A, ArrayList B, int C) { 100 | // Sort both lists in descending order 101 | Collections.sort(A, Collections.reverseOrder()); 102 | Collections.sort(B, Collections.reverseOrder()); 103 | 104 | // Initialize a max heap to store the sum of pairs (Pair.i, Pair.j) and the pair 105 | PriorityQueue pq = new PriorityQueue<>(Collections.reverseOrder()); 106 | // Add the largest possible pair to the max heap 107 | pq.add(new Pair(0, 0, A.get(0) + B.get(0))); 108 | 109 | // Hash set is used to record pairs that have already been inserted into the max heap 110 | HashSet set = new HashSet<>(); 111 | set.add(new Pair(0, 0)); 112 | 113 | // Initialize result list 114 | ArrayList result = new ArrayList<>(); 115 | // Loop for the top C elements 116 | for (int count = 0; count < C; count++) { 117 | // Pop the heap to get the current largest pair sum and its indices 118 | Pair p = pq.poll(); 119 | // Add the current largest pair sum to the result list 120 | result.add(p.sum); 121 | 122 | // Get the indices of the current largest pair 123 | int i = p.i; 124 | int j = p.j; 125 | 126 | // Next possible candidate for max heap is obtained by increasing the element of the first list 127 | Pair temp = new Pair(i+1, j); 128 | // If the pair is not already present inside the map, insert that into max heap and hash set 129 | if (!set.contains(temp)) { 130 | pq.add(new Pair(i+1, j, A.get(i+1) + B.get(j))); 131 | set.add(temp); 132 | } 133 | 134 | // Next possible candidate for max heap is obtained by increasing the element of the second list 135 | temp = new Pair(i, j+1); 136 | // If the pair is not already present inside the map, insert that into max heap and hash set 137 | if (!set.contains(temp)) { 138 | pq.add(new Pair(i, j+1, A.get(i) + B.get(j+1))); 139 | set.add(temp); 140 | } 141 | } 142 | 143 | // Return the top C pair sums 144 | return result; 145 | } 146 | } 147 | 148 | // Pair class to store the pair indices and its sum 149 | class Pair implements Comparable { 150 | int i, j, sum; 151 | Pair(int i, int j, int sum) { 152 | this.i = i; 153 | this.j = j; 154 | this.sum = sum; 155 | } 156 | 157 | Pair(int i, int j) { 158 | this.i = i; 159 | this.j = j; 160 | } 161 | 162 | // Overriding the compareTo method to sort by sum 163 | @Override 164 | public int compareTo(Pair o) { 165 | return this.sum - o.sum; 166 | } 167 | 168 | // Overriding equals method for Pair 169 | @Override 170 | public boolean equals(Object o) { 171 | if (this == o) return true; 172 | if (o == null || getClass() != o.getClass()) return false; 173 | Pair pair = (Pair) o; 174 | return i == pair.i && j == pair.j; 175 | } 176 | 177 | // Overriding hashCode method for Pair 178 | @Override 179 | public int hashCode() { 180 | return Objects.hash(i, j); 181 | } 182 | } 183 | ``` 184 | 185 | ## Complexities 186 | 187 | - Time Complexity: The time complexity for this approach is **`O(C log C)`** because we remove and insert an element into the heap C times and both these operations take **`O(log C)`** time. 188 | - Space Complexity: The space complexity for this approach is **`O(C)`** because in the worst case our heap and hash set can contain upto C number of pairs. 189 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | . 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 dipjul 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Coding Interview Patterns 2 | 3 | ## Coding Interview Patterns 4 | 5 | ### 1. Pattern: Two Pointers 6 | 7 | 1. Introduction 8 | 2. Pair with Target Sum (easy) [LeetCode](https://leetcode.com/problems/two-sum/) 9 | 3. Remove Duplicates (easy) [LeetCode](https://leetcode.com/problems/remove-duplicates-from-sorted-list/) [LeetCode](https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/) [LeetCode](https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii/) [LeetCode](https://leetcode.com/problems/find-the-duplicate-number/) [LeetCode](https://leetcode.com/problems/duplicate-zeros/) 10 | 4. Squaring a Sorted Array (easy) [LeetCode](https://leetcode.com/problems/squares-of-a-sorted-array/) 11 | 5. Triplet Sum to Zero (medium) [LeetCode](https://leetcode.com/problems/3sum/) 12 | 6. Triplet Sum Close to Target (medium) [LeetCode](https://leetcode.com/problems/3sum-closest/) 13 | 7. Triplets with Smaller Sum (medium) [LintCode](https://www.lintcode.com/problem/3sum-smaller/description) 14 | 8. Subarrays with Product Less than a Target (medium) [LeetCode](https://leetcode.com/problems/subarray-product-less-than-k/) 15 | 9. Dutch National Flag Problem (medium) [CoderByte](https://coderbyte.com/algorithm/dutch-national-flag-sorting-problem) 16 | 10. Problem Challenge 1: Quadruple Sum to Target (medium) [Leetcode](https://leetcode.com/problems/4sum/) 17 | 11. Problem Challenge 2: Comparing Strings containing Backspaces (medium) [Leetcode](https://leetcode.com/problems/backspace-string-compare/) 18 | 12. Problem Challenge 3: Minimum Window Sort (medium) [Leetcode](https://leetcode.com/problems/shortest-unsorted-continuous-subarray/) [Ideserve](https://www.ideserve.co.in/learn/minimum-length-subarray-sorting-which-results-in-sorted-array) 19 | 20 | ### 2. Pattern: Fast & Slow pointers 21 | 22 | 1. Introduction [emre.me](https://emre.me/coding-patterns/fast-slow-pointers/) 23 | 2. LinkedList Cycle (easy) [Leetcode](https://leetcode.com/problems/linked-list-cycle/) 24 | 3. Start of LinkedList Cycle (medium) [Leetcode](https://leetcode.com/problems/linked-list-cycle-ii/) 25 | 4. Happy Number (medium) [Leetcode](https://leetcode.com/problems/happy-number/) 26 | 5. Middle of the LinkedList (easy) [Leetcode](https://leetcode.com/problems/middle-of-the-linked-list/) 27 | 6. Problem Challenge 1: Palindrome LinkedList (medium) [Leetcode](https://leetcode.com/problems/palindrome-linked-list/) 28 | 7. Problem Challenge 2: Rearrange a LinkedList (medium) [Leetcode](https://leetcode.com/problems/reorder-list/) 29 | 8. Problem Challenge 3: Cycle in a Circular Array (hard) [Leetcode](https://leetcode.com/problems/circular-array-loop/) 30 | 31 | ### 3. Pattern: Sliding Window 32 | 33 | 1. Introduction 34 | 2. Maximum Sum Subarray of Size K (easy) 35 | 3. Smallest Subarray with a given sum (easy) [Educative.io](https://www.educative.io/courses/grokking-the-coding-interview/7XMlMEQPnnQ) 36 | 4. Longest Substring with K Distinct Characters (medium) [Educative.io](https://www.educative.io/courses/grokking-the-coding-interview/YQQwQMWLx80) 37 | 5. Fruits into Baskets (medium) [LeetCode](https://leetcode.com/problems/fruit-into-baskets/) 38 | 6. No-repeat Substring (hard) [LeetCode](https://leetcode.com/problems/longest-substring-without-repeating-characters/) 39 | 7. Longest Substring with Same Letters after Replacement (hard) [LeetCode](https://leetcode.com/problems/longest-repeating-character-replacement/) 40 | 8. Longest Subarray with Ones after Replacement (hard) [LeetCode](https://leetcode.com/problems/max-consecutive-ones-iii/) 41 | 9. Problem Challenge 1: Permutation in a String (hard) [Leetcode](https://leetcode.com/problems/permutation-in-string/) 42 | 10. Problem Challenge 2: String Anagrams (hard) [Leetcode](https://leetcode.com/problems/find-all-anagrams-in-a-string/) 43 | 11. Problem Challenge 3: Smallest Window containing Substring (hard) [Leetcode](https://leetcode.com/problems/minimum-window-substring/) 44 | 12. Problem Challenge 4: Words Concatenation (hard) [Leetcode](https://leetcode.com/problems/substring-with-concatenation-of-all-words/) 45 | 46 | ### 4. Pattern: Merge Intervals 47 | 48 | 1. Introduction [Educative.io](https://www.educative.io/courses/grokking-the-coding-interview/3YVYvogqXpA) 49 | 2. Merge Intervals (medium) [Educative.io](https://www.educative.io/courses/grokking-the-coding-interview/3jyVPKRA8yx) 50 | 3. Insert Interval (medium) [Educative.io](https://www.educative.io/courses/grokking-the-coding-interview/3jKlyNMJPEM) 51 | 4. Intervals Intersection (medium) [Educative.io](https://www.educative.io/courses/grokking-the-coding-interview/JExVVqRAN9D) 52 | 5. Conflicting Appointments (medium) [Geeksforgeeks](https://www.geeksforgeeks.org/check-if-any-two-intervals-overlap-among-a-given-set-of-intervals/) 53 | 6. Problem Challenge 1: Minimum Meeting Rooms (hard) [Lintcode](https://www.lintcode.com/problem/meeting-rooms-ii/) 54 | 7. Problem Challenge 2: Maximum CPU Load (hard) [Geeksforgeeks](https://www.geeksforgeeks.org/maximum-cpu-load-from-the-given-list-of-jobs/) 55 | 8. Problem Challenge 3: Employee Free Time (hard) [CoderTrain](https://www.codertrain.co/employee-free-time) 56 | 57 | ### 5. Pattern: Cyclic Sort 58 | 59 | 1. Introduction [emre.me](https://emre.me/coding-patterns/cyclic-sort/) 60 | 2. Cyclic Sort (easy) [Geeksforgeeks](https://www.geeksforgeeks.org/sort-an-array-which-contain-1-to-n-values-in-on-using-cycle-sort/) 61 | 3. Find the Missing Number (easy) [Leetcode](https://leetcode.com/problems/missing-number/) 62 | 4. Find all Missing Numbers (easy) [Leetcode](https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/) 63 | 5. Find the Duplicate Number (easy) [Leetcode](https://leetcode.com/problems/find-the-duplicate-number/) 64 | 6. Find all Duplicate Numbers (easy) [Leetcode](https://leetcode.com/problems/find-all-duplicates-in-an-array/) 65 | 7. Problem Challenge 1: Find the Corrupt Pair (easy) [TheCodingSimplified](https://thecodingsimplified.com/find-currupt-pair/) 66 | 8. Problem Challenge 2: Find the Smallest Missing Positive Number (medium) [Leetcode](https://leetcode.com/problems/first-missing-positive/) 67 | 9. Problem Challenge 3: Find the First K Missing Positive Numbers (hard) [TheCodingSimplified](https://thecodingsimplified.com/find-the-first-k-missing-positive-number/) 68 | 69 | ### 6. Pattern: In-place Reversal of a LinkedList 70 | 71 | 1. Introduction [emre.me](https://emre.me/coding-patterns/in-place-reversal-of-a-linked-list/) 72 | 2. Reverse a LinkedList (easy) [Leetcode](https://leetcode.com/problems/reverse-linked-list/) 73 | 3. Reverse a Sub-list (medium) [Leetcode](https://leetcode.com/problems/reverse-linked-list-ii/) 74 | 4. Reverse every K-element Sub-list (medium) [Leetcode](https://leetcode.com/problems/reverse-nodes-in-k-group/) 75 | 5. Problem Challenge 1: Reverse alternating K-element Sub-list (medium) [Geeksforgeeks](https://www.geeksforgeeks.org/reverse-alternate-k-nodes-in-a-singly-linked-list/) 76 | 6. Problem Challenge 2: Rotate a LinkedList (medium) [Leetcode](https://leetcode.com/problems/rotate-list/) 77 | 78 | ### 7. Pattern: Stack 79 | 80 | 1. Introduction to Stack (Operations, Implementation, Applications) 81 | 2. Balanced Parentheses [Leetcode](https://leetcode.com/problems/valid-parentheses/description/) 82 | 3. Reverse a String 83 | 4. Decimal to Binary Conversion 84 | 5. Next Greater Element [Leetcode - I](https://leetcode.com/problems/next-greater-element-i/) [Leetcode -II](https://leetcode.com/problems/next-greater-element-ii/) [Leetcode - III (Hard)](https://leetcode.com/problems/next-greater-element-iv/) 85 | 6. Sorting a Stack 86 | 7. Simplify Path [Leetcode](https://leetcode.com/problems/simplify-path/) 87 | 88 | ### 8. Pattern: Monotonic Stack 89 | 90 | 1. Introduction to Monotonic Stack 91 | 2. Next Greater Element (easy) [Leetcode - I](https://leetcode.com/problems/next-greater-element-i/) [Leetcode -II](https://leetcode.com/problems/next-greater-element-ii/) [Leetcode - III (Hard)](https://leetcode.com/problems/next-greater-element-iv/) 92 | 3. Daily Temperatures (easy) [Leetcode](https://leetcode.com/problems/daily-temperatures/) 93 | 4. Remove Nodes From Linked List (easy) [Leetcode](https://leetcode.com/problems/remove-nodes-from-linked-list/) 94 | 5. Remove All Adjacent Duplicates In String (easy) [Leetcode](https://leetcode.com/problems/remove-all-adjacent-duplicates-in-string/) 95 | 6. Remove All Adjacent Duplicates in String II (medium) [Leetcode](https://leetcode.com/problems/remove-all-adjacent-duplicates-in-string-ii/) 96 | 7. Remove K Digits (hard) [Leetcode](https://leetcode.com/problems/remove-k-digits/) 97 | 98 | ### 9. Pattern: Hash Maps 99 | 100 | 1. Introduction (Hashing, Hash Tables, Issues) 101 | 2. First Non-repeating Character (easy) [Leetcode](https://leetcode.com/problems/first-unique-character-in-a-string/) 102 | 3. Largest Unique Number (easy) [Leetcode+](https://leetcode.com/problems/largest-unique-number/) 103 | 4. Maximum Number of Balloons (easy) [Leetcode](https://leetcode.com/problems/maximum-number-of-balloons/) 104 | 5. Longest Palindrome(easy) [Leetcode](https://leetcode.com/problems/longest-palindrome/) 105 | 6. Ransom Note (easy) [Leetcode](https://leetcode.com/problems/ransom-note/) 106 | 107 | ### 10. Pattern: Tree Breadth First Search 108 | 109 | 1. Introduction 110 | 2. Binary Tree Level Order Traversal (easy) [Leetcode](https://leetcode.com/problems/binary-tree-level-order-traversal/) 111 | 3. Reverse Level Order Traversal (easy) [Leetcode](https://leetcode.com/problems/binary-tree-level-order-traversal-ii/) 112 | 4. Zigzag Traversal (medium) [Leetcode](https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/) 113 | 5. Level Averages in a Binary Tree (easy) [Leetcode](https://leetcode.com/problems/average-of-levels-in-binary-tree/) 114 | 6. Minimum Depth of a Binary Tree (easy) [Leetcode](https://leetcode.com/problems/minimum-depth-of-binary-tree/) 115 | 7. Maximum Depth of a Binary Tree (easy) [Leetcode](https://leetcode.com/problems/maximum-depth-of-binary-tree/) 116 | 8. Level Order Successor (easy) [Geeksforgeeks](https://www.geeksforgeeks.org/level-order-successor-of-a-node-in-binary-tree/) 117 | 9. Connect Level Order Siblings (medium) [Leetcode](https://leetcode.com/problems/populating-next-right-pointers-in-each-node/) 118 | 10. Problem Challenge 1: Connect All Level Order Siblings (medium) [Educative](https://www.educative.io/m/connect-all-siblings) 119 | 11. Problem Challenge 2: Right View of a Binary Tree (easy) [Leetcode](https://leetcode.com/problems/binary-tree-right-side-view/) 120 | 121 | 122 | ### 11. Pattern: Tree Depth First Search 123 | 124 | 1. Introduction 125 | 2. Binary Tree Path Sum (easy) [Leetcode](https://leetcode.com/problems/path-sum/) 126 | 3. All Paths for a Sum (medium) [Leetcode](https://leetcode.com/problems/path-sum-iii/) 127 | 4. Sum of Path Numbers (medium) [Leetcode](https://leetcode.com/problems/sum-root-to-leaf-numbers/) 128 | 5. Path With Given Sequence (medium) [Geeksforgeeks](https://www.geeksforgeeks.org/check-root-leaf-path-given-sequence/) 129 | 6. Count Paths for a Sum (medium) [Leetcode](https://leetcode.com/problems/path-sum-iii/) 130 | 7. Problem Challenge 1: Tree Diameter (medium) [Leetcode](https://leetcode.com/problems/diameter-of-binary-tree/) 131 | 8. Problem Challenge 2: Path with Maximum Sum (hard) [Leetcode](https://leetcode.com/problems/binary-tree-maximum-path-sum/) 132 | 133 | 134 | ### 12. Pattern: Graphs 135 | 136 | 1. Introduction to Graph (Representations, Abstract Data Type (ADT)) 137 | 2. Graph Traversal: Depth First Search(DFS) 138 | 3. Graph Traversal: Breadth First Search (BFS) 139 | 4. Find if Path Exists in Graph(easy) [Leetcode](https://leetcode.com/problems/find-if-path-exists-in-graph/) 140 | 5. Number of Provinces (medium) [Leetcode](https://leetcode.com/problems/number-of-provinces/) 141 | 6. Minimum Number of Vertices to Reach All Nodes(medium) [Leetcode](https://leetcode.com/problems/minimum-number-of-vertices-to-reach-all-nodes/) 142 | 143 | 144 | ### 13. Pattern: Island (Matrix traversal) 145 | 146 | 1. Introduction to Island Pattern 147 | 2. Number of Islands (easy) [Leetcode](https://leetcode.com/problems/number-of-islands/) 148 | 3. Biggest Island (easy) 149 | 4. Flood Fill (easy) [Leetcode](https://leetcode.com/problems/flood-fill/) 150 | 5. Number of Closed Islands (easy) [Leetcode](https://leetcode.com/problems/number-of-closed-islands/) 151 | 6. Problem Challenge 1 (easy) 152 | 7. Problem Challenge 2 (medium) 153 | 8. Problem Challenge 3 (medium) 154 | 155 | 156 | ### 14. Pattern: Two Heaps 157 | 158 | 1. Introduction 159 | 2. Find the Median of a Number Stream (medium) [Leetcode](https://leetcode.com/problems/find-median-from-data-stream/) 160 | 3. Sliding Window Median (hard) [Leetcode](https://leetcode.com/problems/sliding-window-median/) 161 | 4. Maximize Capital (hard) [Leetcode](https://leetcode.com/problems/ipo/) 162 | 163 | 5. **Maximum Sum Combinations* (medium) [InterviewBit](https://www.interviewbit.com/problems/maximum-sum-combinations/) 164 | 165 | 166 | ### 15. Pattern: Subsets 167 | 168 | 1. Introduction [Educative.io](https://www.educative.io/courses/grokking-the-coding-interview/R87WmWYrELz) 169 | 2. Subsets (easy) [Educative.io](https://www.educative.io/courses/grokking-the-coding-interview/gx2OqlvEnWG) 170 | 3. Subsets With Duplicates (easy) [Educative.io](https://www.educative.io/courses/grokking-the-coding-interview/7npk3V3JQNr) 171 | 4. Permutations (medium) [Educative.io](https://www.educative.io/courses/grokking-the-coding-interview/B8R83jyN3KY) 172 | 5. String Permutations by changing case (medium) 173 | 6. Balanced Parentheses (hard) 174 | 7. Unique Generalized Abbreviations (hard) [Leetcode](https://leetcode.com/problems/generalized-abbreviation/) 175 | 176 | 177 | ### [16. Pattern: Modified Binary Search](binary-search/BinarySearch.md) 178 | 179 | 1. Introduction [Complete Pattern Theory and Solutions](binary-search/BinarySearch.md) 180 | 2. Order-agnostic Binary Search (easy) [Geeksforgeeks](https://www.geeksforgeeks.org/order-agnostic-binary-search/) 181 | 3. Ceiling of a Number (medium) [Geeksforgeeks-Ceil](https://www.geeksforgeeks.org/ceiling-in-a-sorted-array/) [Geeksforgeeks-Floor](https://www.geeksforgeeks.org/floor-in-a-sorted-array/) 182 | 4. Next Letter (medium) [Leetcode](https://leetcode.com/problems/find-smallest-letter-greater-than-target/) 183 | 5. Number Range (medium) [Leetcode](https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/) 184 | 6. Search in a Sorted Infinite Array (medium) [Leetcode](https://www.geeksforgeeks.org/find-position-element-sorted-array-infinite-numbers/) 185 | 7. Minimum Difference Element (medium): Find the floor & ceil take the difference, minimum would be the ans 186 | 8. Bitonic Array Maximum (easy) [Geeksforgeeks](https://www.geeksforgeeks.org/find-the-maximum-element-in-an-array-which-is-first-increasing-and-then-decreasing/) 187 | 9. Problem Challenge 1: Search Bitonic Array (medium) [Leetcode](https://leetcode.com/problems/find-in-mountain-array/) 188 | 10. Problem Challenge 2: Search in Rotated Array (medium) [Leetcode](https://leetcode.com/problems/search-in-rotated-sorted-array/) 189 | 11. Problem Challenge 3: Rotation Count (medium) [Geeksforgeeks](https://www.geeksforgeeks.org/find-rotation-count-rotated-sorted-array/) 190 | 12. *Search a 2D Matrix (medium) [Leetcode](https://leetcode.com/problems/search-a-2d-matrix/) 191 | 13. *Minimum Number of Days to Make m Bouquets (medium) [Leetcode](https://leetcode.com/problems/minimum-number-of-days-to-make-m-bouquets/) 192 | 14. *Koko Eating Bananas (medium) [Leetcode](https://leetcode.com/problems/koko-eating-bananas/) 193 | 15. *Capacity To Ship Packages Within D Days (medium) [Leetcode](https://leetcode.com/problems/capacity-to-ship-packages-within-d-days/) 194 | 16. *Median of Two Sorted Arrays (hard) [Leetcode](https://leetcode.com/problems/median-of-two-sorted-arrays/) 195 | 196 | 197 | ### 17. Pattern: Bitwise XOR 198 | 199 | 1. Introduction 200 | 2. Single Number (easy) 201 | 3. Two Single Numbers (medium) 202 | 4. Complement of Base 10 Number (medium) 203 | 5. Problem Challenge 1: Flip and Invert an Image (hard) 204 | 205 | 206 | ### 18. Pattern: Top 'K' Elements 207 | 208 | 1. [Introduction](13.-pattern-top-k-elements/01.Introduction.md) 209 | 2. Top 'K' Numbers (easy) [Solution](13.-pattern-top-k-elements/02.top-k-numbers.md) 210 | 3. Kth Smallest Number (easy) 211 | 4. 'K' Closest Points to the Origin (easy) [Leetcode](https://leetcode.com/problems/k-closest-points-to-origin/) 212 | 5. Connect Ropes (easy) 213 | 6. Top 'K' Frequent Numbers (medium) 214 | 7. Frequency Sort (medium) 215 | 8. Kth Largest Number in a Stream (medium) [Leetcode](https://leetcode.com/problems/kth-largest-element-in-a-stream/) 216 | 9. 'K' Closest Numbers (medium) 217 | 10. Maximum Distinct Elements (medium) 218 | 11. Sum of Elements (medium) 219 | 12. Rearrange String (hard)
220 | 13. Problem Challenge 1: Rearrange String K Distance Apart (hard) 221 | 14. Problem Challenge 2: Scheduling Tasks (hard) 222 | 15. Problem Challenge 3: Frequency Stack (hard) 223 | 224 | 16. *[*Heap Implementation*](13.-pattern-top-k-elements/13.HeapImplementation.md) 225 | 226 | 227 | ### 19. Pattern: K-way merge 228 | 229 | 1. Introduction 230 | 2. Merge K Sorted Lists (medium) [Leetcode](https://leetcode.com/problems/merge-k-sorted-lists/) 231 | 3. Kth Smallest Number in M Sorted Lists (Medium) [Geeksforgeeks](https://www.geeksforgeeks.org/find-m-th-smallest-value-in-k-sorted-arrays/) 232 | 4. Kth Smallest Number in a Sorted Matrix (Hard) [Educative.io](https://www.educative.io/courses/grokking-the-coding-interview/x1NJVYKNvqz) 233 | 5. Smallest Number Range (Hard) [Leetcode](https://leetcode.com/problems/smallest-range-covering-elements-from-k-lists/) 234 | 6. Problem Challenge 1: K Pairs with Largest Sums (hard) 235 | 236 | 237 | ### 20. Pattern: Greedy Algorithms 238 | 239 | 1. Introduction to Greedy Algorithm 240 | 2. Valid Palindrome II (easy) [Leetcode](https://leetcode.com/problems/valid-palindrome-ii/) 241 | 3. Maximum Length of Pair Chain (medium) [Leetcode](https://leetcode.com/problems/maximum-length-of-pair-chain/) 242 | 4. Minimum Add to Make Parentheses Valid (medium) [Leetcode](https://leetcode.com/problems/minimum-add-to-make-parentheses-valid/) 243 | 5. Remove Duplicate Letters (medium) [Leetcode](https://leetcode.com/problems/remove-duplicate-letters/) 244 | 6. Largest Palindromic Number (Medium) [Leetcode](https://leetcode.com/problems/largest-palindromic-number/) 245 | 7. Removing Minimum and Maximum From Array (medium) [Leetcode](https://leetcode.com/problems/removing-minimum-and-maximum-from-array/) 246 | 247 | 248 | ### 21. Pattern : 0/1 Knapsack (Dynamic Programming) 249 | 250 | 1. Introduction 251 | 2. 0/1 Knapsack (medium) [Geeksforgeeks](https://www.geeksforgeeks.org/0-1-knapsack-problem-dp-10/) 252 | 3. Equal Subset Sum Partition (medium) [Leetcode](https://leetcode.com/problems/partition-equal-subset-sum/) 253 | 4. Subset Sum (medium) [Geeksforgeeks](https://www.geeksforgeeks.org/subset-sum-problem-dp-25/) 254 | 5. Minimum Subset Sum Difference (hard) [Geeksforgeeks](https://www.geeksforgeeks.org/partition-a-set-into-two-subsets-such-that-the-difference-of-subset-sums-is-minimum/) 255 | 6. Problem Challenge 1: Count of Subset Sum (hard) 256 | 7. Problem Challenge 2: Target Sum (hard) 257 | 258 | 259 | ### 22. Pattern: Backtracking 260 | 261 | 1. Introduction to Backtracking Pattern 262 | 2. Combination Sum (medium) [Leetcode - I](https://leetcode.com/problems/combination-sum/) [Leetcode - II](https://leetcode.com/problems/combination-sum-ii/) [Leetcode - III](https://leetcode.com/problems/combination-sum-iii/) [Leetcode - IV](https://leetcode.com/problems/combination-sum-iv/) 263 | 3. Word Search (medium) [Leetcode - I](https://leetcode.com/problems/word-search/) [Leetcode - II (Hard)](https://leetcode.com/problems/word-search-ii/) 264 | 4. Sudoku Solver (hard) [Leetcode](https://leetcode.com/problems/sudoku-solver/) 265 | 5. Factor Combinations (medium) [Leetcode+](https://leetcode.com/problems/factor-combinations/) 266 | 6. Split a String Into the Max Number of Unique Substrings (medium) [Leetcode](https://leetcode.com/problems/split-a-string-into-the-max-number-of-unique-substrings/) 267 | 268 | 269 | ### 23. Pattern: Trie 270 | 271 | 1. Introduction to Trie 272 | 2. Implement Trie (Prefix Tree) (medium) [Leetcode](https://leetcode.com/problems/implement-trie-prefix-tree/) 273 | 3. Index Pairs of a String (easy) [Leetcode+](https://leetcode.com/problems/index-pairs-of-a-string/) 274 | 4. Design Add and Search Words Data Structure (medium) [Leetcode](https://leetcode.com/problems/design-add-and-search-words-data-structure/) 275 | 5. Extra Characters in a String (medium) [Leetcode](https://leetcode.com/problems/extra-characters-in-a-string/) 276 | 6. Search Suggestions System (medium) [Leetcode](https://leetcode.com/problems/search-suggestions-system/) 277 | 278 | 279 | ### 24. Pattern: Topological Sort (Graph) 280 | 281 | 1. Introduction 282 | 2. Topological Sort (medium) [Youtube](https://www.youtube.com/watch?v=cIBFEhD77b4) 283 | 3. Tasks Scheduling (medium) [Leetcode-Similar](https://leetcode.com/problems/course-schedule/) 284 | 4. Tasks Scheduling Order (medium) [Leetcode-Similar](https://leetcode.com/problems/course-schedule/) 285 | 5. All Tasks Scheduling Orders (hard) [Leetcode-Similar](https://leetcode.com/problems/course-schedule-ii/) 286 | 6. Alien Dictionary (hard) [Leetcode](https://leetcode.com/problems/alien-dictionary/) 287 | 7. Problem Challenge 1: Reconstructing a Sequence (hard) [Leetcode](https://leetcode.com/problems/sequence-reconstruction/) 288 | 8. Problem Challenge 2: Minimum Height Trees (hard) [Leetcode](https://leetcode.com/problems/minimum-height-trees/) 289 | 290 | 291 | ### 25. Pattern: Union Find 292 | 293 | 1. Introduction to Union Find Pattern 294 | 2. Redundant Connection (medium) [Leetcode - I](https://leetcode.com/problems/redundant-connection/) [Leetcode - II (Hard)](https://leetcode.com/problems/redundant-connection-ii/) 295 | 3. Number of Provinces (medium) [Leetcode](https://leetcode.com/problems/number-of-provinces/) 296 | 4. Is Graph Bipartite? (medium) [Leetcode](https://leetcode.com/problems/is-graph-bipartite/) 297 | 5. Path With Minimum Effort (medium) [Leetcode](https://leetcode.com/problems/path-with-minimum-effort/) 298 | 299 | 300 | ### 26. Ordered Set 301 | 302 | 1. Introduction to Ordered Set Pattern 303 | 2. Merge Similar Items (easy) [Leetcode](https://leetcode.com/problems/merge-similar-items/) 304 | 3. 132 Pattern (medium) [Leetcode](https://leetcode.com/problems/132-pattern/) 305 | 4. My Calendar I (medium) [Leetcode](https://leetcode.com/problems/my-calendar-i/) [Leetcode - II](https://leetcode.com/problems/my-calendar-ii/) [Leetcode - III (Hard)](https://leetcode.com/problems/my-calendar-iii/) 306 | 5. Longest Continuous Subarray (medium) 307 | 308 | 309 | ### 27. Pattern: Multi-thread 310 | 311 | 1. Introduction to Multi-threaded Pattern 312 | 2. Same Tree (medium) 313 | 3. Invert Binary Tree (medium) 314 | 4. Binary Search Tree Iterator (medium) 315 | 316 | 317 | ### 28. Miscellaneous 318 | 319 | 1. Kth Smallest Number (hard) 320 | 321 | 322 | ### Revision 323 | 324 | 1. [Coding Patterns: A Cheat Sheet](revision/Revision.md) 325 | 326 | 327 | ### Test Your Knowledge 328 | 1. [Easy Problems](test-your-knowledge/1.EasyProblems.md) 329 | 2. [Medium Problems](test-your-knowledge/2.MediumProblems.md) 330 | 3. [Hard Problems](test-your-knowledge/3.HardProblems.md) 331 | 332 | 333 | > ***Note:*** Problems marked with `*` are added as per my recommendations. 334 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | * [Coding Interview Patterns](README.md) 4 | * [1. Pattern: Sliding Window](1.-pattern-sliding-window/README.md) 5 | * [1.0 Introduction](1.-pattern-sliding-window/1.0-introduction.md) 6 | * [1.1 Maximum Sum Subarray of Size K (easy)](1.-pattern-sliding-window/1.1-maximum-sum-subarray-of-size-k-easy.md) 7 | * [1.2 Smallest Subarray with a given sum (easy)](1.-pattern-sliding-window/1.2-smallest-subarray-with-a-given-sum-easy.md) 8 | * [1.3 Longest Substring with K Distinct Characters (medium)](1.-pattern-sliding-window/1.3-longest-substring-with-k-distinct-characters-medium.md) 9 | * [1.4 Fruits into Baskets (medium)](1.-pattern-sliding-window/1.4-fruits-into-baskets-medium.md) 10 | * [1.5 No-repeat Substring (hard)](1.-pattern-sliding-window/1.5-no-repeat-substring-hard.md) 11 | * [1.6 Longest Substring with Same Letters after Replacement (hard)](1.-pattern-sliding-window/1.6-longest-substring-with-same-letters-after-replacement-hard.md) 12 | * [1.7 Longest Subarray with Ones after Replacement (hard)](1.-pattern-sliding-window/1.7-longest-subarray-with-ones-after-replacement-hard.md) 13 | * [1.8 - Permutation in a String (hard)](1.-pattern-sliding-window/1.8-permutation-in-a-string-hard.md) 14 | * [1.9 String Anagrams (hard)](1.-pattern-sliding-window/1.9-string-anagrams-hard.md) 15 | * [1.10 Smallest Window containing Substring (hard)](1.-pattern-sliding-window/1.10-smallest-window-containing-substring-hard.md) 16 | * [1.11 Words Concatenation (hard)](1.-pattern-sliding-window/1.11-words-concatenation-hard.md) 17 | * [2. Pattern: Two Pointers](2.-pattern-two-pointers/README.md) 18 | * [2.0 Introduction](2.-pattern-two-pointers/2.0-introduction.md) 19 | * [2.1 Pair with Target Sum (easy)](2.-pattern-two-pointers/2.1-pair-with-target-sum-easy.md) 20 | * [2.2 Remove Duplicates (easy)](2.-pattern-two-pointers/2.2-remove-duplicates-easy.md) 21 | * [2.3 Squaring a Sorted Array (easy)](2.-pattern-two-pointers/2.3-squaring-a-sorted-array-easy.md) 22 | * [2.4 Triplet Sum to Zero (medium)](2.-pattern-two-pointers/2.4-triplet-sum-to-zero-medium.md) 23 | * [2.5 Triplet Sum Close to Target (medium)](2.-pattern-two-pointers/2.5-triplet-sum-close-to-target-medium.md) 24 | * [2.6 Triplets with Smaller Sum (medium)](2.-pattern-two-pointers/2.6-triplets-with-smaller-sum-medium.md) 25 | * [2.7 Subarrays with Product Less than a Target (medium)](2.-pattern-two-pointers/2.7-subarrays-with-product-less-than-a-target-medium.md) 26 | * [2.8 Dutch National Flag Problem (medium)](2.-pattern-two-pointers/2.8-dutch-national-flag-problem-medium.md) 27 | * [2.9 Comparing Strings containing Backspaces (medium)](2.-pattern-two-pointers/2.9-comparing-strings-containing-backspaces-medium.md) 28 | * [2.10 Minimum Window Sort (medium)](2.-pattern-two-pointers/2.10-minimum-window-sort-medium.md) 29 | * [7. Pattern: Tree Breadth First Search](untitled/README.md) 30 | * [7.0 Introduction](untitled/7.0-introduction.md) 31 | * [7.1 Binary Tree Level Order Traversal (easy)](untitled/7.1-binary-tree-level-order-traversal-easy.md) 32 | * [7.2 Reverse Level Order Traversal (easy)](untitled/7.2-reverse-level-order-traversal-easy.md) 33 | * [7.3 Zigzag Traversal (medium)](untitled/7.3-zigzag-traversal-medium.md) 34 | * [7.4 Level Averages in a Binary Tree (easy)](untitled/7.4-level-averages-in-a-binary-tree-easy.md) 35 | * [7.5 Minimum Depth of a Binary Tree (easy)](untitled/7.5-minimum-depth-of-a-binary-tree-easy.md) 36 | * [7.6 Maximum Depth of Binary Tree (easy)](untitled/7.6-maximum-depth-of-binary-tree-easy.md) 37 | * [7.7 Level Order Successor (easy)](untitled/7.7-level-order-successor-easy.md) 38 | * [7.8 Connect Level Order Siblings (medium)](untitled/7.8-connect-level-order-siblings-medium.md) 39 | * [7.9 Problem Challenge 1 - Connect All Level Order Siblings (medium)](untitled/7.9-problem-challenge-1-connect-all-level-order-siblings-medium.md) 40 | * [7.10 Problem Challenge 2 - Right View of a Binary Tree (easy)](untitled/7.10-problem-challenge-2-right-view-of-a-binary-tree-easy.md) 41 | * [11. Pattern: Modified Binary Search](11.-pattern-modified-binary-search/README.md) 42 | * [11.1 Introduction](11.-pattern-modified-binary-search/11.1-introduction.md) 43 | * [11.2 Order-agnostic Binary Search (easy)](11.-pattern-modified-binary-search/11.2-order-agnostic-binary-search-easy.md) 44 | * [11.3](11.-pattern-modified-binary-search/11.3.md) 45 | * [16. Pattern: Topological Sort (Graph)](16.-pattern-topological-sort-graph/README.md) 46 | * [16.1 Introduction](16.-pattern-topological-sort-graph/16.1-introduction.md) 47 | * [16.2 Topological Sort (medium)](16.-pattern-topological-sort-graph/16.2-topological-sort-medium.md) 48 | * [16.3 Tasks Scheduling (medium)](16.-pattern-topological-sort-graph/16.3-tasks-scheduling-medium.md) 49 | * [16.4 Tasks Scheduling Order (medium)](16.-pattern-topological-sort-graph/16.4-tasks-scheduling-order-medium.md) 50 | * [Contributor Covenant Code of Conduct](code\_of\_conduct.md) 51 | * [Page 1](page-1.md) 52 | -------------------------------------------------------------------------------- /binary-search/image-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/binary-search/image-1.png -------------------------------------------------------------------------------- /binary-search/image-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/binary-search/image-2.png -------------------------------------------------------------------------------- /binary-search/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dipjul/Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/e9443b131cfeddf81919e3bb4f43c8537e5fae7e/binary-search/image.png -------------------------------------------------------------------------------- /code_of_conduct.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. 8 | 9 | ## Our Standards 10 | 11 | Examples of behavior that contributes to a positive environment for our community include: 12 | 13 | * Demonstrating empathy and kindness toward other people 14 | * Being respectful of differing opinions, viewpoints, and experiences 15 | * Giving and gracefully accepting constructive feedback 16 | * Accepting responsibility and apologizing to those affected by our mistakes, 17 | 18 | and learning from the experience 19 | 20 | * Focusing on what is best not just for us as individuals, but for the 21 | 22 | overall community 23 | 24 | Examples of unacceptable behavior include: 25 | 26 | * The use of sexualized language or imagery, and sexual attention or 27 | 28 | advances of any kind 29 | 30 | * Trolling, insulting or derogatory comments, and personal or political attacks 31 | * Public or private harassment 32 | * Publishing others' private information, such as a physical or email 33 | 34 | address, without their explicit permission 35 | 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | 38 | professional setting 39 | 40 | ## Enforcement Responsibilities 41 | 42 | Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. 43 | 44 | Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. 49 | 50 | ## Enforcement 51 | 52 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at . All complaints will be reviewed and investigated promptly and fairly. 53 | 54 | All community leaders are obligated to respect the privacy and security of the reporter of any incident. 55 | 56 | ## Enforcement Guidelines 57 | 58 | Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: 59 | 60 | ### 1. Correction 61 | 62 | **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. 63 | 64 | **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. 65 | 66 | ### 2. Warning 67 | 68 | **Community Impact**: A violation through a single incident or series of actions. 69 | 70 | **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. 71 | 72 | ### 3. Temporary Ban 73 | 74 | **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. 75 | 76 | **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. 77 | 78 | ### 4. Permanent Ban 79 | 80 | **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. 81 | 82 | **Consequence**: A permanent ban from any sort of public interaction within the community. 83 | 84 | ## Attribution 85 | 86 | This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.0, available at [https://www.contributor-covenant.org/version/2/0/code\_of\_conduct.html](https://www.contributor-covenant.org/version/2/0/code_of_conduct.html). 87 | 88 | Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). 89 | 90 | For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq](https://www.contributor-covenant.org/faq). Translations are available at [https://www.contributor-covenant.org/translations](https://www.contributor-covenant.org/translations). 91 | 92 | -------------------------------------------------------------------------------- /revision/Revision.md: -------------------------------------------------------------------------------- 1 | # Patterns for Problem Solving 2 | 3 | ## Pattern: Two Pointers 4 | **Description:** This method uses two pointers to traverse an array or a list from different ends or directions. 5 | **Usage:** It's particularly useful for ordered data structures, where we can make intelligent decisions based on the position of the pointers. 6 | **Problems:** 'Pair with Target Sum', 'Remove Duplicates', 'Squaring a Sorted Array'. 7 | 8 | ## Pattern: Island (Matrix Traversal) 9 | **Description:** It involves traversing a matrix to find 'islands' or contiguous groups of elements. 10 | **Usage:** It's generally used in grid-based problems, especially when we need to group connected elements together. 11 | **Problems:** 'Number of Islands', 'Max Area of Island', 'Flood Fill'. 12 | 13 | ## Pattern: Fast & Slow Pointers 14 | **Description:** In this method, two pointers move at different speeds in a data structure. 15 | **Usage:** It is commonly used to detect cycles in a structure, find middle elements, or to solve other specific problems related to linked lists. 16 | **Problems:** 'LinkedList Cycle', 'Middle of the LinkedList', 'Palindrome LinkedList'. 17 | 18 | ## Pattern: Sliding Window 19 | **Description:** This pattern involves creating a 'window' into the data structure and then moving that window around to gather specific information. 20 | **Usage:** Mostly used in array or list-based problems where you need to find a contiguous subset that fulfills certain conditions. 21 | **Problems:** 'Maximum Sum Subarray of Size K', 'Smallest Subarray with a given sum', 'Longest Substring with K Distinct Characters'. 22 | 23 | ## Pattern: Merge Intervals 24 | **Description:** This pattern involves merging overlapping intervals. 25 | **Usage:** Often used in problems involving time intervals, ranges, or sequences. 26 | **Problems:** 'Merge Intervals', 'Insert Interval', 'Intervals Intersection'. 27 | 28 | ## Pattern: Cyclic Sort 29 | **Description:** This pattern involves sorting an array containing numbers in a given range. 30 | **Usage:** It's useful in situations where the data involves a finite range of natural numbers. 31 | **Problems:** 'Cyclic Sort', 'Find the Missing Number', 'Find all Duplicates'. 32 | 33 | ## Pattern: In-place Reversal of a Linked List 34 | **Description:** This pattern involves reversing elements of a linked list in-place. 35 | **Usage:** It's generally used when reversing a sequence without using extra space. 36 | **Problems:** 'Reverse a LinkedList', 'Reverse a Sub-list', 'Reverse Every K-element Sub-list'. 37 | 38 | ## Pattern: Tree Breadth First Search 39 | **Description:** This pattern involves level-by-level traversal of a tree. 40 | **Usage:** It's used when we need to traverse a tree or graph in a level-by-level (breadth-first) manner. 41 | **Problems:** 'Level Order Traversal', 'Reverse Level Order Traversal', 'Zigzag Traversal'. 42 | 43 | ## Pattern: Tree Depth First Search 44 | **Description:** This pattern involves traversing a tree or graph depth-wise before visiting siblings or neighbors. 45 | **Usage:** It's used when you need to search deeper into a tree/graph first before going across. 46 | **Problems:** 'Binary Tree Path Sum', 'All Paths for a Sum', 'Count Paths for a Sum'. 47 | 48 | ## Pattern: Two Heaps 49 | **Description:** This pattern involves using two heaps to divide a set of numbers into two parts. 50 | **Usage:** It's useful when you need to find median numbers in a sequence, or other similar problems. 51 | **Problems:** 'Find the Median of a Number Stream', 'Sliding Window Median', 'Maximize Capital'. 52 | 53 | ## Pattern: Subsets 54 | **Description:** This pattern involves generating all subsets of a set. 55 | **Usage:** It's helpful for solving problems that require exploring all subsets of a given set. 56 | **Problems:** 'Subsets', 'Subsets With Duplicates', 'Permutations'. 57 | 58 | ## Pattern: Modified Binary Search 59 | **Description:** This is a tweaked version of the binary search algorithm. 60 | **Usage:** It's used when a simple binary search isn't sufficient, like finding a number in a bitonic array. 61 | **Problems:** 'Order-agnostic Binary Search', 'Ceiling of a Number', 'Next Letter'. 62 | 63 | ## Pattern: Top 'K' Elements 64 | **Description:** This pattern is used to find the top 'k' elements among a certain category. 65 | **Usage:** It's commonly used in problems involving sorting, searching, and in heap data structures. 66 | **Problems:** 'Top K Frequent Numbers', 'Kth Largest Number in a Stream', 'Top K Frequent Elements'. 67 | 68 | ## Pattern: Bitwise XOR 69 | **Description:** This pattern involves the use of Bitwise XOR to solve various array-based problems. 70 | **Usage:** It's used when we need to manipulate and compare bits directly. 71 | **Problems:** 'Single Number', 'Two Single Numbers', 'Complement of Base 10 Number'. 72 | 73 | ## Pattern: Backtracking 74 | **Description:** This pattern involves exploring all possible solutions and then backtracking to correct the course whenever you're on the wrong path. 75 | **Usage:** It's typically used for solving complex combinatorial problems, puzzles, and games. 76 | **Problems:** 'Sudoku Solver', 'N-Queens', 'Generate Parentheses'. 77 | 78 | ## Pattern: 0/1 Knapsack (Dynamic Programming) 79 | **Description:** This pattern deals with problems where items have different values and weights, and we need to determine the maximum value we can carry. 80 | **Usage:** It's typically used in optimization problems, especially those involving physical constraints. 81 | **Problems:** '0/1 Knapsack', 'Equal Subset Sum Partition', 'Subset Sum'. 82 | 83 | ## Pattern: Topological Sort (Graph) 84 | **Description:** This pattern involves sorting nodes in a directed graph in a specific order where the preceding node comes before the following node. 85 | **Usage:** It's used for scheduling problems and in scenarios where order needs to be imposed on how you process nodes. 86 | **Problems:** 'Task Scheduling Order', 'All Tasks Scheduling Orders', 'Alien Dictionary'. 87 | 88 | ## Pattern: K-way Merge 89 | **Description:** This pattern involves merging 'k' sorted lists. 90 | **Usage:** It's typically used in problems involving lists, where merging is required. 91 | **Problems:** 'Merge K Sorted Lists', 'Kth Smallest Number in M Sorted Lists', 'Smallest Number Range'. 92 | 93 | ## Pattern: Monotonic Stack 94 | **Description:** This pattern involves using a stack to maintain a monotonic (either entirely non-increasing or non-decreasing) order of elements. 95 | **Usage:** It's often used for solving problems where you need to find the next greater or smaller elements. 96 | **Problems:** 'Next Greater Element', 'Next Smaller Element', 'Largest Rectangle in Histogram'. 97 | 98 | ## Pattern: Multi-threaded 99 | **Description:** This pattern involves designing algorithms that can execute multiple threads in parallel. 100 | **Usage:** It's used in situations where a task can be divided into independent sub-tasks that can execute concurrently. 101 | **Problems:** 'Invert Binary Tree', 'Binary Search Tree Iterator', 'Same Tree'. 102 | 103 | ## Pattern: Union Find 104 | **Description:** Union Find, also known as Disjoint Set Union (DSU), is a data structure that keeps track of a partition of a set into disjoint subsets. 105 | **Usage:** This pattern is particularly useful for problems where we need to find whether 2 elements belong to the same group or need to solve connectivity-related problems in a graph or tree. 106 | **Problems:** 'Graph Redundant Connection', 'Number of Provinces', 'Is Graph Bipart'. 107 | -------------------------------------------------------------------------------- /test-your-knowledge/1.EasyProblems.md: -------------------------------------------------------------------------------- 1 | # Easy Problems 2 | 3 | 1. Two Sum (easy) 4 | 2. Valid Perfect Square (easy) 5 | 3. Best Time to Buy and Sell (easy) 6 | 4. Valid Parentheses (Easy) 7 | 5. Subtree of Another Tree (easy) -------------------------------------------------------------------------------- /test-your-knowledge/2.MediumProblems.md: -------------------------------------------------------------------------------- 1 | # Medium Problems 2 | 3 | 1. Daily Temperatures (Medium) 4 | 2. Group Anagrams (Medium) 5 | 3. Decode String (Medium) 6 | 4. Valid Sudoku (Medium) 7 | 5. Product of Array Except Self (Medium) 8 | 6. Maximum Product Subarray (Medium) 9 | 7. Container With Most Water (Medium) 10 | 8. Palindromic Substrings (Medium) 11 | 9. Remove Nth Node From End of List (Medium) 12 | 10. Find Minimum in Rotated Sorted Array (Medium) 13 | 11. Pacific Atlantic Water Flow (Medium) 14 | 12. Validate Binary Search Tree (medium) 15 | 13. Construct Binary Tree from Preorder and Inorder Traversal (medium) 16 | 14. Clone Graph (medium) 17 | 15. House Robber II (medium) 18 | 16. Decode Ways (medium) 19 | 17. Unique Paths (medium) 20 | 18. Word Break (medium) 21 | 19. Lowest Common Ancestor of a Binary Search Tree (medium) 22 | 20. Longest Consecutive Sequence (medium) 23 | 21. Meeting Rooms II (medium) 24 | 22. Encode and Decode Strings 25 | 23. Number of Connected Components in an Undirected Graph 26 | 24. Graph Valid Tree (medium) 27 | 25. Implement Trie (Prefix Tree) (medium) 28 | 26. Design Add and Search Words Data Structure (medium) -------------------------------------------------------------------------------- /test-your-knowledge/3.HardProblems.md: -------------------------------------------------------------------------------- 1 | # Hard Problems 2 | 3 | 1. Longest Valid Parentheses (hard) 4 | 2. Serialize and Deserialize Binary Tree (hard) -------------------------------------------------------------------------------- /untitled/7.0-introduction.md: -------------------------------------------------------------------------------- 1 | # 7.0 Introduction 2 | 3 | 4 | 5 | Here are the steps of our algorithm: 6 | 7 | 1. Start by pushing the `root` node to the queue. 8 | 2. Keep iterating until the queue is empty. 9 | 3. In each iteration, first count the elements in the queue (let’s call it `levelSize`). We will have these many nodes in the current level. 10 | 4. Next, remove `levelSize` nodes from the queue and push their `value` in an array to represent the current level. 11 | 5. After removing each node from the queue, insert both of its children into the queue. 12 | 6. If the queue is not empty, repeat from step 3 for the next level. 13 | 14 | Example 1: 15 | 16 | ![](<../.gitbook/assets/image (9).png>) 17 | 18 | ![](<../.gitbook/assets/image (8).png>) 19 | 20 | 21 | 22 | ![](<../.gitbook/assets/image (11).png>) 23 | 24 | ![](<../.gitbook/assets/image (10) (1).png>) 25 | 26 | ![](<../.gitbook/assets/image (5).png>) 27 | 28 | ![](<../.gitbook/assets/image (7).png>) 29 | 30 | ![](<../.gitbook/assets/image (12).png>) 31 | 32 | ![](<../.gitbook/assets/image (13).png>) 33 | -------------------------------------------------------------------------------- /untitled/7.1-binary-tree-level-order-traversal-easy.md: -------------------------------------------------------------------------------- 1 | # 7.1 Binary Tree Level Order Traversal (easy) 2 | 3 | 4 | 5 | Given the `root` of a binary tree, return _the level order traversal of its nodes' values_. (i.e., from left to right, level by level). 6 | 7 | 8 | 9 | **Example 1:** 10 | 11 | ![](https://assets.leetcode.com/uploads/2021/02/19/tree1.jpg) 12 | 13 | ``` 14 | Input: root = [3,9,20,null,null,15,7] 15 | Output: [[3],[9,20],[15,7]] 16 | ``` 17 | 18 | **Example 2:** 19 | 20 | ``` 21 | Input: root = [1] 22 | Output: [[1]] 23 | ``` 24 | 25 | **Example 3:** 26 | 27 | ``` 28 | Input: root = [] 29 | Output: [] 30 | ``` 31 | 32 | 33 | 34 | **Constraints:** 35 | 36 | * The number of nodes in the tree is in the range `[0, 2000]`. 37 | * `-1000 <= Node.val <= 1000` 38 | 39 | ``` 40 | import java.util.*; 41 | 42 | class TreeNode { 43 | int val; 44 | TreeNode left; 45 | TreeNode right; 46 | 47 | TreeNode(int x) { 48 | val = x; 49 | } 50 | }; 51 | 52 | class Main { 53 | public static List> traverse(TreeNode root) { 54 | List> result = new ArrayList>(); 55 | if (root == null) 56 | return result; 57 | 58 | Queue queue = new LinkedList<>(); 59 | queue.offer(root); 60 | while (!queue.isEmpty()) { 61 | int levelSize = queue.size(); 62 | List currentLevel = new ArrayList<>(levelSize); 63 | for (int i = 0; i < levelSize; i++) { 64 | TreeNode currentNode = queue.poll(); 65 | // add the node to the current level 66 | currentLevel.add(currentNode.val); 67 | // insert the children of current node in the queue 68 | if (currentNode.left != null) 69 | queue.offer(currentNode.left); 70 | if (currentNode.right != null) 71 | queue.offer(currentNode.right); 72 | } 73 | result.add(currentLevel); 74 | } 75 | 76 | return result; 77 | } 78 | 79 | public static void main(String[] args) { 80 | TreeNode root = new TreeNode(12); 81 | root.left = new TreeNode(7); 82 | root.right = new TreeNode(1); 83 | root.left.left = new TreeNode(9); 84 | root.right.left = new TreeNode(10); 85 | root.right.right = new TreeNode(5); 86 | List> result = Main.traverse(root); 87 | System.out.println("Level order traversal: " + result); 88 | } 89 | } 90 | ``` 91 | 92 | **Time complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/xV7E64m4lnz#time-complexity) 93 | 94 | The time complexity of the above algorithm is O(N), where ‘N’ is the total number of nodes in the tree. This is due to the fact that we traverse each node once. 95 | 96 | **Space complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/xV7E64m4lnz#space-complexity) 97 | 98 | The space complexity of the above algorithm will be O(N) as we need to return a list containing the level order traversal. We will also need O(N) space for the queue. Since we can have a maximum of N/2 nodes at any level (this could happen only at the lowest level), therefore we will need O(N) space to store them in the queue. 99 | -------------------------------------------------------------------------------- /untitled/7.10-problem-challenge-2-right-view-of-a-binary-tree-easy.md: -------------------------------------------------------------------------------- 1 | # 7.9 Problem Challenge 2 - Right View of a Binary Tree (easy) 2 | 3 | 4 | 5 | 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_. 6 | 7 | 8 | 9 | **Example 1:** 10 | 11 | ![](https://assets.leetcode.com/uploads/2021/02/14/tree.jpg) 12 | 13 | ``` 14 | Input: root = [1,2,3,null,5,null,4] 15 | Output: [1,3,4] 16 | ``` 17 | 18 | **Example 2:** 19 | 20 | ``` 21 | Input: root = [1,null,3] 22 | Output: [1,3] 23 | ``` 24 | 25 | **Example 3:** 26 | 27 | ``` 28 | Input: root = [] 29 | Output: [] 30 | ``` 31 | 32 | 33 | 34 | **Constraints:** 35 | 36 | * The number of nodes in the tree is in the range `[0, 100]`. 37 | * `-100 <= Node.val <= 100` 38 | 39 | ``` 40 | import java.util.*; 41 | 42 | class TreeNode { 43 | int val; 44 | TreeNode left; 45 | TreeNode right; 46 | 47 | TreeNode(int x) { 48 | val = x; 49 | } 50 | }; 51 | 52 | class Main { 53 | public static List traverse(TreeNode root) { 54 | List result = new ArrayList<>(); 55 | if(root == null) return result; 56 | 57 | Queue q = new LinkedList<>(); 58 | q.offer(root); 59 | 60 | while(!q.isEmpty()) { 61 | int levelSize = q.size(); 62 | // List currLevel = new ArrayList<>(); 63 | for(int i = 0; i < levelSize; i++) { 64 | TreeNode curr = q.poll(); 65 | // currLevel.add(curr); 66 | if(i == levelSize-1) 67 | result.add(curr); 68 | 69 | if(curr.left != null) q.offer(curr.left); 70 | if(curr.right != null) q.offer(curr.right); 71 | } 72 | 73 | // result.add(currLevel.get(currLevel.size()-1)); 74 | } 75 | 76 | return result; 77 | } 78 | 79 | public static void main(String[] args) { 80 | TreeNode root = new TreeNode(12); 81 | root.left = new TreeNode(7); 82 | root.right = new TreeNode(1); 83 | root.left.left = new TreeNode(9); 84 | root.right.left = new TreeNode(10); 85 | root.right.right = new TreeNode(5); 86 | root.left.left.left = new TreeNode(3); 87 | List result = Main.traverse(root); 88 | for (TreeNode node : result) { 89 | System.out.print(node.val + " "); 90 | } 91 | } 92 | } 93 | ``` 94 | 95 | **Time complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/m2YYxXDOJ03#time-complexity) 96 | 97 | The time complexity of the above algorithm is O(N), where ‘N’ is the total number of nodes in the tree. This is due to the fact that we traverse each node once. 98 | 99 | **Space complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/m2YYxXDOJ03#space-complexity) 100 | 101 | The space complexity of the above algorithm will be O(N), which is required for the queue. Since we can have a maximum of N/2 nodes at any level (this could happen only at the lowest level), therefore we will need O(N) space to store them in the queue. 102 | -------------------------------------------------------------------------------- /untitled/7.2-reverse-level-order-traversal-easy.md: -------------------------------------------------------------------------------- 1 | # 7.2 Reverse Level Order Traversal (easy) 2 | 3 | 4 | 5 | Given the `root` of a binary tree, return _the bottom-up level order traversal of its nodes' values_. (i.e., from left to right, level by level from leaf to root). 6 | 7 | 8 | 9 | **Example 1:** 10 | 11 | ![](https://assets.leetcode.com/uploads/2021/02/19/tree1.jpg) 12 | 13 | ``` 14 | Input: root = [3,9,20,null,null,15,7] 15 | Output: [[15,7],[9,20],[3]] 16 | ``` 17 | 18 | **Example 2:** 19 | 20 | ``` 21 | Input: root = [1] 22 | Output: [[1]] 23 | ``` 24 | 25 | **Example 3:** 26 | 27 | ``` 28 | Input: root = [] 29 | Output: [] 30 | ``` 31 | 32 | ``` 33 | import java.util.*; 34 | 35 | class TreeNode { 36 | int val; 37 | TreeNode left; 38 | TreeNode right; 39 | 40 | TreeNode(int x) { 41 | val = x; 42 | } 43 | }; 44 | 45 | class Main { 46 | public static List> traverse(TreeNode root) { 47 | List> result = new LinkedList>(); 48 | if(root == null) return result; 49 | Queue queue = new LinkedList<>(); 50 | queue.offer(root); 51 | 52 | while(!queue.isEmpty()) { 53 | int levelSize = queue.size(); 54 | List currLevel = new ArrayList<>(); 55 | for(int i = 0; i < levelSize; i++) { 56 | TreeNode currNode = queue.poll(); 57 | currLevel.add(currNode.val); 58 | if(currNode.left != null) 59 | queue.offer(currNode.left); 60 | if(currNode.right != null) 61 | queue.offer(currNode.right); 62 | } 63 | result.add(0,currLevel); 64 | } 65 | return result; 66 | } 67 | 68 | public static void main(String[] args) { 69 | TreeNode root = new TreeNode(12); 70 | root.left = new TreeNode(7); 71 | root.right = new TreeNode(1); 72 | root.left.left = new TreeNode(9); 73 | root.right.left = new TreeNode(10); 74 | root.right.right = new TreeNode(5); 75 | List> result = Main.traverse(root); 76 | System.out.println("Reverse level order traversal: " + result); 77 | } 78 | } 79 | ``` 80 | 81 | **Time complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/m2N6GwARL8r#time-complexity) 82 | 83 | The time complexity of the above algorithm is O(N), where ‘N’ is the total number of nodes in the tree. This is due to the fact that we traverse each node once. 84 | 85 | **Space complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/m2N6GwARL8r#space-complexity) 86 | 87 | The space complexity of the above algorithm will be O(N) as we need to return a list containing the level order traversal. We will also need O(N) space for the queue. Since we can have a maximum of N/2 nodes at any level (this could happen only at the lowest level), therefore we will need O(N) space to store them in the queue. 88 | -------------------------------------------------------------------------------- /untitled/7.3-zigzag-traversal-medium.md: -------------------------------------------------------------------------------- 1 | # 7.3 Zigzag Traversal (medium) 2 | 3 | 4 | 5 | Given the `root` of a binary tree, return _the zigzag level order traversal of its nodes' values_. (i.e., from left to right, then right to left for the next level and alternate between). 6 | 7 | 8 | 9 | **Example 1:** 10 | 11 | ![](https://assets.leetcode.com/uploads/2021/02/19/tree1.jpg) 12 | 13 | ``` 14 | Input: root = [3,9,20,null,null,15,7] 15 | Output: [[3],[20,9],[15,7]] 16 | ``` 17 | 18 | **Example 2:** 19 | 20 | ``` 21 | Input: root = [1] 22 | Output: [[1]] 23 | ``` 24 | 25 | **Example 3:** 26 | 27 | ``` 28 | Input: root = [] 29 | Output: [] 30 | ``` 31 | 32 | 33 | 34 | **Constraints:** 35 | 36 | * The number of nodes in the tree is in the range `[0, 2000]`. 37 | * `-100 <= Node.val <= 100` 38 | 39 | ``` 40 | import java.util.*; 41 | 42 | class TreeNode { 43 | int val; 44 | TreeNode left; 45 | TreeNode right; 46 | 47 | TreeNode(int x) { 48 | val = x; 49 | } 50 | }; 51 | 52 | class Main { 53 | public static List> traverse(TreeNode root) { 54 | List> result = new ArrayList>(); 55 | if(root == null) return result; 56 | Queue queue = new LinkedList<>(); 57 | queue.offer(root); 58 | boolean leftToRight = true; 59 | // int level = 0; 60 | while(!queue.isEmpty()) { 61 | int levelSize = queue.size(); 62 | List currLevel = new ArrayList<>(); 63 | for(int i = 0; i < levelSize; i++) { 64 | TreeNode currNode = queue.poll(); 65 | if(leftToRight) 66 | currLevel.add(currNode.val); 67 | else 68 | currLevel.add(0, currNode.val); 69 | 70 | if(currNode.left != null) queue.offer(currNode.left); 71 | if(currNode.right != null) queue.offer(currNode.right); 72 | } 73 | result.add(currLevel); 74 | leftToRight = !leftToRight; 75 | } 76 | return result; 77 | } 78 | 79 | public static void main(String[] args) { 80 | TreeNode root = new TreeNode(12); 81 | root.left = new TreeNode(7); 82 | root.right = new TreeNode(1); 83 | root.left.left = new TreeNode(9); 84 | root.right.left = new TreeNode(10); 85 | root.right.right = new TreeNode(5); 86 | root.right.left.left = new TreeNode(20); 87 | root.right.left.right = new TreeNode(17); 88 | List> result = Main.traverse(root); 89 | System.out.println("Zigzag traversal: " + result); 90 | } 91 | } 92 | 93 | ``` 94 | 95 | **Time complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/qVA27MMYYn0#time-complexity) 96 | 97 | The time complexity of the above algorithm is O(N), where ‘N’ is the total number of nodes in the tree. This is due to the fact that we traverse each node once. 98 | 99 | **Space complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/qVA27MMYYn0#space-complexity) 100 | 101 | The space complexity of the above algorithm will be O(N) as we need to return a list containing the level order traversal. We will also need O(N) space for the queue. Since we can have a maximum of N/2 nodes at any level (this could happen only at the lowest level), therefore we will need O(N) space to store them in the queue. 102 | -------------------------------------------------------------------------------- /untitled/7.4-level-averages-in-a-binary-tree-easy.md: -------------------------------------------------------------------------------- 1 | # 7.4 Level Averages in a Binary Tree (easy) 2 | 3 | 4 | 5 | Given the `root` of a binary tree, return _the average value of the nodes on each level in the form of an array_. Answers within `10-5` of the actual answer will be accepted. 6 | 7 | 8 | 9 | **Example 1:** 10 | 11 | ![](https://assets.leetcode.com/uploads/2021/03/09/avg1-tree.jpg) 12 | 13 | ``` 14 | Input: root = [3,9,20,null,null,15,7] 15 | Output: [3.00000,14.50000,11.00000] 16 | Explanation: The average value of nodes on level 0 is 3, on level 1 is 14.5, and on level 2 is 11. 17 | Hence return [3, 14.5, 11]. 18 | ``` 19 | 20 | **Example 2:** 21 | 22 | ![](https://assets.leetcode.com/uploads/2021/03/09/avg2-tree.jpg) 23 | 24 | ``` 25 | Input: root = [3,9,20,15,7] 26 | Output: [3.00000,14.50000,11.00000] 27 | ``` 28 | 29 | 30 | 31 | **Constraints:** 32 | 33 | * The number of nodes in the tree is in the range `[1, 104]`. 34 | * `-231 <= Node.val <= 231 - 1` 35 | 36 | ``` 37 | import java.util.*; 38 | 39 | class TreeNode { 40 | int val; 41 | TreeNode left; 42 | TreeNode right; 43 | 44 | TreeNode(int x) { 45 | val = x; 46 | } 47 | }; 48 | 49 | class Main { 50 | public static List findLevelAverages(TreeNode root) { 51 | List result = new ArrayList<>(); 52 | if(root == null) return result; 53 | 54 | Queue queue = new LinkedList<>(); 55 | queue.offer(root); 56 | 57 | while(!queue.isEmpty()) { 58 | int levelSize = queue.size(); 59 | double sum = 0; 60 | for(int i = 0; i < levelSize; i++) { 61 | TreeNode currNode = queue.poll(); 62 | sum += (double)currNode.val; 63 | 64 | if(currNode.left != null) queue.offer(currNode.left); 65 | if(currNode.right != null) queue.offer(currNode.right); 66 | } 67 | result.add(sum/(double)levelSize); 68 | } 69 | return result; 70 | } 71 | 72 | public static void main(String[] args) { 73 | TreeNode root = new TreeNode(12); 74 | root.left = new TreeNode(7); 75 | root.right = new TreeNode(1); 76 | root.left.left = new TreeNode(9); 77 | root.left.right = new TreeNode(2); 78 | root.right.left = new TreeNode(10); 79 | root.right.right = new TreeNode(5); 80 | List result = Main.findLevelAverages(root); 81 | System.out.print("Level averages are: " + result); 82 | } 83 | } 84 | ``` 85 | 86 | **Time complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/YQWkA2l67GW#time-complexity) 87 | 88 | The time complexity of the above algorithm is O(N), where ‘N’ is the total number of nodes in the tree. This is due to the fact that we traverse each node once. 89 | 90 | **Space complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/YQWkA2l67GW#space-complexity) 91 | 92 | The space complexity of the above algorithm will be O(N) which is required for the queue. Since we can have a maximum of N/2 nodes at any level (this could happen only at the lowest level), therefore we will need O(N) space to store them in the queue. 93 | -------------------------------------------------------------------------------- /untitled/7.5-minimum-depth-of-a-binary-tree-easy.md: -------------------------------------------------------------------------------- 1 | # 7.5 Minimum Depth of a Binary Tree (easy) 2 | 3 | 4 | 5 | Given a binary tree, find its minimum depth. 6 | 7 | The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. 8 | 9 | **Note:** A leaf is a node with no children. 10 | 11 | 12 | 13 | **Example 1:** 14 | 15 | ![](https://assets.leetcode.com/uploads/2020/10/12/ex\_depth.jpg) 16 | 17 | ``` 18 | Input: root = [3,9,20,null,null,15,7] 19 | Output: 2 20 | ``` 21 | 22 | **Example 2:** 23 | 24 | ``` 25 | Input: root = [2,null,3,null,4,null,5,null,6] 26 | Output: 5 27 | ``` 28 | 29 | 30 | 31 | **Constraints:** 32 | 33 | * The number of nodes in the tree is in the range `[0, 105]`. 34 | * `-1000 <= Node.val <= 1000` 35 | 36 | ``` 37 | import java.util.*; 38 | 39 | class TreeNode { 40 | int val; 41 | TreeNode left; 42 | TreeNode right; 43 | 44 | TreeNode(int x) { 45 | val = x; 46 | } 47 | }; 48 | 49 | class Main { 50 | public static int findDepth(TreeNode root) { 51 | if(root == null) return 0; 52 | Queue queue = new LinkedList<>(); 53 | queue.offer(root); 54 | int depth = 1; 55 | while(!queue.isEmpty()) { 56 | int levelSize = queue.size(); 57 | for(int i = 0; i < levelSize; i++) { 58 | TreeNode currNode = queue.poll(); 59 | 60 | if(currNode.left != null) queue.offer(currNode.left); 61 | if(currNode.right != null) queue.offer(currNode.right); 62 | if(currNode.left == null && currNode.right == null) { 63 | return depth; 64 | } 65 | 66 | } 67 | depth++; 68 | } 69 | return depth; 70 | } 71 | 72 | public static void main(String[] args) { 73 | TreeNode root = new TreeNode(12); 74 | root.left = new TreeNode(7); 75 | root.right = new TreeNode(1); 76 | root.right.left = new TreeNode(10); 77 | root.right.right = new TreeNode(5); 78 | System.out.println("Tree Minimum Depth: " + Main.findDepth(root)); 79 | root.left.left = new TreeNode(9); 80 | root.right.left.left = new TreeNode(11); 81 | System.out.println("Tree Minimum Depth: " + Main.findDepth(root)); 82 | } 83 | } 84 | ``` 85 | 86 | **Time complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/3jwVx84OMkO#time-complexity) 87 | 88 | The time complexity of the above algorithm is O(N), where ‘N’ is the total number of nodes in the tree. This is due to the fact that we traverse each node once. 89 | 90 | **Space complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/3jwVx84OMkO#space-complexity) 91 | 92 | The space complexity of the above algorithm will be O(N) which is required for the queue. Since we can have a maximum of N/2 nodes at any level (this could happen only at the lowest level), therefore we will need O(N) space to store them in the queue 93 | -------------------------------------------------------------------------------- /untitled/7.6-maximum-depth-of-binary-tree-easy.md: -------------------------------------------------------------------------------- 1 | # 7.6 Maximum Depth of Binary Tree (easy) 2 | 3 | 4 | 5 | Given the `root` of a binary tree, return _its maximum depth_. 6 | 7 | A binary tree's **maximum depth** is the number of nodes along the longest path from the root node down to the farthest leaf node. 8 | 9 | 10 | 11 | **Example 1:** 12 | 13 | ![](https://assets.leetcode.com/uploads/2020/11/26/tmp-tree.jpg) 14 | 15 | ``` 16 | Input: root = [3,9,20,null,null,15,7] 17 | Output: 3 18 | ``` 19 | 20 | **Example 2:** 21 | 22 | ``` 23 | Input: root = [1,null,2] 24 | Output: 2 25 | ``` 26 | 27 | 28 | 29 | **Constraints:** 30 | 31 | * The number of nodes in the tree is in the range `[0, 104]`. 32 | * `-100 <= Node.val <= 100` 33 | 34 | ``` 35 | import java.util.*; 36 | 37 | class TreeNode { 38 | int val; 39 | TreeNode left; 40 | TreeNode right; 41 | 42 | TreeNode(int x) { 43 | val = x; 44 | } 45 | }; 46 | 47 | class Main { 48 | public static int findDepth(TreeNode root) { 49 | if (root == null) 50 | return 0; 51 | Queue queue = new LinkedList<>(); 52 | int maximumTreeDepth = 0; 53 | queue.offer(root); 54 | 55 | while(!queue.isEmpty()) { 56 | maximumTreeDepth++; 57 | int levelSize = queue.size(); 58 | for(int i = 0; i < levelSize; i++) { 59 | TreeNode currNode = queue.poll(); 60 | if(currNode.left != null) queue.offer(currNode.left); 61 | if(currNode.right != null) queue.offer(currNode.right); 62 | } 63 | } 64 | 65 | 66 | return maximumTreeDepth; 67 | } 68 | 69 | public static void main(String[] args) { 70 | TreeNode root = new TreeNode(12); 71 | root.left = new TreeNode(7); 72 | root.right = new TreeNode(1); 73 | root.right.left = new TreeNode(10); 74 | root.right.right = new TreeNode(5); 75 | System.out.println("Tree Maximum Depth: " + Main.findDepth(root)); 76 | root.left.left = new TreeNode(9); 77 | root.right.left.left = new TreeNode(11); 78 | System.out.println("Tree Maximum Depth: " + Main.findDepth(root)); 79 | } 80 | } 81 | ``` 82 | 83 | **Time complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/3jwVx84OMkO#time-complexity) 84 | 85 | The time complexity of the above algorithm is O(N), where ‘N’ is the total number of nodes in the tree. This is due to the fact that we traverse each node once. 86 | 87 | **Space complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/3jwVx84OMkO#space-complexity) 88 | 89 | The space complexity of the above algorithm will be O(N) which is required for the queue. Since we can have a maximum of N/2 nodes at any level (this could happen only at the lowest level), therefore we will need O(N) space to store them in the queue 90 | -------------------------------------------------------------------------------- /untitled/7.7-level-order-successor-easy.md: -------------------------------------------------------------------------------- 1 | # 7.6 Level Order Successor (easy) 2 | 3 | #### Problem Statement [#](https://www.educative.io/courses/grokking-the-coding-interview/7nO4VmA74Lr#problem-statement) 4 | 5 | Given a binary tree and a node, find the level order successor of the given node in the tree. The level order successor is the node that appears right after the given node in the level order traversal. 6 | 7 | **Example 1:** 8 | 9 | ![](<../.gitbook/assets/image (5) (1).png>) 10 | 11 | **Example 2:** 12 | 13 | ![](<../.gitbook/assets/image (8) (1).png>) 14 | 15 | **Example 3:** 16 | 17 | ![](<../.gitbook/assets/image (7) (1).png>) 18 | 19 | ``` 20 | import java.util.*; 21 | 22 | class TreeNode { 23 | int val; 24 | TreeNode left; 25 | TreeNode right; 26 | 27 | TreeNode(int x) { 28 | val = x; 29 | } 30 | }; 31 | 32 | class Main { 33 | public static TreeNode findSuccessor(TreeNode root, int key) { 34 | TreeNode result = null; 35 | if(root == null) return result; 36 | // List arr = new ArrayList(); 37 | Queue queue = new LinkedList<>(); 38 | queue.offer(root); 39 | while(!queue.isEmpty()) { 40 | int levelSize = queue.size(); 41 | for(int i = 0; i < levelSize; i++) { 42 | TreeNode curr = queue.poll(); 43 | // arr.add(curr); 44 | if(curr.left != null) queue.offer(curr.left); 45 | if(curr.right != null) queue.offer(curr.right); 46 | if(curr.val == key) { 47 | result = queue.peek(); 48 | break; 49 | } 50 | } 51 | } 52 | 53 | return result; 54 | } 55 | 56 | public static void main(String[] args) { 57 | TreeNode root = new TreeNode(12); 58 | root.left = new TreeNode(7); 59 | root.right = new TreeNode(1); 60 | root.left.left = new TreeNode(9); 61 | root.right.left = new TreeNode(10); 62 | root.right.right = new TreeNode(5); 63 | TreeNode result = Main.findSuccessor(root, 12); 64 | if (result != null) 65 | System.out.println(result.val + " "); 66 | result = Main.findSuccessor(root, 9); 67 | if (result != null) 68 | System.out.println(result.val + " "); 69 | } 70 | } 71 | ``` 72 | 73 | **Time complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/7nO4VmA74Lr#time-complexity) 74 | 75 | The time complexity of the above algorithm is O(N), where ‘N’ is the total number of nodes in the tree. This is due to the fact that we traverse each node once. 76 | 77 | **Space complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/7nO4VmA74Lr#space-complexity) 78 | 79 | The space complexity of the above algorithm will be O(N)which is required for the queue. Since we can have a maximum of N/2 nodes at any level (this could happen only at the lowest level), therefore we will need O(N) space to store them in the queue. 80 | -------------------------------------------------------------------------------- /untitled/7.8-connect-level-order-siblings-medium.md: -------------------------------------------------------------------------------- 1 | # 7.7 Connect Level Order Siblings (medium) 2 | 3 | 4 | 5 | You are given a **perfect binary tree** where all leaves are on the same level, and every parent has two children. The binary tree has the following definition: 6 | 7 | ``` 8 | struct Node { 9 | int val; 10 | Node *left; 11 | Node *right; 12 | Node *next; 13 | } 14 | ``` 15 | 16 | Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to `NULL`. 17 | 18 | Initially, all next pointers are set to `NULL`. 19 | 20 | 21 | 22 | **Example 1:** 23 | 24 | ![](https://assets.leetcode.com/uploads/2019/02/14/116\_sample.png) 25 | 26 | ``` 27 | Input: root = [1,2,3,4,5,6,7] 28 | Output: [1,#,2,3,#,4,5,6,7,#] 29 | Explanation: Given the above perfect binary tree (Figure A), your function should populate each next pointer to point to its next right node, just like in Figure B. The serialized output is in level order as connected by the next pointers, with '#' signifying the end of each level. 30 | ``` 31 | 32 | **Example 2:** 33 | 34 | ``` 35 | Input: root = [] 36 | Output: [] 37 | ``` 38 | 39 | 40 | 41 | **Constraints:** 42 | 43 | * The number of nodes in the tree is in the range `[0, 212 - 1]`. 44 | * `-1000 <= Node.val <= 1000` 45 | 46 | ``` 47 | /* 48 | // Definition for a Node. 49 | class Node { 50 | public int val; 51 | public Node left; 52 | public Node right; 53 | public Node next; 54 | 55 | public Node() {} 56 | 57 | public Node(int _val) { 58 | val = _val; 59 | } 60 | 61 | public Node(int _val, Node _left, Node _right, Node _next) { 62 | val = _val; 63 | left = _left; 64 | right = _right; 65 | next = _next; 66 | } 67 | }; 68 | */ 69 | 70 | class Solution { 71 | public Node connect(Node root) { 72 | // Node result = null; 73 | if(root == null) return null; 74 | Queue q = new LinkedList<>(); 75 | q.offer(root); 76 | 77 | while(!q.isEmpty()) { 78 | int levelSize = q.size(); 79 | Node prev = null; 80 | 81 | for(int i = 0; i < levelSize; i++) { 82 | Node curr = q.poll(); 83 | if(prev != null) 84 | prev.next = curr; 85 | prev = curr; 86 | 87 | if(curr.left != null) q.offer(curr.left); 88 | if(curr.right != null) q.offer(curr.right); 89 | } 90 | } 91 | return root; 92 | } 93 | } 94 | ``` 95 | 96 | **Time complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/m2YYxXDOJ03#time-complexity) 97 | 98 | The time complexity of the above algorithm is O(N), where ‘N’ is the total number of nodes in the tree. This is due to the fact that we traverse each node once. 99 | 100 | **Space complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/m2YYxXDOJ03#space-complexity) 101 | 102 | The space complexity of the above algorithm will be O(N), which is required for the queue. Since we can have a maximum of N/2 nodes at any level (this could happen only at the lowest level), therefore we will need O(N) space to store them in the queue. 103 | -------------------------------------------------------------------------------- /untitled/7.9-problem-challenge-1-connect-all-level-order-siblings-medium.md: -------------------------------------------------------------------------------- 1 | # 7.8 Problem Challenge 1 - Connect All Level Order Siblings (medium) 2 | 3 | Given a binary tree, connect each node with its level order successor. The last node of each level should point to the first node of the next level. 4 | 5 | Example 1: 6 | 7 | ![](<../.gitbook/assets/image (6).png>) 8 | 9 | Example 2: 10 | 11 | ![](<../.gitbook/assets/image (4).png>) 12 | 13 | 14 | 15 | ``` 16 | import java.util.*; 17 | 18 | class TreeNode { 19 | int val; 20 | TreeNode left; 21 | TreeNode right; 22 | TreeNode next; 23 | 24 | TreeNode(int x) { 25 | val = x; 26 | left = right = next = null; 27 | } 28 | }; 29 | 30 | class Main { 31 | public static void connect(TreeNode root) { 32 | if(root == null) return; 33 | 34 | Queue queue = new LinkedList<>(); 35 | queue.offer(root); 36 | TreeNode prev = null; 37 | while(!queue.isEmpty()) { 38 | int levelSize = queue.size(); 39 | for(int i = 0; i < levelSize; i++) { 40 | TreeNode curr = queue.poll(); 41 | if(prev != null) 42 | prev.next = curr; 43 | prev = curr; 44 | 45 | if(curr.left != null) queue.offer(curr.left); 46 | if(curr.right != null) queue.offer(curr.right); 47 | } 48 | } 49 | } 50 | 51 | public static void main(String[] args) { 52 | TreeNode root = new TreeNode(12); 53 | root.left = new TreeNode(7); 54 | root.right = new TreeNode(1); 55 | root.left.left = new TreeNode(9); 56 | root.right.left = new TreeNode(10); 57 | root.right.right = new TreeNode(5); 58 | Main.connect(root); 59 | 60 | // level order traversal using 'next' pointer 61 | TreeNode current = root; 62 | System.out.println("Traversal using 'next' pointer: "); 63 | while (current != null) { 64 | System.out.print(current.val + " "); 65 | current = current.next; 66 | } 67 | } 68 | } 69 | ``` 70 | 71 | **Time complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/m2YYxXDOJ03#time-complexity) 72 | 73 | The time complexity of the above algorithm is O(N), where ‘N’ is the total number of nodes in the tree. This is due to the fact that we traverse each node once. 74 | 75 | **Space complexity** [**#**](https://www.educative.io/courses/grokking-the-coding-interview/m2YYxXDOJ03#space-complexity) 76 | 77 | The space complexity of the above algorithm will be O(N), which is required for the queue. Since we can have a maximum of N/2 nodes at any level (this could happen only at the lowest level), therefore we will need O(N) space to store them in the queue. 78 | -------------------------------------------------------------------------------- /untitled/README.md: -------------------------------------------------------------------------------- 1 | # Coming Soon . . . 2 | 3 | --------------------------------------------------------------------------------