in this video I'm going to solve blind 75 questions and all 75 questions in a single video now you must be wondering what blind 75 is well on one fateful day on December 30th 2018 just a day after my birthday basically there was a Facebook engineer and that engineer uh posted the list of 75 most popular questions on lead code by topic and he posted it on a website called Blind now for those who don't know blind is a very popular website where you can anonymously share whatever he wants to for your company and your identity is basically defined by the company you work for so it's a great place and uh if you want go and check it out that blind 75 list and I have basically decided to take on every single question solve them and put everything in just one video uh it took a lot of time to make this video for sure as you can imagine it's going to be very very very long video and uh I thank you for your patience and also encourage you to complete the all 75 questions now the question is will it be enough for your technical interview preparation in my honest opinion no but it is going to be a great start because you would be done with almost all the popular topics and you would have actually more than fundamental idea about what each one of them are and what type of questions to answer so doing this is going to be almost like 70% of the prep Journey then only you need to do more and more practice but this is this is going to be a great starting point and I wish you best of luck for your interview preparation Journey uh let's get started with the questions today we are going to do the number one problem inside the lead to code which is to some problem and this question has been literally asked by hundreds of companies hundreds of times uh any company that you want to get a job of at least have asked this question at some point in their history uh if we see the list of companies it's like Amazon Adobe Google Apple Microsoft Facebook Bloomberg Uber Expedia Spotify Goldman sax and then also companies like TCS sa Square uh Snapchat by dance Twitter service now and these are just some of the companies that are my dream companies that have already asked this problem and that's why I'm paying my atmost attention I hope you also enjoy the video so this is a lead code easy problem and probably the most like problem on lead code uh basically we are given an uh integer array of numbers and we are also given an integer value Target and we need to return the indices of two numbers such that they sum up to this target value that we are given so if we try to understand this with an example suppose we are given the values like 2 7 uh 11 and 15 and we are also given a Target value is uh 9 so in this case we can clearly see that this 2 and 7 if we sum that up it becomes 9 and uh that's why in this case we need to return the index values of this one so index values would be 0o and one and this would be the answer we need to return uh also in the another example we are given the values as 3 2 and 4 and we are given the target value to be six now because the target value is six we can actually do 3 + 3 = to six as well in this case but this is not the correct approach because we only have one three and we don't have the other three so this would not be the correct solution the correct solution would actually be 2 + 4 so if we do 2 + 4 it would become the six so that's why in this case we will need to return the index value is uh 1 and two and this would be the answer it's really easy to understand the problem statement let's see that what could be the different approaches to solve this problem okay so first of all we are going to solve this in Brute Force way and the idea is that at any point we are iterating over we need to find that what is the remaining value from this target number so suppose we are checking that whether one exists in a pair that sums up to this value number 13 what we are going to do is we are going to do 13 minus 1 so we will get the remaining value as 12 now we need to check that whether inside the remaining portion of the array whether this 12 exist or not so if 12 exist ex we can actually return the index values but in this case 12 does not exist if we iterate over all the values so we can simply return uh simply ignore this first case saying that there exist no pair where one is part of it which sums up to 13 now we will start repeating the same process for the remaining values so now we are at this value number eight again we will do 13 - 8 so the value becomes 5 now we will check that whether this five exists inside the remaining array so we will check the remaining values and we can see that five already exist over here so because five exist over here and8 also exists over here we can return the index values so in this case the index value for 8 is going to be one and index value for this five is going to be four and this would be our answer so this solution would work perfectly fine but what is the issue with this solution is actually the time complexity is going to be bigo of n Square why n Square because notice that for every single element we will have to check all the other elements that whether a certain remaining value exist or not and uh we could repeating the same process for all the elements so that's why this is the B of n sare time complexity the question is can we do something better and the answer is yes let me quickly show you how okay so we will use the same example now previously we know that in the Brute Force we were doing big of n sare time complexity why because at every single element if we wanted to find that okay for the remaining value this going to be 13 - 1 the remaining value is going to be 12 so in order for us to find this remaining value we had to iterate over all the places inside the given input array but what if we can shorten that time and one way to do is that whatever this given input is currently it is unsorted if we sort this given input so the sorted value or the sorted array would become something like this 1 2 5 8 and 15 now this is the sorted array now what we are going to do is uh our Target is still going to be this value number 13 but rather than checking those uh remaining values inside this given original input we are actually going to do it inside the sorted input and let me quickly show you how so first of all we are going to do okay this value is 1 so we we are going to do 13 minus 1 so the remaining value is 12 now we need to find that we 12 exist inside the sorted array and this can be done actually in log and time why because we are going to do binary search uh because this array is sorted and uh we know that binary search actually takes log and time which we can do it pretty quickly so immediately we identify that okay 12 does not exist inside this given uh array so we will ignore this and we will move with the next element so now this one does not need it to be tested we will check for this value number two so we will do 13 - 2 so 13 - 2 is actually going to be uh 11 so 11 also does not exist and because 11 does not exist we can ignore this value number two as well now again we will check for this value number five so we when we do 13 minus this value number five the remaining value becomes 8 and we can clearly see that okay 8 exist inside this given uh sorted array and because 8 and five exist all we need to do is we need to return the index values so then we will iterate over this given input and we will trying to find the index values of this 8 and five which we can actually do it in bigo of end time and that we can simply return whatever the index value is and that would be our solution so this this Ro is actually much better Improvement than whatever our Brute Force approach was which had big of n Square time but what are the issues with this approach so if we see the time complexity in this case the time complexity is actually going to be bigo of n log n to convert this original input from uh its original form to the sorted form and uh then it takes log in time to perform binary search and then it takes big off end time to do find the index values but all of that can be generalized to say that okay we need to complete this in big off n log n time now the question is can we do something better and can we do it in a linear time and the answer is less yes let me quickly show it to you how Okay so again we are going to use the same example and what we are going to do is we are going to use a hashmap now inside the hash map we are actually going to store two items as key value pair so as the key we are going to store the numbers inside this given array so we are going to store numbers as a key and we are going to store the index values as the uh values for the those uh particular numbers and what we are going to do is first of all we are going to do okay at any position we are going to find the remaining value so we are going to do 13 - 1 so the remaining value in this case is going to be 12 and now we will try to see whether this 12 exists inside this given hashmap and that can be done in constant time because uh that is the property of hashmap that is the beauty of hashmap so we will try to see okay so 12 does not exist in this case so because 12 does not exist we will add this value and its index position to this hashmap to see that whether in future we we can use it or not so we will add the value as 1 and we will add the index value as zero again we will repeat the same process so now we will move on to the next value so the next value in this case is going to be value number 8 so uh 13 - 8 the remaining value is five but five does not exist inside the hashmap yet so we will add an entry for this value number eight and its index position is one again we will move on to the next value the next value is 15 so we'll do 13 - 15 so 13 - 15 is actually- 2 and min-2 does not exist over here so again we will add the value number 15 to our hashmap so we are we will add an entry called 15 and the index value is two again for this two the 13 the 11 does not exist so we'll add an entry for this two and the index value is three now when we are at this value number five we will do 13 - 5 so 13 - 5 gives us the value as 8 now in the hashmap we can clearly see that 8 exist over here and its index position is this one and we are iterating this five so we know that what is the index value of this five so we can clearly return the value of this uh pair as 1 and 4 which is the corresponding index values of this 8 and five and that would be our solution and this answer would be the perfect solution uh if we see the time and space complexity in this case the time complexity is actually going to be biger of n why because because we are iterating over this given input just once we don't have to do anything else uh if we see the space complexity in this case the space complexity is also going to be big off n because we have to create this additional hashmap and we have to enter all the numbers that are present inside this given hashmap uh inside this given array and this would be the most optimal solution let's move on to coding now so first of all we will create a hashmap to store uh the integer values once that is done we will create a for Loop and we will iterate over the given input put and first of all we will calculate a variable called difference and for this difference variable we will do Target minus whatever the current value from the array we are at and then we have to check that if the value exist inside the hashmap that we have created if it does exist we can actually return and if the value does not exist uh we can actually add that entry to our hashmap and now out of the loop we'll simply return null uh because then otherwise it will give us an error let's try to run this code okay seems like our solution is working let's try to submit the code and our solution is actually pretty efficient it's uh almost like 99% faster than all the other Solutions and I would be posting this in the com M so you can check it out from there today we are going to do best time to buy and sell stocks lead code problem this question has a very real life practical application that is why it is very famous amongst it companies as an interview question uh if we see some of the companies where I want to work at who have already asked this question there are companies like Amazon Microsoft Facebook Bloomberg Google Goldman Sachs Apple Uber Snapchat Yahoo B dance door Das eBay net F and Reddit so that's why I'm paying my atmost attention I hope you also enjoy the video this is the lead code easy problem and you can see that it has been one of the most like problems on lead code if we try to understand the problem statement B basically we are given an array called prices where any single uh value inside this given array indicates the price of that particular stock and that on that particular day now we want to maximize our profit by choosing a single day to buy the stock and choosing a different day to sell the stock sometime in the future and our aim is to maximize our profit so if we try to see it with an example suppose this is the example that we are given where we are given six different prices for a stock and we are told that we need to maximize The Profit so I have drawn it on a graph over here so it makes things more easy to understand and we know that at any given position it shows that what is the price of that particular stock so initially the stock price on first day was price 7 now on the second day the price fell down to price one so we are not making any profit we are actually going down and we are losing the money but if we see over here so this day it's one and this day the price is five so if we see over here between these two days we actually made a profit of $4 again price fell next day to $3 and then again price rise to $6 so over here we lost $2 over here we again made some gain of $3 and at the end the price was four over here again we lost $2 so the thing is if we just just do it like this uh we don't get the maximized profits why because we are only seeing that what is the difference between every single day but if we see that if we do something if we buy the stock on this particular day which means that we are buying the stock when the stock price is at one and if we sell the price when the stock price at six so which means if we sell when the stock price is at six we can actually make a profit of $5 this is the answer we need to return return that this is the maximum profit we can make based on these stock prices let me show you that what would be the Brute Force approach and then I will show you that what would be the optimal approach so for the Brute Force approach one thing we can do is that we take every single position of buy and sell price for these given stocks which means that we make every single pair so first of all we see that if we buy the stock at Price seven and we sell at Price one again we sell at Price five again we sell at Price three and so on and so forth what is the maximum profit we are getting and we will create a variable C profit and we will keep track that what is the maximum number we have find found so far once we are done with this value number seven we would ignore this case and then again we will repeat the same thing with value number five so we start buying uh so we start that our Buy price is at Value number one and again we start checking all of the comparisons that what would be the profit and eventually we would find a pair where buy value is one and sell value is actually six which means that we would gain profit of $5 and then we will return this as our answer like this solution would work as expected we will get the desired result but the thing is this is not the most OP optimal approach why this is not the most optimal approach because if we see uh the time complexity the time complexity in this case is actually going to be big go of n Square why n Square because for any single entry we will have to take a look at every single entry in the remaining array and we will iterate this process so that is why it is a very timec consuming process and we need to find a way to do something better and uh let me quickly show you that what would be the optimal solution in this case so for the optimal approach what we are going to do is we are actually going to see that uh when do we get the maximized profit we only get the maximized profit when we buy at the lowest value and we sell at the highest value so this is the logic we are going to apply over here that uh we are going to buy the stock at the lowest value and we are going to sell the stock at the highest value but thing is it is not as easy as finding like the maximum value and the minimum value because in this case maximum value is actually seven and minimum value is actually one we don't need to get the difference of these two value because if we do that we will get an answer of six but the thing is uh we are actually dealing with stocks so we can only buy stocks uh in the past which means that if we decide to buy a stock over here we can only sell it afterwards we can't sell it uh to some value in the before so that's why that is one thing we need to keep track of that we have to make sure that this linear property of buying and selling is maintain maintained in this case so what we are going to do is we are going to have a variable called buy and that is going to keep track of what is the minimum value we have stored so far and we are going to see that at any given moment whatever the minimum buy value is if on that particular day we try to sell a stock what is the profit we are getting so let me quickly draw three variables over here so we are going to have three variables called buy sell and profit now first of all we are at this position number seven which means that we are buying the stock at 7 and we can't do anything about it because we don't have any way to sell it uh so we will start with the second position so now on the second day the stock price fell down to one which means that if we can we have already bought this stock at Value number seven if we try to sell it at Value number one it really does not give much progress but one thing we can do over here is that because today the stock price is actually low we can reduce that whatever the buying price is from 7 to 1 so we will do that so now the Buy price is actually 1 and uh we are not selling anything or we are not doing anything again now the next day the uh price is price of the stock is five so we'll try to do that okay what is the 5 - 1 which is the minimum price we have bought stock so far and 5 - 1 is actually Four which is the maximum profit we have made so far and we don't need to update this buy value because we have already bought it at a lower price than whatever the current price of the stock is now we will move on to the next value so next value the stock price is actually three which means three is still greater than value number one which means we don't need to update this value number three but we will have to check that whether we are making any greater profit or not so again we will do 3 minus whatever this buy value is the buy value is 1 so 3 minus 1 so the current profit we make is actually two but I think is two is actually less than four which means we can we don't need to update the profit we have made so far now again we will ignore this case we will move on to the next value so the next value the stock price is actually at six so stock price is now at 6 and now again we will do 6 - 1 so 6 - 1 uh selling price would would be actually five and because this is five and this profit is actually greater than whatever profit we have achieved so far so the current maximum profit we have made so far is five now again the stock price is at four so again the selling price on this day would be four and we don't need to update the buying price because the buying price is already at 1 which is lower than four and now we will do 4 Min - 1 so 4 Min - 1 if we do we still make profit but this profit is only $3 and $3 is actually less than whatever the maximum profit we have made so far now we are at the end of our Loop and now we don't have any more values to iterate over inside the given array which means whatever the result we have start stored inside the maximum profit variable we will just return that and in this case we will return answer as five and this answer would work perfectly fine this is like the most desired answer we need if we see the time and space complexity in this case the time complexity is actually biger of n why biger of n because notice that we are on completing everything in a single iteration uh in terms of space complexity uh for the space space complexity we are not actually using any additional space apart from storing couple of variables so that's why space is also constant so that's why this is a very good approach we are solving this in big of N and big big of end time and big of one space complexity so first of all we are going to initialize a variable called Min and we are going to give it the first value of the given prices uh we are going to create a variable called profit to note down the maximum profit we can acheve even initially we are going to mark it as zero and then we will update the value inside our Loop so now we are going to run a for Loop across the given array now inside the given Loop first of all we will check that whether we need to update the value of Min or not so we will check that if the current Min value is less than whatever the value of I is then we will update the value of Min and also we will check that whether the current profit we can make by selling the stock on that particular day comparing with the Min value uh we will choose the maximum profit profit we can and once this Loop ends we simply need to return the whatever value we have stored in the profit variable let's try to run this code okay seems like our code is working as expected let's submit it and our code is actually pretty efficient it runs faster than a lot of other Solutions and I will be posting this code in the comments so you can check it out from there thank you today we are going to do contains duplicate lead code problem and if we see some of the companies where I want to work at who have already asked this question there are companies like Amazon Adobe Apple Google Microsoft Facebook Bloomberg Uber Yahoo and Airbnb have already asked this question so that's why I'm paying my utmost attention I hope you also enjoy the video so this is a lead code easy problem and basically we are given an integer array called nums and we need to check that whether this nums contains any duplicate values or not if it contains the duplicate values we need to return true if it does not contain a duplicate value we need to return false so let's try to understand this with couple of examples so in the first example over here we are given four values inside this array 1 2 3 and 1 we can see that this number one actually appears twice which means that there contains a duplicate so in this case we will return true uh if we Tak another example in the second input we are given four distinct value 1 2 3 4 and all the values are distinct so that's why there is no there are no duplicate entries so in this case we can return false let's see that what would be the different approaches to solve this problem uh suppose we are given an example that looks like this now in The Brute Force what we are going to do is we are going to compare every single value with all the other values that are present inside this given array so first of all we will take this value number one and we will see that in the rest of the remaining array does one appear again or not if it does not appear then we will move on to the next value and again we will repeat the same process so first of all we will take this value number one now this all these four values they are not one which means we can Define that one does not appear any time in this given array uh now we check for this value number two for the value number two if we check over here these two are not two but this is actually a true so the moment we identify that there exist a value that we are already searching for uh if that is present inside this given array we can return true immediately that yes uh this input contains duplicates and this would be the answer in this case this road Force solution works as expected but uh if we see the time and space complexity in this case the time complexity is actually going to be big go of n squ why n Square because for every single element we will have to compare all the other remaining elements and then again we will repeat the same process for all the remaining characters which means that uh the time complexity becomes bigger of n Square so let's see that how can we improve upon that now one way to improve our root for solution is by using sorting let's try to understand this with an example suppose we take this input and we create a sorted input we will get a sorted array that looks like this now inside the sorted array all we will have to do is just compare any two adjacent values so first of all we compare this one with with this value number two they are both not same which means we can ignore this case now we compare this two with this next value which is also two which means because these two are same we can determine that there exists a duplicate in this case and we can return true immediately so if we see the time complexity in this case the time complexity is actually going to be bigo of n log n why n logn because we will have to convert this nums to the sorted eror and that that takes n log n time after doing this uh checking that whether it contains the duplicate or not only takes big off end time but the thing is uh this generically we can write this as big of n log n and if we see this time complexity this is a much bigger Improvement than our Brute Force approach which which had the time complexity of big of n square but let's see that whether we can do anything better with this and whether we can find an optimal solution for this one as well now for the optimal solution what we are going to do is we are actually going to use an additional data structure and in terms of additional data structure we are going to use a hash set now the idea is that first of all we will check that any value we are iterating over in this given input if that is already present inside this hash or not if it is present we can return true immediately if it is not present we will add that entry to the hash and then we will start iterating over the next element with the same procedure so let's see that in action first of all we will check for this value number one so one is not present inside the hash set so we will add an entry called one over here now we are at this position number two two is again not present inside this hash set so we will add an entry called two over here uh three and four both are not present so again we will add entry for three and four over here now again we are at this value number two now when we check that whether it contains inside the hash or not we can immediately say that it exists inside the hash because we already have an entry over here and we can do this in constant time because hash set the finding operation takes big go of one time or constant time so that's why it is it becomes really efficient for us so in this case we can return true immediately that hey we are at the position where we where this array contains the duplicate values uh and somehow if we reach to the end of this uh array and we don't find any duplicate entries inside the server hash set then we can return return false in that case as well so if we see the time and space complexity in this case the time complexity is actually going to be bigo of n only because we have to iterate this given input once nothing more than that if we see the space complexity in this case the space complexity is actually going to be biger of n as well because we have to create an additional data structure hash set where we will store all the elements that are present inside this given input first of all we are going to create a hashtag called visited now we are going to iterate over this given input nums so inside our for Loop first of all we are going to check that the value we are visiting if that is present inside our visited hash set or not if it is present which means we can return true immediately that there exist a duplicate if it is not present we will add an entry to our hash set in any case if we get out of the loop we can determine that we did not find any duplicate V entries and we can return false in this case now let's try to run this code okay seems like our code is working as expected let's submit this code and our code runs pretty efficiently compared to lot of other solution I will be posting this in the comments so you can check it out from there thank you today we are going to do product of an array except self lead code problem if we see some of the companies where I want to get a job who have already asked this question there are companies like Amazon Microsoft Facebook Apple Uber Bloomberg lift Google wman X IBM Twitter Tik Tok and Linkedin so that's why I'm paying my atmost attention I hope you also enjoy the video this is a lead code medium problem and also very well- like problems on lead code uh basically we are given an integer array called nums and we need to return a new array called answer array such that every single value of that particular index position inside this answer array is actually equal to the product of all the other values that are present inside this given nums array except that particular I element so suppose we are given an input array that looks like this this case we will have to create an answer array for the answer and that would be of the same size of whatever this input array we are given now in this answer array suppose we want to enter the value at this uh second position or corresponding to the second index value what we are going to do is we are actually going to take the product of this value number one 3 and four and whatever the product of these three values are we will actually put it as the answer for this value same thing we are going to do for this uh next value where we are going to take products of these two elements and this element but we won't take the product of this element from this original given input array and whatever the answer is we will actually put it over here inside the answer are uh in order to enter this first element we will actually have to do the product of these three values so in the product of these three values is going to be 24 uh now for the second element we will have to do the product of this first element and this last two elements so that is going to be 12 uh for this third and fourth element we will again repeat the same process and we will get subsequent values like 8 and six by doing the corresponding products and at the end we will have to return this as the answer array and uh basically this is what the problem is asking us to do uh even the name is also self-explanatory that we need to return the product of an array except self but we are given a very specific declaration over here that we need to use it in bigo of end time without using the division operator and why it is asking us to use solve this problem without using division operator because if we were allowed to use division operator suppose we are given an input we can just do the product of all of these value and we will get an answer called 24 and then all we have to do is for this answer array we will take this value 24 and then we will iterate over this input array and start dividing it with this 24 so even in the answer we will get if we divide 24 by 1 we will get the value as 24 if we divide 24 by by 2 we will get value 12 if we divide 24 by 3 we will get value 8 so so on and so forth so it would become very easy for us to solve this problem so that is why they are explicitly asking us that we should not be using the division operator now the most basic BR Force way to solve this problem is actually we take any single value and then we iterate over all the remaining values and do its product and put it in the answer array so we will create an answer array that looks like this we will First Take This value so we will iterate over this given nums array and for all these three values we will do its product and we will get the value is 24 now again we will repeat the same process but this time we will be iterating over the second element so because we are iterating over the second element we will take this first value and we will take these two values and we will do that sum so we will get value number 12 and again we will repeat the same process so essentially this is bound to give us the correct answer and we would get it in this case but thing is this is this would not be the correct way why because if we see the time complexity in this case the time complexity is actually going to be bigger of n sare why n Square because we will have to iterate over this array for every single character we will have to iterate once and even for any particular character we will have to iterate over all of the values again just to find their product number and that takes n Square time and we are explicitly told that we will have to solve this problem and we go of end time so let's see that what would be the way to achieve that okay so now for the better approach we will actually have to put down one intuition to use and the intuition is suppose this is the element we want to get the product for in the answer so the idea is that we are actually going to take the product value of first two elements and we will take the product of this last element again if we take this portion this value number two we will take the product of all the elements that are present on the left of this value number two and we will take the product of all the elements that are present on the right of this product number this value number two so that is the idea that for every single location we will have to take product of all the values that are behind or pre to that particular level so we can call it as prefix and all the values that come after that value and we can call it post fix so now the idea becomes quite simple what we are going to do is we are going to have two arrays called prefix and postfix and we are going to iterate over this nums array once and for every single position we are actually going to keep track of all the values that come before it and after it and we are going to put down their ER values like their product values and at the end we will just do a multiplication between this pre and post arrays and then we will we should get our answer so let's see that in action and also one more thing that because for this particular element that are the edges uh so for this value number four there is nothing on the right side so like we can't do anything but uh for the Simplicity purposes we will consider that anything on the right side is actually one because anything multiplied by one Remains the Same and same thing we are going to do for this left Edge as well that because for this value number one there is nothing in the prefix so again by default we will treat this as value number one as well so that will help us in uh doing some counting right so let's see that in action so first of all for this value number one we we are calculating the prefix values so this one actually has nothing on the left but it only has one so we'll do 1 * 1 and we will get the answer as one now for this value number two actually all we need to do is whatever the left element is we we just need to do the product of all of them so the left element in this case is only one and we will just put it over here as well now in this case the value number three we will have to do product of all these elements so one way to do it is to do this like 1 * two so do the product of all the these two elements but that is actually time consuming one better way to do it is that uh if we take this particular element value number two this already contains the product of all the values that are be present before that so why are we doing the effort of doing the product of this value number one and two that is just costing us additional resources the better approaches that we for this value number three uh we are over at this position all we have to do is we just take whatever the value we have stored over here which is the prefix of all the values before this value number two multiply by whatever this value is present and that would be the prefix sum for this value number three so what we are going to do in this case is we will take this value number two so we will take this value number two and we'll take this value number one from here from the prefix array that we have already calculated and we will do 2 * 1 in this case we will get value as two so we will add two over here and again for this value number four again we are going to repeat the same process so now this time we are going to take the value before four that is three so we will take three and we will multiply it by whatever value we have already found in this prefix array which is 2 so 3 * 2 is actually going to be 6 and so now we are done with this prefix array again we are going to repeat the same thing for the pro postfix array so this is The Edge value so we can simply do four * 1 so we'll add the value four directly over here now this is value number three for this value number three all we'll have to do is just take product of this value so this is already four so we will again add four over here now uh for this value number two all we have to do is we will take the value this uh whatever value that is present over here 3 multiply by whatever value we have already calculated in the post fix over here which is 12 so we will have a value called 12 over here for this element number two and now again for this element number one we are going to repeat the same process we will take this two and multiply it by whatever value we have calculated inside our postfix array and this is going to be 2 * 12 okay now we are done with both of our arrays now the task is actually quite simple now we will create our answer array and we are going to Simply do the multiplication of every single one of these values so this becomes 24 * 1 24 this becomes 12 this becomes 8 and this becomes oh I made a mistake over here this has to be 1 not four because we are actually doing the multiplication of all the elements that are present on the right side of this value so this would become six and this is the solution that we are we are going to do uh this solution actually works perfectly fine there are no issues with that if you see the time and space complexity in this case the time complexity is actually going to be bigo of uh 3 * n why 3 * n because we will have to iterate over this n to first of all create this prefix array then we we have to iterate over end times to create this postfix array and then again we will have to iterate over both of them to create this answer array so we are doing like three times n work but in general we can write this as big of N and in terms of space complexity uh we are actually creating couple of arrays so we also have to do big off n as space complexity so the idea is can we do something better and the answer is yes there is one way to actually do this both prefix and postfix array in a single array and that to insert the answer ARR that we are planning to create okay so let's keep the same example and we want to find the optimal solution for this one well the idea is that rather than doing two separate prefix and postfix arrays we are actually going to create an answer array and we are going to add all the values and now we are going to do prefix and postfix multiplication inside the same answer array and let me quickly show you how uh first of all we are going to use couple of variables called prefix and postfix so let me uh add their values and by default they are going to have value as one now what we are going to do is uh first of all we are going to iterate over this given input uh nums and we are going to calculate the prefix for every single element inside this answer array and we are also going to update the value inside this pre function uh or pre variable and then again we will iterate in the reverse order and we will keep on updating the postfix values inside the answer and by the time we are done our answer array should have been completely filled out let me quickly show you that in the action so first of all uh for this value number one uh this is actually the prefix fix of every every value that is present behind this one and uh the multiplication of all of those values so because there is nothing over here we can consider this to be one by default so I'll not write it over here I'll just write over here that for this first element inside this answer array uh the nums actually does not have anything on the left side side left side so we can consider this to be one now we are going to we are at this second position for the second position what we are going to do is we are going to take the multiplication of whatever the value we have on the left side right so even on the left side we only have value one and even the prefix value is also one so far by default so we are going to add one over here again now we are at this value number two or three so for this value number three what we are going to do is we are actually going to take the the value that is before that which is two and we are going to multiply it with whatever the pre variable we have so we were also doing the same thing for this value number two as well but because both the values are one we were not getting any other result but in this case we will actually get a result of two and because we are getting a result of two the result of three is also updated also being updated to Value number two um because it will help us to know further down for the next elements that what is the value of prefix now we are at this value number four so again we are going to repeat the same process we will take this value number three and we will take whatever the value of this prefix we have which is two so 3 * 2 the value is six so we'll add value six over here okay and now we are done filling up this prefix portion and we have taken the prefix of every single element inside this answer array now we are going to do the reverse order now inside the reverse order again for this value number four actually uh there is nothing on the right side of this value number four which means there is nothing on the post fix so we can consider it as one now because this is already one what we are going to do is whatever value we have calculated so far we are going to multiply it so if we multiply 6 by 1 the answer we get is six okay so so far uh for this value number four the answer is six now we are at this value number three for this value number three what we are going to do is we we have to calculate everything on the postfix side so this value is four so we are take going to take value four multiply by whatever value of this postfix variable we have which is 1 so 4 * 1 becomes 1 so now we have the value as four for this post fix so we are going to update the value of the post fix to be four and we are also going to multiply this four with whatever the value we already calculated for this value number three which is 2 so 4 * 2 is going to be 8 and this is going to be answer for this value number three that this is the product of all the numbers for this value number three except itself now we are at this value number two for Value number two we are going to take value number three multiplied by whatever the post variable we have post variable is actually 4 so 3 * 4 is actually 12 so we are going to update that value over here first of all so now we have the value 12 over here and we will have to take this 12 and multiply it with whatever value we have already stored over here which is 1 so 1 * 12 is also 12 and now again we are at this last position so again for the last position we are going to repeat the same process we will take whatever the value that is after this value number one which is two so we will take this two we will multiply it with whatever value we have store inside this post variable which is again 12 so 2 * 12 and we this becomes actually 24 so we will do 24 and we will take 24 multip by whatever value we have already stored inside this answer array which is one so 24 * 1 becomes 24 and this is the answer and if you look closely this actually becomes the complete answer that we are looking for and we have actually done everything in place without using any additional data structure or any additional array and we don't have to use basically any extra space so this is the best way to approach this problem and this is the solution that any interviewer would want to see if we see the time complexity in this case the time complexity is actually going to be bigo of 2N why 2N because first of all we are iterating over from uh left to right calculating this pre variable and then we are iterating on the reverse order calculating this post variable and updating the values but still which is good if we see the space complexity in this case well space complexity is actually constant because we are not using any additional space for this answer array we are given inside this uh question statement that we have to create a new array so that we are anyways going to create but apart from that we are only using couple of variables to store some data and uh that's why this is a very good approach now let's move on to coding of all we are going to create a new array called result and by default we are going to set all the values as one we are going to initialize the two variable called prefix and postfix and we are going to assign the value as one for both of them okay now we are going to run our first for Loop to iterate from left to right and we are going to update the value of prefix inside our answer uh array so first of all we are going to update the value inside our result array and then we are going to to update the value of our prefix variable so after this Loop ends basically we should have U prefix values filled out for every single position inside our result array now we are going to run another loop and we are going to come in the reverse order and first of all we are going to update the value inside the result array so any single value inside the result is actually going to be multiplication of whatever the value we already had multiply by postf fix variable also have to up the value of postfix variable we are good to go oh actually I made a mistake this should be pre only not prefix okay and after this second Loop ends essentially our result error should have been populated so we can simply return that let's try to run this code okay seems like our solution is working as expected let's submit this code and our code runs pretty efficiently compared to a lot of other Solutions so that's why this is really good approach I will be posting the solution in the comments so you can check it out from there thank you today we are going to do maximum subar lead code problem and if you see some of the companies where I want to get a job who have already asked this question there are companies like LinkedIn Amazon Apple Microsoft Google adob Facebook Bloomberg Uber H dance Yahoo eBay and spunk so that's why I'm paying my at most attention I hope you also enjoy the video so this is a lead code medium problem and very well like problem on lead code basically we are given an array called nums and we need to find a continuous sub array which has the largest sum and then return the sum value we are also told that a sub array is a continuous part of any array so we are given the definition of it now let's try to understand this with an example so suppose this is the example we are given well I have actually drawn this example uh in much bigger format over here so for this example what we are going to do is we are going to see different sub barries and then we are going to see that what is the maximum sum we have we are able to find so far and then in the end we will return whatever the maximum sum you have found so first of all this value is actually -2 so because this value is -2 even if all the remaining values they are positive it makes no sense for us to keep this value so we are going to ignore this value and we are not going to keep it in our current subarray now this value is positive one so that is good but again combination of these two is actually minus 2 so again we cannot keep this in the our continuous subar well now this value is actually pos4 and which is good sign now these two value this is again still positive3 which is also a good sign and the combination of these three is again five and then we add this value so this becomes six and we are going to keep on updating the max value as well so max value so far we have found so far is six that we can say that up until this point the sub ARA there where we have found the maximum value to be is 6 now this is again minus 5 so the if we do 6 + - 5 we still get posit positive 1 value which is again positive so we are keeping this as a subarray and then again this value is + 4 so + 4 + 1 becomes + 5 so this is also positive but thing is uh in the end up until this point the maximum value we were able to find is six so because it was six we are going to return six as the answer this is what the problem is asking us to do we need to find the sum of Maximum sub array and then return that value so let's see what would be different approaches to solve this problem basically we need to find the maximum sub array what we can do is we will try to find every single possible sub array try to see the sum of all of those characters and whichever possess the maximum sum we simply return that sum so let's see that in action so first of all what we are going to do is we are going to take some of this character then we are going to take some of these two characters then we are going to take some of these three characters and so on and so forth we are keep on repeating the process with the first element after we are done with this essentially we are going to get rid of this first element and now whatever the remaining elements are we are going to start taking some of those values so in this case what again we are going to do is we'll take this element then again we will take these two elements and again we will take these three elements and overall we will keep on making the sum and eventually we would find the answer and the answer in this case is going to be the sum of these three characters and whatever the answer is we can simply return that so this approach would work as expected but the issue with this root Force solution is actually that we are doing lot of repetitive work if we see the time complexity in this case the time complexity is actually going to be big go of n s so let's see that what would be the better way to solve this before we come up with the optimal solution first of all let's make couple of things very clear uh what is our aim and what is the thing that we are trying to find well basically we are trying to find that what is the maximum sum sub array at any given moment there can be any current sub array that we are iterating over which could be the maximum sub array or could not be the maximum sub aray we don't know but at any given moment we will have need to have the ability to keep track of some of all the characters that are present in that particular subarray so which means that we are going to have a variable called current or current subarray where we are going to keep track of the sum of all the current variables that we we have iterated over and we are keeping track of uh well second thing is that we need to find the maximum sub array and amongst any of the sub arrays anyone could be the maximum sub array so we are also going to keep track of another variable called maximum subar where we are going to keep track of Maximum current some we have found so far so well these two things are understandable right uh they are from programming perspective but there is also one more thing that is actually rational and the rational thing is that at any given moment suppose this value is actually minus 3 so current Su sum or current sub array we have found is actually minus 3 so if this value is min -3 because this value is negative so if this value is negative even though all the remaining values they are positive and they keep on increasing the value in size this minus 3 is always going to have to cause them to have a lesser value so if that is the case why are we even bothering to keeping this value at our Bay or at our disposal so the idea is at any given moment for our current subarray the moment we would identify that the current value or some set of current values they are causing it to have a negative value if that is the case we are going to immediately update our current subarray and then we will keep on moving towards the next values and based on these two Logics uh all we are going to do is we are going to iterate over our given array and keep on going to updating the current sub array and then keep on updating the maximum sub array we have found so far and in the end we should be able to find the answer so let's see that traversal in action before we start iterating over this VAR we are going to Define some default values for this current and maximum variable the default value for current is going to be the zero and for maximum it's going to be whatever the first element of the this given arrays which is minus 3 that is to cover an edge case where we are only given one element now let's start iterating over Okay so now uh the sum of these two elements is actually going to be - 3 + 2 so - 3 + 2 is actually going to be Min -1 which is still less than zero so because this is less than Zer we are not going to update our current Max variable and the maximum sum we are actually able to find so far is going to be zero which is definitely greater than - 3 now again the for these three variables again the sum is going to be negative so we are not going to do anything and we are going to ignore all three of these cases now this value is actually positive so because this value is positive the current sum we have is going to be 8 so which means we'll have to update the maximum sum we we have found so far to be the value eight as well now again we add the sum of these two values so 8 + -1 so 8 + -1 actually becomes 7 so this becomes 7 Which is less than whatever the maximum value we have found so far so we don't need to update the max variable now we again add this value to our current sum so 7 + 2 7 + 2 is 9 9 is greater than whatever the maximum value we had so this becomes 9 okay now again this is also a positive value three so we can do 9 + 3 which becomes 12 so we are again going to add the value 12 to our maximum sum that we have we have been able to find so far and then this value is actually -5 so we can do 12 + - 5 so 12 + - 5 is going to be 7 and again because this value is still positive we are keeping this current subar going on because we we don't know future values might be positive values and this can also go up pretty quickly now uh we are we have actually reached to the end of this array and we don't have any more elements to go over so the maximum sum we have found so far is 12 and this is what we need to return as the answer in this case uh and so this is the most optimal approach to solve this problem if we see time and space complexity in this case the time complexity is actually going to be big of n why big of n because we'll have to iterate over every single array or every single value that is present inside this given array which takes bigo of end time if we see space complexity in this case the space complexity is actually bigo of one or constant space because apart from storing these couple of variables we are not using any additional space so that's why space complexity is very minimal first of all we are going to initialize two variable called current sum and maximum sum for current sum we are going to initialize the value to be zero and for maximum sum we are going to initialize the value to be the first value inside this given nums array we are going to create a for Loop to iterate over this given array now we are going to check that whether the current sum if that is less than zero or not if that is less than zero we are going to update the value of current sum to zero that is not the case we are going to calculate the value for current sum and maximum sum so current sum is going to be current sum plus whatever the current uh value inside this given nums array we have and we will have to check that whether the current sum we have created if that is the maximum sum or not and after Loop PS We simply have to return maximum sum let's try to run this code seems like our solution is working as expected let's submit this code and our code runs pretty efficiently I will be posting this in the comments so you can check it out from there thank you today we are going to do maximum product sub array this is a very popular problem on lead code and if you see some of the companies that I want to get a job who have already asked this question there are companies like Amazon LinkedIn Microsoft Google Apple Bloomberg Facebook and Uber so that's why I'm paying my atmost attention I hope you also enjoy the video okay so this is a lead code medium problem and as mentioned a very well like problem on lead code basically we are given an integer array called nums and we need to find a continuous non-empty sub array that has the largest product and we need to return the product uh we are also given the definition that what a subarray is that that is basically a continuous sequence inside the any given array and let's try to understand this problem with the with an example so I have broaden this example over here and basically we are trying to find the maximum product sub array so a sub array that contains the maximum product in this case this is a negative value and that changes the dynamic equation so in this case the product of these two elements that is a sub array is actually going to be six and all the other sub arrays they are always going to have lesser values than six so in this case as the answer we need to return six that that is the maximum product sub array we can make for this given input array and this is what the problem is asking us to do so first let's see that what is going to be the Brute Force way to solve this problem well the Brute Force way to solve this problem is that we are asked to find the maximum product sub array right so if we are asked to find something of a sub array why don't we check every single sub array see that what is the product we can make and find the maximum amongst that so like do the baby steps so what we are going to do is we are going to keep on iterating over every single sub array that we can make uh we are going to see that we are going to have a variable called answer and uh in the answer we are only going to store the maximum value we have found so far and then we will keep on repeating the same process for all the remaining sub arrays and eventually we would find a pair that contains the maximum product subarray and in this case the answer is actually going to be the 6 * 7 that is 4 42 and we will have 42 populated as the answer eventually so the Brute Force way is a very trivial way but it leads to the correct solution so if you are only looking for solution you will get it using Brute Force but what are the issues with this one well the issues clearly we can see over here that we will have to iterate over every single sub array that is there and that would lead us to have a Time complexity of bigo of n Square so which is bad very bad because for every single element uh we will have to iterate over every other elements and then keep on repeating the same process so the idea is to see that can we find something of a better time complexity we can actually achieve that using the most important concept inside our computer programming and that is called dynamic programming using the dynamic Pro programming we are basically going to have two pointers to store some critical important results and that is going to lead us to find the maximum product sub array so first let's understand one thing regarding what is being asked we are trying to find the product now we know that for the product suppose if all the integers are just positive integers then basically it is the product of all the integers that we need to return right the thing is that is not always the case we could encounter negative integers and the negative integers leads to very uh interesting results the interesting results are that first of all we suppose in this case uh these three values if we do product of them okay the product of these two is six and the 6 * -3 leads us to -8 to be the product over here right the thing is now this value seems very low value because of the negative value but imagine that over here rather than this 4 being positive if we had a -4 then that is actually going to lead us to have a very beautiful results that if we do -8 * -4 the answer is going to be + 72 and that is going to be the maximum product subar so you see what I'm trying to say the moment we encountered a negative value immediately we found it to have the minimum value but that negative value lead us to have some better consequential results in the future so we don't know that whether we whenever we encounter a negative value we don't know whether we should keep it or not so that is a tricky part that is why we are going to use dynamic programming and we are actually going to use two pointers and these two pointers are going to be that at any given position we are at inside our array we are going to see that up until this point what is the minimum value we have been able to achieve and what is the maximum value we have been able to achieve or basically what I'm trying to say is what is the minimum product we have been able to achieve and what is the maximum product we have been able to achieve and every single value we could have three possibilities so let me clean this up a bit at every single value we are at there could be three possibilities either this value could be part of a sub array that leads us to have the maximum product or it could have been a part of a sub array that leads us to have the least value up until this point or this could be the start of a new sub array that leads us to have a maximum product in the future the idea is at any given position we are going to check three things and the three things we are going to check is that up until this point whatever the minimum value we had which is which we have stored so far we we are going to multiply this value with this minimum value we are also going to multiply this value with whatever the maximum value we have able we have been able to store so far and we are also going to compare this value by itself so we have basically three values at any given position the value with the previous minimum value the value with the previous maximum value and the value by itself and for all of these three values we are going to see that what is the minimum value we are able to make we will store that what is the maximum value we we are able to make among these three values we will store that as well and eventually we would reach to the end of our loop with the maximum value we have been able to generate and we will have a parameter called answer and in the answer parameter whenever we identify a better maximum value we would populate that so this is the approach I'm suggesting now let me try to go over an ex an example okay so suppose this is the example we are have and now let's try to use dynamic programming in this case with two pointers so we are going to create two pointers called Min and Max and for every single value we are going to compare it with three values that we are going to compare it with then we are going to populate these results we are also going to have a variable called answer we will update it based on the maximum value we have found so far okay so first value is five so we for all the three values we only have five we can't compare any with it anything okay so minimum value we have found so far is going to be five maximum is also going to be five and that's it now this next value is three okay so now let's see that what are three values that we have to compare so first value is three by itself next value is 3 * the minimum value so 3 * 5 and next value is 3 * maximum value so again 3 * 5 so the three values we have is 3 15 and 15 okay so now the minimum value amongst these three is going to be three so we are going to populate that and the maximum value is going to be 15 so we are again going to populate that the answer so far that the best we have received is 15 so we are going to populate that okay now let's get rid of this one now again we are at the next element that is one so now the three values we have is 1 1 * whatever the minimum value so that is three so the value is going to be three and the 1 * the maximum value that is 15 okay now amongst these three values the minimum value we can able to make is going to be one okay so let's populate that and the maximum value is going to be 15 the answer is going to remain the same now let's clean this up okay now Things become interesting when we reach to this value 9 minus 2 okay now the three values we have is going to be min-2 by itself then Min -2 * the minimum previous minimum value so PR previous minimum value in this case is 1 so - 2 * 1 is going to be min-2 and the previous maximum value so previous maximum value in this case is 15 so - 2 * 15 is going to be -3 okay now these are the three values we have and now we are going to see that what is the minimum and maximum value we are able to generate right so currently the minimum value we are able to generate is going to be minus 30 so we are going to store that over here okay and the maximum value we are able to generate in this case is going to be min-2 so we are going to store that over here okay now we are good up until this point now this value is zero so the three values that we have to compare is going to be 0 0 times the minimum value so that is again going to be the 0o and 0 * maximum value that is again going to be the zero so all three values are zero so let's put zeros over here now again uh we are at this value number5 so now the three values that we have to compare is going to be -5 and then both of these are zero so it's going to be 0 0 again so currently the maximum value we are able to generate is going to be the 0 so we are again going to populate the value with zero and the minimum value we are able to generate is5 so we are going to populate the value with5 now the next value is 8 okay so now the three values we have to compare is 8 8 * -5 is going to be -4 and 8 * uh the 0 is going to be zero okay now uh the three values that we have let's compare them and let's find the minimum value so minimum value in this case is going to be -40 so we are going to put it over here the maximum value we are going to have is 8 so let's populate that over here here okay now we are at this value number minus 3 so with this minus 3 we again we have three options so minus 3 then - 3 * this -40 that leads us to positive 120 and - 3 * 8 that leads us to -24 okay so now in this case the minimum value we have so far is going to be- 24 which is this one and the maximum value we are going to have is going to be 120 and this 120 is greater than this value number 15 so we are also going to update that in our answer answer and now we have reached to the end of our array so end of our dynamic programming Journey so we'll stop here and whatever value we have found in the answer we are going to return this as the answer so in this case answer is 120 that is the correct answer if we see and if we compare this to our Brute Force well essentially because we are using the beautiful concept of dynamic programming we are completely everything in just one single iteration and all we are doing is just storing couple of variables uh to store the previously calculated results and comparing different values that leads us to have the correct answer and find the maximum product sub array in a single iteration which is wonderful if we see time complexity in this case the time complexity is is actually going to be bigger of N and the space complexity is actually going to be big go of constant space complexity because apart from storing couple of variables we are not storing any other data so this is a very good time and space complexity to have compared to a Brute Force approach that had the time complexity of big of n Square which was very bad so first let's take care of some edge cases that if the given number is empty we can simply return zero so now we will initialize A Min variable a Max variable and a result variable okay so now let's run a for Loop to iterate over our given nums array let's initialize a variable called current to keep track of the current variable we are at okay now we will have to calculate max and Min value so first let's calculate max value so this takes care care of comparing three values for for our Max variable and we are using math. Max function two times uh because that is the way to do it I think in Python you can do it just without using like two math. Max functions now let's calculate our Min value as well the thing is for our Min value we will also have to use the max value but since previously we have already calculated our max value it makes no sense for us to use that over here so what I'm going to do is I'm going to create a temporary variable and this temporary variable I'm going to calculate the max value then for the calculation of Min value basically I'm going to use the previous U Max variable now because this is the temporary variable we will assign this value to Max we will also have to keep on updating our result variable as well that's it uh basically when the loop ends we should have our answer populated in the result variable so let's return that now let's try to run this code okay seems like our solution is working as expected let's submit this code and our code runs pretty efficiently compared to to a lot of other Solutions and I would be posting this solution in the comments so you can check it out from there today we are going to do find minimum in a rotated sorted array and if we see some of the companies where I want to get a job who already asked this question there are companies like Microsoft Amazon Uber Facebook Apple Bloomberg Google and Tik Tok so that's why I'm paying my atmost attention I hope you also enjoy the video so this is a lead code medium problem and basically we need to find the minimum inside a rotated sort array now you will ask that what does a rotated sorted array means we are actually given some definition of what a rotated sorted array is if you want you can iterate over this definition but thing is let me quickly show it to you by an example basically we are originally given a sorted array now for this sorted array if we take the rightmost element and put it on the leftmost position and all the other subsequent elements we flip it one side on the right side we can determine this to be rotated one time so if I take this or original sorted array and if I rotate one time so one time rotated array is going to look like this you can see that this five that was originally at the rightmost position has been flipped to the leftmost position and all the other values we put shifted them one position on the right now if I uh rotate this one more time So eventually I would I would have rotated this array to two times basically the result I would get is going to look like this that where the first two values are four and five and then we have one 1 2 and 3 now over here this four that was originally over here that came to this place now we can rotate it like three times four times as many times as we want like we can only rotate it up until five five times because there are only five elements now basically in any rotated array we need to find that what is the minimum value that is present in it so if we try to understand this with an example over here we are given some array uh where the original version of array was 1 2 3 4 5 that got rotated three times and we were given this as the input now if we see the minimum value in this case is one so we need to return one as the answer we are also given one key important detail that we have to find that we must write an algorithm that runs in bigo of log and time so that is the key part first let's see that what is going to be the Brute Force approach to solve this problem well the Brute Force approach that comes to our mind is that why don't we start iterating over the given array we have a variable called Min or answer or whatever you want to call it and then uh we start iterating over all the subsequent elements one at a time and whenever we find a lower value basically we update that in the Min variable So eventually when we start iterating when we would have completed iteration we would find the value one to be the lowest value that we can find inside this array and that we are going to return as the answer this solution leads us to the correct answer there are no issues with this one but why this brute brute force solution does not work in your interviewer interviewer or anywhere else is because this solution actually happens in big go of end time because we are iterating over all the N elements and we were explicitly told that we need to solve this problem in B go of log and time so that's why this root Force solution won't work now whenever we see log and solution immediate thing that comes to our mind is that we are going to use binary search right and that is true that we are going to use binary search in this case but before we do that let's make some logic clear well the key part of the logic we have is that if we compare the left and right element for any given array if the array is completely sorted which is the case in over here that the entire array has been completely sorted there are no mismatching pairs right so because this array is completely sorted if we compare the leftmost element and rightmost element or any element with its left element uh basically we would find that the value at the left element is is always less than whatever value at the right element we have like if we compare these three variables and if we compare the right variable to be over here basically again in this case the right is three and left is one so we can conclude that this whole portion is sorted if we have the right variable located at this position uh basically we we have the value of left to be one and right to be five again left is less than one so we can conclude that this whole portion is actually sorted so the lowest value that we can achieve in this whole ption between this left and right is going to be whatever value that is located at the leftmost position now whenever we compare the left value and right value and we determine that left is actually greater than right if we find that left is actually greater than right we can determine that the minimum value exists somewhere between left and right we don't know that at what position minimum value exist but thing is we need to achieve to the direction where we can actually find left is is less than right because remember over here currently the value of left is three and value of right is two so in this case left is actually greater than two whenever we have to find the minimum value we will have to move in a Direction Where We will reach to a conclusion where left is less than right and in order to achieve that what we are going to do is we are going to compare the value of the left to the middle pointer that exist and depending on the value of the middle pointer we would determine that the minimum value if does it exist on the left side of the middle pointer or on the right side of the middle pointer and depending on that we will update our value of left pointer or right pointer so let me show you with a broader example what I'm trying to say so I have drawn a big example over here and first let's uh assign our initial values of left and right right uh so we have the values of left and right set up for us now we know that we need to reach to a position where left is less than right if that is the case then we will have some interesting results right but currently if we see the value of left is two and value of right is one so left is actually greater than one so now we will have to move in some Direction so now what we are going to do is we are going to find the mid value and also remember we are going to have an answer variable that is going to store the lowest value we have been able to find So Far So currently the value of left is two value of right is one right so we are not going to do anything in the answer yet now we are going to find the middle pointer so the current middle pointer is going to be at position number four why because left position is 0o right position is 8 so 0 + 8 is equal to 8 / 2 that gives us the middle value and middle value in this case is going to be the four right so the value that is located at the fourth position is six now we need to compare the values between left and mid left and mid if we compare left is two and mid is six so 2 is less than six now remember whenever we identify that the left value is less than whatever the value we compared we can can dictate that every value in between is actually greater than the value of the left which means that no value amongst these values can be the answer or can be the minimum value because remember we already know that on the right hand side the value is actually less than left and because of that we will have to update our migration on the right side and also remember whenever we compare the value of left value with the mid value what whatever the lower value is we are going to store it so currently the lowest value we have been able to find is two so we are going to store two as the answer right now we are going to switch our left pointer to go on the right side of the mid so now let me clean this up a bit so now this is going to be our new left pointer and this is going to be our new right pointer again we are going to compare the value of left and right so left is actually greater than right right so now we will have to find the midp pointer midp pointer in this case is going to be left plus right divided by two so current value of left is five right is 8 so 13 divided by 2 if we put it uh floor value we will get the value of six so 6 is going to be the middle pointer in this case so now we have the six to be the middle pointer now we are going to compare left with the middle pointer and now in this case left is actually less than middle pointer which means that answer cannot lie between left and middle pointer and again we will have to update the value of the left pointer also for this leftmost value we will compare that whether we need to update the answer or not so answer currently we had was two and this is seven so we don't need to update the answer and we are good up until this point okay now again we determine that this value is not the answer now our left pointer comes at this position our right pointer comes at this position again we are going to compare the values of left and right so currently left is actually less than right and that is the ideal scenario that we found that left is Les actually less than right which means that now left is at the correct position to be the lowest position that it can be uh before before it iterates or it takes overr right and now because of this one uh we are going to update uh we are going to see that whether we need to update our answer or not so current answer we had was two and because left was less than right we are going to compare the left value with this answer value and uh the left value is actually zero so we are going to update the answer to be zero and in this case this is the correct answer that we are able to find and we are going to return that uh let's try to understand the same thing with another example so in this case left is over here right is over here currently uh left is actually greater than right so because of that we will have to find the middle value so middle value is going to be this one so now if we see currently the left is actually greater than middle value as well which means we cannot determine that the left and middle portion is actually completely sorted we can only determine that the middle and right portion is completely sorted so in this case we are actually going to update the value of the right pointer and we are going to determine that these are all the values that are not part of the answer answer so we can just simply ignore them and we will not do anything for these values so now currently our right pointer comes over here now because of that we are again going to repeat the same process and we will try to find the middle value middle value in this case is going to be eight right so we are going to compare left with the middle value so left with the middle value if we compare left is actually less than the middle value if that is the case we can determine that no value over here is the middle minimum value so we can simply ignore that and now our left value becomes this one our right value becomes this one and now if we compare left is actually less than right left is less than right that is the ideal scenario that we were looking for which means that now left is at the correct position where the value is actually minimum and in the answer we are going to denote the value to be zero and that is going to be the answer we are going to return now if we see time complexity in this case the time complexity is actually going to be big go of log n because remember during any single iteration we actually removed the half of the candidates that we are we were trying to search for and that is why we are actually using binary search in this program to solve this problem and that is the logic we are going to use uh and now let's move on to the coding so first of all we are going to initialize three variables left right and answer now we are going to test for an edge case that if the nums array only has one element basically we can return that as the answer okay if that is not the case we are going to run our while loop that while left is less than or equal to right first we are going to check that if the current left and right position makes the array completely sorted or not and that can only happen if the value at number of left is actually less than whatever the value of nums at right we have and if that is the case we are going to see that whether we need to update our answer or not if that is not the case we will have to calculate the middle pointer so first we are going to initialize a value called mid and we are going to calculate the middle pointer after calculating the mid pointer we are again going to check that whether we need to update our answer or not now we are going to see that which way on the midp pointer do we need to take the jump so if uh we if we find out that the current value of left is actually less than or equal to Mid value then we will have to update the value of left pointer to the right side of the mid and if that is not the case which means we will have to update our right pointer basically that's all we have to do for our binary search operation after this Loop ends we can simply return whatever we have stored in the answer and now let's try to run this code okay seems like our solution is working as expected let's submit this code and our code is actually pretty fast compared to a lot of other Solutions and I will be actually posting the solution in the comment so you can check it out from there today we are going to do search in a rotated sorted array and if you see some of the companies where I want to get a job who have already asked this question there are companies like Amazon Microsoft Facebook LinkedIn Bloomberg Apple TiK ToK by Dan Google Goldman sex Uber and eBay so that's why I'm paying my at most attention I hope you also enjoy the video this is a lead code medium problem and also a very well-like problem on lead code basically we are trying to search an element inside a rotated sorted array now if you notice this is very similar to one of the previous videos we soled recently and you can check it out that over here now uh we are basically given an array called nums and we are also given a Target value and we need to check that whether this target value exist inside this nums array or not if it does we need to return the index of that Target value now the special part about this question is that the nums array we are given is actually a sorted array that has been rotated certain times so it sounds confusing at first that what does a rotated sorted array means so you can either read this definition that has been provided over here but uh let me make it a little bit clear for you uh basically a rotated sorted array is that initially an array is a fully sorted array which is the case over here you can see that all the elements are sorted and they are all in ascending order and the thing is whenever we rotate one time basically we take the rightmost element we put it on the leftmost side and then we flip all the elements one side or one position to the right and that is how we rotate and uh rotate a sorted array so if we consider this to be the original array suppose we rotate it one time we will get a result that looks like this where this five that was originally on the rightmost position came on the leftmost position and all the other subsequent value we jumped it one step on the right side if we rotate two times again the four and five would come on the left side and all the values would be shifted two times on the right side if we rotate three times basically all the values would uh be rotated three times and we would get an array that looks like this so the idea is we are given a form of a rotated sorted array the thing is we don't know that how many times it has been rotated ated or what not we are also given some Target element and we need to see that whether this target element exist inside this array or not so suppose uh this is the array we are given as the input and we are given Target is equal to uh three if that is the case then in this case three exist inside this array and its index value is zero so we need to return zero as the answer and this is what is being asked for this problem so now let's see that what are going to be couple of different approaches to solve this problem the first approach we have is a brute Force approach in The Brute Force approach what you can do is suppose this is the ARR we are given and we are given the target value to be zero well if we see what we simply do is we start iterating over this array uh one by one and every single time we iterate until we find the value that exist if the target value exists inside this array whatever its index position is which is three in this case we return that as the answer and if we somehow reach to the end of this array and we do not find this target value we simply return that okay the target do does not exist right the thing is this solution is not the most optimal solution why because the time complexity for this solution is going to be bigo of n meanwhile if we read the problem statement we are explicitly told that we need to complete this in bigo of log and time complexity and this big go of n is just just not good enough okay before we come up with the optimal solution first let's understand couple of Concepts regarding the sorted arrays right for the sorted arrays uh if we compare any left element with any right element uh if we at any point identify that left is actually less than right and we know that this given array is a sorted array right and this left is actually less than right so if that is the case all the elements between this left and right will be sorted in ascending order that is one of the properties of a sorted array we already know that now uh the tricky part we have is that the array we are given is actually rotated so the thing is we will have to take care of this rotated part as well and we don't know that how many times it has been rotated so suppose we are given an array like this this has been rotated few times right now whenever we compare the left element with the right element initially uh we can clearly see in this case that left is actually three and right is actually two which means left is actually greater than right and remember we already know that when left is less than right we already know that all the elements in between they are actually sorted and if we are trying to find some Target value that falls between this left value and this right value we can immediately find that Target value suppose we are given the target value to be three we know that left value is zero and right value is five so because of that this target value has to be somewhere between this 0 and 5 because it it can only exist between 0 and 5 because this portion is sorted three cannot be outside of the scope the thing is we cannot say that for certain in this case because over here currently if we see left is actually greater than right which means we can determine one thing that this whole portion is not sorted but thing is we already know that a chunk of this portion is sorted which is this that 345 this is sorted in ascending order again same way this 012 that is also sorted in ascending order why because this was a rotated array right so the thing is what now we are going to do is we are trying to find some Target value right so our aim is that suppose we are given the target value to be four right now we are trying to find the value four the thing is for this rotated array the idea we are going to use is that when we determine that left is actually greater than right which means that this whole portion is not sorted right that is the key part this whole portion is not sorted but some chunk of this portion has to be sorted and that we can determine by defining some middle value so in this case suppose we put down a middle value so so suppose we have a middle value that is zero right now with this zero what we are going to do is we are actually going to compare this left with this middle value if we compare this left with this middle value left value is equal to 3 and middle value is equal to Z so if that is the case left is actually greater than middle value so since that is the case we are we won't be able to do much over here and uh basically what we will do is now again we are going to compare this middle value with this right value So currently middle value is actually zero uh the right value is actually two so middle value is actually less than right which means because this was the rotated array we can determine that all the values between this middle value and this right value is actually completely sorted this is the important property that we have to Define that this whole portion is completely sorted because of that now we will see okay our Target value is actually Four uh the current middle value is 0 current right value is equal to two which means four does not fall between 0 and 2 because it does not fall between 0 and two we can concretely say that four cannot be part of this particular chain so immediately we can ignore all of these cases and now what we'll do is we will shift our right pointer to One Step before mid why because we were certainly able to say that this sorted property of this rotated sorted array help us determine that four is not part of this one all the elements between these portions were between 0 and two now we are going to move our right pointer over here so let me clean this up a bit so now currently our left pointer is here right pointer is here right now if we see left is equal to 3 right is equal to 5 if that is the case left is actually less than right and this is what the golden thing we wanted now we can clearly determine that this whole portion 3 4 5 that is completely sorted because this is completely sorted all we will have to do is just use binary search uh in order to find the target value so what we are going to do is we are going to compare uh the middle value so middle value in this case is four four is actually exactly the target value we are looking for so we will return the index position of four which is one in this case as the answer and the answer over here is going to be the one that we are going to written now after explaining this whole thing let me quickly go over one of the examples to see that how we will solve optimal solution using binary search okay so now as mentioned we are actually going to do the binary search operation on this rotated sorted array right and the target we are trying to find is the value number zero now now we are going to use our two pointers so first pointer we have is left that is located at this position number three and right pointer is located POS this position number two in this case currently left is actually greater than right which is not what we want so now we will have to determine that which portion of the array is sorted and based on that where this target value could lie so we are going to compare with with the middle value so in this case the middle value is going to be seven right so now we have this value number 7 that is located as the middle value okay now for this middle value we are going to compare it with left and right value So currently if we see left is actually less than middle value and this is what we wanted the moment we identify left is actually less than middle value we can clearly determine that this whole portion is completely sorted okay now we will compare the target value we are looking for with the values of left and mid so if we see the target value is actually outside the scope of this left and mid which means that Target value cannot exist between these places immediately we can determine that so we will ignore all of these cases and now we will have to update our left pointer to go on the right side of the middle pointer so we will do that so now we will have our left new left value the located at this position and the new right value located at this position now we are again trying to find the value zero okay now immediately over here we can see that left by itself is actually zero so that makes our life much more easier and we can simply return the index value of this left to be five as the answer and in this case we are going to return answer as the five and basically all we are doing is we are actually using the middle value to determine that which portion of the array is sorted depending on that and based on the target value we decide that which way we will have to make the jump and then we get our desired answer if we see time complexity in this case the time complexity is actually going to be big go of log n Only why because uh remember in a single iteration we were able to get rid of all of these elements immediately which means every single iteration we are doing like half uh we are getting rid of half of the elements so that is why the time complexity is log n and that is what we wanted if we see space complexity in this case the space complexity is actually going to be constant space because we are not using any any additional data structure first of all we are going to Define couple of variables left and right okay now we are going to initialize our while loop that while left is less than or equal to right and inside our Loop first of all we are going to calculate the mid pointer now we are going to check for the condition that if the given value of mid if that is equal to Target if that is the case we can simply return the index at Mid okay if that is not the case now we will have to first of all Define that which portion of the midp pointer is actually completely sorted so first let's put the condition that if the given value of left if that is less than or equal to whatever the value of mid is if that is the case we can Define that the values between left and mid is completely sorted right so now all we will have to do is we'll have to see that where Target lies does it lies between left and mid value or it lies somewhere else so first we are going to see that what if the target lies outside of left and mid value if Target lies outside basically we will have to update our left pointer to go mid + one and we will continue with our journey if that is not the case we which means Target lies between left and mid and if that is the case we will have to update our right pointer to come between left and mid so we will do right equal to Mid minus one okay now uh we take care of the scenario that the numbers of left is not less than or equal to Mid which means that the values between mid and uh right is actually sorted and if that is the case again we are going to repeat the same process first we are going to check that whether the target value is outside the scope of mid value and right pointer so if the value is outside of the scope which means we will have to update our right pointer to search on the other portion of the array so right is going to become mid minus one and if that is not the case which means that the values lies between uh mid and right value if that is the case we will update our left pointer to search between uh mid and right so left would become mid + one and basically this uh loop should take care of the scenario and we would be able to find our answer and uh just for the sake of putting something outside so we don't get a compilation error we are going to return minus one but our answer would have been returned by this now let's try to run this code okay seems like our solution is working as expected let's submit this code and our code runs pretty efficiently compared to a lot of other Solutions and I would be posting the solution in the comments so you can check it out from there thank you today we are going to do threeome lead code problem and it is a very interesting problem if you see some of the companies where I want to get a job who already asked this question there are companies like Amazon Microsoft Apple Facebook Uber Bloomberg Google Tesla F dance and Linkedin so that's why I'm paying my atmost attention I hope you also enjoy the video so this is a lead code medium problem and also a very well-like problem on lead code basically we are given an integer array called nums and we need to return the tripletes now we need to return the tripletes such that the sum of all of those triplets is actually equal to zero and we are also given the definition that the elements has to be unique so i j and k is supposed to be the triplets and they should not be the same they should be different values we are also told that the answer set must not contain any duplicate tripletes so this is an additional set of complexity that we will have to take care of now let's try to understand this problem with couple of examples that are provided over here and I have actually broadened these examples so let's try to understand them so suppose this is the input array we are given we need to find the triplets such that the sum of each all the triplets is equal to zero so if we see that in this example we can actually find the sum of these three values to be zero so first of all we are going to add these three entries into our answer that Min - 1 0 and 1 uh this triplet equals to Zer so we can add that to our answer list uh second triplet we can find is the value -1 again Min -1 and value + 2 because -1 + -1 + + 2 is also equal to Z so again we can add it to our answer Set uh that 2 -1 and -1 is the answer now apart from that we cannot find any more triplet so this is the only answer we are going to return one critical thing to understand over here is that this minus one is actually using two times in two different answers that is perfectly fine but we cannot have an answer where we already have the value like -1 0 and min-1 and again we have the value minus 0 and + one this should not be the answer so this is one of the conditions that is given uh second condition is that all the values of i j and k has to be unique so they are located at unique positions because we cannot use the same value again and again we cannot do something like 0 plus 0 + 0 equal to 0 and return that as the answer of the triplet because in this case we only have one zero not three zeros so just keep all of these things in mind if we take a look at the second example over here we actually do not have any pair that equals to zero right so in this case we are only going to return an empty array as the answer and basically this is what the problem is asking us to solve now there can be two potential solutions for this threeome problem that we are trying to deal with uh first solution is actually a twosome problem solution that is also another lead Cod problem where we use hashing to generate the solution for this twosome problem uh second solution is two some two problem where we actually use two pointers to come up with the that solution and in this case we are going to see that how using hashing we can solve this threesome problem or how using two pointers we can solve this three threesome problem because both of this concept can be useful uh we can choose either one of them now I'm going to show you uh the theoretical knowledge of both the problems but I'm only going to show you coding for this two some two problem let me know in the comments if you want to see the code for this two some problem as well and I can show it to you okay so first let's see that what is going to be the optimal solution using the solution we used in the twm problem now if you want to know more about two suome problem you can check out my video over here and that is going to give you much more clarity okay now let's get back to the our question so if we suppose this is the original input that we are given and we are trying to find a set of tripletes that sum up to zero right which means we are trying to find three different values where I + J + K is equal to Z okay that is the whole idea the technique we are going to use is that okay suppose this this is the first value right suppose if we consider I is equal to - 5 once that is done what we will have to do is we will have to try to find that if J + K is equal to + 5 if that exist inside this remaining array if that is the case then we would actually have a triplate called I + J + K that sums up to 0 because I is equal to -5 J + K is equal to + 5 and now we simply need to see that inside the remaining array do we have a pair J plus K that is equal to + 5 and that was the original question for this two some problem so that is how everything is linked internally the idea is okay that we can find it easily using a hash map or a hash set and then we would be able to get this answer the problem that would come in this case is that because we are trying to avoid duplicates and what would happen with this approaches that okay suppose if we consider I is equal to-5 right we would actually have an answer where the values of - 5 0 and + 5 exist as one of the answer and we are able to generate this okay so now we are able to say that okay this minus 5 we have already taken care of and we found the correct answer but if we look somewhere inside the remaining array we would also find another minus 5 so when we try to repeat the same logic basically even for this minus5 we will also have the I equal to - 5 and we will try to find J + k equal +5 then again we would have another answer that also looks like - 5 0 and 5 and remember remember these is going to be the duplicate value that we are trying to avoid so in order to make our lives easier what we can simply do is if we take this input array and if we sort this input array and because if we when we sort this input array we are going to have the same looking values right next to each other so we can only have a condition that the moment we find out that two adjacent values they are same if that is the case that if we find the two adjacent values to be the same then we are simply going to ignore that case and move on to the next okay so now after this whole explanation let me clean this up a bit and create the sorted array so now we have our sorted are right now we are trying to we will try to see that what could be the potential i j and k values now based on the I value we will also have to determine that what should be the J plus K value and based on the J value we will also have to determine that what should be the K value right that is how we are going to do the things so first let's try to see that if I is equal to - 5 if I is equal to- 5 we will have to find J + k equal to + 5 if we have to find J + k equal to + 5 we'll try to start iterating over this remaining array again we are going to create a hash map or a hash set over here so let's create a hash set first okay now uh we are going to start iterating over all the remaining values okay so suppose this value is minus5 so we'll try to consider J to be minus 5 if J J is equal to be minus5 then K has to be + 10 and now we are trying to see that okay we'll see that if this K is equal to 10 exist if that is the case we will return that if it does not exist we are going to add that value to our hash map okay okay so because K is equal to 10 does not exist we will have to add all the values to our hash map and remember there is a property of a hash set where it does not exist duplicate value so we will only have unique values inside over here so since J is equal to -5 didn't work we'll try to see that whether J is equal to-3 works or not so if J is equal to -3 then in that case we will need the K value to be+ 8 uh Plus 8 also does not exist and we can look that up immediately because of this hash set right now we'll try to find another value okay so if that didn't work we'll try to see that whether J is equal to0 works or not okay so if J is supposed to be zero then the value of K has to be + 5 okay that we can look up immediately and we would be able to find that K is equal to + 5 already exists inside our hashmap so immediately we found that we are actually going to have an answer list where we are going to populate the values of i j and k we found okay so we are going to add the values - 5 0 and plus 5 immediately now we are going to repeat the same process for the all the remaining values right so and uh for every single value we will also have to create the new hash set and new i j and k values so we will empty this one okay now the new I value is actually minus5 the thing is this is a track because we already had a value minus 5 that we already iterated over so we will not have to use this one and that is how we are going to avoid duplicates now suppose if next I value is - 3 okay so if I value is minus 3 then J + K has to be + 3 okay so if J + K has to be+ 3 Let's see that what could be the potential remaining J plus K values over here okay so over here currently J value is zero so if J value is zero then K value has to be plus three okay so we'll try to see that inside the remaining array whether plus three exist or not plus three does not exist but that is going to help us F fulfill our hash so we are going to add all the entries to our hash map and uh we couldn't find K is equal to 3 so now we are going to try the new value of J J is equal to 0 so again because this 0 we already consider for J we should not be considering this zero so we can just simply jump over okay so now next value is J is equal to 1 if J is equal to 1 we will try to see that whether K is equal to 2 exist or not and K is equal to 2 already exist that we can clearly see over here so because it exists we are actually going to have J and K values properly set up and uh we are also going to add one more triplet to our answer answer that is - 3 1 and 2 okay now we can ignore this one okay now current I value is zero okay if I value is zero then J + K has to be zero okay so now we are we will try to find J + K to be zero now inside the current method okay now this next value of J potential value of J uh this is the zeroth value so we'll try to add this value by the way I forgot to clear the hash but it would be cleared okay now uh if J is equal to 0 then K also has to be zero okay so currently K is equal to 0 does not exist inside the remaining array so because it does not exist we will try to jump onto the next value of J if J is equal to 1 can work or not so if we try to put J is equal to 1 it is definitely not going to work and we won't be able to find a pair J + K is equal to 0 so I is equal to 0 is also not going to work because I is equal to 0 not going to work uh and U and we are we have already taken care of this zero so which means we don't have to see for this zero now we'll try to see that whether I is equal to work or not but the question is do we really want to check whether I is equal to work one is going to work or not because inside the remaining array all the values are actually going to be positive values so because these values are going to be positive values J + K is always going to increase the value of whatever the sum of i j and k is going to be because this I is positive so immediately we can stop our search and whatever the answer we have found we can actually return return that as the answer and that is the whole approach and if we see time complexity in this case the time complexity is actually going to be big of n log n that is to sort the array plus bigo of n Square why because for any single I value we will have to find J and K value which means for every single one of them we will have to iterate over the entire list of all the arrays so that takes like Bas we go of n square and that is the best we can do if you see space complexity space complexity is going to be big of n because for this sorting operation it takes big of end time and plus we are also creating this hash so that also takes big off end space okay now we will try to see that what is going to be the optimal solution using the two sum 2 problem now if you want to learn more about this problem you can check it out my video over here and this is a very good explanation for that now uh we are going to use the same example as the input and as mentioned for the reasons explained before basically we are going to use the sorted array in this case as well so from this original input we are actually going to create a sorted array first so that is going to help us avoid duplicates now the again idea is that currently we are going to consider the one value to be I okay so suppose we are going to consider I is equal to Minus 5 if that is the case J and K value could be po potentially possible where J + K is equal to + 5 right and inside this remaining array we will have to find the plus 5 value so what we are going to do is we are going to initialize couple of variable Ables uh so first is going to be left pointer and second is going to be right pointer now every time we are going to do left plus right if left plus right is equal to 5 then basically we are good our life is set and we can simply add it to our uh J plus K values if that is not the case if we somehow find that left plus right is actually greater than five if that is the case then somehow we will have to reduce the sum of this left plus right how can we reduce the sum of left plus right by shifting this right pointer on the left Point left hand side why because all the values on the left of this right pointer are actually less than whatever this right value we had and if somehow we identify that okay this left plus right is actually less than the answer five if that is the case we are going to update our left pointer to go one step on the right side so then we would be able to increase the sum that we are trying to achieve and that is how we would be able to generate the correct J and K values so let's try to see the approach in action so suppose currently the the I value is equal to -5 okay I is equal to - 5 J + K is equal to + 5 we are trying to find so once we have the J + K value we are trying to find we are going to initialize two variables left and right okay so currently our left pointer and right pointer we are going to be concerned with that and we are also going to be concerned with left plus right sum and uh how that is referring to whatever the value we are trying to find okay so currently the target value is five okay now the current left position is minus 5 current right position is + 5 so left plus right is equal to 0 0 is actually less than minus 5 so because 0 is less than minus 5 we will have to update the value of our left pointer to go one step on the right so now the current left pointer is - 3 - 3 + 5 so if we do - 3 + 5 the value we get is 2 2 is still less than 5 so because 2 is less than 5 again we are going to update our left pointer so now the left pointer is at zeroth position right over here uh and uh currently the sum we are going to get is that okay this is 0 this is 5 so 0 + 5 is equal to 5 So currently left plus right is equal Al to 5 5 is exactly what we are looking for based on this remainder value we have created okay so now this left pointer can be assigned to this J value and right pointer can be assigned to this K value and we can actually populate our answer so inside our answer we are going to have the first entry called minus 5 0 and + 5 as one of the answer okay now we are done with taking care of this minus 5 so now we'll have to take care of this another value but again same thing this value is also minus same as the previous value so again we are going to ignore this case as well and now currently our I is going to be minus 3 okay so now if we put our I to be minus 3 uh our J + K sum has to be + three in this case Okay so J + K has to be+ 3 again if j+ K has to be+ three we will also have to update our left and right pointer So currently left pointer is also going to be at the position zero right is going to be position number five okay and we will also have to update this value as well that this has to be three okay now uh currently 0 + 5 is actually 5 5 is actually greater than three so because 5 is greater than three we will have to reduce the value of our right pointer So currently our right pointer is going to come over here so now the right pointer value is actually two okay so if we do 0 + 2 0 + 2 is actually going to be three so three uh sorry so now if we do 0 + 2 0 + 2 is actually going to be 2 2 is now less than whatever the value of three is because of that we will have to update our left pointer to go on the right side now the moment we do that okay this value is also zero same as the previous value so because of that because we have already calculated this zero we are actually going to ignore this zero as the left pointer and our left pointer is going to come over here okay so now the value of our left pointer is actually 1 so 1 + 2 so 1 + 2 is actually three and three is what we are looking for that we already find the answer so we are also going to populate the values of left and right over here and inside the answer we are going to have one more entry called minus 3 + 1 and +2 okay now uh okay now we have taken care of all the cases now again this value I is equal to 0 if I is equal to 0 we will not be able to generate the answer and now in this case I is going to be one so that is going to be the positive value so because of that we are actually going to break out of it and simply whatever the answer we have found we are able to return return that as the answer using this two pointer solution and even for if we see the time and space complexity in this case the time complexity is also going to be big of n² plus bigo of n log n why because we will have to do the Sorting operation if we see space complexity the space complexity is also going to be big of and that is going to depend on the implementation for the Sorting we are using uh so that is how we are able to generate the solution if you see in this case we are actually not using any additional H set so that is a plus benefit in my opinion and if you show both the approaches in any interview interviewer would be like more than happy with you so first of all we are going to sort the given input nums and we are also going to create a new variable called result to store the list of list that is needed over here now we are going to run a for Loop across the given input nums notice inside the for Loop we are only running it up until the point where the value of nums of I is actually less than zero uh and the moment it gets greater than zero there is no point in continuing with the loop so we just simply ignore that now inside the loop we are actually going to call over two Su two function but for that we actually have couple of conditions that we are going to take care of so first condition is that if the given value of I is equal to Zer or the starting position then we do it or we check that whether the two adjacent values of I and IUS one are they same or not if they are not same then only we call our two sum two function otherwise we ignore that particular entry inside the method uh we are going to call the two sum two method uh where we are going to pass in the value of the given input integer nums the current I position and the result uh variable and basically that's it once this for Loop ends basically by with the help of this two some two method our result should have been populated so we can simply return the result now it's time to create the new two sum 2 method first of all we are going to initialize two pointers called left and right now we are going to have our while loop that while left is less than right we are going to do some interesting things first of all we are going to have a variable called sum that is going to calculate the current total sum now we are going to check that if the given sum if that is less than zero if that is the case we will have to increase the value of the left pointer else if we are going to check that if the given sum is greater than zero if that is the case then we will have to reduce the value of our right pointer and if both are not the cases which means our current sum is exactly zero so first of all we are going to add a new entry to our result uh variable that we have created after adding the values to the result we will again have to update our left pointer until the point that whether the two adjacent values of left pointer they are same or not basically that's it this should have taken care of all the scenarios and uh this should be working now let's try to run this code okay seems like our solution is working as expected let's submit this code and our code runs decently efficiently today we are going to do container with most water lead code problem and if you see some of the companies where I want to get a job who already asked this question there are companies like Amazon Apple Google Microsoft Facebook Goldman sax bite dance Bloomberg Tik Tok Uber and Tesla so that's why I'm paying my atmost attention I hope you also enjoy the video this is a lead code medium problem and also very well- like problem on lead code and like any lead heat Cod problem we are given some input and we are expected to get some results from this particular input but before we start understanding this problem uh first let's see this concept that I'm trying to explain okay so suppose we are given a container that looks like this and we are trying to see that how much water can we fill in this container well the logic is actually quite simple we can only fill water up until this point inside this given container uh anything more if we try to add water over here that water would simply spill out we won't be able to fill our water above this line so that is a given fact right that is a very simple explanation now if I ask you that how much water is present in this container so then in that case the answer is simple there can only be water up until this point nothing more than that so in this case uh for this particular container rather than considering this container to be a container if we consider this to be a rectangle things becomes easy for us because we know that uh the surface area of rectangle is the amount of water we can store in this particular container and we know the formula to calculate the area inside any given rectangle suppose this is the height of the container and this is the width of the container if we are given these two values basically if we do H * W height crosses height multiplied by width we will get the amount of area and that would equivalent that how much water we can hold in any given container now let's uh try to understand another scenario suppose we are given a container that looks like this or we are given a container that looks like this in these two cases how much water can we store well the answer is again simple we can only fill water up until this point till the lower Edge on On Any Given container not more than that so now in this case we are actually given two different heights for each sides of the given container right so suppose this side is H1 and this side is H2 and same goes over here this one is H1 and this one is H2 if that is the case if we try to calculate the area in this case the area equation for the water is going to change why because we are not going to use H1 over here because this is the higher side we are actually going to use H2 which is the Lower Side so in this case uh the area is going to be H2 * width for this particular container but for this particular container the equation is actually going to be H1 * width because this H1 is actually smaller in this case so these are the two concepts that you will have to understand and now let's go back to the problem okay so now in the problem we are actually given an array called Heights of length n and now if we try to plot this array of height in on a graph we can consider that based on the x-axis we can actually create a container and then we need to find that what is the container we can create that contains the most amount of water and then we need to return the amount of water that the maximum container can store now I know that the wording may sound confusing so it would be better by understanding with this example suppose we are given an array Heights like this so if we try to plot this array Heights on a graph we can actually get a graph that looks like this now in this graph you can see that there is a difference between lines and based on these line differences we can actually create some sort of containers between any two vertices uh and the amount of water we can fill depending will depend on the Lower Side of the height rather than higher side of the height so in this case we can actually create a container that looks like this so if we try to consider this index number one and index number four uh the container we can create is going to look like this where this is the amount of water we can fill nothing more than that now remember as mentioned earlier that for every single time if we want to calculate that what is the amount of water we can find we need to calculate the area of the presumed rectangle and for that we need the height which we already have based on these values which we can derive from the array and we need the value of the width so width we can achieve by calculating the difference between any two places uh on the x-axis and uh these values we can determine depending on the index values of the given input array so it makes our lives easier uh so in this case if we try to see that some of the containers that we can make we can make a container that looks like this among these two values and then we can calculate its water so I'm just showing you for an example so in this case the minimum height is actually five so height is going to be five and the width in this case is actually going to be 2 so 5 * 2 we can see that okay there is 10 units of water we can put in this container if this was to be the be the container the thing is we are trying to find the maximum maximum water we can make amongst any given container so in this case the answer is actually going to be this container uh where the current height is 7even among seven and 8 so we are going to choose 7even as the height okay so h is equal to 7 so okay uh it's going to be 7 * the distance so distance in this case Okay this value is 2 and this value is 9 so distance is also 7 so in this case 49 is the maximum unit of water we can contain and that is going to be stored between this container uh and basically I hope that this makes understanding this problem easier and after understanding the problem now let's focus on different solutions that we can achieve the first approach we have is a Brute Force approach and suppose this is the input we are given if we try to plot it on a graph we can actually create a graph that looks like this now the idea is we are actually going to check every single container that we can possibly make and depending on that we will try to see that what is the what container contains the most amount of water so basically we are going to have two variable first variable is called area to contain to calculate the water at any given container and second is going to be the max variable that is going to be update its value whenever we find a better area or maximum water we can contain right so first we will start with this first index and we will try to see that okay what is the container we can make with between the index one and two we can make a container that looks like this what is the container we can make between 1 and three we can make a container that looks like this uh and say so on and so forth we will keep on repeating our uh graph after being done with this value number one we will ignore that and we will start focusing from value number two so from value number two we can make container that looks like this and then again a container that looks like this and blah blah so on and so forth and eventually we would find an answer in this case between this value number two and 7 indexes that if we make this container that is going to hold maximum amount of water and in this case the answer is going to be okay so for this area height is going to be four because that is the smaller among these two and the width is actually going to be five because 2 - 7 is five so maximum area is going to be 20 and 20 is the answer we are going to return so this solution would work as expected but if we see the issue with this solution the issue is actually time complexity why time complexity because for every single value we are comparing it with all the other values to see what is the container we can create and we are not doing things efficiently so basically the time complexity in this case is biger of n Square which is very bad and we will have to do something better so let's see that what is the better approach we can get so for the optimal solution we are actually going to use two pointers to our advantage and we will try to see that what is the optimal container we can make so we are going to have a pointer left located at the first position and we are going to have a pointer right located at the last position the idea is both pointers are going to come towards each other until they meet or cross each other now every single position we will try to see that depending on the values of left and right what is the container we can make uh and then we will try to calculate its area and after calculating the area we are going to compare the heights between left and right and whichever has greater height we are going to keep that height and then we are going to update the remaining counter so left cter counter will go on the right side or right right counter will come on the left side uh so let's see the solution in action and it will make more sense so basically uh initially first if we see currently the height at left is three and height at right is two okay so if we want to calculate the area we are going to calculate the smaller amount okay so currently the smaller height is actually two and if we see the width width in this case is going to be 7even okay so current area we are able to calculate is 14 we are also going to have a variable called Max area so currently the max area we have been able to find is 14 okay so far so good now we will try to compare the heights between left and right okay so currently left height is actually greater so it is in our interest to move right counter one step to the left rather than moving the left counter okay so in this case right counter is going to come at come over here now again we are going to repeat the same process so now currently the height at right counter is six and left counter is three okay so now if we we will have to calculate the area again so we are going to choose the smaller value amongst the height So currently this is going to be three as the smaller height and width is going to be six okay so currently the area we can get is 18 18 is greater than 14 so we are going to update the maximum area maximum water we can contain to 18 uh now we are going to compare the height between left and right now in this case the height at right is actually greater than left so we are going to update our left pointer to go one step to the right uh now this left pointer is located over here currently the height is two again we are going to calculate the area so this height is actually going to become two and the width is actually going to become 5 so 2 * 5 is actually 10 uh so because 10 is less than 18 we are not going to update the maximum value we have been able to find again we are going to calculate the heights between left and right so again right height is greater so we will update the left pointer to go on one step on the right side uh now currently the height over here is 7 and uh currently the other height is six so we are going to choose the smaller height so the height we are going to choose is going to be six uh six times the width is going to decrease okay so currently the width value we have is going to be okay this is uh okay this is left pointer so 3 - 1 4 okay so 6 Time 4 and so this area becomes 24 24 is actually greater than 18 so because 24 is actually greater than 18 we are going to update the maximum area we are been able to calculate okay so this is 24 now again we are going to compare the heights between the left pointer and right pointer So currently right pointer is actually less so now we will have to update the value of the right pointer So currently this becomes our right pointer now this value is three this value of left pointer is seven so again the height is actually going to be three and the width is going to be three as well so this is going to be 3 * 3 so this is 9 we we don't need to update the the max value again if we compare the heights the right is actually smaller so again we will update the value of the right counter so now this time the right counter is reaching at this value number one so if we calculate the this container this container the uh area is actually going to be two so uh 2 * 1 so 2 * 1 is only 2 so we don't need to do anything again we will update the right counter so currently the value of route right counter is four and the left counter is seven okay so we are going to have a container that looks like this so so 4 * 7 uh sorry uh 4 * 1 is going to be 4 as well uh so then we in this case we don't need to update the max value and if we try to update the left or right variable again that they would cross each other so because they would cross each other now we can end up get out of our Loop so whatever the maximum result we have found so far that is going to be the solution we need to return return so in this case the answer is actually going to be 24 as that this is the maximum units of water we can contain between uh basically this container this water container and uh that is the answer we need to return return uh if you see the beautiful thing about this solution uh this whole solution gets completed in a single iteration uh between these two pointers and if we see time complexity in this case the time complexity is actually going to be big off n Only which is much better Improvement compared to our Brute Force approach which had the time complexity of big of n Square which was really bad so we can avoid that if you see space complexity the space complexity is also good because apart from using couple of pointers we are not using any additional space so space complexity is actually constant space which is wonderful uh and uh this is a very good approach and a very good way to learn two pointer problem and uh I hope you understood it now let's move on to the coding first of all we are going to initialize couple of variables so first variable is going to be Max and that is that we are going to initialize it to zero uh then we are going to initialize two pointers left and right and left is going to have the value of zero and right is going to have the value of whatever the length of Height's array is we run our while loop that while left is less than right now first of all we will have to calculate the width so width is going to be right minus left so now we have the width and we already have the height from this Heights array we will calculate the area so this uh equation should give us the area we are selecting the Lesser height amongst right height and left height and uh now we will see that whether we need to update the max value as well and now we will have to update our left or right pointer so we will check that okay if the current height of left is that is less than or equal to the right height we will update the left counter if that is not the case we will update the right pointer to go one step on the left side and uh in the end we can simply return the max variable that we have calculated and that should be it let's try to run this code okay seems like our solution is working as expected and our solution runs pretty efficiently compared to a lot of other Solutions and I will be posting this in the comments so you can check it out from there thank you today we are going to do a very important problem uh climbing stairs though it's a lead code easy problem everyone should do this problem because it gives you a really good introduction towards dynamic programming and this is one of the Core Concepts that lot of companies likes to ask uh so let's understand the problem statement We Are Climbing the staircase and it takes end steps to reach to the top and uh every time we can either climb one or two steps and uh we need to show that how many distinct or how many separate ways can we climb to the top we are going to understand this problem with three examples suppose uh we only we are only given just one step and we need to climb that one step so how many distinct way we can climb that step only one because we just take one step and we are already at the top so there will be only one distinct ways we can climb to the top suppose we are given two distinct steps and we need we are trying to reach to the top so this is our first step and this is our second step uh the distinct ways are actually two uh one way is we take First Step at the first step and we then we take one step again so this would be our first uh approach and second way we can directly take two steps because remember we can either take one or two steps so if we directly take two steps we will still reach at the top so in this case we can do it in two distinct ways uh for the third example suppose we are given three steps that and we need to find that how many different ways we can climb that apologies on my painting I'm not the Pablo Picasso of this generation for sure the first way we can climb over here would be the most simple one that we take one step each time to to reach to the top second way would be to take two steps directly at the beginning and then take one more step and the third way is that we take one step at the beginning and then we take two steps other than that there are no other possible ways to reach to top apart from these three so the total number of different ways we can reach to the top for the staircase number three is actually three and now that we understand that what we need to calculate let's see what could be the different approaches our first intuition is that if we start at the Step Zero and suppose our n is equal to five that we need to calculate if we take the decision that at every single level we are either going to take one step or two steps uh and then when we reach to number five we will calculate that how many distinct ways we took to reach to Value number five and then uh all the combination of all those uh distinct ways would be uh the separate ways we can reach to five so that would be our answer and this is the most primitive approach we can take so let me show you how it would look so at the beginning at Value number zero we have two possibilities we can either take one step or we can take two steps and we can reach to the Second Step suppose we only take one step then again we have two possibilities we can e again take just one step and we will reach to two or we would we would take two steps to reach to the step number three again same so over here we will reach to three and over here we will reach to four and now over here we would reach to four but notice that at the four we only have one possibility we can only take one step because if we take two step we reach to six Which is higher than our given input so we can only take one step and now we have reached to the final point that we can reach to uh but at the four we still have and even at the three we have possibility to reach at four or we can take two steps directly and we can reach to five so over here again we end our possibilities but at Value number four we would take one more step and we can reach to Value number five now at this value three we still have two options we can either take one step we would reach to four again we take one step we would reach to five or we can take two steps directly and we can reach to five now we have exhausted all the possibilities from zero to left side of the subtree if we take the first step as one so now let's explore the possibilities on the right side notice that at all the elements where I have done the square or number five shows a distinct way so suppose for this one the distinct way would be just to keep on taking one step each time for this one we are taking one step up until the U the third step and then we are taking the two steps so if we calculate all these values the number of different ways we can do this is 1 2 3 4 5 6 7 and 8 So based on this we can determine that there are eight distinct ways we can take if we are given the N is equal to 5 and if we want to climb the five step stairs so we can have a recursive function that at every location of n would uh would call itself uh for I + 1 and I + 2 while I is less than or equal to n and we would be able to reach out to this solution but the issue issue with this solution is this is highly inefficient and if we see over here at any given node we are doing we are making two decisions and based on those two decisions we are again making two decisions down the line so pretty soon if our value of n goes High we would be running out of the possibilities and the time complexity for this approach is actually 2 to the power of n where n are the number of nodes or in this case number of stairs but this is a pretty heavy time complexity and we should avoid it in all cases so let's see that what are the better approaches we can take the first approach we can take is actually to reuse the work that we have already calculated if we see this graph it becomes pretty evident that we are doing lot of repetitive work every single time suppose if we just take this left side of the route and we have calculated the results up until this point we know that whenever we are at Value number four there is only one possible way to which we can reach to the top and we are doing this work again and again and again at different locations again same thing happens when we are at Value number three if we are at Value number three there are only two distinct possible ways we can reach to Value number five so even when we are at Value number three suppose we have calculated that over here when we are at Value number three we only have two distinct ways to reach to Value number five why are we doing all of this repeated work over here then again over here this could be avoided and same can be avoided for the work done at Value number two we calculate towards this route and we calculate all the possibilities so we know that from value number four there can only be one distinct route from value number three there can only be two distinct route and from value number two there can only be three distinct routes possible so we can use this to our advantage if we know that at Value number two we can only have three possible uh different V values we can directly use that over here and we can get rid of all of these values because we know that at Value number two uh when we reach to the Second Step there are only three distinct possible ways to reach five again same thing would apply over here that at Value number three we know that there are only two distinct ways we can reach to five so at after the first step whenever we reach at the third step we can directly say that there are only two distinct possible ways we can reach to five and not we don't we won't have to do all the calculations same over here whenever we reach at four we know that there is only one distinct route we can reach because we calculated it over here so we can again get rid of this step we will simply put it over here and we can just say that there is only one distinct ways we can um reach so using this we are able to avoid lot of extra work that was being done so let's see that what would be the approach for this solution would be where we are storing all the results that have been previously calculated uh in some sort of an array and we are going through the nodes so notice that we are only going through the nodes once and then whenever we encounter those nodes again we are using whatever values we have stored uh beforehand and we are reusing that so the amount of work being done is actually pretty small and if we see the the time complexity for this approach the time complexity is actually bigo of n because in one single iteration we are able to determine all the distinct ways that we can reach to five and then we are just reusing those values at different positions in the given Loop and if we see the space complexity the space complexity is also bigger of n because we will have to create some sort of data structure to store the values of all the distinct ways we can reach to five uh at any given location if we see if we consider this from our Brute Force approach this is actually a much better Improvement but can we still get a better result suppose our given value n is equal to 4 we can represent it like this and now let's try to understand the logic behind that how can we calculate that how many number of different ways are there to reach each four first we have to determine that what are the direct elements or direct values from where we can directly jump to four so we know that we can either do one jump One Step jump or two step jumps so from three if we do one step jump we can directly come to four and from two if we do a two-step jump we can directly come to four now this is a really important thing to consider what this essentially is telling uh telling us that no matter how many way how many different ways we can reach to this value two if somehow we can reach to this value two all of those ways would allow us to reach to Value number four directly so let me show you how what I mean so we know that there are two distinct way to reach to two our first way is we reach to one and then from one we reach to two and once we are at two we can directly go to four now second way to reach to two is that at the beginning we directly take two steps forward and we reach to two once we are at two we can directly go to four and this would also be a distinct route but in both the cases the common thing is that we found out the number of times we were able to reach to two and both of in both of those cases we ended up at four again same thing occurs when we consider the value three that we know that from three we are just one step away to reach to four so basically all the routes that can lead up to us to reach to Value number three can lead up to can lead us to reach to Value number four and let's take an example for that as well so from the beginning we can reach we can go to one then we can go to two and then we can reach to three and that would lead us to four so this is uh one possible route second possible route is that we can directly go to two and then we can go to three and from three again we will be ending up at 4 we initially start at one so we take one jump and then we take two jump to reach to three then we would be able to reach to four so in both the cases essentially once we are at the value either two or three we end up uh being on uh this uh value four so the moment we reach to element number two or element number three we can say that from there we can directly reach to element number four and we cannot go any anywhere further from four because there does not exist any step over here so we end at four and the number of distinct way we can reach to four would actually be the summation of two Val the summation of number of different ways we can reach for Value number two plus the number of different ways we can reach value number three so suppose we Define that we need to calculate that how many distinct ways we can reach to four and this DW represents distinct ways to reach four we can calculate this as the distinct ways to that we can reach to Value number three plus the distinct ways we can reach value number two and summation of these two values would lead us to the number of distinct ways we can reach to Value number four and this is a really important property and based on this we would be able to solve our dynamic programming solution so let's clear this up a little bit basically in our algorithm we will keep track of two values uh value uh one jump and two jump so one step jump and two step jump we will keep track of these two and the initial value would be that for one step it would be one for two step it would be two and uh we can just put a condition that if the value of n is equal to 1 we would just simply return one uh because that would be our base case and uh we can't do any we can't go any further than that and now we have the values for uh first element and second element so we will start our Loop and in our Loop we will start it with value number three all the way up to n inclusive U we the reason we are starting it at Value number three is because we have already calculated the results for Value number one and value number two uh as value number one would just be one and find for Value number two the number of possible ways we can find would be in in this parameter two jump now inside the loop we will calculate this property so we will simply do do a total of uh whatever the value of 1 + 2 we have so we need to update the value for 1 and two in order to update the value of 1 and two we need to First understand that what value number one and two represents in our given example so one represents the element the position of that element from where we can if we just take one jump we can reach to our I element so if we are calculating that I is equal to 3 and we need to calculate the values of 1 and 2 1 originally one would be here and two would be here and now we we will do a total and total will give us the value for uh element number three once we are done with this and once we are going for the next iteration in the next iteration we will need to create we will need to update the values so such that uh this four uh gets the value of 3 and two so two would be jumped over here which means that two would receive the whatever the value of total we we calculated of this 1 + 2 and our value one would jump to this position and uh it will take whatever the value of formal two we had so the new graph would become like for Value number four this would become the two and this would become the one and uh when we are inside the loop we will do a total and again we will repeat the same process that we will jump our one over here and we will jump over two on this position so we will get the whatever value of total we have we will put it in the two and and uh yeah at the end of the loop we can return to so over here we would Define 1 is equal to whatever value of two we had and 2 is equal to whatever value of total we have and at the end of the loop we will just simply return whatever the value of two we found as our result and we can simply return two over here now let's understand let's calculate the time space complexity for this approach the time complexity the time complexity would be bigo of n where n represents the number of steps that we are given and for the space complexity we can calculate in bigo of one time because other than storing couple of uh parameters we are not using any additional space uh so this would be a pretty efficient solution there is also one more solution that provides the answer in actually log n time and also constant time but the thing is those are pretty mathematical and they in my opinion does not serve the purpose of checking your computer related knowledge so even in the interview if we come up with this approach and if we show that we know dynamic programming I think this would give us an edge over other candidates and this would be sufficient for us to prove that yes we are more familiar with uh computer science related Concepts and yeah we might not be up to date on mathematical Concepts but uh this is not where the what the Fang companies are judging us on now let's move on to coding okay so first of all we are going to create a condition that if n is equal to 1 we will just simply return one and now let's define two parameters for uh one step and two steps so we can say one step and and we can initialize the value as one and we can say two we can create a variable for two steps and we can initi we will initialize the value s two and now we will create a for Loop and we will create a for Loop starting from the third position because we already we already have the results for uh n is equal to 1 and N is n is equal to 2 well I is less than or equal to n i++ inside the loop first of all we will just create a variable total to store the sum of 1 + 2 and with every iteration we need to update the values of one and two so one will become the whatever value of two we have and two will actually be the total value and at the end of the loop we can simply return the value of two and this should Define the total number of distinct paths we can take let's try to run the code looks like our solution is working let's try to submit the code let's try to submit the code yeah our solution is actually 100% faster than all the other Java submissions which is pretty good to have and uh I hope you like the video let me know what kind of videos you want me to do more and I will be doing bunch of other videos on dynamic programming so it would become more evident and you can we will be able to Gras the grasp the dynamic programming concept together today we are going to work upon a very important dynamic programming problem uh coin change and which in my opinion everyone should do it at least 2 three four times until you get a real grasp of the co concept on how to solve it and uh let's understand the problem statement we are given an integer array of coins uh representing coins of different denominations and we are also given an integer amount that represents the total amount of money that we want to generate now we need to return the fewest number of coins that we can use to make up to the amount that has been provided over here and if the amount of money cannot be repres uh reproduced we need need to return minus one let's try to understand this by an example so in the given example the number of coins we are given is 1 2 and 5 and the amount we are given is 11 so suppose so based on the example we can clearly see that the most optimal way we can uh create this 11 is by using 5 + 5 + 1 so so in general this sums up to 11 and if we see the number of coins it we are actually using uh three number of coins to generate this value if we look at the second example uh basically we are only given one coin the value number two and the amount we are given is actually three so no matter how many times we use the the number of coins to we cannot generate the some ount three so in that case we need to return minus1 while in this case we would be returning three because we are using these three coins so once we have this clear now let's try to understand that what could be the different approaches we can take to solve this problem uh the first approach that comes to our mind is actually to use uh greedy approach where uh whenever we are given the number of coins uh so let's take uh a one of our own custom examples and we also need to keep in mind that whenever you are solving or giving any Fang interviews make sure to have your own Uh custom inputs because uh Fang companies really like uh this kind of stuff uh and that uh shows that you are able to think outside of the box and you can also create test cases on your own so suppose we are given an input like this and the amount we need to create is actually 8 so in our greedy approach basically we at any given moment for the given uh amount we will take the biggest coin that is smaller than this amount and keep repeating till we reach this amount now let me show you that why this approach won't work because if we see here uh the amount we have is eight and the biggest denomination of coin we can create that is lesser than 8 is six so if we take this so let's create uh our answer where where we keep track of how many coins we are using so we use six over here we take uh 8 to 6 so we subtract 6 - 8 uh we get the remaining value is two so since the remaining value is two uh we cannot use these three coins anymore because they all are greater than two and if we were to subtract this coin from two we our result would actually be negative so we cannot use that but we cannot you we can still use value number one so if we do that and if we use the coin number one because this is a greedy approach so we will add the coin number one to our answer as well and so now the remaining value will be one so again we cannot use these three values but we can still use one so we will use one the remaining amount is zero which means that we have reached our total amount of eight and we would add the value number number one over here once we do that essentially if we calculate in the answer we are using uh three separate coins to reach the amount eight so our answer would be three in this case and we would return three but notice that this answer is actually not the lowest number of coins we can use actually if we just use the coins three and five we can simply create this value eight and uh our result in this case should actually be two not three uh so greedy approach doesn't work at all now let's see what could be the next approach we we can take over here uh we are given an input like this and uh we need to reach out to a particular amount eight so at any given point uh if we start basically start calculating from zero and we will keep on making choices based on the number of coins we have until we either reach to this value eight or our choices actually becomes greater than eight until these two things happen we can keep on making choices given our uh coin denominations and based on that we can actually create our own uh decision tree and in the decision tree whenever we reach at Value number eight we will keep track of the value keep track of the path and based on that path we can calculate that what are the minimum number of iterations we have to make so initially we are at zeroth position so from zeroth position we have four options that we can take uh so let's take let's make four these four decisions 1 3 5 and six now at every single decision we still have four more decisions that we can take to reach out to the this value eight so again at Value number one we still have four more decisions we can make so let's do that and again at every single iteration we we still have four more decisions and with every decisions we come closer to this value number eight so initially over here complete eight were remaining over here we are only dealt with uh creating the value seven because we already used one coin the remaining value would be 7 so over here the remaining value would be 1 the over here the remaining value would be two over here the remaining value would be four and over here the remaining value would be six and suppose we continue on this path again we would still have four choices and notice that the remaining value we wanted to create was six which we are able to achieve over here so the sum for this particular path one again one and then again six is actually eight which means that we have found a potential route and if we see the number of coins we had to use we had to use 1 2 and three coins so current amount um current answer we need to return is actually three and since we have found this route all all the other routes if you see the values would not reach to eight and uh we can cancel out these values and basically uh because if we keep going on we will still have to make more decisions and the number of Route will be will definitely be greater than three so we can start eliminating these routes and we have one potential route over here again if we keep on going down this path of three and keep making more decisions we would would end up with an a result that would be greater than three or we would not reach eight at all so we can ignore this again we can ignore this uh from five and at 6 uh we would still find a root something like this where because notice even at six we still have four decisions we can make so we can make e we can choose either one 3 or five or six and notice that only one is remaining over here and we can select this one so we would have another potential route uh starting from one going to six and then again going to one that sums up to eight but again for this route as well we need to use three coins so our answer will still remain three and it won't be Chang but this is where we find another answer and now we have exhausted all the possibilities from value number one so we can just ignore all of this let's get rid of it so we we have something that is more uh clear and not so much congested now let's try to see that what could be the possibilities from this value number three so even at Value number three uh the remaining amount we have would be five and at Value number three we still have four more possibilities that we can choose from 1 3 5 and six and notice that in all of these possib these three possibilities uh we would not reach eight uh so we would not reach basically the remaining value would not be uh zero which means but if we get down over here five over here only five is remaining and we directly have a coin five present at the decision tree three and if we calculate the route the route would look like uh 1 and then two so basically we are only using one coin over here and we are using second coin over here so we are only using two coins to reach to this value eight so we can simply update our answer U that we have found a new minimum value that can come up as our answer and we can uh set the value as two now we can continue to search and keep on making more decision trees and uh even for those nodes we will continue to making uh further down decisions uh to see if we can find a better answer but we won't be able to find a better answer than two and eventually we would have to return this value so this solution in a way it works and it works uh as expected at least we are getting the answer but the issue with this approach is that time complexity is actually so bad it's uh not even in polom time it's simply in exponential time and the time complexity suppose the amount we are given if we consider it as M essentially until we reach this amount M we are at every time keep on making multiple decisions uh based on the number of coins that are given so we can compute the time complexity is Big go of M to the power of n where m is the given amount and N are the number of coins that are present at any given moment this is such a bad time complexity that we even if we ask NASA to run this command they won't be able to do it U more more than up to a certain values and uh we need to find a better approach and in the optimal solution we are simply going to use just two golden words dynamic programming and let me show you how we can solve this via Dynamic program programmatically and M we are just like a rational person we are just going to think it uh in terms of int intuitively that if we are given this problem just to solve on a pen and paper how we are going to do it um and one approach is that we can basically start from the value number zero we can keep on reaching towards the amount we want to reach out to uh and for every single element that we have found we will found that uh for 1 2 3 4 how many number of coins it took us uh to generate that particular amount and once we are sure with this value whatever value we have generated the amount for one or amount for two we would be able to use this uh later down the road and let's take an examp let's continue with our example and see how can we achieve that so uh we are given the example 1 3 5 and 6 and the amount we want to generate is 8 so initially we would create an array of amount from zero all the way up to amount of 8 and we will initialize all the values uh by any value that is higher than 8 so let's say 8 + 1 and now we will start start with our solution so so far all the values are actually 8 + 1 in this amount array uh and this represents that these are the number of coins that are needed in order for us to generate any particular value now if we just want to generate zero coins uh how many number of coins do we need well answer is pretty trival actually uh we simply need zero coins uh and this becomes our base case so now let's St let's say for the second value amount of one that if we want to generate value number one how many distinct coins we need so whatever value is we will check first of all in our coins for all the values uh that are given in the coin to see if we can directly use if the given coin is lesser than the value we are trying to achieve can we use that coin so since the value is one we can clearly see over here that this one if we just use one coin we would be able to generate this value one so the answer in this scenario becomes pretty simple that if we just use one coin we would be able to generate this value and notice that for Value number one we cannot use any of these three coins because they are all greater than our value one so there is no point in using them now let's repeat the process for amount two so for amount two if we want to generate the value to how many minimum number of coins we need so first of all let's check with the first value okay so coin is actually less than two so we can use this coin we will use this coin so if we use that coin basically we have already used one coin so far and we since we use coin number one and we want to achieve value two we can see that now the value we are trying to generate is actually 2 - 1 so again value number one now we want to generate value number one and if we we can do to either two things either we can go back to all these coins again we try to generate that value or notice this beautiful thing over here that we have already calculated that if we want to generate amount one how many coins we are going to need so why are we being so picky and why are are we doing all this extra work and why are we making our lives miserable our cpu's life miserable by doing all these additional calculations why can't we just store this somewhere and if we have stored it we can simply use it uh over here so in this case we can see that we have already used one coin in order for us to generate this one and now once we have generated this one we know that the am the number of coins that are needed to create value one is already uted so we will do 1 plus amount to generate one coin and this would be the answer if we want to generate two the value two from the given coins and this would become 1 + 1 so two and this would be our direct answer and these are the minimum number of coins that we can use to generate value number two the reason I'm emphasizing so much on this is because this exactly is the code concept of dynamic programming and we have just hit a very big hammer to its head basically we have said that hey I'm going to take this dynamic programming all the way I'm going to chew it all it up so it becomes a second nature to me and now let's continue with our example this is going to be a really long video but I hope that I recommend that if you just understood at any point I would just suggest you to go ahead and uh start skipping over so now the value for amount two is actually two now let's calculate for amount three the if we look at for amount three we have now we have two options either first of all we can start uh either first of all we can start with this value one we'll take value one then again the remaining value would be two and we have already calculated that what is the amount that is remaining for Value number two over here so if we let's take that approach just to just for the sake of understanding so first of all we use coin number one so we use coin number one and plus the amount that is remaining is actually 3 - 2 so we still have amount two that needs to be computed in order for us to achieve this value three so we can see that uh for this one the way we can do it is one coin that we already used plus whatever the amount two we that we need to use and notice amount two has already been computed over here so we can say that 1 + uh 2 = to 3 so if we choose one of these coins and we try to achieve the value number three initially we would be able to uh find our answer uh by using minimum of three tokens now again we notice that now since we have computed this coin we notice that three value number three is actually less than or equal to this given coin 3 and we can use it to Advantage so now we know that we want to achieve value number three over here if we just use this one coin we would be able to achieve this amount number three and current minimum amount that we have calculated that is that we need minimum three coins in order for us to achieve value number three so why are we using three coins because our aim is to use the minimum number of values so we can simply just say that if we just use one single coin that is of denomination three we would be able to calculate the result as three for this amount three and we won't be able to do anything with these two because they are already greater than three so we can't make three with those denominations now let's move forward with our uh with the next value amount of four and if we generate the amount four how how many number of coins we need so basically if we just take this first coin we know that we have already used one coin and plus we have the value remaining as uh amount three amount three is already computed we are using the best knowledge of computer processing we can and based on that we can we can simply determine that oh and by the way this would be one not three my mistake so we can just simply say that if you want to generate amount four we can do 1 plus amount three is already 1 so we can use two and this would be the minimum solution that even if we use the first coin as three we would use second coin as one and still we will get the same answer so I'm not going to do whole computation but you get the idea so for amount four we can say that uh two are the minimum number of coins we need in order order for us to generate amount 4 if we want to do amount five how many coins we need and the answer is pretty simple we already have this five present over here so we can just simply write one and uh notice again notice that we are going to check all the coins uh and when we get to five we will be able to say that this this is the minimum number of coins we can use uh next is amount of six if you want to generate amount of six again the answer is one because we are already given a six over here here and we are going to check through all the coins that are lesser Less in the value of whatever the amount that we are trying to calculate now let's calculate for amount of seven if we are calculating for amount of seven and if we check for the first coin uh the first coin is actually zero so basically we can just simply say that uh the first coin is the first coin is actually one so basically we can just simply say that uh we now we need we have already calculated the one coin Co plus now we need to calculate the amount 6 because 7 - 1 is equal to 6 and we have we already have the result for amount six so we can just simply write that we need uh at least two coins in order for us to generate the value number seven and now let's try to calculate our output that we are want we are we have already given that we need to calculate uh the8 so if we can want to calculate amount 8 and based on this table it becomes pretty simple initially so first of all we'll calculate this with value one so basically we would be doing the calculation something like uh one coin that we have already used plus amount of seven and we know that amount of seven um from our previous computation is actually value number two so we will do 1 + 2 = to 3 uh for this amount 8 that we are trying to calculate but uh can we do something better and remember that we are going to check all the coins so because we are going to check all the coins when we get to coin number three our solution would be that we have used one coin and that is the coin uh value is three and because we have used three now we need to generate the amount 8 - 3 = to 5 so we can say that we used one coin to generate the value three and now we need to generate value five in order for us to achieve this amount equals to 8 so if we do 1 plus amount of five what is the answer and the amount of five is already calculated over here um as one so we'll just simply use that value and we'll do 1 + 1 = to 2 and we will carry on with our computation with this value fine uh value five again we will find the answer two uh because we will do 5 + 3 and when we get to Value number six we will again find the answer to generate the amount 8 as three because we'll do like uh 6 Plus plus amount of two so uh the minimum number of coins that we can find in order for us to generate value number eight is actually two and we can simply return uh this value two now notice that we also have to take care of the scenario where we cannot create the amount based on the given coins and if we cannot create the amount uh at the end of our C computation the value for amount would amount of Any Given let's say8 that we cannot compute in this case would actually be uh the value 8 + 1 so equals to 9 because notice that at the beginning of our array this is how we initialize the values to and if after all the computation we found that the value of amount is actually the original by default value that we set which is amount + one if that is the case we know that we are not able to generate this value and we are not able to make any impact with our solution because the coins cannot generate this value we will simply return minus one and this solution would work perfectly fine this is a really beautiful solution and if you go through with this approach in your interview you are going to just be very impressive candidate and all the Fang companies would want to hire you so what let's calculate the time and space complexity so time complexity for this one would be uh actually bigo of n time M now why n * n because we are running the loop to calculate the value n and n is actually the value of this amount or whatever is given so we are Loop we are going through a loop n times and M are the number of coins uh because notice that over here for every single element we will have to use the we will have to go through all the coins in in order to generate the value so the time complexity would be big of n * m and the space complexity would be bigo of n because we are creating an additional data structure array to store all these values and the values we are storing up to is actually uh the amount whatever amount we are given so we can say that the space complexity would be big of in okay so let's create an array uh amount and its size would be amount + one we fill out all the values inside the amount as amount + 1 this would help us determine that whether uh if we cannot create the value we we need to return minus one or not and now uh we will set up the initial value for amount of uh 0o would be zero now let's create our Loop so we will start with i equal to 1 because we have already calculated the value for amount zero and while I is less than or equal to amount uh now notice that for every single value of I we need to calculate for all the values of coins so we will do we will have another loop uh that would iterate our coins and first of all we'll check that if our present I is actually greater than or equal to whatever value of coin that we are comparing it with so if this is true then only we will check that whether what is the amount uh for any given J sorry any given I so we'll do a minimum value of either the value itself so whatever value we already have or we will take one coin of any J and we'll do an amount of IUS J and Yep this is the main logic uh because in this logic we are calculating uh all the amounts and we are using it uh further down the road as well so after this iteration we just need to check that if uh for any given amount so amount of amount if that is um less than the value amount + one which means that we have been able to generate this amount so in that case we would return whatever the value we found else we can simply return minus one let's try to run this code we made a silly mistake again oh we need to check with coins of J yeah looks like our code Works let's try to submit this and yeah our submission is actually pretty efficient compared to other uh others who have submitted today we are going to do a very important lead code medium problem uh longest increasing subsequence and I have decided to break this video in two parts in the first part I'm going to discuss the uh Brute Force solution and an accepted uh solution for this problem and in the second part I'm going to show the optimal solution but the thing is the optimal solution is really difficult to achieve and it's a little bit tricky to come up with so let's understand the problem statement basically we are given an array of numbers and we need to find the length of longest strictly increasing uh subsequence so uh subsequence means that suppose we are given an input like this uh 1 2 4 5 so we can say that uh the value 2 and five is actually a subsequence of this given initial problem let's try to understand that what is the input given so we are given over here and 18 and this example and uh if we take these numbers uh 2 3 7 and 1 1 uh this would be our longest increasing subsequence so if we get rid of this value five this would be the longest subsequence we can make where all the values are in increasing order and the length of all the values would be four which is what we need to return as a part of this uh output so once we know the problem statement let's see that what could be the Brute Force approach so in the Brute Force approach so in the Brute Force approach we are simply going to take every single subsequence that we can possibly make uh keep a parameter that tracks the length of any subsequence and eventually at the end we we should be able to find a subsequence with the maximum length so let's take a small example and see that how what are the possible subsequences we can make so suppose our given input is 5 3 and8 I'm only taking three elements because I I need to show that uh why this approach is bad and what are the possible subsequences we can make out of this so let's start making all the possible subsequences uh the possible subsequence would be 5 5 3 58 3 38 8 8 and 5 38 these are the possible subsequences we can make out of only the these given three problems and if we check the length of each of them and if we find out the property that which one is the which one is a strictly increasing order we found that this is the strictly increasing order and the maximum length we can achieve is two so this solution works it works fine the problem is that notice that we are only given three elements over here and based on this three elements we are able to make almost seven subsequences mathematically it's actually 2 to the power of 3 minus one and for any s any single given n this is the number of subsequences we can make so um suppose we are given n values in the given input the number of subsequences we we would be able to make would be 2 to the^ of n-1 so if we calculate the time complexity we can just say that the time complexity is actually big go of 2 to the power of n which is extremely horrendous uh time complexity and this is exponential so even give with with enough numbers even NASA won't be able to solve this one so let's move on to the next approach now now we want to find the better approach and we know that the way to do this is to use dynamic programming but thing is how can we identify that we need to find the solution using dynamic programming also what dynamic programming solution are we going to use so I'll be discussing both the things in uh next portion and uh first of all let's take an example we'll try to see how we are going to solve it then I'll show you how we can determine that we are using the dynamic programming and after that we would be imp implying uh the result and I would be showing you the coding example suppose our given is suppose this is the input given and we need to find the longest increasing substring so just by looking at the given example we can determine that the longest increasing sub substring actually exist between 7 8 16 and 27 and now let's see that how can we come up with this solution how do we determine that this is dynamic programming suppose we are just given an example like this we are just given one value that let's say the value is s if we are only given seven what is the longest increasing substring we can make well the answer is quite simple we can simply make just one substring uh of length one so this actually becomes our base case that if we are only given one value we are guaranteed to have at least one substring that would be the longest increasing substring that we can make so now let's see that how can we use this logic say that for all the given elements basically there exist one substring at least that is the longest increasing substring let's just Mark all the values as one we know that if we are only given the value 10 the longest increasing sub substring we can make would only be 1 but then it comes to the second value now we have something to compare to suppose the S value if this was greater than 10 and we only had two values we can see that at the second position the longest increas in substring that we would be able to make would actually be whatever we have made so far + one so we would have been made two but over here that's not the case and over here the value 7 is actually less than whatever uh we are given the value before that which means that we the longest substring we have at the value 7even would also be one so this would be true in this case but now when we come to8 we have two possibilities what are the total substrings we can make up until this point up until eight okay so for this value eight what is what is the one thing that we can determine we can basically determine that there are three possibilities of the substrings we can have and we can compute one possibility is we could have a substring like 10 and 8 second one is we have we could have substring 7even and 8 and third one is we could have a substring 8 by itself uh in case if all the values before eight are actually uh greater than 8 so in this scenario from 10 to 8 we know that 10 is already greater than 8 so we cannot create a substring over here so let's ignore this scenario for the second scenario 7 to 8 actually this is a valid increasing substring because 7 is less than 8 and uh it comes after it so what we can determine is that the longest increasing substring we can make at Value number eight would be whatever the longest increasing substring we have made up up until this point so whatever the longest increasing substring we have made for the value number 7even plus 1 because 8 is coming after 7even and 8 is just one step after it so the we can see that longest increasing substring at Value number eight would actually be whatever we have found up until longest for the longest increasing substring of 7 + 1 and this is how we can determine that this should be solved as a dynamic programming problem because in dynamic programming basically whatever calculations we make in the past we keep track of them in some way either through an array or storing them in variable somehow and based on those results we actually use it in upcoming future calculations so that we don't have to calculate everything from the scratch so this is one way we can determine that this problem should be solved do using dynamic programming because if we just look at the problem we understand that we need to find the longest increasing substring which means that we need to keep track of whatever we we have calculated so far in the past and using those results we would make decisions that whether we want to keep this current current value or we want to ignore this current value so this is a very important thing to keep in mind and this is uh basically the core concept of finding the P pattern when ever you are given uh that whether the problem is dynamic problem or dynamic programming problem or not because in in the interview the interviewer is not going to tell you that hey this is a dynamic programming problem and just go and solve in that manner so now let's again continue with our example so we can determine that currently the value at uh 8 the longest in the longest increasing substring we could make at Value number 8 is one but we just found that from 7 to 8 we can actually make a substring as well so this B would become actually two and we can see that up until the point of 8 the longest increasing substring we can make is actually two and not one now let's move forward now let's consider for Value number five at Value number five let's again compare from 10 to 5 we cannot do anything because 10 is already greater than five so there is no point of doing this conversation let's again let's compare uh 7 to 5 from 7 to 5 we cannot do anything because 7 is greater than 5 and also 8 is greater than 5 so at Value number five there are no values that are less than five so the at Value number five the longest increasing substring we can make is actually size one because there does not exist a smaller number before five in our given input so we will keep this one as it is because we have already made all the all the calculations now let's calculate the for this value number 16 and actually for Value number 16 if you notice that all the values are smaller so this would be a very good point for us to understand that how everything works so from 10 to 16 we notice that 10 is smaller than 16 so there is a possibility and uh basically we can say that whatever the longest increasing substring we have found at 10 if we do it+ one that would become 16 so the longest increasing substring for 10 we have found is actually 1 so 1 + 1 = 2 so let's just up upate the value to over here and now let's move on with our calculation so we are done with this 10 let's calculate with 7 so if we do 7 to 16 actually again we will do 1 + 1 uh because l s of 7 so 1 + 1 is again two we have already we already have two so there is no point in updating the value Let's ignore this let's do again with the value 8 so from 8 to 16 we know that the value of 8 is actually two so over here at Value number 16 we can say that increasing substring at Value number 8 + 1 so it becomes 2 + 1 and 2 + 1 okay I made a mistake I think this is one that represents five and that value for 16 is actually over here so I'll just write it down so uh Lis of 8 + 1 is actually uh 2 + 1 which is three which is greater than whatever the longest increasing sub substring we have so far so which means we can update this value so over here the longest we have found so far is actually three and now we can also create create one more substring from from 5 to 16 if we calculate from 5 to 16 we found that the value is actually 1 + 1 would be two which is not greater than whatever we have at 16 so we can say that up until this point 16 the longest subring out of all of these values we can make is actually three uh for the Valu up until the point of 16 and let's move forward with our calculation so again the next value is 27 27 is greater than all the other values so if we do 10 + 10 to 27 we would find the value as 2 uh we will do 7 to 27 we will find the value as 1 + 1 again 2 we will do 8 to 27 we would find the value 2 + 1 as 3 again we will do 5 to 27 the value we would find would be 2 and at the end we would do 16 to 27 and and we know that the value at 16 is 3 so we would be able to find the value as 3 + 1 and because we have calculated all these results we don't have to do calculations all the way from beginning and we are just able to use the results we have stored so far so we know that the maximum value we can find is 3 + 1 so we would update the value at U longest increasing subring at Value number 27 to 4 and then we come to our last value 9 so and again we will do the whole thing for 9 so 10 is greater than 9 so we cannot do anything uh 7 is less than 9 so we will we can for this one we can have the value as two uh 8 is also less than 9 so from 8 to 9 value we can have would be three uh five is also less than 9 so from 5 to 9 the value we would have would be uh 1 + 2 2 from 16 to 9 we cannot do anything anything because 16 is greater than 9 and from 27 to 9 we cannot do anything because 27 is uh less definitely greater than 9 which means that the maximum value we could have find so far over here for 9 is actually three and that comes from uh the 8 + 1 so we will update the value over here as 3 and now we just need to find that what is the maximum value we have found in this uh array that we have created based on the calculation so basically clearly we can see that this value four is the maximum value we have found and that would be our answer that would that is what we would be returning as uh longest increasing substring the thing is we actually don't need to itate over the entire uh entire array again we could have actually done this when we are calculating or when we are making this are we could have just keep track of one parameter called Max and we would compare it with whatever the value we calculate at each location so whenever we find a new maximum value we'll just store it in this value and at the end of our Loop and this Max parameter should have our uh final solution and we can definitely return this and this solution would work perfectly fine now let's calculate the time complexity so basically the time complexity for this one would be big of n Square um and it's pretty un simple to understand that because for every single element we are basically taking all the elements before that and comparing it with whatever the element we have we did the same for every single element so uh for n element n we might have to compare it with nus1 values so the time complexity becomes bigger of N squ and if we calculate the space complexity the space complexity is also biger of n because we need to create this additional array to store all the values and and uh this is a good time complexity and good space complexity compared to our Brute Force approach remember our Brute Force approach the value we had was actually 2 to the power of n which was way higher this was almost exponential time complexity and we have done significant improvements from this one and we have actually moved to n Square so this solution would work perfectly fine in any interview and uh I'll move on to coding but thing is I would be making another video uh to explain that how can we solve the same problem uh using n log n complexity and this is actually pretty ideal and if you can achieve this in any interview uh if you if you can come up with this comp time complexity uh right then and there in an interview you can be guaranteed that you would be placed in any company you want so let's move on to coding now so first of all we will create a new array called Lis and we would uh create the array of size whatever the size we are given for the input nums and we will initialize the array with value one we will also create a parameter called Max uh that will keep track of the maximum uh maximum longest increasing subsequence inside the loop and we will initialize the value as one so now let's create our two Loops so first of all we will create a loop that is starting at position number uh one not zero because we need something to compare to otherwise all the values would be just uh one before that and we will run it till the length of the given array well will now this would be our Inner Loop and we would start it from position zero and we will run it all the way up to the position I now inside the loop first we need to determine that whether our current I that is on the right side of uh the array is actually lesser is actually greater value than whatever our J is if that is the case then only we would move forward with the calculation so if I is greater than J now we will do our calculation for the uh dynamic programming so the value of I would actually be the maximum value we can achieve for whatever Lis of I we already have or 1 plus whatever Lis of J we have achieved and this would be our uh recurrence uh relation I guess that is what it is called in dynamic programming uh so this is just to keep in mind that uh yeah if you mention that this is the recurrence relation it sounds really good impression sounds cool as well and also we check that whether the current Lis value is our Max or not so we'll just just check the existing max value with the new Lis that we just created and uh yeah I think that's pretty much it after this Loop runs uh we can simply return whatever we have found for the value Max and this this should be our answer let's try to run the code I think we made some silly mistake yeah yeah looks like our code is working let's try to submit it and uh our submission works but if you notice that our submission is not actually the best submission uh it's only faster than 55. 54% of the online submissions and that is because our this subm this solution is actually work in uh bigo of n Square times today we are going to do a very interesting lead code problem longest common subsequence and uh unlike many other interview questions this actually is a very good problem to solve because it do it does have real life use cases which almost all computer Engineers use on a daily basis uh basically GitHub is one of the prime example that uses uh the solution of longest common subsequence in its uh functionality this is going to be a really long video because I want to make sure that I be as thorough with my thought process as I can and that is why I have decided to break this video in different chunks so if you are comfortable feel free to directly jump to that portion and this is the approach we are going to take where understand the lead code problem uh we are going to come up with a primitive solution using recursion then we will see that how can we use memorization to improvise on the recurs recursive part and then we are going to see that how can we use dynamic programming to get the optimal solution and basically once we have the optimal solution we are going to write the Java code for it so let's understand the problem in order to understand the problem first first we have to understand a very key factor that what is a subsequence basically if any value is given suppose uh we are given a string a equal to x y and z a subsequence is any elements that are present in this given uh given sequence uh though they might be out of order so x z is a subsequence y z is a subsequence uh y by itself is a sub subsequence but if we consider like YX this is not a subsequence because if you see the order in which they are represented over here is not the order in which they are represented over here so just keep in mind and now once we have have it clear that what a subsequence is let's understand the problem statement so we are given two strings uh text one and text two and we need to return the length of their longest common subsequence and if there is no uh longest common subsequence we just return zero so let's take it by an example that is given over here so if our a is a b c d and e and B is a c and e so now we need to find the longest common subsequence uh it's pretty simple that if we just draw the lines we can determine that uh a is a a is present in both both the cases uh C is also present and E is also present and notice that there is there exist this B and D but if if we remove this B and D basically a c and e will remain same in for both the U for both the strings so we can say that a c and e are a subsequence that is present in both the places and we want to return their length so in this case the length would be three see that what should be the most primitive approach to solve this problem once we understand that we are going to make improvements to it and based on the improvements we are going to come up with the optimal solution so basically uh most simple thing that you are going to do is compare every single element with every single other element keep on doing it and whenever you find a match do something else so let's see that what what should be the approach uh we will start by checking all the elements from first element to this uh element in the B we don't find any match okay we move on to the next one okay now again we do the same thing over here we find a match the moment we find a match now now we need to find the longest common subsequence the way we are going to find longest common subsequence is only by eliminating whatever we have calculated so far so the thing is now the area of calculation that we are going to achieve is actually limited to up until this point and up until these points on the B side and the reason we are going to do the the reason we have to do this is because if we don't do it if we just move on to the next element basically we are going to lose that connection that we have made made at this point a and we need to find the longest common subsequence so after this my long speech Let's see that what should be the way forward now we again start comparing with C but now we are only going to compare with these three values so C2 I no match c2x again no match c2b again no match so we don't find any value over over here again we repeat the same process for this K so again there is no there is no match but now when we come to this I yes we find a match and when we find a match we repeat the same process so the process is that now the area of a search that we have to perform uh on the first first string and on the second string we only have these two elements that we need to consider so let's do the same thing uh compare uh e with X nothing and E with B nothing so we have found something but thing is we cannot stop right here because there could be a potential better substring that was not caught over over here but it could might very well be hiding somewhere later in the picture so what we do so far we store the value whatever we have calculated over here and the substring we have calculated so far is of length two uh the values are a and I and now once we have this value we'll again repeat the same process that we were doing now we will again check with the c with all the other values of this uh B substring so uh we find a match over here ET see which means again the area of Interest reduces now we only need to check for these three values and we only need to check for these values on the uh lower substring and when we do that let's repeat the same process so far we have found one common element so we can put one as common element and now we jump to the next elements when we jump to the next element this K okay again we found a match so we do 1 + 1 our area of Interest again shrinks down now it shrinks down to only these four elements on the bottom string and only these two elements on the top string again we repeat the same process we check with I we don't find anything we check with I yes we find something once we have found over here so we do addition over here again and uh now our area of Interest again strings down to only this element and only these two elements again we do the check and yeah we don't find anything so so far the longest substring we have found is actually three We compare two to the three okay three is greater so we are keeping three so far but the thing is we are not done yet we are not out of the words yet we'll have to check for all the other uh remaining values as well so what would be the remaining values so far we have checked until this J A and C now we again repeat the same process from this k okay K2 K there is a match again we will find K to I there is a match the longest common substring we have made so far is only two but three we we already have a better substring so let's keep it on the side now we have calculated the values for K now again let's repeat the same process again with I we compare all the values okay we find the substring over here from this value I again this is only one and we don't find any other values so we are done now we are at the last element I of e and again we check with all the values of B and we don't find any substring so we are done over here basically and this is the most primitive approach now let's try to see that based on this we have found three conditions so far and using these three conditions the most common algorithm we can write is a recursive one I mean you can write an iterative algorithm as well but recursive is just less code and I have already return that for you so let's go over the algorithm we have three conditions first condition is at any point if we reach the null value we can't return anything so we return zero basically this is our terminating case and eventually we will reach to this position now notice that we start at position zero and on first and second substring A and B now second position second case is that we find out a match that the value of whatever I and J is for B is actually same if there is a match we do this process so whatever the way we calculated these values so we simply do 1 plus whatever the remaining amount or whatever the remaining area is left on the substring and that is what we are doing so we do an addition of one and we again repeat the same process to finding the longest common substring and now notice that we increased both the values of I and both the values of J and if that is not not the case if we don't find a match which is going to happen on most of the cases if this happens what we can do well we can find the maximum value we can find amongst the remaining substrings so what would be the remaining substrings suppose the value is this one is a of I and this one is B of J we are at this these two positions we don't find a match what we are going to do we are simply going to check from the next value onwards whether there exist a potential match if does it does not exist we again jump to the next value again we check for the same thing if we want to write it in a different manner we can do the same thing at B over here as well so if we are at B of J we don't find a match over here what we can do we can just simply go to the next value keep on checking with a if we find a match good if you don't find a match repeat the process so in either case and whatever we found we we need to return the maximum value we have found because we need to find the maximum longest common substring so we do an a of I or A and B of J + 1 or a of I + 1 and B of J whatever is the maximum uh that we get we just put it in our result now since we have we already know this let's try to solve the recursive problem with one of our own custom example I have taken a very small example and you'll know soon why I'm just taking a pretty small example so let's start with a of z and b of 0 so a of z and b of Z the values are J and R there there is no match which means now we have two possibilities either we do a of 0 and B of 1 or we do a of 1 and B of0 so let's expand on this uh left sub tree for now and then we will do the remaining portion so again again now over here again we have to so what are the values so it's uh J and O So J and O there is no match so again we have two possibilities we can either do a of 0 and B of 2 or we can do a of 1 and B of one so a of z and b of 2 again we found the value J and N there is no match so we move on if we move on again we do a of 0 and B of 3 but notice that b of 3 is actually a null value over here so if since there is a null value we cannot return anything over here so this becomes zero we return zero now we still have do we still have possibility yes we we have possibility over here as well that we have the possibility to calculate a of 1 and B of 2 but now let's again elaborate on this portion so this a of 1 and B of 1 is value O Okay so O is a potential match so yeah that's good uh both values are same which means that we can do 1 plus over here so now we have done one plus and now we need to do uh the whatever the least longest common subsequence we found for a of two and B of two so a of two the value is h b of 2 the value is n there is no match so because there is no match again we move forward so we have two options over here we can either do uh a of uh 2 and B of 3 or we can do a of 3 and b of two so a of 2 and B of 3 we already know that b of3 is null value so we can return this as zero so we have we haven't found anything on this side and we cannot move forward over here a of 3 and b of 2 so a of 3 the value is n and B of 2 the value is also n so over here we find a match so the value is n Bingo which means that we can do one plus over here so the maximum imum of these two is actually zero so there is nothing else to calculate but the thing is we already calculated a match over here so there is 1 + 0 which means the value for this a of3 b of2 is actually 1 now because this value is 1 we again do a comparison between these two values so 0 and 1 1 is obviously greater which means that the result for this a of 2 B of two would be one now over here the value is one and this we already had a match which means we need to do 1 plus whatever value we have found of a of two and B of2 so the value of a of2 and b b of two we have found as 1 so we will over here the value of a of 1 and B of 1 would be 1 + 1 = 2 over here we have found the value as zero and uh over here the values we need to compare to with is two so of obviously two is greater so we are going to store the result of a of z b of 1 as 2 and and now we'll need to calculate the right side of the sub tree when we calculate the right side of the sub tree we are actually calculating the values a of 1 and B of0 now a of 1 and B of0 is uh actually again we have two possibilities we can either do a of 1 B of 1 or we can do a of 2 and B of0 now notice that this a of 1 B of 1 does the same familiar yes it does because we have already calculated its results right across right very next to it let me clean this up a bit so we have already calculated this result but the thing is we are still going and we are will eventually keep on going keep on going keep on going and uh then we will try to find the solution and eventually we will be finding the solution as two because that is the longest common subsequence we have over here is is of value to but thing is the what are the issues with the recursive approach well the issue is pretty pretty common the time complexity is actually 2 to the power of n and why it is 2 to the power of n because at every single location we have two options whether we can choose it or whether we cannot choose it whether we can choose it or we cannot choose it and pretty soon uh within just few elements we had over here I couldn't even draw the entire uh subon subon on this side why because the values are simply growing too big and this is the problem with the current recursive approach but thing is how can we tackle this current recursive approach well the reason is just right the answer is just staring at us uh and it is right over here that because we are doing lot of repetitive work and Som if we somehow uh have a way to store whatever the results we calculate over here and if we just put them put those results uh apply the logic over here that okay if the value Val are null we return zero if the values are same we return whatever the value of one plus the I + 1 and J + 1 or and if if values are not not matching at all we simply check that what is the maximum amount we can reach to either the either comparing the next value on the a string or comparing the next value on the B string and that is how we would be able to calculate the result if we somehow store the these values and use it in our approach we would be able to compute this pretty faster and not in this exponential time and the Art of storing the values of the recursive function in some form to use it later down the way is actually called memorization so if you want to put a definition just like madeup definition you can create a definition like this but it's actually really interesting to understand and uh so let's see that what could be the approach okay so now let's try to use memorization and uh we are going to use the same example now between these two values there can be three possibilities uh that we can have between any given elements the possibility is either the element is null if any of the element is null we simply return zero so that that's Bas case uh either the both the values are same so if the values are same we simply need to do 1 plus least common element of whatever we have found so a of I + 1 and B of J + 1 but what this uh and suppose if this is a of I and B of J so what this a i + 1 and J + one represent if we take it in a matrix suppose uh this is the value we are considering and we found that okay there is a potential match over here between these 0 0 values so 1 plus uh LCM of this would mean that whatever the value we have over here because this would be one this would be one so whatever we have value we have in diagonal if we do 1 plus that value we would find the answer that lies at this position so just keep this in mind we are going to use it uh somewhere and the second and the last option is that the values are different if the values are different we know that uh our we need to find the maximum value for any I and J values that that are different we need to find the maximum value between uh I + 1 and J or J + 1 and I so amongst these and I and J are respected for A and B so just keep in mind so if we look at this we can determine that basically suppose for this particular element we need to determine that what is the value for this one and uh we realize that okay the value over here is suppose X and Y so they are not matching so we need to find the maximum value So currently this position is one and this position is also one so what are the two possibilities we have we could have a value at position 21 so position 21 would be the value over here so whatever value we have over here and second second possibility we can have is position one two so position one two would be over here so we need to find the maximum value amongst these two we need to find the maximum values amongst these two in order to calculate that what what should be the value for this value this one would be and now we have these three things uh we can actually use it in our Matrix so let's start filling up the values over here first we determine that um the value and first we determine that okay J and R for this position the values are not matching up if the values are not matching up we need to see that what is the maximum value returned between these two values the thing is we don't know these two values it but keep in mind that this should be the approach now again over here that the values for values are not matching up so for this position we need to find the maximum value between these two points again over here the values are not matching up so we need to find the maximum values between this and this point the thing is we have a null value over here so this will always be zero so whatever value we have stored over here we can just impart that value over here and that's pretty understandable uh again if we look over here this position again the values of O and R are not matching if they are not matching we again repeat the same process now over here uh actually we have a match actually actually this o and O matches so if we have a match we choose a different approach we basically uh take go on the right side go on the diagonal and whatever value we find we do an addition with whatever value we have on the diagonal of that and uh again over here there is no match so if there is no match we need to find the maximum value between these two now we keep on repeating these things and the only number we can calculate so far is actually this last one the value of n where because okay over here both the values are same so the for this position we can say that this would actually be 1+ diagonal and over here in the diagonal we have null value so basically this would result up in zero so we can say that so far over here the value of n would be one but I thing is this is a really important important property based on this we can do lot of things so let's try to do those things over here so currently our n is 1 and uh so far the what are the common values we have found basically the common values we have found is only over here uh so over here I'll just mark it as something to indicate that this is the common value all the other values they are not matching up apart from this uh nine so now for this value we can say that the result would be whatever we have over here and over here but this is null this is zero so we can just impart this one again we can do the same thing and again we can do the same thing now even for this particular position this particular position we need to find the maximum value between this point and this point but the thing is over here the value is null so nothing exists over here and this value is one so again we can impart the same thing over here and same go same happens for this position so we we have failed these values so far based on these values okay now over here the values are not matching up if the values are not matching up we do maximum of next element or bottom element so both are one so we can again do one now at this particular position what we and again over here we need to do maximum of this and this so again we do one but now for this particular position we still have a match between this o and O which means we need to do a diagonal + 1 so if we do diagonal + one the diagonal the value we have is 1 so if we do diagonal + 1 we actually get the value is 2 so this becomes our two and now for this position we need to do a maximum of these two values so that's obviously two again for these position we need to do maximum these two values again the value is two and for this position we need to do maximum these two values so the answer is two now at the end we can simply return whatever whatever we found at zeroth position and this would provide us the maximum longest common substring we find and we are able to calculate this because we actually stored some of the values in memorization we went over the Matrix again we implied the logic we have defined over here that if the value is null return zero if the values are same do 1 plus diagonal if the values are different and take the maximum value of either next element or Bott bottom element and that enables us to find the answer of this problem and actually n to the uh n * m uh and using that we can actually find the the solution of this problem in bigo of n * m uh complexity why we are able to use this big go of n * m because we need some time to create this array uh this Matrix and once we have this 2D Matrix filled up we just need to iterate over it and eventually we would find our answer so very very important property to understand and very easily we can do this thing the thing is notice over here that we are still doing bunch of other bunch of things and we are doing a lot of repetitive work because in the during the first iteration we we don't even have any values to compare to so now what can we do so again the beautiful words Dynamic program can be used over here and dynamic programming can actually solve this problem now suppose in the dynamic programming we are again considering the same uh problems and what should be the index value it would be 0 1 2 3 and 012 the thing is notice over here that we actually create a matrix with one value addition for both uh these two lens so let's see that what the values would be so over here this would be John and this would be Ron now for this additional values uh three and four we can actually say that this value is basically null and this value is also null because the string ends at this position so once the string ends we can actually and we know that if we encounter the uh null value at any moment the value for that portion is actually becomes zero so if this is zero we can already prefill these values so let's do that so this would be all the all these values would be zero and all these values would be zero now we have all these values as zero we can start filling up our Matrix and using that we we will be able to compute things pretty fast so let's see that how can we start filling up our Matrix U by the way we can fill up our Matrix in two weeks we can either start uh at the bottom position and go up and side So eventually we will reach over here or we can actually start at this position and eventually we will reach at the end so it's up to us that what approach we want to consider I'm just starting at the bottom and now we are here uh that's a bad pun but okay so this particular position we know that the value that is a match so if there is a match between n and n we need to do 1 plus diagonal diagonal is zero so we can fill up this value as one now for this particular value there is no match we need to do whatever the maximum of diagonal so the value becomes one over here again we need to do maximum of diagonal so the value becomes one again maximum and on this particular uh row uh column three we again do uh we keep on checking the maximum of two values and we just provide those values now at this o and O there is a match so this point there is a match but before that there is no match so over here again we check the maximum of next adjacent values so the value becomes one again maximum of adjacent values the value becomes one over here we see a match so whenever we see a match we do 1 plus diagonal so 1 plus diagonal is actually two which means we can just put the value two over here now since we have two over here this would become actually the maximum of adjacent because there is a mismatch between R and O So maximum of adjacent is two and again the maximum of adjacent between these two values is two so at the end we just find the maximum value and that is two and uh see our solution how beautiful it looks we were able to calculate everything because we had this original initial case using this initial case we were able to compute all the values and over here because we had uh like these NS matching we were able to get one because one plus diagonal but even if this was not a match this this was something else basically we could have filled this value with zero as well and then then again we will subsequently move forward with our solution I hope that this data power uh this dynamic programming solution makes sense uh you are able to understand that what what how we come up with why we created this additional uh column and row and uh treating them as a base case we starts filling up our Matrix and basically this problem was originally uh NP hard problem what NP hard means is that uh the problem is non Po in runs in non- polinomial time but using the smartness of computer and uh because we are storing the values and we are keeping track of it we are actually able to solve it in uh n * m time complexity so even for data power dynamic programming approach the time complexity would be B of n * m and uh the space complexity would also be B of n * m because we are we need to create an additional Matrix to store all these values so first of all we'll create a matrix to store uh the values now we will create two Loops to iterate over the Matrix we will start at the bottom right position and eventually we will end up at the 0 0 position so now inside the loop we have have two conditions uh first condition is if both values are matching so if so if both values matches we need to do 1 plus uh diagonal so okay now we have taken care of one case uh second case is that both values are different so if both values are different for Matrix of I and J would be we need to select the maximum value out of the adjacent values and uh yeah I think this this should be it this should be our uh logic and uh let's try to return the position return return whatever value found at the first position and uh let's try to run the code okay as expected there are some errors oh okay our solution seems to be working let's try to submit this and yeah our solution works pretty fast uh it is comparing to other it's pretty [Music] faster Hello friends we are still not employed by Fang company so let's not stop lead coding till we get there today we are going to do a very important lead code medium problem word break uh let's understand the problem statement so basically we are given a string s and we are also given a dictionary your string word dict and we need to return true if s can be segmented by all the words that are given inside the word dict so if we look at the example suppose our s is lead code and the verdict we are given is uh first set is lead and second set is code we can clearly see that this lead code we can generate from whatever we are whatever the values we are given in this this dictionary so we will return true in this case and we are also mentioned that we can use the same word multiple times so suppose if this problem was lead code lead uh code uh something like this we would still return true because um all whatever words are we can still make it through this dictionary but if we were given some wording like this that lead code lde so up until this point we have the words that we can make from this uh dictionary the thing is this l e there is not a specific word given for that uh the word we are given in the word dictionary is lead so it does not match so in that scenario we would return false otherwise we would return true okay let's try to understand that what would be the Brute Force approach suppose we are given s is equal to e PN and the dictionary we are given is uh e s p and N so we can clearly see that all the words we can are present in the word dictionary so the answer should be true uh and uh in The Brute Force solution we are going to use a bottom up approach so uh and in this uh video I'm going to show bottom up approach all the way um even for the optimal solution so this can also be solved as a top down approach so let me know if you want to make a separate video on that uh and there is also one more thing to consider suppose we are given something like s is equal to null value or empty string and in the word dictionary we are given some elements like a b a b blah blah blah so this case we can clearly return as true why because this empty element will always be there uh though it might not be showing but the thing is if there is if there are no elements in our given string the we can always return true because the emptiness Al also exist in this word dictionary so we are going to use this logic and uh let's see that how we can build our uh B brot Force so we are doing bottom up so we are starting from the lowest value and eventually we are going to make the whole world so the first value we need to so we are at the zeroth position the first value we need to make is uh simply the word break of a value e and the word break of value e is very easy to calculate um we only need to check that whether the word break of uh empty string and the value e exist in this given word dictionary or not so basically and we know that if there is an empty string scenario this will always be true because I just explained it to you how so we only need to see that whether this e exists in this word dictionary or not if this exists we can clearly say that this is true and the we can uh denote the value of word break of e as true now the second option we second decision we can make over here would be to see the word break of two elements so e and s and how can we determine the word break of e and s uh well again it's simple so we need to we have two ways to determine that either we can do a word break of empty string and we can check that whether this es s value is present in this word dictionary or not or we can do a word break of value e because we know that this is always true the word break of Mt is always true so we can do a word break of e and we can check that whether the value uh s is present uh in this given word dictionary or not and word break of e we already know how to do it uh for this word break of e we need to do word break of Mt and we need to calculate the value of uh to see that whether this e is present or not the third option over here we can have is uh uh and you guessed it correctly the word break of three elements so e p and for this three elements we again have three more possibilities so word break of empty string and uh we need to check that whether ESP all these three exist in this uh scenario or we need to check that whether the word break off uh whether the word break off this uh e and SP exist and the word break of E S and P exist and yeah so these are the three ways we can determine that whether the word break of ESP exist uh the next option we have is uh the final scenario that whether the word break of ESPN exist or not and to check that we we will have four possibilities so first one is that we check the empty string and we check whether the ESN the whole word is uh present in this word dictionary or not or we can check that whether the word break of e is present and SPN these three values are present or not or we can check that word break of e s is present and we can check for pn or we can check word break of es and we can check the value n so these would be the four cases where we need to calculate all of these and for every single one of them so even in order to calculate this word break of e we will use uh the this method to calculate this word break of e s we will calculate this uh whole method and uh yeah so this would be the BR Force solution eventually we would find that uh whether we are able to make this ESPN or not and uh whatever a result we get we just need to uh bring it upwards and we would be able to find the solution so this solution works but it works in a very horrible way because at every single location we have two possibilities to make whether we want to keep that element or not whether we want to keep that element or not and our decision tree keeps on growing and growing and growing and though we will come to the correct solution but it's going to take us a lot of iterations to achieve that because over here you can see that we only had these four elements uh that we need to consider we generated such a big tree and over here most of the values we did not even completed the whole uh sub iteration for them because it's going to I would be running out of space so the time complexity as you have guessed the correctly for this approach is actually big go of 2 to the power n because at every single location we are making two decisions which is pretty bad and why it is 2 to the power n because we are calculating everything at the same time so see that do we have a room where we can save whatever we have calculated before and can we use it further down the road of course we can because notice over here this W word break of e we are using it over here but we have already calculated its value so why do we need to calculate its value again over here same goes with word this word break of es s we have already calculated the value over here so why are we repeating this whole process there are lot of repeated effort this is repeated this is repeated this is repeated we have already calculated all these values so somehow if we just create a cache we store that whatever the values we have calculated so far and keep track of that cache and whenever we need to encounter that uh whatever value we are calculating right now we can simply check that whether that has already been calculated and uh using that we can actually come up to a better solution since you guessed it correctly that because we are using something that we have already calculated in past we are keeping it keeping a track of it in some form and we are using it further down uh in our next iterations so basically we are using the most beautiful thing in the computer programming the dynamic programming approach in the dynamic programming we are going to create a single array of size whatever the input given input string is and uh based on that particular array we will calculate all the values that have been calculated so far and because this is a bottom up approach we are going to uh start filling up array from the zeroth position and we will reach reach at the end and in the end after all the calculation we will just simply return whatever the value we have calculated over here so let's see that what would be the optimal solution suppose um again we are considering the same example s is equal to ESN and the word we are given is e s NN and now let's create a new data structure uh called DP of an array that is of size four and uh there would be so 0 1 2 3 4 now we know that this zero position uh would always be true and uh why it would be true because this indicates that for DP of size zero which means that for string of size zero does it does the word dictionary contains this particular element or not this is what this DP is representing that every at every single location whether the value of uh that length of the character is it present in this word dictionary or not so DP of0 we know that that's an empty string and if it it is an empty string we can determine the value as true so this would become our base case and this is very important to identify in a dynamic programming problem that we need to have a base case and uh in initially we would set up all the other values as false and uh we will run our iteration so let's see that what each each of these values are going to represent and you guessed it correctly that this value represents uh word break of 0 this represents the word break of one so in this case it would be the value e this represents the word break of value e s this represents the word break of value es and this one represents the whole word so word break of the value ESN and uh yeah so at the end whatever we whatever result we find over here if we just return that that would be our perfect solution so example we are going to take is the same one that we have been uh discussing so uh the S is ESPN and the value of word is e SP and n and we know that our uh dynamic programming of value zero this is our base case that is true so what we are going to do is we are going to iterate over starting from single element we are going to keep on increasing the size of our element depending on the size of our element we are going to fill up this DP array and uh at the end we'll just return return the value so initially we will have we will calculate for just for Value e so DP of 1 would be calculating the word break for Value e so let's see that whether this value e is present in this uh word dictionary or not so the value is present so we can say that the DP of one is true okay this is good now let's check for the second element so uh for DP of E2 this would be calculating the word break for e s now we know that we can break down this word break for ES in two parts either we can do like an empty string and we can check for this value es or we can do the word break for the value e and we can check for the value s in this uh given word dictionary if we check if we go for this one es es is not present over here so we are left with uh the second approach in the second approach we know that uh word break of e which means this DP of one so DP of 1 is already true so we can see that okay this is true now we only need to check that whether this s is present or not so s directly is not present in this word dictionary which means that this condition is not satisfied this condition is not satisfied so we can say that the value for DP of 2 is actually false so we will just mention it over here that this is false okay let's try to calculate the DP of 3 so DP of 3 means word break of elements es word break of es means three things uh first one is that uh we need we can directly calculate to see that if ESP is present or not this is not present so this condition won't work second one is we can check that whether the uh word break of e is present and the word SP is present or not and third we can check is whether that word break of e s is true and uh the p is present now the thing is we already know that this condition is not true the ESP is not present which means uh we we need to check these two conditions now let's check this bottom condition first so word break of es s this word break of ES is actually word uh the dyn in the dynamic programming array it's the second position so DP of two we need so DP of 2 and the value P now we know that DP of 2 is already false which means that this condition will also be false so we don't need we don't even need to calculate and we don't even need to check for this element p in the word dictionary because we know that since this DP of uh two is false we can just ignore this case and let's focus on this one so word break of e which means that uh DP of 1 so DP of 1 is true if DP of 1 is true which means that at least this condition is true now we need to check that whether SP exist in the word dictionary or not and SP also exist in the word dictionary which means the DP of three we can consider this as uh true let me also put this one uh on this side now let's calculate the DP of 4 which means word break of ESN so again this will have four conditions now I'm going to write this in a different manner so we can also say that this is DP of 2 and PN because DP of 2 represents this es s and we can also say this as DP of 3 and n and uh yeah these are the four conditions we need to check and if any of the them are true we need to return true over here so let's check the first one does ESPN exist in over here no it does not so this is false uh so WB of e is true so at least one is true but SPN does not exist over here which means this is also false now DP of 2 this is already false which means we don't even need to calculate and check for this PN now the last one is DP of 3 DP of 3 is uh true so this is good now we need to check whether n exist over here or not so n exist over here which means this is true so we find one case that is true so which means that over here we can mark this value as true and remember that uh this given string this is of length 4 so because this is of length four we simply need to return whatever value we find as DP of 4 and that is true so in this scenario we will just return the answer as true and that would be our solution this is a very good solution because notice that we are already calculating what we need so far we are keeping track of it at every single position because we have calculated these values we are able to use it effectively and come up to the result let's calculate the time complexity so we are iterating over all the elements at least once so that is an N then we are also creating substrings so for every value n there can be n minus one substrings which means that we need to do additional n work so the time complexity would be bigo of n Cub so this is also pretty high time complexity but if you compare it with uh 2 to the power of n this is actually way lesser uh because this time complexity that can still comp uh calculated and uh this is a polom Time complexity but the thing is this one is exponential and uh yeah we don't we need exponential salary but not exponential time complexity so let's uh code up the solution okay let's create a Boolean array uh to store our cache and we'll name it as DP we'll assign its length to s. length + 1 and we know the base case where DP of0 would always be true also uh for this word dictionary uh this is a list so we are going to create a hash Set uh that will store the strings and we will store this word dictionary over there so it becomes faster for us to access the word dictionary we'll just name it word set now I think we are all set to start our Loop so we'll create the two Loops notice we are starting our loop from I equal to 1 because we don't need to uh we already have the value for I equal to Z and we are going to start the second loop from zeroth position and while J is less than I because we only need need to go up to I point now inside the loop first of all we will check that whether the dynamic programming for the J value exist or not and this is what I already explained in the uh solution uh explanation that if this is true then only we check that whether the word Set uh contains the substring so we'll use a substring method and we'll provide the parameter as J and I because J is uh less than I and uh if this is true if this is true basically we just need to assign the value of DP of i as true and uh yeah I think I think that's it we don't need to do anything uh and at the end of the loop we can simply return the value of our U DP of s do length and uh yeah also when we find this value DP of I is equal to True which means that we can break out of this uh inner loop because there won't be other another pair that we need to calculate because even at any moment if we find a single true that's sufficient for us so let's try to run this code okay uh looks like our solution is working let's try to submit this yeah our solution works it is accepted by lead code but notice that this solution is actually pretty slow uh it is taking a lot of time and uh it is not as fast as our other Solutions so there is one trick we can do is rather than going from I uh from J equal to 0 to I we can actually go in reverse so we can start the position of J equal to i- 1 and we can see that whether J is greater than or equal to Z and we will do J minus minus that way we would be able to find this uh little bit faster so let's try to run the code first yeah this works let's try to submit it and see the significant difference now our solution is much faster and uh even if you see over here previously this one was running in 13 Mill and this one is now runs in 4 millisecond basically we are just eliminating uh and breaking out of this inner loop faster we are not doing anything [Music] special Hello friends we are still not employed by a Fang company so let's not stop lead coding till we get there today we are going to do a very important lead code problem and uh I have provided the introduction of what are the things to expect from this video uh we are going to solve the combination sum problem and uh first of all I'll be showing that what are the top companies that have recently asked this question from lead code premium uh we'll understand the problem statement we'll also find the optimal solution and we will also determine that what would be the intuition behind it uh we will create an example and we'll walk through it and uh at the end I I'm going to write a Java code I'm going to explain it thoroughly that uh how we come up to it and uh also we will be explaining the time and space complexity so first of all uh these are the top companies that that have asked this this problem recently and uh if if we see from past 6 months to a year um it's eBay go Google Goldman Sachs and these companies and in pretty recently Amazon has asked this question 20 times in its interviews Facebook has asked this question 18 times in its interviews so I highly highly suggest you to take a look at this problem understand it completely and uh then uh practice it as much as you can this is a medium problem and we are given uh distinct integer called candidates and we are also given a Target integer and we need to return return all the unique combinations of candidates where we can reach up to the Target value now this is little bit tricky part to to find all the unique combinations uh for this target candidate because uh let's try to understand this with an example so over here we are given the candidates as uh 2 3 6 and 7 and we need to reach the value number s so we can clearly see that s is already present over here so we can return this one the thing is we need to return all the unique combinations so one unique combination is seven uh second unique combination and also we also one more thing we can use the same number uh from the can candidate unlimited times so if we apply this Theory then we can find another value that can reach to the sum of seven then that would be 2 + 2 + three if we do that this also sums up to seven so we need to return a list where the two values are 2 2 and three and the second uh element is just seven and this would be our solution for this given problem okay let's try to understand this problem with a custom example and it is really important to create your own custom examples because it shows that you have the ability to think out of outside of the box and you can create test cases on your own if it is a really important skill to have for any engineer and especially Fang Engineers so we are given three candidates two five and six and we need to see that what are all the combinations we can get out of these Comin uh candidates to achieve the target value eight now just by looking at it we know that the two combinations we can create is uh 2 2 2 two this is one combination and the second combination we can create is 2 six uh and this would be our answer the thing is let's see that what would be the most in most B basic solution we can come up with and what would be the intuition behind it and based on that we would be able to create an algorithm uh that would solve this problem so initially we are at this position zero now at this position zero we have three possibilities from which we which direction we can go uh we can either go to this value number two we can go to the value number five or we can go to the value number six the because these are the three candidates that we are given and also we should not forget that the target value we want to achieve is eight okay so keeping this in mind we need to go and pick a side where we need to go further and uh keep going so again let's just go on One Direction for all the cases we can so over here we are at two now remember that we can use same element infinite times which means that there can be one possibility as 2 two of course there can also be one possibility as 2 2 two of course the thing is uh notice that we need to put a constraint for the number of decisions we are making and the constraints is that if at any point the the direction that where we are fetching all the candidates if the sum of those can they can either be less than uh Target they can either be equal to Target or they can be greater than Target these are the three possibilities we can have if it is less than Target which means that there is still room for us to find find the potential combination which means we can keep further going on that direction if we are already at Value number eight or value whatever Target we are we can directly put this value in the result but if we and which means that we have found the combination so there is no point in going further after we have already found the combination because all the elements they are only going to add up to whatever combination we have which means that we won't be able to find another Sol condition uh combination with the same numbers that were used to achieve this equal to and the third option is that the value could be greater than eight if it is greater than eight why are we keep on going or to do more iterations and uh putting more more strain in our computer there is no point in doing it because we could have infinite options and if we do it this would be like the most worst this would be like the best way to deplete the resources of our company so we don't want to do that so now since we have kept these things in our mind now let's see that what how can we use them over here so so far the sum we have found up until this point is only two but the thing is over here we have two candidates and the sum we have found so far is four which is still less than eight uh this is six again still less than eight now over here we can have one more possibility as uh 2 2 2 and two and if we do the sum of this this is 8 which means that this is actually equal to whatever the target value we had so we can add this to our result combination we would have that we have already find one value in our result and we will just add it as uh 2 2 2 2 this is one combination that we have found so far but thing is we are not done yet because we still have other candidates that we need to look at and uh we need to check the possibilities but thing is we have concluded at least one thing so far and that thing is we can't go further down on this path because all the values would be greater than eight and which is not what we want so the only way we can go is actually we can go back and see that have we missed out on any combination so over here the next possibility we can get is we have already used two as our candidate for this value 2 2 2 so the next possibility we can over can have over here is uh it can be 2 2 2 and 5 or it can be 2 2 2 and six so let's do some of all the combinations so some of these combinations would be uh 11 and some of these combinations would be 12 notice that both are actually greater than the value of our Target which means that we can't go further down at any of these positions and we have exhausted all the possibilities up until this point so since we have already exhausted the possibilities up until this point the only way we can go is we can go back at this position two we have exhausted all the possibilities that can have one we found the answer and the other two we found that it cannot be part of the combination which means that we have already exhausted all the possibilities for this value 222 as well which means that we can't go down but we can go up so over here have we exhausted all the possibilities so far no there are still room there are still other possibilities that we can check so let's do that so one possibility we can have over here is uh 222 which we already checked the next possibility could be 2 2 5 and the next possibility would be 2 2 6 so some of these values is actually nine and some of of these values is actually 10 Again both are greater than whatever the target value we had which means that it we cannot go for down so we will go back we went back over here we check that we we went through all the possibilities which means that we are done over here but so we can't go down any further on this path but we can go up so if we go up we ask ourselves a question question that have we ex explored all the possibilities this at this position no the possibilities we could have is 2 5 2 6 so let's take this value first so at 25 the current sum we have is 7even 7 is less than whatever value we have as our Target which means that we still have possibilities the possibilities we can have is uh 2 5 5 or 2 2 5 6 notice that over here we only had two possibilities where we can calculate it from we did not had the possibility of 2 2 5 why because we already calculated it for this portion over here remember in the previous iteration we already calculated for this scenario which also shows one very important property and that property is that out of of our candidates uh whatever the candidates we are given if we are at any particular position or any combination of positions uh so whatever value we have as last we can only use that multiple times or we can use the values that come after it we cannot go backwards because we have already exhausted those possibilities in an iteration before this as I showed you earlier that this we have already explored over here and this 2 to the 5 uh 2 five we are exploring at this position two which means that the only combinations we can make up after this point is either 2 5 5 5 something blah blah blah or 2 5 6 6 6 something something like this but we can't make like 2 2 2 5 because we already checked that over here so and this is a very important property that we are going to use okay at this point the sum we can have is 12 which is greater than 8 so we can terminate over here we can't go down any further and over here the sum would be 13 again we can terminate over here we can't go down which means we have to go back so we come back at 25 we say that okay we have explored all the possibilities over here we go to go back to Value number two another thing is at Value number two have we explored all the possibilities no there is still one possibility pending which is 26 so at 26 uh this value the sum would be 8 again this is really critical because we have found a pair that equals to whatever Target value we had which means that we will add this combination to our result list so over here we will add another entry 2 six and after adding this we have explored all the possibilities after this point which means that we would go back back now at this position two we have explored all the possibilities it could have and because we have explored it we will again go back to our zeroth position the thing is we are still at zeroth position so can we stop now no we can't stop because we still have a whole lot of possibilities that we haven't touched so far because remember over here we still have this five and six pending so let's see that what could be the possibilities over here now at five again we can only have two possibilities as explained earlier we could have either 5 five or we could have 5 6 so let's do the sum of these values so 5 five the sum is actually 10 and 5 6 the sum is 11 both are greater than 8 uh which means that we can we can terminate over here so that concludes that at this position five we ran out of the possibilities we went up at this position we are done so again we go back we go back at zeroth position we check that have we any do we have any other options uh where we can explore and yes currently we are at Value number six so six is again less than our Target 8 so we can go further from six the thing is at six we can only do 6 six um we can't do any other combination because those we have already checked so far which means that 66 the value is 12 so 12 12 is already greater than 8 which means that we can't go further from this which means we can't go further we go back uh at 6 we see that have we explored all the possibilities yes we have explored all the possibilities which means again we go back to this position zero so at this position zero we check that now have we explored all the possibilities yes initially we check all the possibilities for the value two again we check for Value five and again we check for Value number six which means that even at zeroth position we are done so our base case has satisfied now whatever we have stored in our result parameter result list so far we can simply return this and this would be our final solution and this is actually the optimal solution that we can achieve notice over here that we are doing lot of repetitive work at any position we were calculating the different uh possibilities we can have we are picking a possibility we are exploring in uh that direction a depth first search uh we kept on exploring once we found a terminating case once we found a ter once we found a terminating case we would go back to a point where we can still explore for more possibilities over here again we would further go down uh to additional possibilities we would find a terminating case again we would come back and eventually we would come back to the Z zth position from where we started and uh after the calculation we will return our return the result so this where at any point we are coming back from where we originally started this is actually called back tracking this is a really important Concept in uh Computing uh computer programming and uh I just showed you that how can we use it and that is why because this concept is really important it has lot of um very practical applications and that's why you see that why all those big companies like Google Facebook Amazon uh Goldman sax they were interested in asking this question to their inter uh to their candidates because they want to know that are you familiarized with very important things that are really critical and uh can you go down that path and uh yeah so since we have found our optimal solution I did not mention explicitly that I was showing you the optimal solution but the thing is I told you that this is the intuition behind it and once we knew the intuition we just need to find a way to implement it in a computer programming the way to implement this you must have guessed it correctly that we were doing so some so much repetitive work again and again and we were using it somewhere and we had some terminating uh conditions that either if the value is equal to or greater than our Target we would terminate which means that we were using uh recursion at it its best uh over here so yeah this is basically our solution so let's calculate the time and space complexity the uh time complexity for this one would be bigo of n to the power T now first let's determine that what this n and t means n is actually the number of uh candidat DS and the least value for this one and T is actually uh the total amount because imagine that what is what could be the longest sequence we can have at any given position well suppose our Target value is8 and our candid candidate is 1 which means that we would do 1 + 1 + 1 up until 8 times till we get the value 8 which means that we need to go in One Direction eight times and at any position we can have multiple options or we can make multiple decisions and from further down we can go ahead which means that we need to do this work n to the power T times until we find the solution so that's that's why this is the time complexity so first of all we'll create our result list and now we will create a list to store the current combination okay now uh we will create a back track method and uh in this would be a recursive method so initially we are going to provide the target our result combination uh zero as the starting point and the candidates array and uh after whatever the result we get back from the uh recursive call we simply need to return whatever we find in this result list so let's create the recursion method okay so first of all we are going to create the terminating cases so if uh Target is equal to zero which means that we have find a combin comination that sums up to the Target value so we can just simply return it to uh simply we can simply add the combination to our result if this is not the cas case we need to return uh we need to check that whether the target is uh less than zero which means that we have already surpassed our Target and we need to break uh so we can just return null if both cases are not true which means we still need to look for our combination so uh we'll start by checking in our combination from the position start and we'll go until we still have candidates now inside the loop first of all we will add whatever candidate we are currently looking for in the our combination list okay after that uh we can do our uh recursive call and as a Target we will have Target minus whatever candidate value we found and start would be e position and I think that that would be it h yeah one more thing we will have to remove the entry from our combination list because we will be doing backtracking when we uh move towards the next value and I think I think this would be it let's try to run the code this should have worked but I don't know why it's not working so we'll just enter the value manually oh it should be candy dates okay our solution seems to be working let's try to submit the code and yeah our solution works perfectly fine [Music] and Hello friends we are still not employed by Fang company so let's not stop lead coding till we get there the problem we are going to do today is actually asked in lot of uh top tier it companies and if we look at the recent data it has been asked in Amazon 20 times Apple eight times Facebook two times uh Google six time so needless to say that this is a really important problem uh so I hope you provide your utmost attention uh this is the outline on how we are going to solve this uh and the things I'm going to cover in this video so first we will understand the problem statement I will be creating a bro for solution uh then we will build an optimal solution with dynamic programming and at the end I'm going to show the Java code for this one basically uh this is a lead code medium problem but in my opinion it should be a lead code easy problem uh because it's not very difficult to understand but the thing is its concept is really important uh that helps you build the conceptual knowledge of dynamic programming which you can use in bunch of different uh problems and lot of fang companies loves to to ask this kind of questions so if we understand the problem statement uh basically we are a professional robber and we are planning to rob houses in each street now the thing is uh the way houses are mentioned uh in the street is that every single house has some amount uh in that particular house but the only condition we have is if we rob one house we cannot Rob the house that is exactly adjacent to it so suppose we decide to rob this house uh if we rob this house which means that we cannot Rob this house or this house and uh we can again if we want we can again drop this one uh so that option we have and the our aim is to maximize our profit so basically we are given an input array nums uh that shows that for every single house how much uh amount of money is presented over there and we need to see that what route can we take which maximizes our input or the amount of money we can steal and uh we need to Pro show that in the output so let's uh try to understand this with an example so basically over here we are given the values as 1 2 3 and one so notice that the maximum uh amount we can uh steal is basically if we go down this path so if we start with the first house and then notti then we can't use uh we can't drop the second house but then we drop the third house and uh the sum of these two would actually become four and this would be our answer so for the Brute Force we are going to solve the same problem uh basically one way to understand the Brute Force approaches that at every single position initially we are at zeroth location so if we just make all the possible pairs uh which we can create create where we can rob houses basically that would be our solution let me show you how so initially at zeroth position now we have two options either we can select the value number one or two so either we can select the first value or second value uh and these are the subsequent values now at this position one we again have two options either we can drop the third house from here or we can skip the third house and we can also Rob the fourth house if we want so the two choices we have over here is either we go down this path or we go down this path and uh at this house number two we only have one option we can't drop this one or we can't drop this three so we can only Rob this one so uh the only choice over here we have is actually one and now we just do the sum of all the values so uh for this path the sum we would get is four uh for this particular path the sum we would get is two I just put it in a box so it's easier to differentiate and down this path the maximum sum we can achieve is three so if we compare these three elements we can clearly see that four is maximum so we simply return four now brot for solution works but the problem with this one is that we need to create every single pair and uh in order to generate pair essentially at every single position we have two options that whether we need to keep this value or we need to we do not need to keep that value and that eventually would bring a lot of different values in our graph and uh on the number of decisions we can make which means that the time complexity for root Force approach would be you guessed it correctly 2 to the power of n where n is basically whatever the number of inputs given over here and you guessed it correctly also I already gave it away uh but we are going to use dynamic programming over here and let me show you how we can use dynamic programming to solve this problem uh we are going to have use a custom example and I have already mentioned it bunch of times that it is really important to have your own custom examples uh that shows that you can think outside outside of the box so over here initially uh we are at this position value number two okay so what we can determine is that initially at this position if we were given only one house what is the maximum amount of value we can steal from this particular house of course the answer is pretty simple we can only steal whatever we are given right because we we are only given just one house so initially at this point suppose if we create an additional data structure that keeps the track of what is the maximum amount of money we can steal up for any element then it becomes then our decision making will become easier and we would be able to choose that what path we want to take uh so let me show you by an example so initially at this position value number two the maximum amount we can drop will only going to be two because there are no other values before that so this is the maximum amount we can drop so far okay now this at Value number four the maximum amount we can drop is actually up until this point it's only 4 because we can't use to uh when we are robbing four uh when we if we choose to rob the second house if we choose to Rob this one we can't use it uh we can't basically use this first house so uh we know that for the first two values these are the maximum amounts we can drop now we are at this position number three so at this position number three we have two options choices are pretty simple either whatever the value maximum we have so far over here which means that so far the maximum value we have is four or whatever the previous maximum value we had plus whatever value we currently are at because remember if we decide to rob this house number three uh basically we can we still have the option to Rob house number two we can't Rob house number four uh so up until this value number five the maximum we can Rob so far is actually uh five why because we can we check that okay up until this point what is the maximum that previous element has dropped basically like one house before this house has robbed and that that maximum value is two so I can do 2 + 3 so maximum I can rob up until this point is actually five so okay we have this knowledge and up until this value the maximum we can Rob is four now let's forget about this one for now because anyways at any given time we are only concerned with the house that are adjacent to each other now we are at this position number nine so what is the maximum value we can draw up until this. n well the answer is quite simple we check that okay uh what are the two values before this 9 so this is five which means that if we decide not to Rob Rob this house the maximum we have robbed so far in this uh sub uh sub array is actually five but how do we decide that whether we want to keep this N9 or not well we just need to apply the same logic the house that is adjacent to 9 before that what is the maximum amount we have found so the maximum for that is 4 and we do 4 + 9 so 4 + 9 is 13 which means that up until this point the maximum we can get the amount is 13 which is definitely greater than five so it is in our interest to keep this pair so far now we can forget about this four because we already calculated its value over here and now at this next value value number 11 again we have two choices do we want to keep 11 or not so again we do the same thing we compare 11 with whatever value we have over here we do first of all we do sum of 11 plus uh this five so we do 11 + 5 okay this one is 16 so which is greater than 13 which means it is in our interest to keep the value 11 uh so again we are going to have 16 over here we can forget about this one because we already calculated its value and uh yeah so we are now the two choices we have is 16 and 13 and this value number two we need to check two items uh so value before that this is 16 and this one is 13 so we do 13 + 2 15 so so far if we decide to keep this value number two in our uh list of houses that we are planing to drop the maximum value we can achieve so far is 15 uh but the thing is we have already found a better option than this 15 and which is 16 uh where if we decide to rob these three houses we will get the optimal answer and notice that every s we were able to complete this whole iteration in just single uh it we were able to complete this whole calculation in just a single Loop uh because we are keeping track of uh whatever the elements we have calculated so far which is the exact use of dynamic programming and we are not using more than one element at any given moment which means that our solution is actually quite helpful and uh very perfect so let's calculate the time and space complexity and basically this would be the optimal solution so time complexity as you have guessed it correctly it's actually bigo of n because we are completing everything in just one single iteration we don't need to do multiple rounds of uh checks and the space complexity uh we have is actually big go of one it's actually constant time because notice that at any given moment the maximum value we are keeping track of is just couple of elements uh and we kept on updating our elements that whatever we are keeping track of which means that uh we are not using that much space we are not creating an additional array to store all the values okay let's create two elements uh we'll name it Rob one and uh initialize it to zero and we'll create a Rob two we'll also initi I it to zero and we will have another variable we'll just name it Max to keep track of Maximum element that we have calculated so far and now let's run a for Loop inside the loop first of all we'll calculate that whether we have achieved the maximum value or not so max would be so whatever value we have at Rob one plus whatever value we are currently at so this is one option or whatever the value of Rob two we have because notice that the Dr Two element is actually right adjacent to this e element and now we need to update the values of Rob one and Rob two so Rob 1 will actually become whatever value of Rob two we had because we are updating it every single iteration and drop two will actually become the maximum value we have found so far and uh yeah I think this this should be our solution and at the end we will return uh the max element so let's try to run this code okay now our solution seems to be working let's try to submit it okay yeah our solution is actually 0o runs in 0 millisecond and it's 100 times faster than all all the other Solutions but the thing is this is not true uh because we are given a limited number of test cases we are Computing everything in just a constant time so that's why it's showing us 100% faster Hello friends we are still not employed by a Fang company so let's not stop lead coding till we get there uh today we are going to do a very important problem House robber 2 and this is actually an extension of original House robber problem I have already solved the House robber problem over here so you can and check out that video and I highly recommend that you check out that video before coming to coming on to this problem uh typically in any interview this problem is actually going to be asked as an as a follow-up question after they have originally asked this house robber problem and that is why if we see the number of companies that have asked this question recently it's actually quite small compared to what we are used to seeing for the other companies but thing is still Amazon and Google have asked this recently even Microsoft asked this just a little bit sometimes back and also few other companies have asked this so this is a lead code medium problem and uh basically the problem statement uh is saying that we are professional robber and we are planning to rob houses along the street now the catch over here is that the all the houses in the in this given Street are actually arranged in a circular fashion and also there there is one more constraint that we cannot uh Rob two houses that are adjacent to each other if we rob two houses that are adjacent to each other uh basically police is going to be called and we will be caught uh so this is a constraint that we have to look into and our uh our motive is to collect or gain or Rob as much money as possible without being caught so let's try to uh let's try to see a victorial representation so basically all the houses in the street are actually placed like this so suppose if we consider that this is our first house uh actually the first house is also neighbor of the last house uh in the given street because all the houses are stored in a circular fashion and now since the houses are stored in a circular fashion that is one more thing that we need to consider and also we cannot Rob two adjacent houses so suppose if we decide to rob this house we cannot Rob this house or we cannot Rob this house so the first example we are given is the houses are uh placed like this and uh these are the amount of money that is uh at each house so basically since there are only three houses we can only Rob one house and we need to select the house with maximum money so it's pretty simple over here that if we select this house we get the maximum money and if we rob the house with value number three we can't Rob uh these two houses because because they are adjacent to each other uh in the second example the houses are stored like this 1 2 3 and 1 and uh the most amount we can collect over here would be if we rob this house and this house so in that case the amount of money we would collect would be four and uh we won't be able to Rob these two houses because they would be adjacent to each other so we already know the Brute Force approach basically The Brute Force approaches to make every single uh pair uh and check out all the possibilities to see how we can uh find the answer but the thing is there is no point in go exploring Brute Force approach over here uh I'll directly go to the most optimal solution that we are going to achieve using dynamic programming because this is an extension of uh House robber one if you want to get get more information about the approach you can check out that video first so for the optimal solution we are going to use a custom example and this this is very important to use custom examples because it shows that you can create test cases on your own and this is a really good skill to have in actual Computer World so suppose the number of houses we are given over here are in this fashion and uh let's try to draw them in a circular manner now basically we can use the same solution we were using in uh House robber one because remember in in House robber one what we are doing we were just simply going through whatever the input we had and we were just keeping track of what is at any location what is the maximum amount of money we can rob up until this element uh by checking the previous values we are essentially going to do the same thing over here but just in a little bit different manner because uh in the House robber one problem we were considering the whole thing because they were uh all the houses were placed in a straight line so we were able to consider consider them like that the thing is over here the additional constraint is that whatever the last amount or the last house is is actually neighbor of the first house which we can see over here that these two houses are neighbors of each other which means that if we at any point decide to rob this house we cannot Rob this house or vice versa that uh if we decide to rob this house first house we need to make sure that we do not Rob this house so the answer is actually quite simple rather than treating this as a circular uh Street why don't we just uh run two functions so basically uh in during the first uh uh loop during the first uh iteration we are going to check the first sub problem and let me show you what I mean the additional constraint we have over here is that if we consider this house uh it is guaranteed that we cannot use the last house or or if we use the last house it is guaranteed that we cannot use the first house so since we know that this condition exist why we are simply going to uh do calculation twice in the first calculation we are going to check between these houses that what is the maximum amount we can Rob and during the second uh loop we are going to check that amongst these houses what is the maximum amount we can Rob and then we we just need to compare that what is the maximum value we have found across both the loops and whatever the maximum value we find we just uh push we just submit it as uh our answer so let's iterate over the uh entire problem okay so these are the two Loops that we are going to iterate over so let's calculate the result for the first uh loop so for at the first position the max maximum amount we can drop so far is only going to be one and at the second house the maximum amount we can drop is only going to be two because we cannot drop the first house now the for the third house we have two options either we keep whatever the value of two we have or we keep the value of 1 plus the third house value and we check we see that whatever is the maximum value amongst these two we are going to keep that so 1 + 15 is going to be 16 and of course 16 is greater than 2 so we are going to say that up until this house number three the maximum amount we can Rob is 16 now we are at the fourth position now over here the maximum amount we can Rob is actually two we have two options either we can Rob on 16 units or we can do 2 plus whatever value at house number four we have so 2 + 11 is actually 13 Which is less than 16 so even up until this point point the maximum amount we can Rob is still going to remain 16 and not 13 because uh definitely 16 is greater than greater value so it is in our interest to uh keep this value 16 now again we are at this position three and also notice that at any given location we are only considered with values that are uh of previous two houses that we have calculated over here we don't need to consider all the values because we are already adding them up and we are only keeping the maximum values so this works in our favor so at Value number three uh the maximum we can achieve is either 16 + 3 or 16 by itself which is this 16 or 16 + 3 so of course 16 + 3 is going to be greater so we are going to store 19 and we don't care about these values anymore because we already have the latest values so far now at Value number six the maximum we can find is going to be 16 + 6 or 19 we need to select whatever is greater so 16 + 6 is 22 this is the greater value so we are going to keep this and we don't care about 19 so we can see that at the end of this first Loop the maximum value we have found so far for this particular uh set of houses is 22 now let's repeat the same process for the second uh uh loop so in the second Loop for the first position the maximum we can Rob so far is two uh at the second house the maximum we can Rob is 15 now over here the maximum we can Rob is either 2 + 11 which is 13 or 15 so of course 15 is greater so we are going to keep 15 over here now at this position number three we can either do 15 plus + 3 or compare it with 15 so 15 + 3 is 18 so we are going to keep 18 over here now at this position we consider these two values so either we do 15 + 6 which is 21 or we check with 18 so 21 is greater so of course we are going to keep this one and now at this last position we check that whether 21 or 18 + 10 so of course 18 + 10 is 28 so we are going to keep that and we are we do not consider about 18 so after this entire Loop the maximum value we have found so far is 28 and the maximum value we had found over here was 22 so our job is pretty simple we just just need to see that whichever value is actually greater we simply return that and in this case 28 is greater than 22 so 28 would be our answer and we just return that value uh this is a very good solution we are building it on top of whatever we have solved for house uh robber one and because we are basically using the same solution we are just changing the scope of uh up until what points we are using this solution so just keep that in mind and uh if we calculate the time and space complexity uh the time complexity for this one is going to be bigo of 2 N uh because we are running two Loops uh 0 to nus1 and N uh 1 to n uh so if if we gener generically mention this it actually becomes becomes bigger of N and uh if we calculate the space complexity the space complexity would be biger of one because we are apart from storing couple of parameters we are not using any additional space so that's why we we are able to run this in a constant time uh sorry constant space okay let's start creating parameters so we are going to need two parameters Rob one and Rob two and we are going to initialize both to zero we will also need two parameters to store two maximum values so we'll name them Max one and Max 2 and Max one will will initialize it to uh the zeroth house and uh Max 2 we can actually initialize it to uh zero because we are not going to consider the first house and we are keeping the max one as zero because in case we are given the condition where we only have uh one input so we can simply return that now let's run a for Loop starting from the first house so I equal to0 to I is less than uh length minus 1 i++ okay over here we are going to calculate max one so max one would be uh maximum value amongst Rob 1 plus uh the the current number we are at or uh the value of Rob two and we also need to update the value of Rob one and Rob two so Rob one would actually become Rob two and uh Rob two will become the maximum value we have found so far now once we are done with this Loop we need to reset the values of Rob 1 uh equal to zero and drop to equal to Z because we are going to use them again in the second Loop and uh we are going to create another for Loop uh I equal to 1 and we are going to set up I is less than so nums do length l++ Okay and essentially we are going to use the same conditions uh by the way this would be Max one we are going to use the same condition so we can just reuse the code and uh we are going to rather than calculating Max one we will be calculating Max 2 so let's do that and uh after the second Loop we still we simply need to return whatever the maximum value we have found amongst Max one and Max 2 and uh this this should be the solution now notice that I'm running two Loops over here but thing is uh an efficient way to do this is to create a function and uh function would uh intake the parameters like start and end value and you can just repeat this process so that would be an uh efficient way to do do this code as well let's try to run this okay seems like our solution is working let's try to submit the code Hello friends we are still not employed by Fang company so let's not stop lead coding till we get there today we are going to do a very important dat code problem decode base and uh this problem has been asked in bunch of different Fang companies like Amazon Google Facebook uh Microsoft Uber lft Apple so I highly recommend that you focus full attention to this problem uh this is the breakdown that we are going to do for this problem we are simply going to understand the problem first we are going to see a bro Force solution based on the Bro Force solution we are going to see that how can we create an optimal solution and eventually we will write the Java code for that and uh this is a lead code medium problem and we are given a note that uh basically a message containing letters can be encoded into numbers using the following method so a is 1 B is 2 and up until that if we keep doing that uh Z is actually 26 and uh we are given a string of uh s that contains digits and we need to return the number of different ways we can decoded so let's understand this with an example suppose our given input s is equal to 12 uh we can decode this in uh two ways so one way to decode this would be to consider one and two as separate elements and uh 12 by itself self as a single digit so this uh the value for 1 and two would become a and b using this logic and uh the value of 12 would become the letter L so we don't need to return these values we don't care about them but thing is we need to return that how many different ways we are uh decoding this given input string and in this case the answer would be two let's take another example so suppose our given input s is equal to 226 how many times uh how many different ways we can decode this one so one way to decode this one is uh 2 and uh 26 so that's one way second way to decode this one is two or two and six so that is second way and the third way to decode this one 22 and six and uh if we check out the values so this would becomes B uh Z this would becomes b b f and this would become v f so over here we can see that there are three ways we are decoding this given string so in the answer we will return the value as three now there is let's consider one more case uh suppose the value 0 0 would be a special case and there could be m multiple possibilities where zero can appear so suppose our given input s is something like 0 1 1 so in this case we won't be decoded in any manner because uh remember that our range starts from this value number one up until 26 so 0 is not part of the range so we cannot begin our string with value zero at the beginning so this won't work uh second possibility that zero could be somewhere in the middle so suppose the our given input s is equal to 1 0 1 something like this so in this case we cannot decode this in 1 and 01 we can't do this why because we can't decode this 01 because remember that in this scenario if zero comes at the beginning we can't decode it uh the way we can decode this is we can consider this as 10 and this as one that value of zero can appear at the end so our input string s can be something like uh 2 0 0 so in this case we can decode this value 2 0 but we can't decode the zero so we won't be able to return anything or our value s can be uh 5 2 0 so in this case we can decode this we can decode this value five and we can decode this value 20 0 because 20 is again between 1 to 26 uh but if we are given something s is equal to like 57 0 we can't decode this because we we can decode this five but we can't decode 70 because 70 is not part of uh this 1 to 26 range so when value zero comes in it becomes a little bit tricky and we have to just take care of it for Brute Force approach let's take a custom example suppose our given s is equal to 2 1 2 3 and uh we need to see that how many different ways we can uh decode this one so Brute Force approach is pretty simple we just take all the possibilities uh starting from the first value and keep moving and keep building our solution and when we reach at the end at any given path we consider it as a one way to decode it so initially we can decode this as two and whatever the remaining value 1 2 3 we can decode this further into 2 1 and whatever value remaining again same thing 2 1 2 and uh this three and and uh in the in the end we can decode this as 2 1 2 3 so this would be one way we would be able to decode this so where if we treat all the values as separate entities now let's see let's go back and see that can we can we have more possibilities so over here we cannot have any more possibilities because this two one and two are already being decoded and this three we only have one possibility to decode it by itself so we don't have any any possibility over here so we go back further up do we have any possibility over here so yes over here we still have possibility that we can decode this 2 and one the same way we have decoded over here but this 23 we can decode it as a single value so of course we reach at the end of the loop so this is one more possibility on how we can decode it now let's go back so for this value 123 uh of course we have we still have more possibilities because over here we are considering this value as two and one separately so over here we will consider this as two as already being decoded and rather than considering this as one a separate character we can also consider it as one two and then we can decode three so this can also be another way so we'll just mark it okay now we have exhausted all the possibilities over here uh considering this value if we start from this value number two so we come back at our main point and let's see that what are the more possibilities we can have over here so we can do rather than choosing two we can choose two one and whatever the remaining Stream So remaining is 23 okay now let's see that how many different possibilities we can have over here so so we can have two possibilities now we can do like 21 2 and 3 so that is one option or we can do 21 and 23 so that is second option and uh yeah both would be a separate ways and apart from these we cannot make any other possibilities so essentially we are uh we can see that there are five different ways to uh decode this 2123 string and uh those five ways are U mentioned over here uh what is the problem with this Brute Force approach well the problem with Brute Force approach is that actually we are doing a lot of repeative work uh how we are doing repeative work if you notice over here that we know that we need to calculate that for this 23 how many different ways we can compute this one but this 23 we have already computed it over here so we since we have already computed over here it is not very fruitful to compute the same thing twice and uh in Brute Force we are not doing it so that is why our uh path will keep on growing and growing until we reach to our all the possibilities which means that we are actually doing exponential work for this Brute Force approach uh so of course the big the time complexity would be big of 2 to the power n which is really bad and uh we should avoid it in all cases and actually it can be avoided pretty simply if we just use memorization if we just create an additional data structure something like an array or something where we store the value of calculations that we have already done and if we at any point come back to the same calculation U that we have we have already computed we can simply return that value so we can use something like an array or hashmap I think hashmap would be more efficient in this case because we we are able to look up things in constant time and if we only apply that we can actually implement this solution the this Brute Force solution in very effective manner we can actually use recursion because uh remember at every single moment we are repeating a sub problem so we are repeating a sub problem and we are Computing that so if we just use memoization with recursion so for for this approach we can actually achieve the answer in time complexity of bigo of n rather than this 2 to 2 to the power n and that would be really efficient okay before I go into the optimal solution I want to show you a few observations suppose our given input s is equal to 7 so how many different ways we can decode it of course only one way we can just use seven suppose our input is 77 we can still only decode it one way uh using like 77 and that would be the only way we would be able to decode it even if our value is 777 7777 whatever the value we have all of these can only be decoded just one way because all of these values they are forming a value where we can only use individual characters now what is the scenario where we can use the characters that are not individual and we can uh collectively use the pair of elements okay now let's take one more example s is equal to 21 2 3 and now let's try to see that how many different ways we can decode this one this is the same one we have used in our Brute Force approach so we know that there are five different ways we can decode this one the thing is we are going to do things a little bit differently over here we are going to decode these all of these values so first we'll start with value number two how many different way ways to decode this one only one way and that way is two now let's consider the second value 21 how many different ways to decode this one well of course two values or two different ways and those ways are two 1 so that is one way and second one is 21 by itself and uh let's take the third value 2 1 2 so there are actually three different ways to decode this one let's consider the next value is 2 1 2 three so we know that for this one there are actually five different ways to decode this and the five ways are okay you must be thinking that why am I writing all these letters because the thing is there is actually a very important uh relationship that exist whenever we find out out uh whenever we add a new value to our to our calculation and if that value that is being added If the previous value of that with that particular value if that falls between this 10 to 26 actually something interesting happens so notice over here that this uh 21 came in okay we are we are checking for this value number 21 now the thing is just for a second imagine if this value was actually 27 so how many difference different ways would we be able to decode this one well only one different way and that one different way would be 2 and 7 so treating both values as separate values uh same goes for 28 29 and any value above but the thing is because this value Falls between this 10 to 26 portion we are able to do something interesting so notice that whatever value we append over here there is there will only always be one way to decode it I'm not talking about the value zero forget about zero apart from zero if there was any other value the way to decode it would be to whatever the way we have been decoding the previous value if we just add that value then that would be the way to decode it which is over here that 2 and one we are already decoding it with whatever value we were using we were decoding before and we were using that way but the thing is over here this 21 by itself falls under this 10 to 26 which means it is a letter by itself so we are able to add it to our decode list and that is why we have two over here okay but now the interesting part comes in okay now over here we are adding one more two and this two Falls between the value 10 to 26 because the appending Val value becomes 12 so this 12 Falls between this 10 to 26 now let's see that how many different ways we are creating the pairs actually 2 1 and two this is same from whatever the pair we had before one just one iteration before okay now this 2 1 we already have had a 21 over here and we are just appending this value two over here so that is also okay because we can append it right so whatever the ways we were we were decoding before we are still using those way but thing is over here something interesting happens because this one two by itself is a way to decode we are actually able to create this 2 one2 pair which we were not able to generate over here we are not able I mean we are using this two over here but the thing is we are using it for 21 but we can't do anything further than that we are already also using this 212 over here and how can we say that we are using this 212 over here is be because this value is basically 12 uh Falls between 10 to 16 but thing is this two actually comes from the first value this one and uh why because at any given moment we find out that there exist a pair with the new value being added and that comes between this 10 to 16 we can actually do some of previous two values that we have calculated so far and the sum of these two would actually give us the number of different ways we can actually decode this one if you still don't believe me let me show you with an with another example let me clean this up a bit now over here we are seeing that five distinct pairs are being made and we are adding the value three over here and we know that this uh pair 23 exist between this 10 to 26 so that is all okay right we we know all of these stuff now let's see that how many different ways we are generating the pair so one way is 212 and we are just appending three this would be the case even if the value was 2129 if the value was 2129 we would still be able to use this way because apart from this three that there would be a 9 over here but that's not the case right now but the thing is we we would still be do it and if you look at look over here this is the same path we were taking and we are just adding one more node so no impact on the number of results second pair we are making is actually 212 and we are appending three over here again that is the case over here that we already had a 212 and we can upend three over here so that that gets uh taken out over here if we had the 2129 we would be appending nine over here so that Still Remains common okay there are no issues with that now next pair over here is 2 and 12 so we also have a 2 and 12 pair and we are adding a three over here which means that even if we had this nine we would still be adding nine and that would be it we we we don't care about it but the thing is if we had this nine we won't be able to generate these two pairs because notice in these two pairs we are actually creating an additional value by the value that has added over here and if we if this value was not between this 10 to 26 this value would not been able to be generated okay now the question comes that we have already exhausted all the possibilities over here so where does these two additional values comes from well actually if we look above over here this one is actually 21 right so we are also using 21 and we are creating a new decode node 23 and we are appending appending it over here also notice over here that this one is 21 and this one is 21 so we are appending a node over here uh 23 which means that at any given location if we want to see that how many times we can decode it we if we know the information of previous two elements and if we do some of those uh we can actually generate it so that's why uh the value for this uh 21 this can be decoded two times uh this value 212 this can be decoded three times so for the value 212 3 actually this 23 Falls between 10 to 26 that is okay that is perfect if that that is the case we simply do an addition and if we do an addition and we just uh find whatever result we have calculated and we can simply return this this is a very effective solution now what could be the other case well the other case could be that the new value we are adding that does not fall between this 10 to 26 so suppose over here the new value we are adding suppose the new value is 2128 something like this so after adding this new value uh this becomes 28 it does not fall between this 10 to 26 because it does not fall between this 10 to 26 actually we don't need to do addition over here we simply need to whatever the route we can make before this element that would be the only possibility we would be able to decode this one as well because that I just showed you over here that over here I was adding a nine and because I was adding a nine I was only able to uh make the new decode paths for these three elements I won't be able to generate these two values and this becomes our recur recurrence relationship and this actually becomes our our dynamic programming solution now let's try to solve this dynamic programming programmatically we know that we need we care about the two previous elements so suppose our given input is like 212 3 we initial and we initialize two values before that as 1 one say we have these two as 1 one now we check at any given location that whether the value we have does it fall does this value with its previous value does it fall between this 10 to 26 okay in this case this 2 does not fall between 10 to 26 if it does not fall between 2 to 26 we just need to take whatever we had from the previous element so previous element over here we had one so we will'll just take one okay now we have this one so again we check with its previous element that whether the value Falls between this 10 to 26 the value becomes 21 it falls between this uh 10 to 26 so we do whatever the previous two elements were we do sum of it so the previous one element is one and the previous second element this one is also one so we do 1 plus so we do 1 + 1 so we can put two over here now we have new element this Falls between this 10 to 26 that's good so we do sum of two previous elements sum of two previous elements is actually 2 + 1 so so we can put three over here now we have this three now it it creates the value 23 again Falls between this so we can do sum of 2 + 3 and that becomes five and this five would be our result so this is a very important dynamic programming Solutions and uh at any given moment if we find out that suppose over here we have an value 8 now this 38 does not fall between this 10 to 26 so it becomes simple that for this pair the number of ways we can decode this will still be five because we'll just take whatever value we have calculated over here the solution works perfectly fine and the time complexity for this case would be bigger of n because we only need to do one iteration across all the strings and uh the space complexity would in this case would actually be big go of one we would be able to complete this in constant space and time because remember that at any given location we only need to keep track of just two elements we don't need to keep track of this whole entire array we just need to starting elements and uh we would keep on iterating them over different values so this is a very good solution and uh okay first of all we'll check that whether the first element is uh zero or not if this is the case we can simply return zero okay so we will create two parameters uh 1 and two and we'll initialize both to Value one let's run a for Loop we'll start the loop from first position and we will go up until the length of the given string we we are running it from I equal to 1 because we already check for the zeroth position first of all we create a value current to keep track of the current element and now we check that if the current uh if the new character that we are trying to add if that is not equal to zero we can assign the one the value of one to current now we also need to check that after adding the value at I position are we getting the twood digigit value between 10 to 26 so first of all let's create a new variable uh called uh value and we'll try to calculate the two- digit value we check the condition so if value is greater than or equal to 10 and value is less than or equal to 26 which means we need to update the current value is current plus whatever the value of 2 we had because remember the value at current we are already adding it as one now we need to update the values of 1 and two so two would become whatever the value of one we had and one would become whatever the value of current we had and uh yeah I think this this would be our solution so at the end of the solution solution we need to return the value of whatever the current value we had but since we are initializing current inside we'll just return the value as one and uh let's try to run the code oh we can initialize the current as zero let's try to run the code okay looks like our solution is working let's try to submit the code okay our solution works pretty fast and pretty efficiently Hello friends we are still not employed by Fang company so let's not stop lead coding till we get there today we are going to do a very important lead code problem unique paths and as you can see that this question has been asked in Google Facebook Amazon Apple Microsoft Bloomberg all huge gigantic it companies so I highly urge you not to miss this video and uh try to understand the problem as as thoroughly as possible um this is going to be the fre framework for the video we are going to understand the problem we are also going to find a primitive approach we are going to find the optimal solution and we will write a Java code for the optimal solution this is a lead code medium problem we are given that there is a robot and an M cross n grid and robot is initially located on the to top left corner now robot tries to go to the bottom right corner so this is the last place where robot wants to reach and uh at any given moment robot can only make one move it it can either go down or it can go right at any point in time uh no other ways it can make so in the problem we are given this m and n and we need to find that how many distinct unique paths can robot take to reach to the bottom right corner or its final destination so suppose our given m is equal to 3 and N is equal to 2 this is one of the test cases so if we see if we draw it on the board it would look like this this is where the robot is initially so I'll just mark it as R and this is the destination that robot wants to reach the bottom right corner now we know we need to find that how many unique paths exist so let's see that how many unique paths can we make and at any given moment robot can either go on the right side or down it cannot make any other steps so let's see that what are the possibilities so this is one possibility so this is one path I'll just mark it somewhere now this is second path I'll also Mark it somewhere so this is second path so have we exhausted all possibilities no there still exist a third path and the third path is like this 1 2 1 and apart from these I we cannot make any uh any more paths so essentially we are existing all the exhaust ing all the possibilities and we can return that for this given M and N the number of unique paths can be three now I hope that this makes problem statement more understandable over here initially we are given an example of M is equal to 3 and N is equal to 7 uh and the number of unique paths they get is 28 but I thing is this would be too such a long uh uh example so I'm not going over it okay let's understand this uh with a custom example so suppose our m is equal to 3 and N is equal to 3 so we would have a grid that looks like this here this is our robot this is our destination now we are going to calculate that at to in order to reach to any element how many unique paths we can take so suppose if we want to reach to this element how many unique paths we can take we can only take one unique path and that would be to take this right step from here we cannot take any other step same goes for this element that we can only have one unique path and that would be to take two right Steps From Here uh we cannot reach to this point any other ways same happens for these two elements as well that we can only take one step down or two steps down to in order to reach to these two elements the thing is there cannot be any other unique path if we want to get here but thing is when we get to this middle points uh something interesting happens and the interesting thing is suppose we want to reach to this point how many unique paths we can take well we can take two unique paths we can take one unique path to reach to reach over here and then over here or we can take one unique path to reach over here and then again reach over here so we can say over here we took two unique paths but thing is if we just see that what are the entry points to get to these this point actually there are only two entry points to get to this point one entry point is that we can if we somehow get to this point we just take one step downwards we we come over here or if we somehow get to this end point if we take one step on the side we reach over here which means that whatever the unique paths we have at these two locations if we just sum these two up it will give us the number of unique paths we can we can take to get to this point so let me show you by by another example now again let's consider this element so in order to reach to this element there are only two ways we can reach to this element we can either take one step from here or we can take one step from here which means that whatever the number of possibilities we have over here that once we get to this point we will be able to come to this unique path okay so that is a given same goes over here that no matter how many number of possibilities we have to come to this point if once we are at here we are guaranteed that we can come to this point so in order to reach to this point the only possible ways are this one and this one so if we sum these two we will find the number of unit unique unique ways we can reach to this element and in this case it would be three if we continue down the same path for this point uh we can take three distinct paths to reach over here and in order to reach to this destination D we can take 3 + 3 six uh unique paths to get to here and this actually becomes our answer okay so based on our previous explanation we know these things so if we see now we need to see that how can we use dynamic programming to solve this problem and the reason we are choosing dynamic programming is because at any single location we are Computing that whatever the previous two results that we have already calculated and we are using them to calculate the next values so that pretty much uh indicates that we need to use dynamic programming over here now let's take a 2X two Matrix and uh we'll just provide the index value values so index values would be 012 012 and we would name this Matrix as DP to refer dynamic programming now the thing is if we want to find out the value at this position we know that it would be sum of these two elements so mathematically we can write them like this that DP of 1 1 because this this is one and this is 1 is actually equal to DP of 0 1 that we have already calculated which is this Value Plus DP of 1 0 which is this value and some of these two will give us this value so generically we can actually write them like this that at any given location DP of M and N would actually become DP of M minus 1 n plus DP of n and n minus1 and this would be our recurrence relation for dynamic programming and I already explain that why are we choosing dynamic programming and our aim is to find that how many distinct ways we can reach to this destination so this destination would actually become uh DP of 2 2 over here and if we compare it with whatever m&n is given uh this actually becomes the value over here this would be become the DP of m-1 and nus1 so we start our calculation like this and eventually we would reach to this point and we just need to return whatever we have found over here and this would be our solution so we can just create two Loops one Loop iterate over the column one Loop one Loop iterates over the rows and eventually we will reach to this end point we return this this becomes our solution and this is a very efficient dynamic programming solution uh any Fang companies Facebook Google Amazon whatever they would be happy to hire you immediately so now let's see that uh what would be the time and space complexity so time complexity would be B go of M * n because we need to iterate over this entire grid so that's why it's because of M * n and space complexity remember that we are creating this edit DP array uh which is 2x2 matrix and we are giving the size as M and N so space complexity would also be big go of M * n and this would be our solution now let's move on to coding okay first of all we'll create a two dimensional array and we'll name it as DP and uh we'll provide the length as m and n now we'll have to create our base case so we will fill our uh twood dimensional array and this is the way to fill a two dimensional array and over here now we'll create two for loops and uh we'll start with i equal to 1 and J is equal to 1 because we already have cases for zero while I is less than m i ++ j is equal to 1 J is less than n okay now we will provide our recurrence relation so DP of of I and J at any location is equal to DP of I -1 J plus DP of i j minus one and uh yeah this is pretty much it this should be working so now let's uh return let's return uh DP of M minus one and g n minus one let's try to run this code oh it should be arrays do fill small error looks like our solution is working let's try to submit the code okay our solution is actually runs in 0 millisecond it's 100% faster than all the other submission which is pretty good and uh I'll be posting this in the [Music] comments Hello friends we are still not employed by Fang company so let's not stop lead coding till we get there today we are going to do Jump game problem recently this problem has been as in Amazon Facebook Apple Google Oracle Tik Tok all these gigantic companies and uh they are some of my dream companies so I'm going to do my utmost Focus for this video and I hope that you uh find it enjoyable this is going to be the framework for the video first we are going to understand the problem then we'll come up with a Brute Force approach we'll improve our Brute Force approach we'll find the optimal solution and then we'll write the Java code for the optimal solution this is a medium problem and we are given an integer array nums and we are initially positioned at the first index so zeroth index each element in the array represents that the ma that is the maximum jump we can take and if that is true can we reach to the last position so if we are able to reach to the last position we would return true if we cannot return reach we can we will return false so let's understand this with an example suppose our given input is like 2 3 1 1 and 4 and initially we are located at this position this is the same example over here so we can see that if we over here we can take maximum two jumps so either we can take one jump and reach over here or we can take two jumps and reach over here let's let's get the gredy approach and we'll take the maximum number amount of jumps so over here if we take two jumps we end up over here over here the maximum jump we can take is only one so we can we'll reach over here again the maximum jump we can take is just one so we will reach over here and this is our last position so since we have reached over here which means that we can conclude that we can uh solve this Jump game and we can reach to this end position so we'll will return true in this case now let's take one more example so suppose we are given input like this 3 2 1 0 and four and if we check for the possibility so over here the maximum number of jumps we can take is three jumps so if we take three jumps we reach at Zero from zero we can't move any any anywhere for forward uh so let's rather than taking three jumps we'll try to take two jumps so if we take two jumps we end up over here and over here the maximum we can take is just one jump so again we end up at zero and lastly rather than taking two jumps from here we'll just take one jump so we'll end up over here at this position number two now at this two the maximum jumps we can take is two so again we end up at the zero which means that in any circumstances if we start at this position number one we cannot reach to this last position so over here we would return false this is basically the problem problem statement uh I have given a custom example that we are at any position we are going to first of all see that what is the maximum jump we can take we'll try to make that jump we'll try to see that using that jump if we can reach to this end index if we cannot reach to the end index somehow we will backtrack we will go back to the position where we initially took the jump from and we'll try some other possibility so let's see that in action so over here we are initially at this position number two the maximum jump we can take is at Value number two so that jump will bring us over here now over here the maximum jump we can take is at uh this position zero which means that we can't move any further so we will backtrack so we will backtrack we will come back over here now again we are at the second position now let's rather than taking the two jump we will reduce our jumping possibility and we will just take jump of one step so now we reach at this value number three and over here with this value number three we can take maximum jump of three steps which means that we can if we take three steps we will end up over here so 1 2 3 and at this position two the maximum number of steps we can take is two which means that even if we take two steps we will cross our last um entry which means that in any case we would be able to reach to this last element and we would return true in this scenario now this approach seems sensible on pen and paper because we are dealing with a small number of uh things uh small small number of input and we are able to clearly see that how the pattern is going on so let's take another example okay so these are the values let me also denote the index values for these now with every single iteration I'm going to note down the uh in the index value transition we are making okay so initially we are at this position number five the maximum jump we can take is a five step which means that we would end up over here so initially we would do something like this so 0 to 5 this is one one step we take we are at zero position which means we can't go forward which means we have to backtrack which means that again uh from five we will come back to this zero index now from five rather than making a jump of five steps we will make jump of four steps and we would end up at this position four so from zero we would end up at this position four now from this four the maximum jump we can make is one so again we will take one step jump and we would end up at this position five again from we are at zero we can't do anything so we will have to backtrack so in order to backtrack we will go to go back to this position number four again we have to backtrack from this position Force we will end up at zero again we will rather than making a jump of four step we will make a jump of three step and we'll end up over here so we end up over here and so on and so forth so you can see that this uh in this approach all we are doing is just we are going someplace we are coming back again we are going we are going and then again we are coming back again we are going to some next element we are going to some next element and we are coming back and suppose this keeps repeating multiple times uh you are essentially depleting your resources because if you see the time complexity at any single iteration uh or at any single value we have two possibilities whether we wants to keep this value in our current transition or we do not want to keep our Val keep this value in our current uh path that we are calculating which means that the input if we make decision tree the decision tree would would keep on growing and growing with uh addition of every single value which means that uh we are basically making lot of decisions and the time complexity in this scenario would actually be big go of 2 to the power n because at every single position we are making two possibilities this is a very bad exponential time complexity which we cannot allow in any scenario okay so the issue in the Brute Force approach we had is that we were doing lot of repetitive work because at any point we found out that we are not able to make any progress from this point we are still ending up at that point so let's see that how can we counter that with a better approach suppose we create an additional data structure over here so we create a dynamic programmatically additional data data structure over here uh let's create an array and in that array we are going to Define that at any position can we reach to this end point and if we identify that yes we can reach to this end point uh we would basically fill that position as true and let's see that how it can help us so if at any point in time we are at this final position we know that this is the main terminating case which means that we can put true over here so this final element we can always put true and this would actually become our base case now we have a base case we are going to start iterating on from right to left Manner and uh we are going to start filling up our DP array to see and in the DP array the only thing we are mentioning is that at any given location if we are able to reach to this end point or not if we can we'll just mark it as true otherwise we'll mark it as false okay so now one step over here this is uh this value has potential to make two jumps uh and it only takes one jump to get to this last point which means that if we end up at this fourth position we can reach to this fifth position which is what we want so over here we can also fill this as true now we are at this zeroth position from this zeroth position can we reach to this fifth position no because we cannot we can basically can't make any jumps so we'll just fill this as false okay now from this one can we end up at this fifth position so we are going to now the interesting part comes now we are going to check that okay this has possibility of only doing one jump right so with one jump we can only end up at this third index now we only need to check that in this DP array for this third index if the value is true or false so in this case this is already false which means that the maximum we can get to is this third place from this third place we can't go anywhere so we don't even need to check these values we can only check this DP table and we can conclude that no we can't go anywhere forward so we will put a false over here as well now we are at this third position now from this third position we will again do the same check but thing is this has potential to do three jumps okay so let's do one jump at a time so First We Take a jump if we take a jump of one step we end up over here we check over here that this is false which means that this is false right now we take second jump with the second jump we end up at this third position we check in this DP array this is also false which means that we can't do anything now from this third position we still have one more possibility that we can take a jump of three uh values so if we take a jump of three values we end up at this position value number uh this index number four so for this index number four we we see that the value is true if we find any true which means that we can say that from this second uh this index uh index number one we can reach to this last end point and now for this position we need to check that it has potential to do two jumps we will only check for one jump so with one jump we will end up at this first uh uh index that one is true which means that we can fill true over here here as well and in the end we just need to return whatever of DP of Zer we found so in this case we can determine that this uh is true which means that we are able to come to final uh end point so this solution is very good it works perfectly fine okay so the time time and space complexity for this approach would be so the time complexity would be bigo of n² because notice that we need to do one iteration to go on the for every single element and sometimes for any given element we might have to do multiple jumps like we did in this case of three so in the worst case we might have to solve this in bigo of n Square time and the space complexity would also be Big O of n uh because we are creating this additional DP AR now this is still much better than our Brute Force approach but our aim is to go into companies like Google Facebook Amazon apple and whatnot so those companies expect the best out of the best Solutions and is this the best out of the best Solutions we can do actually no there is still a better optimal solution and let me show you how we can get there okay and this optimal solution is actually based on uh the dynamic programming solution that we just saw so in dynamic programming what we are doing is we are creating an additional DP array and we are storing that whether we can uh reach to this last element or not but thing is is what if rather than storing this value at any position when we find out that suppose from this position we found out that yes we are able to reach to this last position so why do we need to check that whether we can reach to this last position or not if at any point amongst these values if we end up at this position we would still be able to guarantee that we can reach the last element because we have already checked this this condition so rather than checking to for this whole thing if we just check that okay from here if we can reach to this element or not and if this is true we can simply return true at that moment also and let's see that in action so let me clean this up a bit let's mark all the index values okay initially we create an element called final and this final element represents the last value in the uh given input and initially we set it up to this uh index number five right now our aim is that at any point we found out that among these values if anyone can reach this final element then that element by itself becomes this final so rather than storing all the uh values of uh at any given location we are actually shrinking down our boundary of search initially the final is at this fifth position now we are at this second position so all we need to do is to check that whether our current index I uh our current index and this current value if some of these two is actually greater than whatever final we have So currently the final we have is this uh five so this is the final we have current sum of these two values becomes uh 4 + 2 is equal 6 which is greater than 5 which means that we can update the fin value of our final so now so now this becomes our new Final and we basically don't care about this value anymore now we are at this third location and we try to see that uh the index plus its value so this will this becomes 3 + 0 is it greater than our final no this is not greater than our final because this is three and this is four which means means that we can't do anything over here so we drop this calculation and we check with the next element so over here we have this two and we have the value 1 so 2 + 1 is this uh greater than 4 so greater than final no this is also not true which means we can't do anything over here we again go back now this is 1 and this is 3 Now 1 + 3 is this greater than or equal to Value 4 yes this is greater this is actually equal to 4 four which means that we from this point we can come to this point this is what this concludes and which is what we want right so now we know this information which means that we can update the value of our final again so now the Val the value of our final would become one so at this value and now at this zeroth position we need to check that whether we can reach to this one or not so current so over here the sum of these two value becomes 0 plus uh this is 2 so 2 is definitely greater than the final amount we have is one which means that we can reach over here so the final element would be shifted to this point and our at the end of our iteration the final would be zero so now the final is zero after the end of the iteration we only need to check that what is the value of final if final is zero we return true true if final is anything other than zero we return false and this is a very good solution the whole thing runs in the time complexity of bigo of N and if we see the space complexity we are only storing one additional parameter so we are essentially using constant space and we are solving this problem so this is a very efficient solution let's create a variable called final oh Java I can't use final let's call it final with an extra L and we will assign it value as nums do length minus one and now we'll run a for Loop and we'll start it from I is equal to uh number of length nums do length minus 2 because we already know the result for uh the array length and we will we will run it up until we reach to this zeroth position we'll do I minus minus and inside the loop we are only going to check one condition that if uh the current value of I plus nums of I if they are greater than or equal to whatever the final value we have we can uh update the value of this final parameter to whatever the I value we have and uh yeah that's that should be pretty much it now we only need to check that if uh the value of this final character is uh zero or not so if it is equal to zero we can return true else we can will return false okay let's uh try to run the code seems like our solution is working let's try to submit the code okay our solution works 100% faster than all the other Solutions this is really good sign and uh this is not constant time but because we are basically shifting our uh boundary we are essentially reducing the number of work we can do we can do and also if you see the memory usage we are actually better than uh 86% of all the other Solutions so this was a very small line of code but this uh small line of code actually requires huge set of understanding so see you in the next video thank [Music] you hello friends we are still not employed by Fang company so let not stop lead coding till we get there graph problems have always been a big no no for me I have always been afraid of craft problems but the thing is now I have decided to take them heads on and uh today we are going to start doing more graph videos so this is the first of many graph problems to come and uh this question has been really popular with Facebook recently it's been asked 44 times which is huge number also key other companies like Amazon Google Bloomberg Microsoft Twitter they are also asking this question but the thing is Facebook for some reason has been really interested so I highly urge you to go and uh check this video If Facebook is one of your dream companies to join okay this is a lead code medium problem and we are given a reference node in a connected undirected graph so first let's understand the meaning of these two values suppose we are given a graph like this notice that there are only four nodes and from any single node we can reach to all the other nodes in the given graph which means that this is a connected graph so this is what connected means and undirected graph means suppose we are given a graph like this uh and we establish that a is B's neighbor which means that we can Traverse from a to B and also we can Traverse from B to a so there is no restriction regarding the direction of any direction of any Edge between two nodes so we are given a reference point to that and we need we need to return a deep copy of the graph so what does a deep copy of the graph means that suppose we are given a graph like this so we need to return a graph like this where if you see the values of the nodes they are all the same but the thing is we are not using the exact same nodes we are using different nodes with same node values uh which means that this would be a legitimate case where we can consider this as a deep copy of this original input the thing is if we create a graph like this over here we are using we are using these the same node to represent over here which means that we are not creating a copy of this original graph we are just referencing this point to whatever value we had over here so this is not what we want to give and also if we create some graph like this if we see the values of the nodes the values Remains the Same but the thing is the ordering is different that in terms of neighbor selection and how they are perceived they are different so this is also a false case we need to return a copy of this exact same input just with the nodes that are copied from this one so at the beginning the most basic idea we are going to have is that okay we are given an input we are given a reference point we know that the input graph is connected which means that there are no loose ends that we have to worry about so why don't we just Traverse through the uh in given input graph at every single note we starts creating a a copy of it we start creating the same sort of neighbor connections that we have in the original graph and then just try to return the new graph that would be a perfectly good logical Sol rational person would think and uh that Sol that would be a good entry point to start our solution but thing is we are going to see that with that approach what would be the issue how can we remediate that issue and uh what would be the final solution so let's start so first of all suppose in this given input we started this one position so we create a new node one okay now from this one we can go to any neighbor we can go to two or we can go to four let's say that we go we go clockwise so we go to two so we create a new new neighbor over here called two again from this two we go to three uh and over here keeping the same logic we create a new node now notice one thing that initially we had we created a clone over here we went to its neighbor again we created a clone over here we went to its neighbor again we created a clone over here we will go to its neighbor so basically for we are doing the same problem again and again for different kinds of input so that should immediately click in your mind that this we are going to solve recursively so just keep this in mind that this this is a very good way to use the recursive approach and uh now at this three again we go to its neighbor so we'll create an edge and we'll create a new node for uh for this one so from this four again we go to its neighbor again we go over here but the issue with this approach is that for this our recursion to end we need to have a terminating case but in this scenario we are not terminating it anyhow because the thing is the graph is connected we are terminating in a scenario where if the graph is empty we return something empty or something like that but thing is over here again we when we come back to this one we are still going to see that okay this is one we need to create the clone of it we will create a clone of it again over here which means that we are going to do we are going to overwrite whatever value we have which is which would be the same value again we would go to two we would again create another clone again we would go to three again we would create another clone again four again another clone we so basically we are going to end up inside the loop again and again infinitely this is almost like Infinity War Thanos is going to snap his fingers something like this because we are completely uh destroying our computer resources our company's resources because it's an infinite loop it's never going to stop so and the reason it's never going to stop is because we are doing the repetitive work again and again and again and that is the issue so somehow we need to resolve the issue so how we are going to resolve the issue well basically the idea is simple if at any point suppose we create an additional data structure in that additional data structure we keep track of whatever the value we have traversed already or we have cloned already if we know that which means that initially when we start we are going to check in that new data structure first that hey this element have I use have I cloned it already if I have cloned it already I would skip over I would go to next element if I haven't cloned it already I would create a new clone of it and then I will put the same entry in the hashmap first before I go to the next element so that way when after this first Circle comes and when I come back to the same position I would know that okay I have already calculated this one which means that I don't need to calculate it again and I can skip over it first of all let's let's see that what kind of additional data structure we are going to create where we can immediately find that whether we have visited any particular element or not which means that we are going to do lot of searching hence we will need a data structure that is very quick and efficient in terms of finding the uh any element that whether it contains that element or not uh and the answer is pretty simple if that kind of scenario happens we need to use hashmap or hash or something with the hashing we cannot use the link list over here it would work fine but it's going to add that much more additional time strain or on our system so make sure that you justify your reasoning I mean in the interviews people are not typically going to ask that why did you use hashmap this is a given but the thing is that uh thinking should be clear in your mind that why you are using it and in most of the graph problems uh typically hashmap is being used and now inside this hashmap we are going to store two values so as a key we are going to store a node and as a value we are also going to store the node but thing is as the key we are going to store this input node and as the value we are going to store the cloned node that we will create so let's see that what what should be the algorithm for our solution and how we are going to approach it so initially we start at this position one now at this position one first of all we check that whether we have this entry inside our hash map or not okay we don't have the entry inside the hash map because we can find it in constant time if the entry does not exist we first of all create a clone node okay clone node has been created now after creating the Clone node immediately before even we check for the Neighbors of this one immediately we are going to add an entry inside the Clone node so the value would be the cloned value that we have created and the key would be the original uh input we are given now this is done now we are going to check for this one's neighbor so one let's say we end up at this neighbor number two so again for this neighbor number two first of all we are going to check that whether neighbor number two exist in this hash map or not it does not exist so we will create a clone now the Clone has been created created first we will add the value to the hashmap and after adding the value we would again go again recursively do uh find for the two's neighbors so in this case uh the two's neighbor would be three so we will create uh first we will check that whether three exist in the hashmap three does not exist so we create the node and then we create this one now again we check for the value number four four does not exist so again we create an entry inside the hashmap we provide the key value and then we create the Clone node four again now for the four we again check for its neighbor so Force neighbor one neighbor is one which we already have it in hashman which which means that now we can ignore this case because we have already dealt with one now second neighbor for four is three which already exist in the hashmap which means we can we can be dealt with it uh we go back two is already done one is already done which means that now we are running out of neighbor to take track from inside the given uh original input and we know that the original input is completely connected graph which means that there is at no point there is a possibility that there exists some value five over here that is part of this graph but it is not provided uh using this connection because all the elements are connected which means that this would be our final clone graph that we need to return so after the loop ends and the recurs termination cases trigger we can simply return whatever the Clone graphs we have found because from any single location we are able to guarantee to reach all the other elements and once that that is done essentially we are done so this is a very effective solution basically all we are doing is just we are traversing over the given graph and uh during the traversal we are doing something so in this case we are cloning it um we are using the hashmap to keep track of whatever are the visited elements that we have been through and uh the solution is pretty efficient it's uh it's not the most difficult problem in the world but the thing is I am very bad at graph problems so and I have always been scared of graph problems but the thing is now I have decided to spend more time on graph problems because if you want to join Facebook you can't you can't even think about not doing cph problems okay so today is first of many problems to come uh if we see the time and space complexity time complexity in this case would be big go of v+ e where V is the vertices and E are the number of edges because notice that over here we are only doing this much work we are not doing any additional work so that's pretty simple and in terms of space complexity it would actually be B of V uh in terms of number of vertices because over here we had four vertices and uh in the hashmap we created four entries uh so whatever the number of vertices we are provided we are going to use that and that would be your space complexity so this solution is actually pretty efficient uh we are using depth first search to solve this problem but even we can solve it with using breadth first search so it makes no difference in terms of time complexity the thing is I just did this using depth first search next one I'm going to use breath first search maybe so first of all we are going to create a new hashmap and we are going to name it visited to keep track of whether we have already visited the node node or not now inside the method first of all we are going to check that if the given node is null which means that we can return the node okay and also we are going to check that if uh the if we have already visited the existing node then we are simply going to return whatever the uh value we have stored inside the visited hashmap okay if this is not the case uh first of all we are going to create a clone node so let's just name it clone node and in inside the Clone node we are going to give it the value of whatever the node value that we currently have and we are going to assign a new array list we are going to add the new clone node to the visited node we are going to run a for Loop for all the neighbors of existing node so inside the loop we are going to iterate over the neighbors of the existing node and we are going to create the Clone nodes for that and inside the current clone node we are going to put the neighbor as an array list so and over here we are going to make the recursive call with the neighbor after this Loop ends we are simply going to return the Clone node let's try to run this code okay seems like our solution is working let's try to submit the code okay our solution works and it works pretty efficiently there is still room to make a lot of improvisation as we can see that our solution is not the most efficient but the thing is I'm really bad at graphs so it took me a lot of time to make this video because I need to understand very thoroughly by myself first before I can create the video uh but soon I'm going to do lot of graph videos so it's going to so my video quality is going to improve and also my coding is going to improve so hope for the best and uh let me know in the comments what do you think about the video and uh yeah see you next time thank [Music] you hello friends we are still not employed by Fang company so let's not stop lead coding till we get there today we are going to do core schedule lead code problem and this is one of the most versatile problem uh that has been asked at bunch of different companies like huge huge huge number of companies uh we can see the companies like Amazon Microsoft Facebook Google Tik Tok Snapchat Robin Hood twio Uber eBay Tesla all the companies have asked this question and this question is very practical real life application so that's why a lot of companies like to ask this question so this is a lead code medium problem and we are given a number of courses and we are also given given an array of prerequisites where any single entity in Array is defined like this where where we are given two values suppose A and B separated by a comma which means that we must complete course B first in order for us to complete course a so suppose we are given an entity in the prerequisites like this 1 and zero which indicates that the scor one actually has a prerequisite called course Zer so we can Define it like this that course one has a prerequisite on course z and in terms of the Practical manners we first complete this code course zero in order for us to complete this course one and based on the information given we need to check that whether we can finish all the courses or not and if we can finish all the courses depending on whatever the prerequisits we are given we need to return true otherwise we need to return false okay now that we understand the problem statement let's take a custom example to understand the problem suppose we are given the list of prerequisites like this and we are given the number of courses as four which means that we need to complete the 0 1 2 and 3 these four courses we need to complete and this is the list of prerequisites we are given now we can consider this as actually graph problem uh we can consider these as graph Ed nodes and uh the prerequisite information we can treat them as graph edges so so over here we can say let's plot it on a graph and let's see that how it would look so over here 1 has a dependence on zero so I mention this zero has a dependence on three so let's also mention this and two has a dependence on zero so two has a dependence on zero okay so this is how we can plot this on on a graph and we need to see that whether we can complete all of these forces or four courses or not so the most intuitive solution is to check from the beginning we check at this course number uh zero that can this course number Z be completed or not now in order in order for us to complete this course number zero we see that this course z actually has a uh Edge pointing towards course number three which means that course three is a prerequisite for course zero so we need to complete this course three before we can course complete course zero now with we are at this course three again we check the same thing that whether we can complete the course 3 or not now course 3 does not have any prerequisite which means it can be completed on its own so we say that okay course three can be completed now again we backtrack to zero at Zer we check that do does zero have any other prerequisites that we need to take care of the no Zer is zero only has one prerequisite on course three which we can complete which means that we are able to complete course z as well so we can mark this uh and the square box indicate that we are able to complete that course so we are good so we already knowe that zero can be completed three can be completed now we check for this course number one so at course number one we check that what are the prerequisites for course number one well course number one has a prerequisite on course number zero so we since we already know that course Zer can be completed which means we can uh also conclude that course one can also be completed which me which we can mention over here and we can check for this course number two so course number two also has a prerequisite on course zero which is already done which means we are able to complete course number two as well so in this case for all the four courses we are actually able to complete them and uh we can return true in this case that yes uh based on the given uh number of courses and prerequisites we are able to complete all the courses now we need to check that what could be the scenario if we cannot complete the course so suppose we are given an additional Edge like this in the same example suppose we are given this additional Edge now let's see that how the dynamic would change let me clean this up a bit okay now we have this additional Edge 32 which means that in order for us to complete this course number three we would need to complete course number two as well now let's see that can we complete so initially we would check that can we complete this course zero so in order for us to complete course zero we would need to complete course three okay now in order for us to complete course three we would need to complete course two okay and again in order for us to complete this course two we would have to complete this score zero so notice that we are constantly stuck inside a loop it's the same scenario where you need experience to gain a job and you need a job to gain experience uh it's some somewhat similar kind of example that we are stuck inside the loop which means that no matter what happens we are not able to complete any of these three courses without completing the other one because there is an interdependence between each other and uh essentially in this case we would have to return false that we cannot complete all the courses but the thing is why do why did we have to return this false well the the reason is quite simple basically we in terms of graph manner if we speak what was the difference from this graph compared to this previous graph only this Edge and when we added this Edge what essentially we did was we introduced a loop inside our uh graph among these three values 0 2 and three so we can conclude one thing that at any given moment if we've identified that there exists a loop inside our graph we would be able to immediately return false if there does not exist a loop and we are able to from every single element we are able to complete all these prerequisites in the that scenario we need to return true so now we have these two information let's see that how can we use them and how can we solve this so suppose we are given an example like this and uh these are all the prerequisites that we are given and we need to complete the six total six number of courses uh in order for us to conclude that this graph can be uh scheduled or not so essentially we are going to apply the same logic we are going to first of all take these inputs we are going to convert them in a graph like this uh inside the graph for every single course we are going to see that whether we can justify these prerequisites or not and at any moment if we identify that there exist a loop we will immediately terminate and return false if there does not exist a loop we would uh keep going and uh eventually we would return true so that is the idea and in order for us to achieve that first of all what we are going to need is we are going to need some sort of graph data structure because initially the only only two values we are given is number of courses and the set of prerequisites uh so first of all we would create a data structure like uh hashmap and in inside of our hashmap we are going to store two values we are going to store as a key we are going to store uh the number of courses and as a value we are going to store the uh number of prerequisites that every single course has so initially we would have so this is the number of courses and these are the prerequisites that we have uh and we would try to see that can we complete all the courses or not so first of all we are at this course zero so in order for us to complet this course 0 we need to see that what are the prerequisites for course 0 uh so for course 0 the prerequisites is course 2 now for the course two what is the prerequisite the prerequisite is actually course three okay and now for this course three the prerequisite is actually course 4 so here and the for this particular course 4 the prerequisite is actually course 5 so here now we are at this course 5 we check that can we complete this course for five and yes we are able to complete the course 5 because it there exists an empty list so which means we can conclude that course 5 can be completed over here because there is an empty list so again we back track we go back to course 4 at this course 4 we know that course 5 can can be completed since course 5 can be completed we can also have an empty list over here because it defines that at any moment if we are at this course 4 that course 4 can always be completed because it's pre- requisites are already met so we can have an empty list over here now again we go back if we go back we are at the course three so in order for us to complete this course three we would need to set up an empty list over here because course 4 can be completed um that is done now again we come back to the scor two at the scores two again we will create an empty list and now uh we are at this course zero so at this course zero we only have dependence on course number two so we can also have a an empty list over here basically defining that course zero can be completed okay so that is one observation that has been done well now and see that we were only trying to calculate that can we complete this course 4 but we already concluded that we can complete these all these courses as well and we have already established them inside our hashmap so at any moment uh we only need to identify the remaining courses and not all of these courses that we have Sol already which means we are efficiently improving our solution uh second we come at course one now this course one actually has three dependencies uh course 2 course 4 and course 5 so let's take care of uh each of them one by one first of all we'll check that from course one can we complete course two so we check for this course two and we check that the these prerequisites are already met because there exist an empty list which means that we can eliminate course two from over here from the list of prerequisites because we know it can be completed again we check the same thing for this scores 4 uh over here the sces 4 we again have the empty list so we can also eliminate the course 4 over here as well and again we can repeat the same process for this course 5 that course 5 can also be completed because there exist an empty list which means even at this position course one we can create an empty list over here and now if we look at all the courses the only prerequisites we have are just empty list lists and uh once we achieve that basically we can conclude that we have already reached our solution and we can return true in this case so this solution works perfectly fine but thing is we missed the key point over here like because this was a true scenario we did not identifi any issues but thing is if there was an a loop we were not actually checking that whether we are en encountering any Loop or not so let's see that if we want to encounter any loop at any iteration what would be the additional steps we need to take so let's modify our example a bit suppose we have an additional prere it like this 53 that in order for us to complete this uh course 5 we will need to complete course three so we will have an edge like this and uh let's modify our prerequisites table okay now in this example we know that there exists a loop between this uh 3 4 and 5 so we need to take care of it and in order to take care of it I'm suggesting that we create an additional hash set uh at the beginning of uh checking for any single course so we create a hash set and in the in our head we just name it as visited or something and over here we will keep track at that at any location are we repeating the same element so let me show you what I mean by that so initially suppose that we are at this course zero and then we start our program so we want to check that whether we can complete course z or not so first of all we are we will check that whether we have already visited this course z in this current iteration so we check in this visited node uh that have we visited core zero and because it's a hash set it's a constant time operation so we are not adding any additional strain on the time complexity so we haven't visited this node zero we would uh so we would add an entry over here first now we will check over here that what are the prerequisites for this course zero so the prerequisite is course 2 so again we would add we would check our visited node first so course 2 is not part of it so we would add an entry over here and uh again we would continue over here so now we need to check this course three again we would add it uh entry to the visited node uh we check over here we need to check course 4 four we haven't visited so we would add an entry over here uh then we would check the force prerequisite uh five five we haven't visited so which means we would add an entry over here and now at this five we would check the prerequisite for five so for the prerequisite for five is actually three so we are again at this position three so first of all we'll check that whether we have visited this three or not and this time we would know that yes we have already visited this node 3 uh which means that we are in a loop so this is what this hash Set uh confirms and the moment we find out we can immediately return false over here we don't even need to check any additional uh items in this given uh graph and uh we would be able to terminate our case immediately which means and in case if this Edge was not existent uh this entry for this value number five for this value number five we wouldn't have to check anything and uh we would have been able to complete all of our code and we would have been able to return true but which is not the case this time because there exist an additional prerequisite as specified over here so this would be our final solution and now let's calculate the time and space complexity for this one so for time complexity we can actually complete this whole thing in bigo of V + e time because at any moment the maximum traversal we will have to do is from one uh one node to all the single uh nodes and uh throughout all the single edges so this would be the time complexity and space complexity because we are creating an additional uh data structure like this hashmap and also this hash set but thing is Hash set is going to be smaller so we are only concerned with this hashmap for General time complexity it would be uh sorry space complexity it would be big of V plus e as well and okay first of all we will create a hashmap and we are going to store uh integer and list inside it we will name it course graph okay now we will have to build our graph so essentially we are going to iterate over every single uh prerequisite in the given prerequisites and first of all we will check that whether this prerequisite is already added in our graph or not so if it is added already we only need to append the new prerequisite and if it does not exist we will need to create a new one uh we'll have to create a new entry in our course graph so we will create a new list and add the list and then we will add the entry of the course and uh the list to our graph okay so after this Loop ends uh we should have our graph structure ready so now we will create a hash Set uh that will take care of integer values and we'll name it visited and now we'll have to run a loop for all the courses that we are given and now we will have to create a method to check that whether there exist a cycle inside the loop or not and uh let's name our method that uh course schedule which indicates that whether we can schedule a course or not in this course schedule method we are going to provide the current uh course the visited node and the graph that we had created and if this responds back to false at any given moment we would know that we cannot create the course schedule so we will return false immediately and if this Loop ends and we don't return false which means that everything was successful and we we can return true okay now we will have to create this Score schedule method so let's create a Boolean method now let's uh test our terminating cases so if if our set contains the current course which means that we have detected a cycle so we can terminate immediately so we can return false uh also we check that if uh for the current course uh we if we already have an entry in the graph where it has an empty array list we can return true if that is not the case we will have to iterate over all the prerequisites for any particular uh course so first of all we will add the current course that we are iterating over in our visited hash set then we will iterate over every single prerequisite for that particular course uh we would uh we would call our recursive function so and we will provide the current we will provide the current prerequisite we at we will provide the visited headset and we will provide the graph and if at any point this returns false we can return false immediately however if this uh loop executes we know that for that particular course we are actually able to to complete uh complete the course and we can schedule it so first of all we'll remove it from the visited node and then now since we know that uh this particular course can be completed we would update the entry for that course in our course graph uh so we would Set uh the prerequisite to null which means that in future at any point if we identified this particular course we know that we are able to complete it and we can just move forward quickly and uh at the end we can simply return true in this case so I guess this would be our core schedule function uh where the main logic happens and uh let's try to run the code okay seems like our code is working let's let's try to submit the code okay our solution works and uh it's it works pretty efficiently so I would be putting this solution in the uh comments you can check it out from there and this was a really long video it took me a lot of time to make it so I hope you like it and let me know in the comments on what are your thoughts about this problem um see you next [Music] time Hello friends we are still not employed by Fang company so let's not stop lead coding till we together today we are going to do a very important lead code problem Pacific Atlantic water flow and as you can see that this problem hasn't been last in too many companies but I think is the companies where this problem has been asked are really one of the most important companies in the world uh Google Amazon Uber Microsoft Facebook Apple by Dan which is a parent company of Tik Tok Bloomberg so you can understand the scale that why this problem is important and what kind of companies ask this problem and the thing is main intention for understanding this problem is to not to understand the actual problem but rather the approach behind the solution because that can become a base foundation for too many other problems there is lot of information in this problem statement but if we try to comprehend this using the picture it really it's really simple to understand so I'm just going to go over that essentially we are given uh a grid like this and we are told that this is actually an Island on somewhere in the ocean but thing is it is at the Cross Junction between Pacific Ocean and Atlantic Ocean and the way it represents is that this top and this left edges they are actually Pacific Oceans and this bottom and this right edges they are Atlantic Ocean so this and the second information we are given is that all of these coordinates inside the given um Island represents the height of that particular area and why the height is important because we are told that uh on this particular Island on this particular grid there happens to be lot of rain which means that uh rain falls and we know the property of water that it gets transferred from higher height to lower height we are also told that that rain at any particular cell can travel to can go to four directions it can go to top or right bottom or left which means it cannot go diagonal in any scenario and the condition that if uh it can Trav Traverse from one cell to another cell is that if the height at any particular given cell if it's greater than or equal to the cell we are trying to reach then the water can Traverse travel to that uh that cell which means suppose we take this cell for an example the height for this cell is four which means if the rain falls on this cell we can conclude that rain the rain water will go to cell three it will also go to cell one and cell two but it would not go to this cell five because the height at cell five is greater than uh cell 4 which means that this is cell four and this is cell five so water can't travel like this now the interesting part for this question is that we need to understand that what are the uh cells in the given grid that can travel where if the rainwater Falls it can travel to both Atlantic Ocean and also Pacific Ocean so let me clean this up a bit suppose we consider this uh cell number five and if rainwater falls in the cell number five uh let's see that can it reach Atlantic and Pacific like we know it can reach but in this uh cell cell adjacent to the cell number five the height is three which means water can go over here from this three the water can go to this one and because this is at the edge of of Atlantic uh of course water can go to Atlantic ocean from here now from this uh cell number five uh we know that water can also go on this side because the height is four and from this four the water can go because the height is two Which is less than four and from this this is at the edge which means that at any point whatever the height over here is uh like 1 two whatever value all of that can go to Pacific Ocean so we can conclude that water from this uh cell number five can reach to both Atlantic and Pacific question let's take another example suppose we take an example of this uh value number four so we know that from this cell we cannot go over here we cannot go to five but we can go to two and from two we can go to Atlantic so that concludes one one uh option now let's try to see that can we go to Pacific Ocean so first if we try to go on top okay we can go over here because this is three but from three we cannot go to the top because this is uh four so we can't go Pacific in that this direction if we try to go over here we can reach to this one we cannot go to this seven which means that from this four we can go to Atlantic Ocean but we cannot go to Pacific Ocean so we wouldn't include this in our intersections for every single cell we are going to check that whether it can reach to both Pacific and Atlantic Ocean if it can reach we will just maintain a list or some sort uh that will take take care of all the cells that we are able to reach uh to both the oceans and we would keep on adding them in in this list so first we'll start with this first element uh we know that it can reach to Pacific Ocean but it won't be able to reach Atlantic Ocean because height over on both these cases are greater so we wouldn't include this we would go to next one so over this this again can reach to Pacific but it cannot reach to Atlantic because if we it will Traverse in these two directions but it won't be able to to go any further over here and over here uh same happens for this one for this one and uh basically this solution would work we would find our answer eventually our list would be filled out suppose we are at this location five so we know that this is at the interest exact intersection of both the oceans and it can clearly go to uh the rainwater can clearly go to Pacific and both Atlantic so we would add this particular location in our list and uh eventually the list will be filled out but thing is uh the issue with this approach is that in terms of time complexity we are actually doing lot of lot of repetitive work because for every single cell we are checking all the possibilities and uh we might end up doing in the worst case scenario big go off so suppose this uh is M and these are n cells so we can say that the time complexity would be big go of M * N squared because for every single cell we will have have to iterate over all the other cells and uh this is not a very good time complexity there is there exist a better approach so in order to solve this problem we are actually going to use a different approach and we are the approach we are using is actually if Mountain cannot come to Muhammad Muhammad will have to come to Mountain and what I'm trying to say is suppose that rather than checking at any particular cell that whether it can reach both Atlantic and Pacific Ocean we create two separate grids so we create a grid and another grid so two separate Matrix of Boolean values that has the same size of whatever the input size we are given and at any particular location we just name that that okay this matrix consist the data of all the cells that can actually reach the Pacific uh ocean and this cells contains this Matrix contains all the data of all the cells that can actually reach to the Atlantic Ocean and once we have these two uh matrixes defined uh the moment we find that okay so over here we know that uh this particular element three this can reach to Pacific Ocean so over here suppose this value corresponds to this three so we will set the value is true over here and same goes on this side that suppose we find out that uh this particular element at for position 4 can reach to Atlantic Ocean via this way so whatever the corresponding we have value we have over here we will set that value as true and eventually we will have the entire uh matrixes filled out and once we have those all we need to do is just intersect both of them and find the common elements between both of these Matrix and uh that would be our final list of matrics that contains all the cells that can reach to both Pacific and Atlantic Ocean and this would be our solution well this solution actually works pretty fine it's pretty efficient and and uh all we need to do is we need to figure out that how we are going to generate these two Matrix and what are all the different logic we are going to take let's take the most basic approach I'll be showing you an example that suppose we want to reach to Pacific Ocean how can we fill out that M Matrix now what is the most basic thing we know about Pacific Ocean well we know that for this particular Island all the cells that that are present in this row and all the cells that are present in this Colum colum they are actually at the edge of the island also they are at the very adjacent to Pacific Ocean which means all the water in these positions can actually reach to Pacific Ocean in all the cases so in our Matrix or whatever Matrix we have we can basically Define all the elements these positions as true because we know that they can reach to a Pacific Ocean now previously at any particular location we were actually trying to go outwards to see if water can reach to adjacent cell or not but rather than going outwards why don't we come inwards from the cells we already know that can reach to Pacific Ocean so over here these cells we already know that can that they can reach to Pacific Ocean so if we check that whatever the cells that are adjacent to these cells from this particular cell that can reach to Pacific Ocean can we reach to the these adjacent cells or not and the we find that okay we can reach to some adjacent cells that we haven't already visited so we can set that as true suppose the value over here is three and we know that this is able to reach to Pacific Ocean and suppose the value adjacent to this one is actually six so we know that uh since the height difference there is a height difference and uh over here we need to check the reverse height difference previously uh in this approach we were actually checking that whether the height we are currently at and the height the adjacent cell is actually the height is lesser than whatever the current height we have over here we are coming inwards so we will check that whatever the next cell is that we haven't checked whether its height is greater than whatever the height we currently are at so in this case this is three this is six which means that okay from this cell we can come to this cell and uh over here we know that we are coming to this cell from this particular cell that is already able to reach to Pacific Ocean so over here we can directly mark this one as true and we won't have to do lot of calculation over here because we already know that this cell is true and we are reaching to this cell via this cell and this would be a very good solution and this is how we can actually fill out this entire Matrix like all the remaining portion in bigo of M cross n * in just single traversal because we we are not for any particular cell we are not going to check the whole thing we are only going to check the cell that is exactly adjacent to it suppose we are at this particular cell and we know that this cell can reach to Pacific Ocean we have already set this value as true okay now uh we do calculations like this and suppose before we come over here uh from this route we have already calculated this and we know that this is already true that this can already reach specific o and we are at this position and we are checking this again so first we will already find that whether the value for this particular element has been calculated already or not if it has been calculated we don't need to do repetitive work and we can just simply skip over it uh so that way we can also make uh some runtime adjustments that would be more efficient on our case okay now we need to find a way to somehow create the Matrix that stores the information of all the cells that can reach to Pacific paic ocean and also to Atlantic Ocean uh in order to do that at first I thought that we are going to use dynamic programming over here and the reason I thought is because first of all we are defining a set of uh all the cases that can reach to Pacific Ocean so this becomes our base case once we have our base case defined uh we are essentially going in all the directions to see that if we can reach to next cells and suppose in this case we are able to reach to this cell from over here due to the height difference so we will mark this as true and uh again from over here we will again do the same thing and we will so basically at any point we are using whatever the calculation we have calculated before to generate the next results so that's a very clear indication that we we need to use dynamic programming over here but it turns out that I was not not able to solve it efficiently I was still missing out in a lot of test cases so apparently dynamic programming is is is not the way to go but I still urge that if anyone can solve it using dynamic programming I would be uh more than happy to understand your approach so second thing I tried to do is uh that okay in order to solve this we need to iterate over the entire Matrix and uh in order to iterate over the entire 2D Matrix we we can use We have basically two methods we can use either breadth first search or we can use depth first search to iterate over all of the elements and do some calculation now I'm new to graph Theory and I need to first of all perfect myself on depth first search before I move towards solving the problems using breath first search so I chose the approach of taking depth first search but it can also be solved using breath first search without any issues and we know that in order for us to sell uh to complete this program using depth first search we need to use recursion over here and uh of course we can use recursion because notice that at every single position uh so over here first of all we Define that this can reach to Pacific Ocean Now we move on all the directions and over here we find the height difference so again we know uh that uh this can reach to Pacific Ocean because this can reach to this cell so we mark this as true and then again we repeat the same process that we have just did and again we would mark this as true and again we would repeat the same process so essentially we are doing the same sort of work but for different inputs and that's a very clear indication that we we need to use depth first search uh using recursion and uh let's move on towards coding now first of all we are going to check the condition that if the given input is actually an empty Matrix then we just need to return null okay if that's not the case uh let's create two parameters to store the value of row and column now we'll create to Boolean Matrix to see uh if there to store the value of cells that can reach to Pacific and Atlantic Ocean and we are going to name that Pacific reachable and Atlantic Atlantic reachable and we are going to create both of them to the size of whatever the uh initial Heights Matrix we are given now we will run a for loop on the for both The Matrix Matrix to be filled out and in order to fill both the Matrix we are going to create a DFS method and inside the DFS method we are going to provide the row and column location and uh we are also going to provide a Pacific and Atlantic Matrix so first we'll do it for Pacific Matrix and we are also going to provide uh the input Heights that we are given we are again going to call the same function for for the Atlantic we'll iterate using column as well now before we calculate the result first let's create the method now inside the DFS method we will have to iterate over for any particular cell we will have to iterate over all four of its uh adjacent cells so we'll just create a 2d array called uh directions and we are going to use it uh to iterate over all the adjacent uh or neighboring cells so we are at this DFS location which means that we already know that this row and this column pair is already able to reach to subsequent whatever reachable uh Matrix that we are trying to calculate so which means that we will set that value as true now we will start iterating over the neighbors of whatever the current cell we are at and we are going to create the new row and new column now we will have to check that if this uh new row and new column are they out of bounds or not if that's the case we just ignore that uh and we continue we also check that if we have the if the new row and column uh cell have we if we have that value calculated before we can also just ignore that case okay if both the cases are not true uh we will check that if the height difference of the previous cell and new cell is in our favor or not which means if the heights for the new row and new column if that is greater than or equal to whatever the previous height was if that is true we will need to call the DFS function again with the new row and new column and uh this this would be our Logic for this DFS method because we are eliminating all the cases and we are also calling the recursive function based on the height difference so after these four uh entries run we should have both of our Pacific reachable and Atlantic reachable Matrix is filled out and now it's just a matter of finding the common elements between them so first of all let's create a list of lists uh to store our result and we'll just name it as result just going to iterate over the entire array uh row and column wise and we are only going to check that if both the values are true in both the Atlantic and Pacific Ocean cells so if if both are true we can add it to our list so uh after this Loop runs we simply need to return whatever the result we found and uh that should be our solution let's try to run this code okay seems like our solution is working let's try to submit this code okay our solution also works it is uh accepted by lead code but thing is it's it's not the most efficient uh solution so let's see that if we can do some modifications and uh one modification I can think of is uh rather than calling this DFS system right here and checking this condition all the time what if we revert the condition and if this condition is satisfied we can return we can just uh return it and we can just continue before so that's why Loop breaks more times before and uh if all of these conditions are not true then only we will call our DFS function let's try to run the code okay the code is working let's let's try to submit the code okay we see some improvement in our code and now it's a little bit faster than what our previous result was so I'll be posting this code in the solution you can check it out from there uh from the comments and uh let me know if how do you like the video [Music] thank Hello friends the problem we are going to do today is one of the most versatile most asked question in the history of uh lead code questions like if you just look at the sheer numbers of the amount this question has been asked and the range of companies this question has been asked it like it's just mindboggling uh whatever your dream company might be in the entire world this if and if they do good technical interviews they must have asked this question probably at least 2 three 5 10 times uh to their candidates if I only had 10 minutes to prepare for a technical interview I'm going to choose this question at at the top of my choice like just look at the the companies over here like Amazon Microsoft Bloomberg Facebook Google LinkedIn Oracle Apple Bown which is basically Tik Tok door Dash Yahoo PTM uh Walmart Tesla Samsung so I doubt that there are any companies left that didn't ask this question and the question we are going to do today is number of islands and uh I'm going to pay my at most attention to this problem now in the input problem we are given a grid of M cross n as a 2d binary Matrix and uh in this particular grid we are uh the all the cells are filled with either values of one or value of zero and whatever the value that represents as value of one actually represents land in the real life and all the values that are uh marked as zero is actually water and uh we need to find that what are the total number of islands inside this particular grid now based on the definition we know that uh suppose if we have uh some sort of body of uh land something like this and if it is entirely covered by uh body body of water we can say that this particular body of uh land is actually an island and uh we that is what we are trying to find in this given problem now we are also Al told one more thing that at the edges of this particular grid like all of these values this is also water which means that suppose we are given uh an input like this where uh all of these values are zeros and we only have just one single one over here this we can also conclude as an island because uh on these three sides of the island is already water and on the outside is also water because we are told that everything on the outside is also water so just keep keep this in mind that if we find some place at the edge of the grid we still consider it to be surrounded by water if all the other side inside the grid is also water and our aim is to find that uh how how what is the maximum number number of islands that are present inside the given grid now this problem is actually pretty simple like if you if we just see over here like in this particular input if we try to find uh for this example one that how many number of islands there exist actually there only exists just one Island and that is uh this one because notice this that these all ones are actually able to be connect with each other because they're adjacent to each other uh if for any particular cell suppose this is marked as one and this is a part of land and any cell adjacent to this cell is also marked as one we can say that both of these are a common part of land because there does not exist anything in between they are right adjacent to each other and this is what we are given over here so in this example we only we can only find one Island now if we take the second example we can see that there are actually more than one Islands so so this is the first island that we can find this one is by itself uh and if we see all four sides of it uh this is zero this is Zer this is zero and this is zero so this is also an island and these two ones they are also an island so in this example we actually have three uh three distinct Islands okay suppose we are given a custom example like this and I have mentioned in my previous videos that it it is really important to come up with your own custom examples because it shows that you can think on your own and you can create test cases on your own it's a really important skill for any computer engineer to have now suppose this is the grid that we are given and uh this blue line indicates the body of water we have outside of our original grid so this is just for understanding purposes I'm just going to get rid of it now so it does not become an issue and I can explain the problem better so we know that there is water outside now the most basic approach is that we starts traversing through the entire Grid in some manner like there are B bunch of different ways to Traverse through the the given grid and we try to see that at any moment if we find one which means that so far we have find a body of water uh land now since we have found this one we need to see that what are the different Islands we can create and we can can create bunch of different Islands if uh all the values are relate are connected with one like no matter how many number of values are connected with any single one we would Mark all of them as just one Island as long as they they are connected with each other and basically what we are doing is we are trying to find separate set of ones understand what I'm saying we are I will repeat we are trying to find separate set of of ones so in this example if we just see that how many different sets we can find like we can find this one set of one we can find this another set of ones and we can find this third set of ones and over here we only have one individual element but still that is a set on its own like even if we only have just one acre of land it's still a piece of land which we can consider as Island so that is what we are trying to find and uh let me just revert back okay so now we know that what we are trying to find the most basic approaches we starts traversing through the given input array and uh we start traversing okay suppose we Traverse the first row we don't find anything okay now again we start traversing over here we don't find anything now at this point we find that okay there exist an element one one over here the moment we find that there exist an element one over here we are going to call our function and basically what that function is going to do is it is going to iterate over all the adjacent cells and it is going to keep on iterating till we exhaust all the ones that are connected with this one so till we exhaust all the sets that are associated with this particular one so let me just go back a bit and uh this is the approach we are going to take that initially currently we came to this particular item we find that okay there exist a one over here now because there exist a one we need to find all the ones that are connected with this one so what we are going to do is we are going to mark this coordinate and once we have this coordinate location first of all we are going to uh increase in the number of islands we have like initially we the number of islands we have is zero now we because we find at least a single one which means that we have found at least one Island so we will update the the number of islands we have now since we have already updated the number of islands uh and we have we already have coordinates for this one first of all we will mark this one as zero so let's mark this one as zero okay and now from this coordinate we will try to find all of its neighbors to see that their EX exist any adjacent ones so over here we find that uh okay this one is also one and this one is also one so we are going to repeat the same process uh and remember we are not going to update our Islands in this case because we are still connected with whatever the previous value we had found before so we are still in the same set of one that we were dealing with so there is no point in updating that but we have to exhaust all the ones that are connected with this original one we had found before so so we will check over here okay this is one so because this is one we will uh we will change its value to zero because it it now it becomes part of this uh original set we had uh now again we are from here we are going to repeat the same process okay we don't find any ones from this point so we are good but remember over here we we didn't ex exhaust all the possibilities from our original coordinate so we still have to do some work so again we will come back we will find one over here which means we will have to turn turn it to zero so we will convert this one to Z as well and now from this particular uh position we will try to repeat the same process so we will check all of its neighbors and all of it neor its neighbors in this scenario are now zero which means we are good like we have at least exhausted some possibility and we have and we have at least found one set of Island okay now we will again repeat with our process and notice that I convert all these three values to zeros because we already found an island over here and now uh we will repeat the same process so again we will start traversing our uh Matrix and over here we encounter the one again which means now we have encountered a new set of Island so we will update the value in our Islands we will update this to two again we are going to repeat the same process so first of all we will update this one to zero and uh now this is zero we still have to check its neighbors we find an adjacent neighbor again we uh we flip it to zero first and again we go to the next element again we flip it to zero and now we won't find any more neighbors that uh are uh basically one which means that again we will start traversing so we keep on traversing over and over and over and we don't find any ones but now we are at this point again we find a one we update our Island so our number of Island becomes three and now we need to find all the neighbors that are uh present in this particular Island and we set all of the those values to zero so these values are set up to zero and now um we check that okay no neighbor actually has a value of one which means we have exhausted all the possibilities of uh number of neighbors uh that could be a part of the island and now again we repeat the same process and now we find this one and this is the last element so again we increase the number of islands that we have found to four and we set this up to zero and now because we have exhausted all the possibility and we reach to the end of the grid we can simply return whatever the value we find in the number of islands and that would be our solution suppose we we were given uh an input with all the zeros like like over here we wouldn't have found any Island and we can simply return zero in that case as well but this is like a very basic approach and the approach we took in this scenario is actually depth first search uh to find the set of ones that are adjacent to each other like we could have used bre BFS as well but I mentioned earlier like I'm trying to learn graph Theory and first I'm going to master DFS then I will start working on the BFS so that's why I decided to do choose the approach of depth first search in this scenario okay and uh the time complexity in this case would be uh actually bigo of M cross n time complexity because that is in uh we have to iterate over entire grid that is given and the space complexity would also be bigo of M cross n in the worst case scenario suppose that we are given a grid where all the values are just ones which means that for every any single element we will have to iterate over all the entire uh grid and uh that could be the worst time worst time and space complexity first we'll create two parameters row and column to calculate the uh current row row and column values for the given grid okay and we will also create a variable called Island and initially we will set it up to Value zero and we would update this every time we encounter one inside the given Matrix and inside the loop we will have a condition that if the current I and J position inside the grid is actually equal to 1 then only we are going to call our DFS function so first we'll do Island we'll increase the value of islands and now we will call our DFS function in the DFS we are going to provide the I position the J position and we will also provide the grid that uh we are working on and uh once this Loop ends like we should have all the set of separate ones and uh we should have all the values of the total number of islands so we can simply return the number of islands we have have found okay now we need to create the logic to implement this DFS function so first we'll create a function inside the function we will need the values for uh the row and column again for the entire grid so we'll just name them new row and uh this would be grids length and we will also create a parameter called new column this would be the first uh positions length and uh this is basically same as finding the row and column we found over here but we need to use it so I'm just giving different names we'll also create a 2d array of uh called directions this would make our lives easier and allow us to iterate over uh all the adjacent values of any current position and we are going to initialize it with default values we have this established first we'll put a condition that if the current row and column are the out of bounds or not and we will also put an additional condition that if uh the current value we are at inside the grid if that is already zero or not because if that is already zero we won't have to do anything so if any of the these conditions satisfy we can simply break out of the DFS function and this would be our terminating case if this is not true first of all we will uh update the current position we are at inside the grid and we will name we'll enter the value as zero because remember we have already updated the uh Island islands and now we will just run a for Loop and it over all the four directions so that will be that will allow us to go over all the neighboring uh candidates of this row and column uh that we have and now we are simply going to call DF s on uh row plus direction of zero and column plus direction of one and we'll also provide the value of grid as well and uh yeah I guess this should be our logic and uh we can try to run this code okay okay looks like we messed something up oh okay seems like our solution is working let's try to submit the code seems like our solution is also working [Music] but Hello friends we are still not employed by Fan company so let's not stop lead coding till we get there uh today we are going to do longest consecutive sequence problem and this problem has been asked in Google Microsoft Facebook Apple uh Goldman Sachs Uber Twitter bite dance so it's lot of companies and lot of huge ID companies that have asked this problem so I I'm going to pay my most attention I hope you also do it and uh I have I just have one request for all of you guys like uh my YouTube channel if you see most of the people they are not even subscribed and uh it takes a lot of time and lot of effort to make these videos so I would really appreciate if you can just subscribe like uh basically we are given an unsorted array of integer nums and we need to return the length of longest consecutive elements inside the sequence uh also we there could be possible that there might be duplicates in our given unsorted array so we just need to take care of those as well and let's uh try to understand this with an example so the example we are given over here is and over here if we find that what is the longest consecutive sequence we can find the longest consecutive sequence we can make is 1 2 3 4 amongst these values and we can ignore just uh this 100 and 200 because there does not exist any uh consecutive sequence from those values so over here since we find four elements we can return the length of this as four and this would be our answer uh same way if we take another example over here we are given nine elements and all nine elements are actually part of the longest in longest consecutive sequence so in this scenario we are going to return nine so in the Bro Force approach we are not going to do anything clever we are just going to take the most basic approach that we can and try to find the longest consecutive subsequence so suppose at any moment we are given an input like this we are given an empty list we can say that there exist zero longest common subsequence elements and suppose we are given an element like this suppose this is 100 we can say that there exist exactly one longest common subsequence element uh in this given input so that is a given right that even if with a single element we can at least Define that there exist one single longest common subsequence element now over here in this example since we know that there are at least more than zero elements uh in this given input and initially we are at this 100th position which means that we can say that the current longest consecutive subsequence we can find is one and now if we want to find a subsequence in the remaining group that cons that consist this 100 how can we do it like we can only do it in one scenario that in this remaining portion in this remaining elements if there exist element one 1 if this exist we can see that 100 is also part of the uh or could be part of the longest consecutive subsequence so this and this would be our basic approach that at every single position we will try to find that whether the next elements could they be in the in the remaining input and if they do we will update our longest consecutive subsequence and whatever the maximum value we find we are going to return it as our answer so we will also create another variable called Uh current subsequence um and that would take care of what is the current subsequence that we are trying to find let's just name this current okay and initially the current subsequence is also at also one over here at this 100th position now we'll try to see that whether this 100 1 exists in the remaining portion and it does not exist which means we will move forward so we'll move forward with the element four now for this element four we need to see that whether element five exist or not so element 5 also does not exist so we'll move on with this 200 for 200 we will see whether 2 2011 exist this also does not exist for this one we will try to see that whether two exist so two exist in the remaining array now because to exist the current subsequence we had was of value one we will update it to Value two now because this two exist exist we can not break right now we'll try to find more values so we'll again try to see that whether three exists and three also exist which is over here so again we will update this value to three again because three exists we will try to see whether four exist four also exist and it is present over here so we will update the current value of longest consecutive subsequence we have found to four now we will try to see whether five exist now five does not exist which means that four is the longest we have found so far and uh then we will try to update the value of longest consecutive subsequence we have found to whatever the current value is because uh previous value of this was one and now this new value is four but we are not done yet we have only check up until this one so now we will check for this two so again for this two we will and uh by the way we will reevaluate this value back to one because now we are starting with the new element so again for this two three exists so we will update the value to two and uh four also exists so we will update the value to three uh but we cannot update the longest common subsequence because four is greater than three and now we again check for this value number three so for Value number 3 4 also exists which means that this value would become two for this value number three but we won't update and in the end we are going to return this four so this is our Brute Force approach like this solution works we get the desired answer but thing is we get the desired answer at a very bad cost like even if we just try to calculate the time complexity in this case the time complexity would actually be big go of n Cube why n Cube because we will need to iterate over every single elements at least once to find the longest common subsequence so that is n amount of work then suppose over here we are initially at this position 100 so we wanted to check that whether 101 exists so in order to do this check we'll have to also have to iterate over the entire Loop so then in that case we will have to do N More work and at any go any given moment suppose over here we identify that this for this one two also exist right and once we identify that two exist we will again check whether three exist again we will check whether four exist again we will check whether five exist so even to do these checks we will have to do N More work so again we will do n work so in total we are going to do n * n * n so n Cube work to solve this Brute Force approach and this is a very disastrous solution now one better approach we can think of is suppose that with the given input if we do some sort of modification can we come up with better solution in faster time complexity like of course we can uh so remember that what we are needed over here here is that we need to find the longest consecutive subsequence of this given input and we are going to see with this custem example how can we modify the input and uh how can we come closer to solution so suppose in this given example rather than keeping the input just like this if we do sort the given input Things become much easier for us and let's see that what would be the sorted result okay so now we have our sorted result now in the sorted result we simply need to find that what is the longest common subsequence that exist longest consecutive subsequence that exist and it's pretty simple to find now because all we need to do is that at any point we know that the definition of uh common subsequence is that suppose we have we are currently at the value I then I + 1 would be a common subsequence then I + 2 would be a common subsequence and this is the only condition we have to take care of and the only other thing we need to worry about is having two duplicate values right next to each other if at any point we encounter two two duplicate values we simply ignore one of those values and move move forward so in in this example we are only going to do two checks uh with the sorted input first check we are going to do is at first position we are going to check that whether this position is exactly same as whatever the previous position we had if that is true we would skip over because we don't need to do anything with that because there are two consecutive two same values and if that is the case so which is the case in this scenario that both values are same which means we would skip over so we would go to the next element and now we are at this next element again we are going to check that the value we are currently at and the value before that if they are same or not so in this case they are not same if they are not the same we are also going to check one more thing that whether the current value of a ofi so suppose this zero is actually a of I and minus whatever the value of a of ius1 so a of IUS one in this case is minus1 so if difference between these two values if it becomes exactly one which means we can conclude that these two values are part of the longest common subsequence and uh we could update their value again as again like bro Force we are going to use two variables one variable to keep track of longest common subsequence we have found so far and second one is to keep track of the current uh subsequence that we are working on so let's see that how how it would work and both both the values would be set up as one initially now initially we are at this zero and one pair and because they are sorted we know that they are always they are always going to be adjacent to each other so this is the only condition we need to worry once we identify that the both values are not same so in this case we can see that uh the current longest uh the current subsequence we have have found is actually size two so we can update the value over here that this is this is two now again we check with this value now this value again it's zero it's the same as this one so we ignore ignore it we don't need to do anything now again we check with this value so this value is actually two now with this two if we put down this equation so 2 - 0 this is not equal to 1 which means that uh this 2 and z are not part of the common subsequence uh if they are not part of the common SE subsequence we we check that now we can't update this current anymore so we check between the current and long longest common subsequence we have so far and the current is actually greater which means we will update the longest consecutive subsequence to two as well and now current we will put it back to one because we will repeat our our search again now we are at this position three so three and two are not same and uh 3 - 2 is actually one which is true which means we update our current so current would become two now we are at this four again 4 - 3 is equal to 1 so again we update our current to three again we added this five so again we need to update our current so current would be updated to four uh because all of these values 2 3 4 5 they are in a common subsequence now we are at the 7 so 7 - 5 they are not equal to 1 which means we we can't update the current so we will need to reset the value of the current so before resetting the value of the current we are also going to check that whether the longest common subsequence needs to update and this needs to be updated to value four because this this one was four before because of these four values and now we can set this value to one again at this position 7 and now we are at this position 200 so 200 and 7 they don't have any correlation so we can't do anything about it and in the end at the end of the loop we are simply going to return whatever the longest common subsequence or current subsequence what are the maximum value we have found between these two and in this case the maximum value we have found is actually Four so this would be our solution now this solution works pretty efficiently it's pretty neat and if we see the time complexity we can complete everything in just one single iteration so we are only doing uh n work but thing is the time complexity in this case would be go of n log n because initially remember that from this given input we will actually have to sort the array as well and sorting takes and log and time but overall if we still compare it with whatever the Brute Force approach we had brute force was actually big of n Cube so this was really bad time complexity and this is much more and much bigger Improvement Upon Our uh scenario now in the optimal solution we are actually going to try couple of things uh first thing we are going to do is we are going to create an additional data structure called called uh hash set and in the hash set we are going to enter all the values that we have found from this array so suppose we create a hash set something like num set now in in this hash set we are going to add all of these values now because we have our hash set ready what we are going to do is uh when we are going to iterate over this hash set and we are only going to start checking for the longest consecutive subsequence from the elements that could be at the start of the ele start of the longest common subsequence and what elements can be start of the longest common subsequence well so if we take uh take this example we can actually see couple of uh uh common subsequences or consecutive subsequence one consecutive subsequence we can find is 99 and 100 which is at these two positions and the second consecutive subsequence we can find is actually 1 2 3 and four now in the what we were doing in the Brute Forces we were checking at every single position that what would be the uh longest common subsequence we can find the thing is we can only find the longest common subsequence from the first element of the start of this uh consecutive subsequence same goes over here that whatever the subsequence we can find at this value number 100 the subsequence that we can find at Value number 199 would always be greater than whatever we can find over here because this by itself is already a subsequence so we are going to use this logic like over here if we put this three 2 3 4 we will only find the consecutive subsequence of length two but this 2 3 4 would have would be three uh would be of length three and this 1 2 3 4 would actually be of length four so we can only find the maximum consecutive subsequence at the start of the uh any uh sub any subsequence not and not somewhere in the middle and the only way to check that whether we are at the start of the subsequence or not is by just checking one very simple uh condition that at any point we check that whether the exact value before that value like one value before the value we currently are at if that exist which means that we are not at the start of the common subsequence let's take it by an example over here and let's see that what would be our approach so first of all we are going to be at this position 100 we are going to check that whether this 100 is start of any consecutive subsequence or not so we check that whether in this given num set does the value 99 exist now we know that 99 exist so because 99 exists 100 cannot be at the start of the common subse consecutive subsequence so we are going to IGN ignore this case we don't have to do anything with this 100 we come up at 99 now we come up at this 99 we check that whether there exist a value before 99 so 98 does it exist in the this num set 98 does not exist which means that at 99 we can be at the start of any common consecutive subsequence so we start a subsequence at 99 and now we will uh initiate initiate our logic and in our logic we are simply going to check that from this 99 how many consecutive numbers we can reach so we are going to check that okay 99 by itself is uh common subsequence of length one so we know that now from this 99 we are going to check that can we reach value number 100 so 100 we can reach and because we are using a hash set we can do all the operations in constant time so we are not adding any strain in our time complexity now we can find the value 100 so we can reach 100 which means that the whatever the longest common subsequence that we longest consecutive subsequence we found we will increase its value to two now again we will try to see that whether we can find 101 like 101 does not exist which means we would break out of over here and the longest common sub subsequence we have found up until this point is actually of length two again we are going to repeat the same process so now we are at this position four we check that whether four uh whether three exist in this set or not so three exist which means we ignore this four now again we are at 200 so we check that whether 199 exist so 199 does not exist which means 200 can be start of the any consecutive subsequence so we again check that there 2011 exist but 2011 does not exist in this uh given example so we ignore this 200 as well because the longest consecutive subsequence we find at this value number 200 is always going to be one and we already have a value that is greater than one again we check at this position one that can one be start of any consecutive subsequence so we check that whether the 1 minus one so we check whether 0 exist in this example or not 0 does not exist which means one can be start so now we set our current subsequence to Value number one and now we check that from this value one how many other values we can reach to so first we check that can we reach the value number two yes we can reach value number two because two already exist so we update whatever the current subsequence we can find to two now from this two we check can we reach three again we can reach three so we will update the current value to three again we check that whether from this three can we reach four and yes we can reach four as well so again we will update the value of our four uh value of the current subsequence to four and from four we check whether we can reach five so five we can't reach which means we are at least able to reach this four so we are able to see that the current subse the longest current subsequence we have found is four and previous value was two so we will update this so this will become uh four and now again we are going to check the same thing for this value number two so that for Value number two does one exist and one exists so we will ignore this again we check for three does two exist two also exist which means we are going to ignore this three and now since we have reached the end of this hash set so we are going to reach whatever we found in the as the longest consecutive subsequence and this would be our answer now if we calculate the time complexity the time complexity would actually be big go of n in this case because we are only iterating over the entire uh input just once uh through this haset uh so this this is a very efficient time complexity and if we see the space complexity the space complexity is actually big of n because we will have to create this additional numerical set and we are going to uh store and memory for that and uh let's see the coding I will be showing the hash set solution in this code uh but I'm I'm going to post both the codes in the comment so you can check it out from there so first of all we are going to check that whether we are given an empty list or not if that's not the case uh first of all we are going to create a hash set we are going to name it num set now we'll run a loop across the the given input and we are going to store all the values to to our hash set this is going to do two things uh it's going to eliminate all the duplicates values and it will only add unique entries in the hash set because hash set has a property that does not allow us it to store duplicate values now we are going to create a parameter to store the longest subsequence and we are going to initialize it with value one now we are going to run a for Loop across the given num set so so initially we are going to check that whether we are starting from the middle of any longest consecutive subsequence if that's the case we are going to ignore that number so if this condition is true we are going to uh continue and go to next element in the loop if this is not the case we are first of all going to Mark the current the number we are at as current number because this is the beginning of any uh longest consecutive subsequence we are also going to create another parameter called current sub that is going to take care of uh the current maximum uh consecutive subsequence we can find and we are only in we are going to initialize it to one and now we are going to put a condition that while uh our hash set contains the current number + one while this condition is true we are going to increase the number and we are also going to increase our current subsequence and after this Loop ends we need to check that whether we have found the longest common subsequence or not so once this Loop ends uh we should have our answer in the longest sub variable so we can simply return that let's try to run this code okay seems like our solution is working working let's try to submit the code and seems like our solution works pretty well and uh it is faster than a lot of other Solutions I I will also post the the Sorting algorithm solution as well so you can check it out from the [Music] comments Hello friends we are still not employed by a Fang company so let's not up lead coding till we get there today we are going to do alien dictionary lead code problem and not only it is a very important problem this problem can actually be asked in multiple ways it can it can be asked directly as a graph question or it can be asked as a follow up question for the previous uh question that we solved verifying an alien dictionary because both questions are very similar and if you want to check that where the solution for this problem is you can check it out from over here also the another reason why this problem is really important is if you just take a list of companies that have asked this problem Airbnb Facebook Google Amazon Bloomberg Microsoft Uber they have all asked this question in last 6 months also ID giants like Pinterest Apple Twitter eBay they all have asked this question in last 6 months to one year and uh bite dance uh Snapchat and flip cart so they have asked this question not fairly recently but still it's important and uh I will be paying my atmost attention because my aim is to clear any Fang interview and uh I hope you also enjoy the video this is a lead code hard problem and it justifies this hard tag uh so let's understand the problem statement essentially we have identified a new alien language that uses English alphabet however the order of those letters is unknown to us now we are given a list of strings uh inside this words and we are told that they are from this alien languages dictionary and in that string the important property this words have is that they are s Ed lexicographically and we need to return a string of unique letters that are present in the in these words and we need to written them in lexicographically increasing order now also there could be possible that there might be multiple Solutions so if there are multiple Solutions we only need to return any one of them and there could be some some cases where this given uh string of words is invalid and if it is invalid we need to return an empty string so in order to understand this problem first of all we will have to identify that what does this lexicographically increasing order means the second thing we will have to understand is that what are the cases where this particular uh input is going to be uh resulting in falsified uh information and what does this string of unique letters with lexico graphically increasing order means because this unique word is actually really important and I'll come to to that later so suppose if we just talk about what is lexor graphically sorted means if we talk about English language if we talk about the words a a b c d uh all the way up to Z this is plain English language that we use on a day-to-day basis now in the English suppose we are given any four letters uh suppose we are given letters like uh q a uh e b r c and uh Q E suppose we are given letters like this right and if we want to sort these four in plain English language how we are going to sort them like of course the answer is simple we are only going to check that what is that position in this given order and based on that particular order we will sort them so if we sort them uh the sorted result would look something like e a QA Q E and RC something like this right and the reason we are able to generate this is because we know that the position of e comes before q and in this case there are two entries Q A and Q E so which means like if we will have to identify that what is the second letter and second letter A comes before E and then this R actually comes before Q so we are able to determine a sequence like this now in this given problem we don't need to generate a sequence like this uh basically we are told that we are not given this information we don't know that what is the order of words are and we are directly given this particular sequence that is already sorted in that particular language so suppose this was to be alien language and if we want to identify that what should be the answer we need to return in this case the few things we can determine from this input is that okay over here the we are checking first uh at any point we are checking any two adjacent words in those two adjacent words we go letter by letter and we try to see that what is the first differing letter that comes to uh in comes to the existence and based on the differing letter whatever the word is presented first should come first in that order rather than second uh word second letter uh so if we compare these two words e a and QA we can see that the first differing word comes as e e and over here it is Q so which means we can determine that e will always come before Q in this particular alien language now don't forget this that this is plain English for just imagine this as an existing scenario so we know one scenario okay that e should come before Q right now over here again if we compare next two words the next two words are QA and Q E okay so in QA and QE notice that the first letter is Q so it is common which which means we cannot identify much information from that but the second letter is a and e which means we can determine that at any given scenario a will always come before E so we can notify that we can also create a scenario like that that a will always come before E and over here I'm denoting this relation by uh an arrow which indicates that at any given moment e should always come before Q because uh it is on the uh beginning end of the arrow and uh the where it is pointing to should comes later and again we will compare these two words q e and RC so if we compare these two words we can identify that okay Q should come before R so we can also denote that relationship that Q will become uh will be before R right and over here now we have these three relations So based on these three relations we can actually establish something uh over here that we can establish that a will always come before e and e will always come before q and Q will always come before R so one of the sequence that we can return return over here is that a e QR okay so this is one of the sequence that we have to maintain at any given cost because we are given these conditions based on the words that were given but thing is will this be our answer and actually this will not be our answer and the reason this will not be our answer is because over here we are given this particular line that we need to return a string of unique letters from this words in the new new alien language that is lexicographically increasing order but thing is over here if we look the original input the in the original input we actually have one more unique character that that we are missing and that particular unique character is so we already took care of e we took care of a we took care of q a q e r all of this we took care of but C the letter c we did not take care of it and the thing is over here based on whatever the input that we are we were given originally we cannot determine the position of C but thing is we know that c is also a unique character and the only thing we know about the positioning is that for these four characters we can Define some positioning like this for C we cannot determine any positioning but the thing is it has to be part of the answer as well and that is why we are told that there could be multiple Solutions and we need we need to return any of them so in this scenario uh this could also be a solution where a e QR and C we are placed at the end or this could also be a a a solution where a we we put C somewhere in the middle and eqr is uh also placed like that the important thing is that we need to maintain this order as long as we are maintaining this order because this C is one of those uh unique letters where we cannot find the dependency for that so we will need to take care of it as well and this is a very important detail that lot of other videos have missed out and uh that is why it took me lot of time to make this video I want to make sure that I go through it completely now let's take one more example from the given input and uh we will again try to find that what should be the answer for that so in the given input we are given the following words these are the words that we are given in the alien dictionary right and our aim is to find that what should be the answer in this case well the first thing is uh that we are what we are going to need uh in order to generate the solution tion in order to generate the solution we are going to need two things we are going to need list of all the unique characters that exist and second thing we are going to need is what are the dependency on uh all between characters and based on these two things we will try to generate some sort of order or some sort of pair and also remember that we will have to consider the scenarios where we could find invalid strings as well so I'll be explaining that and in this in this example so over here um if we see the list of unique characters the unique characters are w r t f e okay these are all the unique characters that we can find in this particular input okay now let's start making dependencies now in order to make dependencies at any given moment we will have to compare two adjacent words and we are going to find first differing character and BAS based on the differing character we are going to establish some dependency so first of all the first uh first two words we are going to compare are w r t and W RF okay in this case w w is common r r is common which means that first differing character is T and F and we already know that these words are sorted so because they are sorted we can determine that t should come before F okay we already know that this is good now what is what are the next two words next two words and we now we are done with this WT the next two words are WF and e r okay so w RF and e r now in this case what is the first differing word well the first differing word is first letter by itself W and D which means we can make another dependency that W should always come before E now we can ignore this again we compare next two words so e r and e t t so over here what is the first so e is common the first differing letter is R and T which means that R should come before T next one is E T T and R ftt so over here the first differing character is e and r so we can also mention that e should always come before R okay now we have these four dependencies for these five unique characters now let's try to see let's try to create a dependency tree from this given input so if we see we can clearly see that okay W is dependent on E and E so w comes before E then e comes before R okay then for R comes before t and t comes before F so this becomes all the dependencies and if we notice all the unique characters they are already part of these dependencies so we are good we don't need to do anything more over here now if we make that what should be the order of uh letters the order of letters in this case would be w e r t f and this would be the correct solution now notice that in order to generate the correct solution what we had to do is we will we had to find all the unique characters all the dependencies once we had all the dependencies we actually had to iterate over all the dependencies see that which dependencies are interconnected based on their interconnection we have we actually had to generate this order and in order to do that we are actually using uh graph Theory and how we are using graph theory is basically all the unique characters in this case are actually nodes and all of these these dependencies are actually edges between those nodes and those edges can be represented as in some form of adjacency list in some sort of hashmap and then we will need to iterate over all the entire graph and then at any moment we will have to go through the graph and find the solution that what what should be the order in which we are able to iterate over all the unique characters which means that all the nodes inside the graph and we need need to generate this order of pairs and if we are able to successfully generate this order of pair we will return whatever we find and if for somehow we find out that the input is invalid we will have to take care of that scenario as well so first let's take a couple of examples where we we can find that the input could be invalid now based on the English language we know that at any given moment if there are two words present W1 and W2 and we know that any sing single word so suppose W1 is actually prefix of this W2 if that is the case then W1 should always come before in the dictionary than W2 let's take it by an example suppose we are given two words uh like bat and Batman if we are given two words like this so if we compare if we start comparing these two words and see that what should be their order we check that okay B is common a is common T is common right now over here this actually ends there is actually an empty list there is nothing over here while over here there are still some values so if that is the case we can determine that this W1 is actually prefix of this W2 because these three characters are also present over here and in that scenario this W1 should always come before W2 at any given moment we identify that this particular character is not present in correct Manner and suppose we are given an input like this that Batman and bat if we at any moment encounter this scenario we can immediately return false because or we can immediately return an empty uh string because this is a wrong ordering so this is one of the failed scenarios where we cannot do anything right so this is very important to understand and we will have to take care of this in our solution the second thing that that will not work is that at any given moment suppose we are given list of words uh suppose the words are like x a b x suppose we are given list of words like this and what this means is that the first letter X should always come before a okay so based on these two we can establish this dependency based on these two we can also establish that a should always come before B okay and over here the next thing is that b and X which means that what this is saying that b should always come before X so if you notice over here that we are actually stuck inside a cycle that X will X needs to come before a a needs to come before B and B needs to come before X so at any moment in our graph whenever we are traversing over all these unique characters and dependencies at any moment we encounter that okay there exist a loop and if we detect that there is a loop from any particular uh node then we can return false immediately or we can say that okay this is an invalid case where the string actually doesn't exist and we will need to break out of the loop suppose we are given a custom example like this words and we are told that all of these words they are lexicographically sorted in the alien dictionary and now we need to return the order of of words uh of all the unique characters that we can find so what should be the approach well in order to do that we are going to need two things uh first thing we are going to need is all the list of all the unique words or all the unique characters and we are also going to need uh the entire dependency uh between any two letters that which should come first and which should come later right so let's start working on it uh so first of all we have b and a okay so we will just add list of unique letters b and a and second word is b b y which means that first differing characters a and Y so we can establish a dependency like this that uh a should come always before y okay now again moving forward with next two values so over here the first differing character is b and a which means that b should always come before a and also uh I forgot to add one more unique character y over here right now uh this B should come before this a so we will add that to our dependency list as well that b should come before a right so this is one dependency and over here we have the unique character D so we will add the unique character d as well now we will uh we have this other word uh these two words and in these two words a is common which means that D and L are differing characters so first of all We'll add the word L over here and over here we have this D right uh so we know that D at any given location will come before L okay so we'll just mention that now over here we have one more unique character T so I'll Al also mention that now the next two words are these two words over here the a is common L and I are different and also we have one more unique character I now uh we know that there is a dependency between L to I so we will also mention that that l should come before I now the next two words are uh a i and a i r now notice over here that this AI is actually prefix of this AI R right which means that this AI will always come before this word AI R but we cannot determine anything regarding this R because this R by itself it has no other thing to compare it result its result with which means that though we have a unique word we don't know that what is the intention for that particular word is and now let's see that in the dependency list that we have created uh among these unique words what are all the words that we are able to find a pair for so one pair we were able to find is for this one this b a y uh let me just draw everything in same color so b a y this is one pair which means we know that at any given moment this b a y order has to be maintained like B always has to come before a and uh y and uh same goes for this d l i that D always has to come before L and all L always has to come before I but in the list of unique characters we are given this R and T as well that are not represented by any dependency which means we can show we can say that this R and this T they are unique characters by themselves which does not have any sort of dependency right so if we want to see that what could be the potential different pairs we can make over here well there could be bunch of different results like there can be so many different permutations and combinations let me just give you a few of them like most simple one would be b a y d l i r t so this is one combination uh where notice that we are just maintaining the entire order now second combination could be uh b d a l y i r t now notice over here that at any given moment we need to make sure that these two orders are are met up so B is always coming before a and a is always coming before y so that is satisfied over here D is always coming before L and L is also coming before I so that is also satisfied this RT they don't have any dependency so it doesn't matter we could have some pair like this that b r t d a y l i this is also valid pair because notice that this B A and Y this is maintained this uh D L and I this is also maintained this position of R and T doesn't matter so there can be bunch of different options that we can choose from and I'm just showing you that uh these are the different results we can have right because we need to take care of unique characters as well so don't forget the unique characters they are really important now what should be the approach in this case well one approach is actually quite simple because we know that we have a unique characters we have the dependency we can choose some data structure like hashmap we can iterate over at any point whenever we identify the dependency we can iterate over the entire hash map we can from any point we will try to see that whether it has any dependency or not if it has dependency we will go to that dependency we will try to iterate over those values and we will try to generate the order list right so let's see that how it can work suppose we create a hash set like uh suppose we create a hash map like this okay suppose this is our hash map and based on these dependencies we know something that we know that okay for in order for us to put down this B we know that a has to come after B which means a has dependency on B right we will mention it over here now for this a a has to come before y so a has to come before y now for this y we don't have any dependency so we'll just leave this value as blank now for this particular d d has to come before L right so we will just mention L over here now this L has to come before I so we will just mention I over here for this I we don't have any dependency so we are good and same goes for this T and R that we don't have any dependency so we are good now since we have this dependency tree let's see that what would be the approach we can take over here so in this scenario suppose if we want to Cal that what would be one of those ordering pair what we can do is we will start traversing through all the all of these values all of these unique characters and remember that this is hashmap so in hashmap we are treating these as key value pair key values and these are actually values so in the keys we are mentioning all the unique characters in the value we are mentioning all the dependencies now over here we will start iterating at this B so first I I'll just Mark B as that we are iterating over it right now from this B we identify that okay we need to have a before B so again we go to a because we will have to check all the dependencies right we cannot just put any letter randomly any place right because this B has some dependency so we'll have to go over that now this a has actually dependency on y so again we'll go to Y and we'll just Mark a as being as part of being visiting and over here we reach at this y why don't have any dependency so we are at this y now notice that we are actually traversing this graph in DFS manner depth for search manner right and at in depth for search at this y we identify that okay this y does not have any dependency so we can just put y to our order list so we can just put y to our order list now from this y we will do a back backrack we will again come back to a again we will do a back track again we will come back to B and then we we are we would be done with this B right that okay we are done with this now again we we start we ignore all of these now we start with this second position now in the second position first we determine that whether we have calculated this value already or not so since a is already calculated over here so we ignore that so we can ignore the second case again we check that whether this y we need to calculate it or not but y we have already calculated so we can ignore this right so we'll ignore this and now we'll move on towards this D now do you see any problem with this one well definitely we are seeing a problem with this one and the problem is that over here the dependency is like this that B has to come before A and A has to come before Y in order for us to generate the dependency uh dependency order but over here when we started traversing the actual dependencies we are getting is actually in reverse order you you see that y comes before uh a and a is coming before B so one way we can do it is that we can start traversing like this one that over here we again come to this D for this D we find the dependency as L for this L we depend find a dependency at I for I don't we don't find anything so we'll just put I over here then we backtrack so again we put l over here and then again we backtrack and then we will put D over here and then we come to this like this I this L and this has already been done so we ignore that we come to this t t does not have any dependency we put it there I has already been processed and we reach at over the over here at R now this order list we got is actually correct but in reverse order because the dependency should be like b a y and uh this should be D Li but over here it's D Li in reverse order and same goes for b a y so what we'll have to do is uh when we calculate the answer we will have to return the reverse of this answer and that would actually satisfy uh these dependencies so that is one way of doing it right uh and there is also another way of doing it and the better way is that when we are actually creating this hashmap we can actually do something different uh previously in the hashmap what we are doing is that over here we had a key as all the unique characters and as the value we had these dependencies exactly as they were mentioned that for this particular B it is dependent on a for this particular a it is dependent on y but thing is that is not true the actual true thing is that actually this y the position of Y should be dependent on it that y cannot be present unless there exist an a value before that if we start so if we rather than storing the dependency on value that is taking care of the value that comes after it if we start taking care in reverse order so let me show you what I mean by that so suppose if we have a hashmap like this and over here in the value we actually present at any given value what should be the previous value that has to be present in order for us to reach at that particular value so what that would do is that if we want to calculate this B we don't need to basically have any value right so over here we will leave this as blank that for B we don't have any dependency but for this particular a we actually have dependency on B that B has to be there in order for us to process this a so we will put a dependency over here saying that okay B needs to be there for us to calculate this value a same goes for y that a needs to be there in order for us to calculate this value y again we reach at this D and for the D we don't have any dependency so we'll just leave it blank but for this particular L again we'll have to have a d over here so we'll put a d over here for so for this T we don't have any dependency so we can leave it blank for this particular I we actually have to put we have to have an L before that so we'll put a dependency over here and for this R we don't have any dependency so we'll leave it blank right so this is the table we actually this is the hashmap that we work with and over here now let's try to iterate over this the hash map essentially our aimim is to iterate over this entire hash map identify that at any point if you are inside the DFS function you are not finding the repeated character so that is item number one second thing to make sure is that you go through all the characters and you start building up the order list so over here we will get so over here we will get uh we initially start at B and at B we don't have any child so we are good to put B over here now next uh and we can can mark that b is already done now we are at this a so for a we need to check that whether B is done or not B we check over here B is already done so we are good which means that we can put a over here so we will put a over here again we will Mark a as being done again we are at this y we check that okay A Y has dependency on a so we check okay a is already done so we can put y over here as well now we are at this D so D does not have any dependency so we can just simply put D over here and we can just mark this as done again from L we check for D D is already marked so we put l over here T does not have any dependence and we Mark L T does not have any dependency so we Mark uh T is done we can put it over here now this I has dependency on l l we have already marked that it is done which means we can complete this I as well and for this particular R it does not have a dependency so we can put it over here now if you if you notice this scenario we are actually fulfilling both of these these dependencies and uh notice that this B comes before a and comes before y so we are good with this dependency this D comes before L and I so we are also good with the second dependency as well and this T and R they were actually separate values so it doesn't matter wherever we put them as long as they are there uh it fulfills our purpose and this is the actual solution that we need to take care of that where initially we will iterate over all the words we will create all the unique characters based on the unique characters we will create the dependency list uh based on the dependency list we can actually create a hash map uh that we are going to use to Traverse as a graph but thing is rather than traversing the original hashmap we can actually create a reverse link reverse list of dependencies and we can iterate over that just once using DFS or BFS anything but we are going to use DFS because I want to master DFS for myself and we and that would be our solution so it took me lot of time to come up with this solution it took me a lot of time to understand this problem okay let's calculate time and space complexity for this problem so the time complexity for this one is going to be bigo of C where C is actually total number of characters that are given in this original input words because notice that there are three actually three parts of this problem the first part is that we need to find all the unique characters like in order to in order for to generate all the unique characters we will have to iterate over uh all the characters that are given in the original input words so that is one part now second part is that we need to create a dependency and in order to generate the dependency again we will have to Traverse all the words and the third part is that we will have to uh so we are generating some sort of hashmap and in the inside the hashmap we will have to iterate over all the values inside the the present hashmap so at any given moment the maximum work we are doing is iterating over the sum of all the characters that are given inside this words so that is why that would be the time complexity and if we want to calculate the space complexity the space complexity would actually depend on the number of unique characters so suppose that in English language the number of unique characters maximum we can have is only 26 right and we are also told that for this alien language the maximum number of unique characters we can have is also going to be 26 so space complexity actually has a finite number and there is only so much it can grow so we can treat space complexity to be bigo of one or constant space complexity for this one even for us to creating this additional hash map the second thing is that suppose if we want to calculate based on the number of unique characters uh we there is also one equation where the space complexity would actually be big go of U plus whatever the U square or n whatever the minimum value of this is and uh let me know in the comments if you want me to explain the space complexity uh in a scenario where the number of unique characters are actually not finite and not 26 like in this case it's 26 so I will just uh leave it as it is but let me know if you want me to explain that first of all we are going to create our hashmap and we are going to actually create it out side of this uh Alien order method that is given because we want to use that hashmap to uh our to other to our DFS method as well so and as a key we are going to use unique characters and as a value we are going to use the dependency so it would be list of characters and we are going to name it revers the list because uh essentially we are just reversing the adjacency list uh also we will create another hashmap to uh essentially store the value of uh any parameter that we are already currently visiting inside our DFS method and uh so we need to create an output of uh strings so we can create a string Builder variable now the first thing we need to do is find all the unique letters inside our given word string of words now this is done now we will have to find all the edges and we will have to add the reverse edges to our reverse the reverse list hashmap now at any given moment we need to check that whether the word two is actually prefix of word one or not if that is the case we can return false immediately and we have found a terminating case where the given uh string of words is not valid okay if that's not the case we will find the first differing character between two words and add it to our add it to our hashmap and notice that we are actually adding the value to the second diff to the second words differential character and the moment we find the first differing character we can actually break out of that particular word now we are going to iterate over the reverse list hashmap that we have created and we are going to run our DFS function okay for for all the keys present inside the reverse list hashmap we are going to run the DFS function and we are also going to check that at any given moment have we receiving the result as false so we are just going to create a Boolean variable result and now we are going to call the DFS function and we are going to uh provide the character inside the reverse list and at any moment if we identify that the result is uh for this result character is actually fault uh we will return uh empty list immediately okay now uh all we need to do is that once we once this DFS step runs um we should have our out put inside the result so we will have to check that whether all the unique characters are have been taken care of or not so we are going to check that whether the length of output if that is less than the size of our uh list if that is the case uh we can return false immediately because we haven't taken care of all the unique uh unique values present and if none of these cases uh happen we will return whatever we find inside the output now the only thing we need to do is we will have to create the DFS method now first of all we are going to check that whether the current character C we are checking if we have already visited that uh or not if we have already visited that we are simply going to uh return false if that's not the case which means first We'll add the current character to our scene uh hashmap and we are going to Mark the entry as false so that way whenever if we encounter the repeated value it will always return false otherwise by default the value would be true okay now for every single uh character inside uh the current for the for the given character we will iterate over inside the uh reverse adj ascy list and at any point if we encounter the result false we will return false immediately if that is not the case uh we will remove the entry from the scene uh hashmap so we'll set the entry as true and uh inside our output string we will append the value and for that particular character we are going to return true okay so I know this is a very long and too many lines of code I'm going to put this in the comments let's try to run the code okay seems like our solution is working and also remember I was talking to you that we will have to take care of all the unique characters uh here let me show you an example so suppose we only have two characters H and P if we are only given input like this and we know that H comes before P right which means that uh in the result we should be getting HP so let's see that what okay so this is this is accepted right but now let's say that we have additional character ha a and PB now over here we don't have any mechanism to measure this a and this B so they become unique characters right and now let's try to run the code for this particular test case so if we do that uh you are going to see that A and B would be at weird locations so over here see the important thing is in our output we are maintaining the order for this H and P and that is what it matters Like A and B over here in our output is actually behind this HP while over here the A and B are actually at the beginning and then there comes HP so it doesn't matter as long as the order that are that is given in the input is maintained and now let's try to submit this code and uh oh wow our solution is actually 99% faster than all the other Solutions and uh I use lot of uh help from the solutions tab from this uh lead premium because it took me a lot of time to understand this problem so I'll be posting this in the comments you can check it out from [Music] there Hello friends we are still not employed by a Fang company so let's not stop lead coding till we get there today we are going to do a very important lead code graph problem uh graph valid tree basically we are checking that whether the given graph is actually a tree or not and this question has been asked in bunch of different top tier companies uh companies like LinkedIn Google Amazon Bloomberg Microsoft and Facebook so these are my dream companies so I'm paying my at most attention I hope you like you enjoy the video okay so this is a lead code medium problem and we are given n number of nodes we are also given a list of edges and we are told that these edges are actually undirected edges now we need to see that whether the given graph is actually a valid tree or not if it is a valid tree we will return true if it is not a valid tree we will return false and we are also given an example to understand this problem like in this example we are given these five nodes and we are given some list of edges based on this list of edges we they have shown that this could be a pictorial representation and over here they are saying that yeah this is a valid tree so that's why they are returning true now the question is in order to understand this first of all we will have to understand that what is the relationship between any graph and a tree what is the difference between a graph and tree and how can from the given input we can identify that okay this is a valid tree or not right that every single tree is also a graph but that is not the case for every single graph that it will always be a tree because if I if I put it in V diagram essentially graph is a actually a super set and it tree is just one of its subset so this can be a tree and uh this is a graph there are lot of cases lot of real life cases to understand that as well like uh the person who got slapped by Will Smith is always going to be a human but not every single human has been slapped by Will Smith it is something in that kind of relationship right now the thing is what are the differences between a graph and a tree that inside the tree all the components are connected or all the nodes are connected there is no restriction for graph that all the noes should be connected and the second difference is inside the inside any tree we will never encounter any Loops so we can just say no Loops while inside the graph there can be Loops let's try to understand this with some examples is is this a valid tree actually yes this is a valid tree because notice over here that from one node like every single nodes are connected with each other and we do not we do not find any single Loops but thing is say for example in this case if I had an additional Edge something like this I can clearly see that there exist a loop between these four uh nodes and because we have identified a loop we can clearly say that this though this is a graph but this is not a tree now let's take another example now this is a valid tree like all the nodes they satisfy these two proper properties that they are connected and there are no Loops the same graph if I had some components like this some additional nodes though they are not connected with all the nodes they are connected with each other or there there are some isolated nodes something like this if this is the case this will always be true that okay this is a graph we can put put it in the category of graph but this will not be a tree and uh in this case we'll need to return false now before we move on towards solution I just have a simple request if you see lot of people they watch my content but they are actually not sub subscribed to my channel it takes me lot of time and lot of effort to make these kind of videos and uh I would really appreciate if you can just show your support and uh subscribe the channel like now this problem actually can be solved in so many different ways and I'm going to show you few different ways on how we can do things now the question is what we need to find basically basically we need to find that whatever this given input is is this a valid tree or not in order to find that whether it's a valid tree or not we need to check two things whether all the nodes are connected and uh if there are any Loops or not right so what I'm suggesting is that we break this problem in two parts in the first part we check that what could be the different ways we can see that whether these nodes uh they are connected or not if they are all connected we are good and if they are not connected we can return uh false immediately that this is not a value tree and once that is done we will find all the ways on which we can identify that uh whether there are any Loops or not right so first let's uh go with the first approach now our aim is to check that whether all the nodes are connected or not what could be the different things we can do over here in order to check that essentially what we will need to do is we'll have to Traverse over whatever this given input graph is now traversing over this given input graph based on the structure we are currently given in the input is going to be a little bit tricky uh based using this uh number of nodes and edges so the question is like first thing we need to do is we will need to convert this given input in either adjacency list or adjacency Matrix either of them can be used and it it will work perfectly fine but in this case I will suggest to use adjacency list we only use adjacency Matrix when there are too many edges and we don't have any clear indication in this case that there would be too many edges and uh we we would try to use an adjacency list right so now we are trying to check that whether all the nodes are connected or not and we have already created our adjacency list now what I'm suggesting is that through this adjacency list we know that we would be able to iterate over this in given input and through this given input what we do is we create a hash set inside the hash set initially it would be empty whenever we are at any point iterating over any single node inside this given hash set we will check that whether that particular node already exists in the hash set or not if it does not exist we will add a new entry inside the hash set and at the end once we have traversed all the values inside the given input uh through this adjacency list what we are going to do is we are going to check that what is the total size of hash set and what is the total number of n given if both are same we can conclude that from any single point we are able to reach to all the other elements and because we were able to reach to all the other elements uh all the elements are connected and uh we at least satisfy one condition so let's see that how it would work suppose uh in our adjacency list we start traversing through this position number one right so initially we check that whether this value number one exist in the hash set or not it does not exist so we'll add an entry over here that okay uh value number one now through this value number one we can Traverse in two direction we can either Traverse to the neighbor on the right or neighbor on the left so let's say that we go to this node number 0o again we add Zero from this zero we go to node number two again we come to two now from this two we can't go any way forward right but the thing is uh we we still need to go back we need we'll need to do back trck we'll go back to one again through one we will go back to three now uh at this three this is not added so we add it over here from this three we will go to four so we will add four over here from this four again we will do a backt trck and we will come back at three and then we will come to five and then we will add five over here now at the end of this hash set we are able to iterate over all the elements inside the given input right and we check that what would be the size of this hash set so so size of this hash set would be six and what is the given n so n is also six which means in this case we are at least able to conclude that this given hash set is is actually satisfying our condition and inside this given graph all the nodes are connected so we are good now suppose in this case if we had an now suppose in this case if we had another node something like this and this was not connected to any of them basically this would not have been entered inside our hash set and our n in this case would have actually been seven rather than six so we can clearly see that if our size of H set is going to be lesser than whatever the number of n we have if that was the case we could have written false immediately because we F found that there exists some not connected component and uh which was not the case in this case so this is one of the very good approaches to identify that whether the graph is connected or not okay now we have taken care of the first part and now we need to take care of the second part that we need to check that whether in the given graph does there exist a cycle or not so first thing that comes to our mind is is that why don't we use uh the visited hash set that we have we have already created and in that visited hash set what we are going to do is at any point in time we are going to start exploring from one of the node in the given input graph from that node we are going we are not going to stop exploring till we uh exhaust all the neighbors of this particular graph and at every single time we are planning to come to next element we would first check that whether that element exist in the visited hash set or not if it exists uh then we would we would consider that there exist a loop and we would break out of it if it does not exist we would add that entry over here so first we will add we will start traversing this value number zero so it is it does not exist in visitor so we will add an entry over here from this zero we will uh we'll start exploring its neighbor so one of its neighbor is uh this value number one and remember that we are going in depth first search so we will not stop until we exhaust all the possibility in One Direction before going to the other neighbor we could do it bre breath for search way as well uh it's up to us now from this one again depth for search we see its neighbor that there is a neighbor to so we add an entry over here uh because it does not exist now remember that this is actually an undirected edge so what does an undirected edge means undirected Edge means that from zero we have an edge to go towards one and from one we have an edge to go towards zero same goes from one that we have an edge to go towards two and from two we have an Edge to go towards one and same goes from uh two that we can go to zero and we can come back now over here from this position number two because we have an edge that goes to zero we can consider that zero is also a neighbor of two in this case from this two we will try to go to the zero and the moment we try to go to the zero we will see that okay it has already been visited it is part of this hash set so we would say that okay there exist a cycle and uh we are pretty happy with ourselves that we have identified a cycle and and now we are done with our case the thing is this is actually a wrong approach and the re why it is a wrong approach it is wrong approach because there exist this undirected Edge and let me show you by an example that what could be the problems if we keep using this visited hash set only and uh how can we uh how can we find false positives so suppose we are given an example like this that uh 0 calls one and uh two and that's it this is the input we are given right and now we don't have any entry inside our hash map now the thing is all the edges are undirected edges now because they are undirected edges we can represent them in different manner so let's represent them in slightly different manner so from zero we have an edge that goes towards one from one we have an edge that goes to zero same goes from 0 to two and 2 to 0 now initially we start traversing from this zero now we we have our algorith that initially we are going to add the entry to visited hash set so zero does not exist so we add the entry towards our visited hash set now from the zero we need to check all of its neighbor before we move on to some other node now from this zero first of all let's say that we go down this path and we check its neighbor to because there exist an edge like this we are able to check its neighbor right so we are at this position number two now at this position number two we don't have an entering the visited headset so we enter and entry over here that uh this is two now from this two again we will need to repeat the same process that we will need to uh check for all the neighbors or all the edges that two this two can point to now it does not have any edges that go further but it has an edge that goes back to zero now the thing is in this case again we will use our same logic so from this two we can still go to zero so we will check that whether we have visited this element zero or not and over here we find that hey we have already visited this element zero which means by our logic that we were previously trying to impose we would have we could have said that okay we have we have found a a cycle a cycle that looks like 0 to two and two to back to zero and we in this case say that hey we have found a cycle and this is not a tree and we will need to return false and blah blah blah the thing is this is actually not the case and why it's not the case is because of this correlation of having an undirected that is causing all this problem which means that we cannot rely only on having a visited hash Set uh if we do that then essentially we are not we are not going to be able to find an answer because in this case we know that from there does not exist an edge and from this uh two we are coming back to zero only because there exist an undirected edge from this 2 to zero and that's why we can consider this zero to be two's neighbor but in reality this zero is actually parent of this uh child 1 and two so if that's the case why are we still doing doing things like this what could be a better approach we can use to find that what would be the solution to detect these Cycles there are couple of different ways where where you can tackle this problem one way to tackle this problem is that initially remember the only reason we are causing this problem is because there exist an undirected edge which means that there exist uh two directed edges from any two nodes so what we can do is we can put a condition that at and from any point if we travel from this one to is zero or two if we are able to travel one in One Direction we would get rid of the remaining Edge and let's see that how it would work so what I'm proposing is that initially uh initially we are at this zeroth position so we check in our visited hash set we don't have any entry so we add an entry over here that okay we are at the zeroth position now now from the zero first let's say we travel to one which means that now we have travel from 0 to 1 in this direction so our aim is that we get rid of this uh reverse Edge in our adjacency list so if we get rid of that now we are at this position number one at this position number one again uh we add an entry over here in our V visited hash set now from this position number one what we have to do is we will have to check that what are all the neighbors that we can travel to or all the children we can travel to but this one does not have any neighbor or children so which means we don't have to worry about anything so over here we can see that okay from this one we can't go anywhere but thing is there still exists some uh some nodes that we haven't traveled to and we are using either BFS or DFS in any manner to Traverse over entire graph right so which means that we will have to do a backtrack so now from this one we do a backtrack now again we end up at this zero but thing is in this scenario remember we are not ending up at this zero because from one there existed an edge like this where we consider zero to be one's neighbor we are coming back to this one because we are using backtracking uh through any BFS or DFS algorithm uh we can we can implement this recursively or rely doesn't matter in any scenario we will have to iterate over all the nodes that are present inside the given graph and since we haven't traveled all the nodes that's why we are coming back to the zero so again this would be a new entry in the visited hash set so again we come back at this zero and this zero we check that okay we have already explored one of the neighbor of the zero but we still have to explore another neighbor so again we repeat the same process from the zero we explored another neighbor of zero we come back at two and immediately we get rid of this uh this Edge that was coming back to it and then we add an entry over here that okay we are at this position number two now from the this two again we don't have any more neighbors to go to so now we have explored all the neighbors of one so we can mark one as being done uh we have explored all the all the neighbors of two so we can Mark or two as being done and now we come back at the zero and we can Mark zero as being done because we have explored all the neighbors of zero possible as well and in any scenario we did not find any single Loop because we did not find repeated value inside our visited hash set so we can determine that there does not exist a cycle and which means in this case we can return true because there are no Cycles so we can say that there is no Loop for this one and the only reason we are able to come up come up to this conclusion is because at every single position we were removing the edge where in One Direction we have already traveled so that is one way to take care of this problem and uh the solution would work as expected as well right now the thing is there could be another solution where we can use the little bit different logic a little bit different data structure and we can do things in better Manner and let's see that what would be that approach so the second approach is that rather than using this visited hash set we don't have we don't need to do anything with this visited hash set let it be used for the purpose of counting that whether all the elements are uh connected components or not uh what I'm proposing is that we created another data structure a hashmap and in that H in this hash map what we plan to do is uh we as a key we have parent and as a child we as a value we have the value of its children now let's see that how could how can we use this combination to do things a little bit differently Al over here let's say that we are given a graph like this that 0 1 2 3 something like this right so 0 is connected to 1 1 is connected to two two is connected to to three and now we have this three connected back to this one as well which means that there exists a cycle over here now because these are undirected edges which means that they are bir directional edges as well so from this zero we can go to one from this one we can go back to zero and blah blah blah whatnot so initially let's say that we are at the zeroth position from the zeroth position we starts exploring its neighbor or children or whatever you want to call so the moment from this zero we are able to reach to this one we would add had an entry over here in this hashmap and the entry we are going to make is that uh zero is actually a parent in this case and one of the children that we could find for this zero is actually node number one so node number one is a children of uh zero and just stay with me that why we are using this approach now again from this node number one we need to explore its neighbors right so what are the neighbors of this node number one we can explore neighbors based on the number of edges that goes out from this node node number one so from this node number one we actually have two edges that goes out first Edge is that from this node number one we can go to node number two now we check in this hashmap that does node number one exist node number one does not exist as a key so we add an entry over here so we add we say that okay parent is one node number one and from this node number one we can actually travel to node number two so we are good with that now again from this node number one we still have possibility that we can go back to this node number zero so again we check in this hashmap okay that whether there exist an entry for this node number uh zero that we are trying to reach remember this very importantly we will check that whether this node number zero that we are trying to reach from this node number one does it exist in the hash map or not okay so zero exist in this hash in this hashmap again we check that from this one we are trying to reach to this zero is this one one of the children of this node zero or not in this case yes one is the children of node number zero if that is the case we can ident identify that this connection from 1 to Zer is actually not a cycle it's just a trivial Loop and that is being caused because there exist an undirectional edge on both the sides so that's why we will ignore this case we will ignore this connection we are not removing the edge again remember we are not removing the edge we are just ignoring this case because in the hash map we are able to find that okay this 0 to one connection is actually just a trivial cycle and we move on with our life so from this one again since we have reached to this two right and two is not existing and two is one of the children of one now again we are at this position number two now again from this position number two what are the different ways we can travel we can either go back to one or we can go to three let's say that we go to three first so we check that whether three exists inside the hash map three does not exist which means we can create an entry that where two is a parent and three is a child we are good with this so far now again from this two when we try to check that from two we are trying to go back to one is that is that a cycle so first we check that whether this one exist in the hash map or not so one exists in the hash map over here and two is one of its children so because two is one of its children we are going to ignore this case and we are going to uh ignore and because we are ignoring this particular we are just going to move on with our lives now we are at this position number three from this three we will check that okay what are the different places we can travel back to so from this three we see that okay one Edge that goes to one one Edge that goes to two first of all let's see let's explore this Edge from 3 to two uh so over here we will check that we are trying to reach to this node number two so two already exist and three is one of its children which means we are going to ignore this Edge so we don't have to worry about anything now again from this three we check for this value number one so okay from this three we try to see that whether we are able to reach to node number one not node number one has already been visited inside the hashmap and that's why we are able to determine that there exist a loop inside over here from where we are actually going back to one of the places that was actually uh not uh that is already been visited in inside our hash map and this hash map acts as both it acts as a visited uh hash set that we were implement we were planning to use and also it acts as a way for us to determining that whether we are detecting the correct Cycles or we are detecting the trivial Cycles between the un directional edges and this would be a way on how we can check the Cycles which means that the combination of this using this hashmap to identify that whether cycle exist or not and using this visited node and iterating over using BF BFS or DFS inside our graph original graph uh using these two data structures we can actually com we can actually get rid of both of our cases where we need to check that whether the graph is connected and we need to check that whether the graph contains any Cycles or not and once because we are able to do both of these things at the end if we are able to reach to end node we will return true if we are not able to reach to end node we we can return false and this solution actually works perfectly fine there are no issues with this solution it is a very elegant solution if you tell it in any interview they are going to be very impressed with the depth and Bre of your uh thinking capabilities what are the space and time complexity over here and can we do something better so let's uh first try to determine that so space complexity in this case we we know that we will have to use a hashmap and we will have to use the visited array as well inside the hashmap we are going to iterate over all the nodes plus all the edges which means that over here the space complexity would be B go of v+ e because we are iterating over all the vertices and all the edges the time complexity in this case would also be big go of V plus e because we'll have to iterate over all every single node and every single edge multiple times in order to come to this solution but the thing is we are not doing Loop inside loop work so which means we are not doing repetitive work at any given moment okay after such a long explanation let's see that that can there be a better approach and yes there is actually a very elegant very beautiful solution where actually we don't even have to go through all of these mess to detect that whether Cycles exist or not in order to do that actually we need a higher knowledge of uh graph Theory what do I mean by that okay uh at any given moment suppose we are given a graph like this that 0 1 2 3 4 suppose we are given a graph like this right now if we want to identify that whether this is a tree or not like in this case we can clearly see that yeah this is a tree there is a very legitimate scenario there are no Cycles all the nodes are connected and blah blah blah what not everything is good with this right can you notice an important property over here the important property that I'm talking about is if you count that what are the number of nodes and what are the number of edges does there exist a correlation Yes actually there exists a correlation and the correlation is that suppose we are given the number of nodes equal to n and if we are given the edges that are n minus one and we deter that all nodes are connected if we determine that all nodes are connected because remember in our solution when we are trying to find finding that whether the nodes are connected or not is much simpler we simply need to use a hash set we need to iterate over whatever the given input we have and uh basically we can determine that okay whether the nodes are connected or not but checking for the cycle is slightly more complicated actually not slightly much more complicated because either we have two options and both options require us modifying lot of things or managing a bunch of different data structures either we can choose to remove the remove the edges like this or we can choose to create a hash set like this in both the cases we are actually doing lot of work so what if we actually don't need to encounter that whether we need to find the Cycles or not if we only encounter that whether the given nodes are connected or not if that is true and at any given moment we identify that okay all the nodes are connected and then we identify this property that whether the number of nodes that are given and number of edges that are given if there is the difference between them is only one if that is the case then the given graph will always be a tree let's see in this scenario in this scenario we can identify that okay from this zero all the nodes are connected that there's one 2 3 and this four we are able to connect to all of them right uh how what is the number of nodes so number of nodes in this scenario is actually five this 1 2 3 4 5 now let's see that what are the number of edges so if we calculate the number of edges the number of edges is okay this is one Edge this is two second Edge this is third Edge and this is fourth Edge there are only four edges that are possible if we have any more edges then for sure there would be a loop because remember where would you add an edge in this scenario you can add an edge over here okay that creates a loop uh let's say that you don't add an edge over here suppose you add an edge over here again it creates a loop well you don't even add an edge over here you add an edge like this so again this creates a loop like this eventually as long as the the difference between the number of nodes and number of edges is actually not exactly one and if the number of nodes are one number higher than whatever the number of total edges are given if that is the case and we determine that all the nodes are connected then we can clearly say that okay everything is good with our life and we don't have to worry about anything why now why we need to check that whether all the nodes are connected or not the only reason we need to check if all the nodes are connected or not is suppose we are given a scenario like this that we are given these three uh these three nodes suppose we are given these four nodes right and in this four nodes so remember our equation is that number of nodes and edges so if nodes are four and if edges are three so we can say that okay everything is good with our life in this case the number of node is 0 1 2 3 okay so total four four nodes we are good number of edges 1 2 3 so this is also good the thing is over here you can see that there exists a cycle over here between these three edges and why there exist a cycle because this particular node is not connected so always at any case we will we have to check that whether all the nodes are connected or not and once we identify that all the nodes are connected we are good and then we can just wrap up our solution so using this solution actually everything becomes so smooth that if we calculate the time and space complexity the time complexity in this case is actually big of n because we only need to iterate over the in given in number of nodes and where n defines the number of nodes if we calculate the space complexity the space complexity is also bigger of n because we only need to Main maintain a hash Set uh to take care of what all the number of connected edges so once we find out that what are the number of connected if all the elements are connected we can immediately identify that whether this given graph is a tree or not so let's move on towards coding now now first of all we are going to check that whether the given number of edges uh it's if its length is uh one less than the number number of nodes are not if that is not the case we can return false immediately so and if that's not if that doesn't happen we will have to make an adjacency list so we will create an adjacency list so it becomes easier for us to iterate over the given input array so for all the given n we are going to treat them as vertices and all the values that are provided in the edges we are going to treat them as edges BAS basically notice over here that we for every single edge we are actually adding two entries inside our Regency list and that is because the given edges are actually undirected so that's why we will have to add an edge for both the nodes uh so if there is an edge between 0o to 1 so we will have to create two edges and the those two edges would be zero uh to one and from Node 1 to 0 so that is what we are doing by the second for Loop okay now we will start iterating over the given graph inside the adjacency list and uh I want to learn that how to iterate over the graph using stack so I'm going to uh do it using stacks and uh I will be doing iterative depth first search so first I'll initialize a stack of integer values and just name it as stack and uh we will also have to create a hash set of uh integers called visited inside our stack we will add the first entry so we will add the node zero and inside our hashmap visited we'll mark the first node as visited we will pop the first node that is inside our stack and then we will start iterating over its neighbors and we'll see that if that uh neighbor has already been visited then then we will simply ignore that case if that is not the case we will start iterating uh we will start adding those neighbors to the to our stack as well and we will also add that neighbor to our visited hashmap as well it would be neighbor not node okay and after this Loop ends we only need to check that what is the size of our hash set so if or else we will return false and uh let's try to run the code okay seems like our solution is working let's try to submit this [Music] code the problem is called number of connected components in an undirected graph and if we see some of the popular companies who have already asked this question there are companies like Tik Tok Amazon Google Facebook LinkedIn Microsoft do das and Twitter so this problem has been really popular amongst top most companies and let's see that what the problem statement is trying to convey basically this is a lead code medium problem and also very well-like problem it says that we have a graph of n nodes that we are already given and we are basically given the edges that defines that there is a connection existing between those two nodes for any given graph now based on that we need to indicate that how many number of connected components are present inside the graph so let's try to understand this with an example in this case currently we are we have five nodes so basically we are given an N is equal to 5 as the number that defines that there are five nodes we are also given these edges so we would we would have given three entries and the first entry is going to be 1 to two uh second entry is going to be 1 to 3 and third entry is going to be 4 to 5 now based on these two items we need to Define that how many number of connected components that exist which in this case we can see that this is the first connected component because these three nodes are connected with each other and same way this is the second connected components so in this example for this given input we can Define that there exist two connected components and we need to return two as the answer so this is the whole of the problem let's try to understand this with one more example suppose in this case currently we are given n is equal to 7 and we are given all of these different edges now in this example we can clearly see that there exist four different connected components and those four components are these that this is the first one this is the second one this is the third one and though this seven is not connected with any other node still this is a connected component in itself because it's connected with itself so in this case in total since we have four connected components we need to return four as the answer now let's see that what is going to be the strategy to solve this problem suppose we take the same example as the input and we will try to see that what would what should be the answer now again remember we are given two things first we are given n is equal to 7 so that we know for sure there exist seven nodes and we are given all of these five edges now based on these number of nodes and edges we can clearly do one simple thing and that is to treat this as a graph problem because that what it is basically we know that a graph is comprised of two items first one is a node and second one is an edge and which we are just told in plain English that this these are the two entities we are given so we are going to treat this one as a graph now the aim is to find connected components which means from any single edge or any single node we will need to Define that how many other nodes that particular node is connected with and if we keep on repeating the same process and the moment we find the connected nodes we can eliminate all of those nodes so and repeat the process for all the seven nodes that are given we would be able to find the number of connected components quite easily and the technique we are going to use over here is the one of the most popular technique in the entire coding industry and that is called breath first search and how we are going to use BFS well we already know that in order to use BFS we will have to use q and you we will also have to use number of visited nodes that we have already visited so using these two items we are going to make our lives so much easier and let me just walk you through the solution first thing we are going to do is we are going to uh start we can start from any node because this is a graph there is no particular definition that we need to start from here or we need to start from here uh say for Simplicity we start from this node node number zero so we are going to have our Q now inside our que currently we don't have any elements and we also have our visited hash set we can also use visited array I'm just giving you example of visited hash set either way we are going to have a mechanism to keep keep track of all the numbers or all the nodes that we have visited so far so this is our visited hash and this one is our Q okay now first we start with node number zero now for node number number Z we are going to mark this one as zero so we are going to NQ with zero now we are also going to Mark 0 as visited okay and we are also going to have one more number that is called the number of connected components so let me just mark this one as counter okay and currently the initial counter value is going to be zero but since we found one node we know for sure that there exist at least one connected component because it could be connected to itself so in that case we are going to increase the number by by one okay now for this particular zero we are going to run BFS and by running BFS what we would be able to do is that we would be able to go through all the neighbors that this zero is connected with and then Mark all of them in the visited hash set so even in the future for this n is equal to 7 if we come back to the same node if that node has already been visited we will just simply skip over it so let's just do that now for this zero it has two Neighbors First neighbor is neighbor 2 and neighbor one currently both are not visited so let's just add entry 0 1 and two over here and then we will mark one and two inside our CU because we need to uh do something with that currently the count is still going to be one because all the nodes are connected now we pop zero out and we process we do the same process with one currently for the value number one uh one is also uh visited so since one is already been visited we do not need to do anything with one and and we can simply pop that one out again two is also visited so we do not need to do anything and we can pop it out now after iterating or after doing the BFS starting with the node Z we have simply eliminated node 2 node one and node Z by itself and so far the count has been one and we have all of these three nodes in our visited haset but we know that there are still seven nodes that we have to take care of so we are going to iteratively go over every single one of them initially we started with zero so we got rid of it let's just start with one again for one since one has already been visited we do not need to increase the counter and move on to the next value again two two has also been visited so we do not need to increase the counter and move on to the next value so all of these this entire compon connected component has been taken care of moving on to the next value starting at position number three since three has not been visited adding three over here adding three in the queue as well going through all the neighbors of three currently three only has one neighbor and that is value number five five is not being visited and also we since we find a new element three I forgot to add the increment the count so now the number of connected components we have found so far is going to be two I forgot that but this is important now uh going back the currently three is connected with five five has not been visited marking five as visited at the same time adding five inside our uh que H to visit it further neighbors of five now three does not have any more Neighbors which means we can get three out or dq3 uh and then we are going to have value number five remaining five has one neighbor that is three but since three has already been visited we cannot do anything with that so we are also going to get rid of five and five has also been taken out this means that currently we do not have any elements inside our BFS function now moving on currently we went through 0 1 2 and 3 now now we need to go through value number four because there are seven elements inside our given input uh for even again repeating the same process for Value number four currently four has not been visited so we will mark value number four as visited at the same time we are going to put four inside our Cu uh we are going to go through the neighbor of four current and we are also going to increase the count I always forget to increase the count which is the most popular thing that which is the most important thing asked in this problem but anyways now going back for value number six uh it is not been visited so we are going to add value number six over here at the same time add value number six over here now we iterated over all the neighbors of four so we are going to DQ four uh after deqing currently there is only element number six staying in six currently has one neighbor that is value number four but since four has already been visited we do not need to add it to our que and then eventually we would pop out six as well now what we have done is that currently in order to find these three connected components we already visited nodes 0 1 2 3 4 5 and six and all of these nodes are visited now in the end we are going to be at the position number seven since for position number seven uh this node has not been visited which means we need to increase the counter so currently the counter is going to be of value number four now we are going to add seven to our list of visited noes and also we are going to Mark 7 inside our Cube since 7 does not have any Neighbors which means we can pop s out immediately and now our Q is empty we have already iterated over all the number of seven nodes that were given as the input and uh we we are basically done with the problem so in the end whatever the value that has been stored inside this count variable is the answer we need to return return so simply at the end we can return return that there are four connected components in this problem and this is the complete solution now if you see how beautifully we were able to come up with the solution and in this case if you see time and space complexity the time complexity is going to be big go of v+ e where V defines the vertices or uh nodes and the E defines edges because that is the time complexity to run the BFS function and go over the entire given input array so this time complexity is pretty good if we see space complexity now space complexity is also going to be big go of V because we are using the additional data structure of Q and also a hash set or array there are two ways to do it I typically like to use hash set but you can also use an array as well both would work uh equally fine in either case this is a very good time and space complexity and remember the one of the most important concept is inside the graph Theory the breath first search allowed us to solve this problem smoothly in a beautiful manner here is the coding solution for number of connected components in an undirected graph where first of all we are given in the input uh the value n and we are also given a 2X two array called edges so first thing we are going to do is create an adjacency list and to create a graph like structure so this is going to allow us to iterate over graph in a much easier fashion which this process is doing where we are running across every single edge and every single node and plotting them on the graph after that we are going to have our Boolean array called visited and we are also going to have a value called count that initially we are going to set it up as zero we are going to run our for Loop starting from value zero to the total number of n that is given in the input and then uh inside the for Loop first thing we are going to check is that the current I position if that is not visited then we are going to call our BFS function and at the same time we we are going to note it as the new connected component found and we are going to increment the number of count now let's see that what is going to happen in our helper method BFS where we are taking a graph as the input we are also taking the number of nodes that have been visited so far and we are also using the starting pointer from which we are entering inside the this given graph uh so first of all we are going to initialize our Cube we are also going to have a visited array that we are going to Mark as uh true for the current node that we are visited and while there are no entries inside the cube first of all we are going to pop the last added element inside the cube visit every single neighbor of that node and for all the neighbors that has not been visited we are going to mark them as visited and we are going to add it to our existing Cube and by doing this operation we would be simply running through every single connected component so suppose here I give you like zero as the input then through this BFS method 0 1 and two all three nodes would be Mark visited because they all are connected and this is what this operation is doing and in the end after this for Loop ends in in our main method we simply need to return the count that we have found that would allow us to find the number of connected components let's try to run this code and our solution works perfectly fine let's submit the code and our code runs decently efficiently and don't worry about that you are not being able to see the code I'm going to put this code inside the GitHub so you would be able to find it quite easily from [Music] there Hello friends we are still not employed by a Fang company so let's not stop lead coding till we get there today we are going to do a very interesting lead code problem interest interval and if you see the number of companies that have asked this question it's really amazing uh the the companies like Google LinkedIn Amazon Robin Hood Facebook Uber Apple Twitter Microsoft service now Bloomberg and Goldman Sach like these are if you see the description of my channel these are my dream companies that I want to get a job of so that's why I'm doing these questions and I'm paying my at most attention I hope you also enjoy the video so this is a lead code medium problem and essentially we are given an array of nonoverlapping intervals this is a multi-dimensional array it's a 2d array and at any given cell essentially we are given the value like start and end which indicates that there exist an interval between those times now our aim is that we need to insert a new interval into the list into the array of intervals that we are already given and we need to we need to maintain this nonoverlapping uh quality of the intervals so if we try to understand this this with an example uh suppose over here we are given a set of interval like 1 3 69 so we are given an interval like this 1 2 3 this is already given and we are also given another interval like 6 to 99 and we need to insert a new interval called 2:5 so if I draw it on paper it would be something like this so two would fall over here and five would fall over here and this is the new interval that we are trying to insert in this original existing interval so how can we insert this new interval well the answer is actually simple essentially what we are going to create a new interval is that that we will start an interval at position number one then from 1 we will have an interval all the way up until the position number five and then we will have another interval from position number six and all the way to position number N9 and this would be the two intervals that we will have to take care of now the thing is in this problem we can clearly uh identify that why did we come up with this approach because we wanted to make sure that we do not we do not have any overlapping intervals so that is why when we found out that this is the existing interval and this is the new interval that we are trying to achieve if we wanted to insert this one there exist an overlap between these positions between this 2 and three so that's why because there was an overlap we actually chose to merge these two intervals and we created a new interval like this and for this one this had no concern with the existing uh new with the coming coming of new interval so that's why we left it as it is so let's see that what could be the different uh uh approaches we can take what could be the different scenarios and how we need to behave in any single scenario of them and essentially that would be our solution so first of all if suppose we are given a number series like this and we are given a list of uh intervals like this that there exist an interval between this value 2 to 4 there exist another interval between this value 8 to 10 and 13 to 15 now we let's see that where different set of intervals can be entered so suppose first of all we are given an interval like this that is not overlapping with or that is not in conflict with any existing interval so let's see that what would be the scenario in that that case suppose we are given an interval like this that from 0 to 1 we are given an interval like this now if we see this new interval it has no sort of conflict with any of the existing intervals if we wanted to add this to our uh array of intervals it would be just pretty simple we simply create a new interval like this 0 to 1 and then return whatever all these values are and this would be our answer so we we should be we would be done in this case there wouldn't be any issue but suppose if this is not not at the first or at the beginning of the intervals if this is at the end of an intervals so suppose this particular uh new interval that we are trying to enter suppose we are given some interval like this that uh from 16 to 17 we are given an interval so suppose we are given interval from 16 to 17 something like this now in this case what would be the approach essentially we would be doing the same thing what we would be doing is we would be transferring this interval on top of whatever the existing intervals we got and how we are going to do it basically we are going to start traversing towards the original given input we are going to see that okay where is the starting point of this new interval and where this new interval can fit inside the existing set of intervals that we have now in order to check that essentially what would be helpful it would be helpful if we had a sorted uh set of intervals and in this scenario all the intervals that we are given they are already sorted so that is why which works in our favor so which means it becomes really easy for understand that where this new interval we wanted to uh shift into and in this case uh so we will start traversing we will first see that okay this is the value two this is this is 16 we don't care so we move forward uh again we are done with this interval now what is the next start point of this interval this is 8 and this is 10 and this is 16 so again again it doesn't matter there is no overlap so we can put this in the answer again this is 15 this is this is 13 this is 15 and this is 16 so again there is no overlap so we can put this in the answer as well and then we find out that after 15 there are no intervals and we need to enter this new inter uh interval 16 and 17 so we simply add it over here from 16 to 17 and we add this to our array of answers as well and we return these four as a new new set of intervals now suppose somewhere in the M rather than this one this these are like easy scenarios where we are given at the beginning or at the end suppose we are given something somewhere in the middle so suppose we are given a new interval that we have to take care of uh something like this that it is from 5 to 7 this is the new interval that we are trying to insert what should be the approach in this case again we are going to repeat the same case over here this is the value 5 and 7 now what we are going to do is we will start iterating over this given input we will see that okay first value is two and uh the end of this in this interval is at four so this is 2 and four and the new interval starting point is five which means there is no conflict so far so we would add this to our set of answers now from this four we reach at this five and at this five is the starting point of this new interval so we check in our original set of intervals that from 5 to 7 does there exist any conflict so from 5 to 7 actually there is no conflict in our original interval so if there is no conflict we simply add a new interval over here from 5 to 7 add it to our list of answers and because we have reached the end of our new interval right we have we have reached the end of our new interval which means what this dictate dictates is that from this point forward there cannot be any exist ing interval that could be causing any sort of overlap with this uh with the arrival of this new interval so whatever the answer or whatever the list of intervals we are given Beyond this point once we have already entered this new interval we can simply add these to our answer array and this would be our solution so this would make our lives very easy and that is how uh we we would be able to handle this scenario as well right now the so far the all the three scenarios we saw we entered the value at the beginning at the end or somewhere in the middle but in all the cases there was no conflict between existing intervals with the new with the arrival of new intervals now suppose the new interval that we are trying to enter uh that new interval is something like 3 to 8 suppose it's something like this that now we need to take care of this scenario where we are handling this new interval and which is from 3 to 8 so what should be the approach in this case well the approach is actually quite simple uh we will start iterating over our input we will find all the intervals so first we we find that what is the start point of this interval so the start point of this interval is two and what is the end point of this interval the end point of this interval is four now what is the and every time with the end interval we are going to compare the start interval of the new uh new inter new interval that we are trying to insert so the start interval of this this one is three and this one is four which means that we know that we will have to enter this three over here and there exist a conflict now since we have identified a conflicting scenario what should be our approach well our approach should be simple that we are going to take a look at this particular interval and we are going to take a look at this particular interval now there exists a conflict because there exists a conflict we are going to check the starting points of both the intervals now in terms of starting points of both intervals this one is smaller than this one so whatever is the smaller we are going to treat this as the starting point of this new interval that we are trying to enter because there exist an overlap amongst these values so we are taking care of the overlap so that's why this would be our starting point this would be the start of this new interval and we are going to drag this new interval up until the end of this point so up until the end of this point when we come we find out that it ex it comes up until all the way to Value number eight now in this scenario we did not had anything in the middle but if we did had anything in the middle that would have been merged by this new interval right but thing is even when we come at this position number eight we see that actually the position number eight is start of another interval so which is this one so if it is start of this interval we cannot just treat this as a separate interval I mean what I'm trying to say is we cannot have an interval like from 2 to 8 is one interval and from 8 to 10 another interval because because this 8 is actually a conflicting point and it is a con because it is a Connecting Point these two intervals also needs to be merged so because this 8 is a Connecting Point we are going to merge this interval with this new interval that we are trying to create and essentially this interval from 8 to 10 will also be dissolved by this new interval and we would have an answer like this in this scenario that uh we would have a new newly created inter interval from 2 to 10 this would be for one interval we have and this would be another interval because remember now we have already entered this one which means all the values Beyond this point are not part of our concern we concern we can simply add it to our uh list and in this scenario the second interval would be uh from 13 to 15 and this would be our answer that we are going to return so this is one conflicting scenario and uh I mentioned that how we are going to tackle it so essentially the different test cases in this case we we can have is that we can either have a scenario where the item lies somewhere between beginning or at the end where it is not conflicting with anyone or it can be existing somewhere in the middle where it is not existing not overlapping with any other interval or it can be a case where it conflicts with some intervals with one interval or more than one intervals in either scenario what we are going to do is the moment we find that there exist a a conflict we are going to see that what is the start Point what is the lower value amongst these two so because the lower value is two we are going to start this new interval starting from the position number two okay now for the end position again we are going to do the same thing we are going to check that what is the end position of this existing interval and what is the end position of this new interval and in the end position we will have to uh check the maximum value because the interval we are trying to create should be the size of biggest interval that we could create which is not overlapping with any other interval so that's why we would have an interval that is maximum amongst these two ending values so these two ending values the value is eight so we would have an interval from 2 to 8 so far but the thing is this is not the end yet because when we come at this eight we will still have to check for the conflicting scenario so over here we have we would have the starting we would have two intervals like this and in the two intervals we have the eight value as the value number eight as common so we are going to merge these two as well and in this case we are going to choose the biggest value we can find as 10 and we are actually rather than having an interval from 2 to 8 we would actually have an interval from 2 to 10 and this is the critical part to understand and this is basically our solution essentially we are using the greedy approach but this is all we don't need to do anything else and if we calculate the time and space complexity the time complexity in this case would be actually big go of n because at at any point for this new interval we would need to find that what what what should be the entry point of this new interval and then we will check for the conflicting scenario if there exists a conflict scenario we will find a way to put it there if there does not exist any conflicting scenario well good for us uh in terms of space complexity well for the space complexity it would also be big off n because we will have to create a new array array of list of intervals that we are going to return so we will have to create a new two-dimensional array something like this in this scenario from where the answer would be 2 to 10 and uh 13 to 15 so this would be our new array that we are creating and we would be returning that so that's why SP that explains the space complexity and uh yeah this would be the solution now the question is where can you use these kinds of approaches like what is the point of having this question in at the first p and actually this is a very interesting question it has lot of practical applications practical applications is like suppose you are trying to design an app where you need to maintain some sort of calendar or we you need to maintain scheduling so the and these are very practical very real life applications uh Google Mail Outlook all the companies they all use this mechanism they all use this mechanism so if we know that where we need to insert an interval where we are not creating any conflict it could be a conflict between shifts of two employees working for a factory or it could be the interval between two trains going through a station so like yeah these are real life practical exams and that's why the that justifies the number of companies that are asking this question so first of all we are going to initialize some variables and we are going to create a new start and new end for the given uh new interval we are also going to create two pointers left and right and left would be at the zeroth position inside the given intervals and right would be the last uh the size of the given intervals we are also going to create a link list to store all the output and then we are going to convert it into the array so now first of all we are going to add all the nonoverlapping intervals that come before the new start so we are going to create a while loop okay now inside our given list we will need to add the new interval so in order to add the new interval we will have to check two there could be two possibilities there might be an overlap or there could not be an overlap so we'll have to take care of both of them so first we are going to create a parameter called interval and we are going to uh store all the value ins inside this parameter now we are going to check the condition that if the current uh position where we need to insert the new interval does there exist an overlap or not so if there is no overlap we can just simply add the new interval so if that's the case we can just simply add the new interval if that is not the case which means there exist an overlap so if there is an overlap we will have to first of all check that what entry we like what should be the uh starting point and ending point of the overlapping character and that we can Define by choosing the minimum out of the starting values or the maximum out of ending values so first of all we are going to add the last value we have in uh our link list inside this new interval variable that we created and now we are going to check that what should be the end point and we would add the new entry to our link uh link list okay now we might have to merge all the elements that are after uh that came because we added this new interval so we will take care of the merge scenario and if there exist an interval we will do the same thing that we did before so essentially we can just repeat this process uh yeah after this Loop runs uh we should have everything stored inside the link list so we can return the link list but we will have to convert the link list to an uh array and this should be our answer let's try to run the code it seems like our solu solution is working let's try to submit this code oh we will have to check for the this end variable here so that's why okay looks like our solution is working and it's actually pretty fast compared to a lot of other Solutions and even in terms of space complexity we are also Al saving a lot of time a lot of space as [Music] well hello friends we are still not employed by a Fang company so let's not stop lead coding till we get there if there is any question that can get you in the Fang it's this one that we are going to solve today because if you just see that the number of companies that have asked this question it's just out of this world this question has been asked by hundreds of companies literally hundreds of times you can see over here that like Facebook and Amazon they both have asked this question recently over 100 times in their interviews so you can imagine the severity and the importance of this problem that we are going to solve apart from Facebook and Amazon if we look at the number of companies that have asked this question there are companies like Google Salesforce Microsoft Bloomberg Apple Uber LinkedIn IBM uh VMware Walmart Tik Tok Adobe Twitter Twitter uh bite dance and uh then there are companies like Yahoo PayPal wish oldman's XX Robin Hood and also plantier square and Netflix so these are all one of my dream companies where I want to get a job that's why I'm making these videos and that's why I made this channel so I would be paying my utmost attention I hope you also enjoy the video this is a lead code medium problem and uh it is one of the most like problems on lead code and that's why a lot of companies likes to ask this problem so essentially we are given an array of intervals where every single entry inside the interval mentions that there exist a start point and an end point of that particular interval now we need to iterate over all of the intervals and then we will need to merge all the overlapping intervals and we need to return an array of nonoverlapping intervals from this given input and uh that would be our solution so if we try to understand this with an example suppose we are given some set of intervals like this now let's try to mention them on this uh number sequence that we have drawn out now over here our aim is to return all the nonoverlapping intervals and if there exist an overlap we will need to merge those two intervals so first of all we'll have to identify that what are the those two intervals where we can see an overlap so essentially if we look at the start values of this interval so the start value over here is 1 and three and if we look at the start value of this second interval the start value is actually 2 and six and over here we can clearly see that there exist an interval amongst these values and this is these are the two two intervals that are causing an overlap and we will have to merge them now the question is first of all we need to know that why did we why we were able to calculate that there exist an um overlap over here based on the given input like this is a pictorial representation we can clearly see that why there is an overlap but in terms of computer we will need to dictate some sort of uh mechanism so essentially we can say over here is that at any point if we start iterating over any number of intervals and if we identify that for those particular intervals if the starting value so in this case the starting value is actually two if this starting value Falls between any interval so because this two currently Falls in between this 1 to 3 this this first interval is 1 to 3 and over here the starting value of this new interval actually falls between the the those places and the moment we identify that okay this two Falls between this 1 and three interval so we know that okay this uh interval that starts at 2 so this 2 to six is also causing an overlap between this given input interval and we'll need to merge them so this would be our condition to identify that at any moment at any interval we are trying to see that whether it intersects with some other interval or not what we are going to check is we are going to see that uh suppose this value is the start value so we are going to see that this start value if that meets if that is less if that is greater than whatever the interval start we are checking and whatever the interval end we are checking for if this condition is true we can determine that there exist an overlap and now since we have already identified that there is an overlap uh we'll need to resolve that so in order to resolve that how we will resolve that is we will create an interval from this value number one to Value number six so essentially we are merging both of these intervals and why how what is the condition we are using to merge these two interval is that we are going to check that okay for the starting point of the new interval what is the minimum value amongst both the start values so Ina in this case over here the first start value is one and second start value is two so the minimum value is actually one so we create an interval that starts at position number one and for the end value there is this three and six so we compare this value three and we compare the value six and we identify that okay six is greater in this case so for the end value we are going to pick the maximum value among two values so we are going to create a new interval like this that is from 1 to six and then uh essentially we have taken care of these two overlapping uh intervals and for this one this 8 to 10 and this 15 to 18 these two intervals they are not causing any kind of overlap so we can just directly put them as it is inside our uh answer so in this case if we try to calculate that what would be our answer the answer is actually quite simple the uh answer in this case is going to be an interval from 1 to 6 and this is the merge interval second interval is going to be 8 to 10 and the third interval is going to be 15 to 18 so this would be our solution and we can simply return this one if let's try to understand the same problem with another example that is given over here so in the second example we are only given two intervals 1 to 4 so this is one interval 1 to 4 so the question comes that are they overlapping integers and the answer is yes why because if we see at this value number four actually Four is Connecting Point for both the intervals so four is the ending point for the interval one and it is the starting point for the inter interval number two so in this case we actually need to merge these two intervals and we will have to create an interval like this that is from value number 1 to 5 and again we are going to use the same logic the logic is going to be that over here the values were 1 to 4 and over here the values were 4 to 5 so for the starting values we are going to choose the Lesser value and for the ending values we are going to pick the maximum value so maximum value in the Lesser value in this case is going to be one and maximum value is going to be five so this would be our intervals and this is the these are all the scenarios that we need to take care of so suppose we are given a custom example like this let's see that what what should be the solution and always remember that it is really important for any programming interview that you come up with your own custom examples it shows that you have the ability to think about all the different kinds of test cases and you can come up some with some unit test on your own so over here our aim is to find that all the non-overlapping integers now for to find all the nonoverlapping integers we already know that what is the condition that how can we determine that any particular value is actually causing an overlap and the way we can do it is that by checking the start value and comparing it with that whether it exists somewhere in between uh any given interval the question is previous two examples we saw they were already sorted so they were all the starting values were already in some in a sorted manner so that's why it was really easy for us to identify that whether there exist an overlap or not but nowhere uh in the sequence we are told that all the input should be sorted so that's why that makes things a little bit more more complicated and let's see that how it does so so over here suppose we are given an input 4 to 6 so we can create an line over here that okay there exists an interval like this from 4 to 6 now second one is 11 to 15 so again there is an input like this 11 to 15 next one is 7 to9 so there exist an input from 7 to 9 and this next input is 2 to 5 so we know that there is an overlap but we are going to just draw it over here and the next one is 13 to 16 so over here we can clearly see that there are two places where there exist an uh in overlap but we don't know that yet right because the input is not sorted and we will have to identify it by ourself so how we are going to actually identify well essentially we are going to use the same logic we are going to check that whether the start value Falls in between any of the interval if it does we are going to determine that okay that this so if it does so we know that this particular interval is in conflict with that interval and then we are going to have to merge it so let's try to do that so over here we are comparing this value number four that is the starting value first of all we are going to check that whether four Falls between 11 to 15 well it does not so we are good with this whether four Falls between 7 to 9 it does not so we are good but over here four actually falls between 2 to 5 because uh 2 is actually less than four and four is actually less than the five so we know that four actually exist over here which means me there exist a conflict between this and this these two intervals so we will have to resolve this conflict how we are going to resolve this conflict well of course we are going to create a new interval so starting value is going to be the lesser of both of them so we are going to have a starting value that is at two and for the ending value it's going to be greater of both of them so the ending value is going to be six so we are going to create a new interval like this that is from this value number two to Value number six and we are good with this one so essentially we have merged these two into intervals so we can uh just simply mention that okay these two are merged or these two are taken care of so we we don't have to worry about them anymore and now we are done with essentially these two intervals right and we have in our answer we already have this uh in this new interval stored now let's see that how can we move forward so again for this 11 to 15 again we will have to repeat the same process so we check that whether this 11 Falls in between some uh interval so first of all we We compare this 11 with this 4 and six so it does not fall in between and also remember that because we are done over here doesn't mean that there could not be any more uh overlaps that we cannot take care of so we might have to do it so that's why we are going to compare again all the values so 11 does not fall between 4 to 6 11 does not fall between 7 to 9 11 does not fall between this 2 to 5 and 11 does not fall between 13 to 16 so so far we are good that okay this 11 to 15 that is is okay we don't have any issue with that now we again check for this 7 to9 so we check that whether this s Falls in between somewhere so 7 does not fall over here it does not fall over here it does not fall over here and it does not fall over here so this 7 to 9 is also good 2 to five we have already checked okay so this value number two two does not fall anywhere so we are good with this interval as well now again we are at this interval number 13 so for this interval number 13 it does not fall here but oh Falls in this place so we again have a conflict between this uh these two intervals so 13 to 16 that is one interval and second one interval is 11 to 15 there exists a conflict so because there exist a conflict we will have to resolve that and we can mark the these two has done so we are going to create a new interval that is 11 and 16 which means lesser values of the starting values and greater values of the ending values and this would be our new interval so we can add this to our answer as well so this would be uh 11 and 16 this is also our answer and now we need to check that amongst these intervals which were the ones that were not part of any overlapping Series so we know that this particular uh this particular value this particular value 4 and six was part of an overlap 2 and five was also part of an overlap 115 and 1316 they all were part of overlap which we have taken care of with these two values so the S and 9 was not part of any overlap so we will have to add that to our answer as well and uh we will add the S and 9 to our answer and this would be our final answer in this case now the thing is we are able to resolve this uh quite easily right we are able to generate the answer we know all the logic and blah blah blah we are able to identify the over overlapping condition if we calculate the time and space complexity in this case the time complexity is actually bigo of n Square why n Square because remember that for every single entity we are going to have to check all the remaining elements same goes for this one that for every single entities we are going to have to check for all the other remaining values so that causes n Square work the question is can we do something better over here and that rather than using this n Square can we uh bring down the time complexity and the answer is yes okay let's sort this given input so the sorted result would be now this is the sorted result now we need to identify that whether there exist a conflict or not so it becomes really simple what we are going to do is we are always going to check the first value and we are going to compare that whether the starting point of any value if that is actually less than the ending point of the previous element if that is the case we would be able to identify that there exist a conflict and always we are going to start checking from the second value because for the first value we know that the first element is already the smallest value so even if there exist a conflict between first two en entities this first one would always act as a starting point of the new merged uh variable or the new merg interval so let's try to do that and over here we will start with the second position we know that okay this one is four We compare it with the last element of the previous interval so last element of previous interval is five so we know that actually Four is less than five in this case we know that there exist an uh overlap between these two values because there is an overlap we can see that we need to check the we need to take the minimum value among among these two so minimum value is actually two so we create a new interval starting at two and for the ending values we will have to check the last values so the ending value in this case would be six so we will have a new interval like this so let's draw a new interval like this on this uh number system now we are already done with these two values now we take a look at this value number seven so again for the seven We compare with the last element in this case so 7 is actually greater than six which means that does not exist a conflict between these two values so we can start creating a new interval from 7 and now again for this 11 we are going to compare it with the last element so over here this value is 9 so 9 is actually less than 11 which means in this case there does not exist a conflict so 7 to 9 is an interval in its own we are good with this one now we have calculated this one now again over here this is 13 and this is 15 so we know that 13 is actually less than 15 so in this case there there exist a conflict between these two values so because there exist a conflict we are going to do the same conflict resolution Technique we amongst this 11 and 13 we are going to pick the smaller value so smaller value is going to be 11 so we pick this one and for this 15 and 16 we are going to pick the greater value so 16 is the greater value so again we are going to create an interval like this that is from 11 to 16 so essentially we have resol we have taken care of two overlaps that existed between the these two values and these two values but we we were able to identify them immediately why because all we have to do is at any point we just have to compare one value that was in the previous interval at any given moment and now over here we can just simply start iterating over whatever the answer we have found so far so in this case we can simply return the answer as uh [Music] 226 729 9 and uh 11 to 16 and this would be our solution now if you look at the look at the solution over here essentially all we had to do is just iterate over the sorted input once so basically to generate this answer we are only doing bigo of n work but the total time complexity in this case is actually going to be Big O of n log n and why n login because we will have to generate the sorted input from this given original input and that takes an log and time first of all we are going to sort the given input okay after sorting the given input based on this uh based on the starting values we are going to uh create a link list and we are going to uh store answer in this uh link list now we are going to iterate every single interval inside the given input so now we are going to check that whether we are at the first position or whether the given interval if that is in conflict or not so if that is not in conflict or there does not exist an overlap we are simply going to add it to our answer okay if that's not the case we have detected a conflict and the moment we detect a conflict we will have to resolve the conflict so essentially we are going to add the new interval that is merged okay and uh after this Loop ends essentially our answer should be in the answer link list so we can return that but in this case we need to return a two dimensional array so we will convert our uh answer uh list to a 2d 2D array okay let's try to run this code seems like our solution is working let's try to submit this code okay our solution works pretty efficiently I will be posting this solution in the comments you can check it out from [Music] there Hello friends we are still not employed by a Fang company so let's not stop lead coding till we get there today we are going to do nonoverlapping intervals problem and this problem is actually very similar to merge interval problems and insert interval problems I have solved both of these problems and I will be posting their links in the description so you can check it out from there like though this problem seems like it has not been asked by many companies actually this can be a very interesting uh post question after these two interview questions so uh usually like all the interval problems they are done in sync and even for this particular problem if we see it has been asked by Tech giants like Facebook Amazon Microsoft Bloomberg Apple Oracle Google byon which is Tik Tok and Snapchat and these are my dream companies so I'm paying my atmost attention I hope you also enjoy the video this is a lead code medium problem and we are basically given an array of intervals where every single entry has a starting point and an ending point that represents that particular interval now our aim is in this problem is that we need to return return that how many minimum numbers of intervals that if we remove uh from this given original input if we remove those then the remaining result should be uh such that all the intervals becomes nonoverlapping so we need to return the number of intervals that we need to remove so let's try to understand this problem with an example that is given over here and over here we are given some set of intervals and let's try to plot them on this given uh number series and see that what would be the answer answer okay so after plotting all of these our aim is to return our aim is to see that okay if there exist an overlap inside this given interval uh we need to return the minimum number of intervals such that all the remaining intervals becomes non-overlapping so over here we can clearly see that okay there exist an overlap between these points and the overlap is actually mainly caused by uh because of this particular interval and these two intervals so our aim is to remove the minimum number of intervals that uh that basically allows all the remaining intervals to become non-overlapping so in this case if we simply remove uh this particular interval that starts at position number one and ends at position number three this big one so if we get rid of this particular big big interval we will have a result where all the intervals they are actually not in collision with each other and they are not over overlapping with each other over here we can see that they uh they actually connect at some point but that is not an overlap like I know that in previous questions we used to consider this as an overlap but you can confirm this with your interviewer that with what approach they want to go so in this case we only get rid of this one interval that was existing and because we get rid of one we will return one that in this given input if we simply remove one interval we would we can determine that okay there exist uh one interval such that uh if we remove that then all the other intervals becomes non-overlapping now to generate the optimal solution the main thing is that we will have to determine that whether there exists an overlap inside the given interval or not now the previous examples we saw the input was already sorted but in the problem statement it is nowhere written that the input should be sorted so input could be something like this where everything is different value now the thing is first of all over here we need to determine that what are the intervals that are actually causing the overlap and then we can determine that what which one should be removed and whatnot blah blah blah what should be the strategy for that now the thing is uh if we plot these uh this given input on side on uh a number system uh we will get a result like this over here we can clearly see that there exist a conflict between uh these two intervals uh which is represented over here the thing is how we were able to identify that there exist a conflict we were able to identify I because the starting point of this particular uh interval was actually falling between uh the two values of some already existing interval so that is the condition we will have to determine if we want to find that whether there exist an overlap or not so over here suppose we get at Value number five and we want to check that whether five has an over has an overlap anywhere so five we will have to check all the other interval so five does not exist between this 2 to 4 so there is no overlap with this one it also does not exist between 8 to 9 so there is no overlap and it does not exist between 1 and three so that's why there is no overlap so now we are we are say that okay this 5 uh 57 has no overlap with any other uh interval now we check for this value number 2 to 4 so again we check the starting point for the value number two so value number two does not fall between 8 to 9 so there is no overlap but two actually falls between this 1 to 3 because 1 is actually less than the value two and two is actually less than the value number three so which means two Falls between between this interval so that's why the interval 2 to 4 and 1 2 3 are in between an overlap and then we will have to take care of that scenario now do you see a problem with this one and the problem is that I can see is that for every single value we will have to check all the other remaining values that whether there exist an overlap or not and that actually causes bigo of n Square time and this is unnecessary work like even just to determine that whether there exist an overlap or not we are actually doing big of n Square work which is like pointless uh there there exist a better approach and the better approach is uh that if we sort the given input and then we sort them based on their starting values things becomes lot a lot easier so let's see that what should be the sorted array now we have sorted this given original set of intervals and now we have all the values sorted so now if we see if we want to identify that whether there exist an overlap all all we need to do is we just need to compare any two adjacent values and the moment we compare any two adjacent values we can directly tell that whether there exist a conflict between them or not how can we tell them is that we only need to check that whether the starting point of any uh second interval compared to its previous interval if that is smaller then we know that there exist a conflict so in this case we can say that between this 1 and 3 and 2 and four there exists a conflict because this particular interval ends at Value number number three and this particular interval starts at Value number two so that's why there is a conflict U meanwhile if we see over here this particular uh interval ends at Value ends at Value number four and this one starts at Value number five so that's why there is no conflict so this is a very easy way for us to determine that whether there exist a conflict or not and if we see in terms of time complexity the time complexity for the sorted operation uh takes only big of n log n which is a big Improvement compared to the previous time comp complexity for this one which was big of n s okay now we have determined that how to identify overlap the question is that how to find that what should be the most number of nodes that we will have to remove and uh what should be the strategy for it so essentially there can be three different scenarios at any given moment the first scenario is that between two intervals there does not exist an overlap so if there does not exist an overlap there is no need for removal so we don't need to remove anything so we are good in this case this is like the most beautiful thing the second scenario is that we are given one interval that is clearly bigger compared to the second interval so essentially we can say that the second this second interval is actually subset of this given bigger interval so in this case things actually becomes pretty easy for us all we need to do is that we simply need to remove the bigger interval because there is a conflict between these two intervals right now which we can see but there could be possib possibility that there might exist some other interval something like this so say in this scenario if we got rid of this interval we still have to we will still find ourself to be having conflict between these two intervals and again in order to resolve that we will have to remove this one as well but rather doing this suppose in this scenario we only had uh two intervals like this and originally if we just got rid of this bigger interval then immediately even though there exist another interval somewhere down which was actually causing an overlap between this original interval still we would we will have to perform less remove operations so that is why uh the strategy should be that always remove the bigger interval now the question comes in scenario like this where the starting point of one interval is actually falling before and the starting point of second interval actually falls somewhere in between so what should be our approach in this scenario and in this scenario as as well uh what I'm suggesting is that we remove the interval that has the longer end point essentially if we at any point identifies ourself in this kind of scenario our strategy should be to remove the end to remove the interval with the end point that is greater so suppose we consider that uh the starting point for this interval is actually 1 to 3 and suppose we consider that uh starting point for this interval is 2 to 4 so in this scenario the the strategy we are going to use is that we are always going to remove the interval 2 to 4 why because the we are going to compare the end values and whichever interval has the greater end value we will decide to remove that particular interval so essentially we are using a gredy approach but by using this gredy approach what we are going to do is that over here we know that for this particular case for this particular interval we only had an interval that was causing an overlap over here but again the same thing could happen that we might have another interval like this where this particular interval was causing an overlap between this and this and also this so immediately remember our input is sorted so we are coming from left to right inside the number sequence so the moment we identify that whatever has the greater end point if we decide to remove that so even over here we already got rid of this one so even over here if that exist another interval that comes after this 1 2 3 still it would not be in overlap with this 1 2 3 and we will have to do less remove operation and this would be our ideal approach if we calculate the time and space complexity uh basically the time complexity in this case is going to be bigo of n log n uh and why n log n essentially uh doing this interal converting this interval from uh normal input to sorted input takes n log n time and then after that once we have this input given essentially all we need to do is just we have to iterate over the given input once because it is already sorted and then we can perform the remove operation and we can count the number of times we removed any interval so that this second part takes big O of n time so total work we are doing is actually big of n log n plus Big O of n but in general we can write this as big of n log n and in terms of space complexity we are not using anything extra so we can just say that it's a constant time space complexity at most at most we are just going to use couple of extra uh variables so first of all we are going to check that if the given intervals is empty so we are going to return uh zero okay if the that's not the case we will have to sort the given input and we are going to sort the given input based on uh the start in values okay after the Sorting we are going to initialize couple of variables so we are going to keep an keep a variable called previous to keep track of the previous element and uh we will initialize it to zero we are also going to have a variable called count to keep track of the number of elements that we will have to remove so we are also going to initialize it to zero and now we are going to run a for Loop that runs over the given sorted input and over here we are going to start it as int I is equal to 1 because we already have the previous value as zero for the comparision and remember that because the input is sorted at any given moment we are only comparing two adjacent elements inside the given interval so first of all we are going to check that if there exist an overlap between two adjacent elements and if there exist an overlap we are going to check that which element is having the greater end value so we we will update the previous counter based on that and if there exist an overlap we are going to increase our count this second if condition dictates that the If the previous uh interval is actually greater than the current interval we are at we will have to update the previous counter to next element and in any case we are going to increment our counter count variable and if this is not the case uh essentially we have found that between two adjacent intervals there does not exist uh any overlap so we are going to increase our uh value of our previous uh count previous variable to the current I so that we can use it for further uh implementation and uh once we are done with this Loop essentially this count variable should have our answer so we can simply return the count variable and and uh this should be our solution let's try to run the code okay seems like our solution is working let's try to submit the code okay our solution is working as expected and uh it's actually pretty efficient in terms of memory usage and even in terms of time complexity it's not that bad compared to other Solutions I would be posting this in the comments and you can check it out from there we are not going to stop till we get into Hello friends we are still not employed by a Fang company so let's un Stop Lead coding till we get there today we are going to do meeting rooms lead code problem and this is actually a lead code premium problem so uh if you want to know that what are the list of companies that have asked this question in this in their interviews that comes later in the video and I have provided the time stamp for that you so you can directly go and check it out let's understand the problem statement essentially we are given an array of meetings uh called intervals and we are given start time and an end time for every single Mee meetings inside this given array now we need to determine that if one person can attend all the meetings or not so let's try to understand this given uh Problem by an example so over here we are given three different meeting times and let's try to plot them on this number sequence that we have created so first meeting starts from zero time and it lasts until 30 minutes second meeting starts at uh 5 minutes and ends at 10 minutes and third meeting starts at 15 minutes and end at 20 minutes so over here we can click clearly see that there is no way possible for one person to attend all the meetings because there exist a conflict between this meeting and this meeting and there also exist a conflict between this meeting and this meeting and this meeting so because there is an overlap between intervals and essentially that's what we will have to determine in this problem so over here we can clearly return false that there does not exist uh any way possible for one person to attend all all the different meetings that are given in this interval now if we take a look at the second example and let's try to plot it in uh uh on a number sequence so over here uh we can imagine a number sequence like this and over here we are given one meeting that is that starts at 7 and ends at Value number 10 and second meeting starts at two and ends at Value number four so over here we can clearly see that it's possible for one person to attend this meeting and after that he can attend or he or she can attend this meeting so in this case we will return true and uh basically that's what we will need to determine now the the tricky part over here is that we will have to determine that how do we identify that there exist overlap between any two values so suppose over here in this example if we are given an another meeting that starts at 3 and ends at 5 something like that now in this case can we say that uh does there ex can one person attend all the meetings or not well we can clearly see that because there is an overlap between these two meetings meetings one person won't be able to attend all three meetings and over here we will have to return fals the thing is why we were able to determine that over here there exists an overlap uh so because over here if we see that the starting point for this meeting and ending point for this meeting is from 2: to 4: so that is one interval and if we look at this one the starting point from this for this one and this ending point for this one is 3 to5 so this is 3 to5 so over here here if we consider this particular um interval we can see that the starting point of this interval actually falls somewhere between any other interval that already exist so at any moment if we determine that the starting point of some interval if it falls between any interval and this condition is satisfied that 2 is actually less than three and 3 is actually less than four which means three Falls in between this interval so that's why we can determine that there exist an overlap and the moment we identify that there is an overlap over here we will immediately return false and uh this is how we are going to approach suppose we are given an input like this uh the different intervals are given and this is the number sequence that we are going to use now over here essentially if we want to determine that can one person attend all the meetings we will have to check that whether there exist a conflict or not so if we look at this first scenario previously we determined that how to identify an overlap so if we look at the starting value of this 20 we will have to check that whether this 20 exist in between some intervals so over here this is 10 to 15 so 20 does not exist over here uh this is 35 to 45 so 20 does not exist over here and this is 10 to 20 now this is this meeting ends at 20 and this meeting starts at 20 so this is also legitimate scenario because 20 is not part of this interval so that is why we can determine that okay this meet meeting is good like the starting point does not have conflict with any other meetings now let's see about this one so this meeting is from 0 to 15 right so does there exist any conflict between these two between this zero so 0er does not exist between this one uh Zer also does not exist over here and Zer does not exist over here so we are good same goes for this 35 that 35 does not exist between these two this one or this one so we are good but when we come to this value number 10 we can clearly see that this 10 actually falls between this 0 to 15 because this condition is satisfied 0 is less than 10 and 10 is less than 15 so over here we can clearly see that there exist an overlap between these two elements and we can clearly we can immediately return false so this approach would work perfectly fine but what is the issue with this approach the issue is that this takes bigo of n Square time why we of n Square time because remember for every single element we will have to check all the remaining elements based on the starting point uh same goes for this one same goes for this one so that's why we are doing n Square work so this work can greatly reduce if we just sort the given input uh based on the meeting start times and let me show you how so let me clean this up and let me sort this given input so now we have the sorted input now in the sorted input if you take a look at it we are actually we are actually able to determine that whether there exist an overlap immediately how all we need to do is we'll need to compare the starting point with the ending point of the previous interval if the starting point is actually less than the ending point of previous interval we can determine that this meeting actually starts before the previous meeting ends and immediately we can identify that whether there exist an overlap or not so this is basically our solution like in this scenario we can clearly see that the moment we are in the meeting from 0 to 15 so there is a meeting going on from 0 to 15 and before this meeting ends there is there is another meeting that starts at 10: and lasts up until 20 minute Mark so there is an overlap over here and immediately we will return false in this case so this approach actually works and uh it is more efficient than the previous approach we suggested uh why it is most more efficient because if we calculate the time complexity the time complexity in this case is going to be biger of n log n for the Sorting operation because from this given input first of all we'll have to create a sorted input and once we are done with that uh if we want to identify the overlap we only need to check any two adjacent values at any given moment and the moment we reach to the end point and we don't find any issues we can return true or if we find any issue we can return false before that so this takes B of end time so total time complexity can be considered as B of n log n and uh in terms of space complexity we are not using any additional space so we can say that we are only using constant time uh to run this problem and uh this is the Final Approach now let me show you the list of com now let me show you the list of companies that have asked this problem and uh if you are not interested you can directly go to coding so essentially companies like Amazon Google Facebook they have all asked this problem recently and Microsoft and Ware they are also really popular well-paying companies that have asked this problem also companies like Bloomberg Adobe and eBay that one of my dream companies that I want to join in apart from the original these Tech Giants so first of all we are going to sort the given input based on the start times of the given intervals after sorting we will have to iterate over all the sorted intervals and we are going to check that whether there exist an overlap or not we are going to check that whether the uh end point of any meeting is greater than the starting point of next meeting if that is the case we are going to return false immediately and if this Loop ends and we are able to reach to the last element we are going to return true that there does not exist an overlap and now let's try to run this code okay seems like our code is working let's try to submit the code okay our submission works and uh the code is actually pretty efficient and uh I would be posting this in the comments it is not too many lines of code and this problem is very similar to the previous three interval problems that we had we have done so I would be posting them in the comments you can you can check it out from [Music] there Hello friends we are still not employed by a Fang company so let's also bade Cod until we get there today today we are going to do a lead code premium problem and uh you can clearly see that this has been one of the most popular lead code premium problems this has been asked in companies that companies like Amazon Facebook Google Bloomberg Microsoft Oracle Walmart Uber Twitter Apple Goldman Sach Tik Tok and by dance and also some other companies like eBay adob suige uh they all have also asked this question uh fairly recently so my aim you all know that I want want to get a job at any top tier Fang company and that's why I'm making these videos so I'm paying my atmost attention and I hope you also enjoy the video lead code medium problem and it is one of the most popular problems on lead code if you see the like to dislike ratio also the name is meeting rooms 2 so basically it is the next version of the original problem meeting rooms that I have already solved over here so you can check it out from there now in this given problem we are basically given an array of meeting times called intervals and we are given a start value and an end value and obviously start value is always going to come before the end value like as it should be now we need to say that based on the given uh number of uh meetings how many number of minimum conference rooms we are required so that all the meetings can be accommodated and we know that for any single meeting we need at least one conference room and when that meeting ends that conference room can be used for some other meeting so suppose uh say for example we have a meeting that starts at uh at 5 uh and ends at 15 minutes and we have another meeting that starts at let's say uh 17 minutes and ends at 27 minutes something like that so in this case if we only have one conference room we are still good why because first of all this meeting will take place all the attendees will attend this meeting at 15 this meeting is going to end and then they are going to leave away from the this uh meeting and then these new people are going to attend the meeting in the same conference room so in this case we can clearly determine that okay with one conference room we are we are we are sufficient to complete all the meetings now but problem comes when say for an example we have a meeting that starts at 0 and ends at 30 minutes uh I'm using this original example that is given so suppose we have we have a meeting that starts at 0 minute and ends at 30 minutes we have another meeting that let's say starts at 5 minutes and ends at 10 minutes and we have another meeting that let's say starts at 15 minutes and end at 20 minutes so something like that so essentially over here we are having three different meetings and now for these three meetings how many minimum number of rooms we need to accommodate all the uh meetings so clearly we can see that essentially there exist an overlap between this this meeting and this meeting there also exist an overlap between this this meeting and this meeting so because there exist an overlap that is causing us to create to have more than one rooms because at any given moment two meetings cannot be two two meetings are happening at the same time but they cannot be placed in one conference conference rooms so now we will have to determine that how many number of conference room we need well we will need in this case we will need two conference rooms why two conference rooms if we look at this start time and end time for all the meetings in initially let's say we have a conference room like this so initially this first meeting takes place which starts at this 0 minute right so let's say that okay this minute is this meeting is being taken place over here now when we reach at this time number five we know that another meeting also needs to be started but this conference room is also already occupied so we cannot use this this conference room so what we'll have to do is we'll have to use another conference room and uh let me draw it over here so we will have to use another conf conference room to accommodate this meeting over here now at this five time number five we started the meeting but we noticed that at time at Value number 10 we also finished this meeting which means that now all the folks that attended this meeting they are actually coming out of the conference room and now this conference room is empty but this conference room is still occupied with this original ongoing meeting so that we will have to take care of so at value number 10 we already emptied this uh conference room but again we start seeing in this order so we can find that at time number 15 we still need one more conference room to attend the meeting so we check okay this conference room is already occupied so we can't do anything but this conference room is empty because this meeting has already been completed which means we don't have to worry about it so this meeting at that starts at time number 15 needs to be placed on this second conference room again and then it ends at minute number 20 so at 20 minutes all the folks they empty the this conference room so again this conference room is now empty now there is no one but this meeting is still going on and when the time clock hits 30 minutes we can see that okay now this particular conference room the first conference room is also going to be empty and folks are going to leave it at time number 30 and this is basically the approach so at any given moment the maximum number of conference rooms we are using to accommodate all the meetings were actually two so in this case we will need to return two as our answer the question comes that why we were able to generate this to why not some other value and how do we programmatically solve this problem well the approach is actually quite simple that over here what we what we needed is only three only two things uh the first thing we needed is that at any point what was the start Point what is the end point and based on the start and end points we can actually uh come up with some very interesting results so if we see over here in this example what we were doing is that at any given moment we are iterating over this time sequence and based on the starting point of the meeting and ending point of the meeting we are either occupying the room or we are emptying the room and just by keeping track of those two activities we can determine that what is the minimum number of rooms that we are that we need in order for us to accommodate all the meetings let me show you how so over here again keeping up with the same example so let's say that in this example we already have the start and end times of all of them so what we can do is we can have two arrays so first array would be for starting values and second array would be for ending values and we are going to sort both the arrays based on the timing so over here the Sorting values would be that what are okay so what are the starting points starting points we have over here is 0 5 and 15 so we have three starting points originally and over here you can see that they are in sorted order but if you look at the original input we can't see them in sorted order order like uh they can be jumbled up or the values can be given in any order right so first of all we will sort everything and then that sorting is going to take big of and log n time so that is uh some activity that we will discuss when we come to the time and space complexity so initially the Sorting position currently this value is 0 5 and 15 okay let me get rid of this extra space okay now for the ending values the ending values are uh 10 20 and 30 so again let's sort sort based on the ending values so 10 uh 20 and 30 and now what we are going to do is at any given moment we are going to check both of these uh arrays and in among these two arrays we are going to see that what is the minimum value amongst either starting value or ending value and we are going to keep a count or keep a variable called meetings and we are going to increase the value based on whatever the results we find over here so let's try to do that so initially we we start we compare these two values we see that okay zero is minimum amongst these two so because we are starting a new meeting which means we will have to occupy a room and because we have to occupy a room what we are going to do is we are going to do meeting Plus+ so essentially the the value of meeting was originally zero so we are going to keep the value as one now we are going to now we are keeping the value as one what we are going to do is we are going to iterate over so this we are keeping at this because this this has not been updated in the ending value but in the starting value this zero has already been taken care of so we ignore this case and now for the starting value We compare this uh value number five so again we compare this value number five with this value number 10 we see that okay the smaller value amongst these two is still the starting point in the starting area and because we are starting a new meeting which means that we haven't completed any meeting but we are starting a new meeting so because we are starting a new meeting we'll still have to add the value of meeting so currently the number of conference rooms we will need we are going to increase it to two and by the way this you can call it consider as meeting rooms I just named it meeting just for Simplicity okay now again we uh we are done with this five so again for the start value we increment and over here we are still at this position number 10 again we compare this 15 and 10 so over here we realize that this 10 is actually smaller than 15 which means we are ending a meeting before so now because we are ending the meeting so we we we will jump on this ending array now we will come to this place and because we ended a meeting which means we will have to subtract the value over here so what we are going to do is rather than having to we will reduce this value back to one but and so now we are at this 15 and 20 so we compare both the values and we realize that okay this 15 comes first so we are starting a meeting now so because we are starting a meeting we we'll again do Plus+ so now this one becomes two and uh we compare this meeting with this answer so both are both values are two so we don't need to update anything and uh that's why uh over here we are done with this case so now there is no more place to start the meetings so actually we can end over here why because over here the moment we are going to like reach this and this value all we are going to do is we are simply going to reduce the the value of this meeting parameter back to one and then again back to zero so there is no point in us for doing all this work if the starting uh array has already been dealt with and this would be our solution uh like this is a very simple solution to understand and easy to come up with and this is also very optimal and it solves the problem efficiently so let's see that what would be the time and space complexity the time complexity in this case is going to be bigo of n log n so this is initially for sorting as I mentioned earlier plus bigo of N and this big of n is to iterate over the start and end array so uh in general we can write this as big off n log n Only and uh now we are done with this one uh in terms of space complexity for the space complexity it would be biger of 2 N because we are storing two arrays and in the both arrays we are storing some n values so what in general we can write this as big of n as well and uh this would be the optimal time and space complexity first of all we are going to check that if the given uh array of intervals is empty or not if it is empty we are going to return zero that is not the case we are going to create two integer arrays start and end and for both the arrays we are actually going to fill out all the values in the start where start array and end array once that is done we are going to iterate over the given input and uh from the given intervals we are going to fill out the start and end array once this is done we are going to sort the given start and end array and once sorting is done uh we are going to initialize a couple of pointers so we are going to name them a start pointer and an end pointer and we are going to initialize the values as zero and these pointers are going to be used to iterate over this start and end array and once these two are done we are also going to have a variable called result uh to keep track of the number of meeting rooms that are needed and we are also going to initialize that to Z and now uh we are going to run a loop but remember that we only need to run a loop until the start array has some values so we are only going to iterate over the start array because once start array is done the result value is always going to go down and at any point we are going to check that whether the current start value is actually greater than or equal to the end value or not if that is the case we will have to update the end array and the reason we are doing it is suppose we are given a couple of arrays like this that uh a meeting starts at Zer and ends at 10 minutes and there is another meeting that starts at 10: and ends at 15 so in this case we can actually use just one uh room or one conference room to iterate over why because first meeting has to end first before the second meeting starts this is a condition that is given and we are going to use that hence if this is the case we are going to decrement the number of uh result that is and we are going to increment the end pointer and if that is not the case so which means that we essentially have a starting a meeting starting before the previous meeting ending and in that case we will always have to increase the number of rooms needed so we can simply increase the result and we will also have to update the starting pointer and at the end uh once this Loop is done we can simply return whatever the result we found let's try to run this code seems like our solution is working let's try to submit this code and we are actually solving this problem way faster than lot of other Java Solutions and uh you can see it over here so I would be posting this code in the solution uh in the comments you can check it out from [Music] there Hello friends we temp by Fang company so let's not stop lead coding till we get there today we are going to do reverse linkless problem and essentially this is a very easy but very important lead code problem as it has been asked at bunch of different companies so this problem has been asked in companies like Amazon Microsoft Apple Bloomberg Facebook uh Google Nvidia Adobe Uber and also IBM eBay PayPal other companies like Goldman sax and then bite dance and a few other companies so I'm paying my atmost attention I hope you also enjoy the video Hello friends I got my results back from the from my Goldman Sachs interview and I didn't clear it which means that I have a long way to go and I still have to do lot of work on my coding and Lead coding skills this is a lead code easy problem and it is one of the most like problems on lead code uh basically we are given a head of a singly link list and we need to reverse the given list and then we need to return the reverse list so problem statement is quite easy to understand in and even if we see the example the example is also quite easy to understand basically we are given a list like this 1 2 3 4 5 and we are at this position and we are given this head value of this link list and basically we need to return the reverse list so in this case the reverse list is going to be 5 4 3 2 1 so essentially we are just iterating over in this direction and this is what we need to return now the thing is there happens to be little bit more complexity because we are told that this is a singly link list so in singly link list all the elements are just stored in a single manner which means that this element only knows that what elements comes after it it does not know that what is the element before it that is pointing to this position so this is the concept of a singly link list and we'll see that how can we solve this problem okay so we need to reverse the link list and we are told that the link list we are given is actually a singly link list the thing is that what is the property of a singly link list that the link the every node in the given link list actually has the value of that particular node and also has the pointer towards the next node inside the link list and whenever we encounter that next node is actually pointing towards n null value we can determine that this is the end of of the given singly link list the issue over here is that we know that at any single position what is the value after it using this next pointer but we don't know that what was the value before it there is no way for us to identify this particular item which means that our aim is to find that how to reverse this link list and in order to reverse this link list what we can do is rather than pointing towards the next pointer we can if at any given position for all the nodes if we just point it to towards the reverse Direction and basically start our linkless traversal from the last node uh we can simply return the reverse link list immediately and this is the approach we are going to take now the question comes that how at any point we can actually uh originally we were pointing on this side how can we start pointing on the reverse direction from any single node and in order to do that what we'll have to do is we'll have to keep track of the previous character or previous node as well and apart from keeping track of the current node so the approach we are going to use in this case is that every single position suppose we are at this element so this is the current element we are at right from this current element we know that how to get to the current do next which means that how to go to the next element we already know that know that the question is we don't know that how to go back so what we are going to do is we are going to keep track of a previous character or previous no node that will always be behind this current node so in this case this would become our previous node and all we will have to do is that over here the current do next is actually pointing towards this node three so rather than current do next pointing towards this node we are going to have current do next Point towards the previous element and we are going to do iteratively for all the values so initially at at the beginning this would be our previous and this would be our current so over here the this value will be pointing towards this on this side so null value now again we will switch our values for previous and current so this would become our previous and this would become our current and again we will flip the value and again we will repeat the same process so this would become our previous this would become our current again we will flip the direction and at the end this would become our previous and if we see the previous do next element it would be a null SE one so we would know that okay this is the end of the original link list so this has to be the start of the new link list and then we can just start iterating over which means that we would have taken care of all of these pointers and now we can simply return the reverse link list in this fashion and this would be our answer so if we see the time and space complexity in this matter the time complexity for this one would be biger of N and the space complexity would only be big of one because at any given position all we have to do is just keep track of couple of variables nothing more than that and that that should take care of all the scenarios so first of all we are going to create a new list node and we are going to name it as previous and we are going to initialize the value as null and we are also going to create a list node called current and we will have it start at the head value okay now we are going to iterate over the given link list so while current is not equal to null we are going to keep running in the loop and inside the loop uh essentially we have to uh flip the values between current and previous so what we can do is current uh do next would be our previous node and then for the previous node we will have to flip it to current node and for the current node we will have to go to the next node in the original single link list so for that we will have to create a temporary variable so let's create a new node and we are going to name it as Temp and we are going to store the current. next node over here and now for the current node we are going to point it to this temp because notice because remember over here we are updating this current. nextt value so that's why okay and uh yeah I think this is it after this Loop ends uh we should have our link list derse so we can simply return the head as previous uh variable and uh this should be it let's try to run this code this seems like our solution is working let's try to submit the code okay our code actually runs 100% faster than all the other solution because it's running in constant time and uh I would be posting this in the comments you can check it out from there thank [Music] you hello friends we are still not Ed by Fang company so let's not stop lead coding till we get there today we are going to do link list cycle problem so basically it is a problem to detect cycle inside the link list and this problem has been asked by bunch of different companies so let's see that what are my dream companies that have asked this problem uh it contains the companies like Amazon Microsoft Shopify Goldman sex that we recently got rejected at uh Google Bloomberg Apple Facebook Yahoo plunk and eBay so these are some of the companies that I'm really interested to get a job into and uh that's why I'm paying my utmost attention I hope you also enjoy the video so this is a lead code easy problem and it is really simple to understand basically we are given the head of a link list and we need to determine that whether this link list contains a cycle or not now first of all we need to understand that what is the property of a link list B basically inside the link list we are given two items first item we are given some data point that represents that particular node inside the link list and we are given the information about the next node inside the given link list and that is how link list keeps on programing placing so we will keep this in mind I like hopefully everyone should be familiar with this one and now the question is that we need to determine that whether inside our given link list does there exist a loop or not so suppose we are given a link list like this and we in this case we can clearly see that there exists a loop between this four and this two the question is that how do we detect that there exist a cycle and uh first solution that comes to mind is the solution that we have been using at different graph and uh some other problems so basically what we can do is at any moment we are given this head position so what we can do is we can create another data structure uh called hash set and inside this hash set we are going to keep track of all the visited nodes uh that we have passed so far and what we are going to do is initially first of all we are going to check that whether at any given node we are currently at if that exist inside this V visited hash side or not if it does not exist we will add it to this visited hash set and we will keep moving forward so at any moment if we encounter the same node we can clearly determine that there exist a cycle so in this case first of all we will check that whether this one exist in the visited haset it does not exist so we will add one over here then again we check for two two does not exist so we will add two over here then again we check for three three does not exist so again we add three over here and again we check for four so four also does not exist so we will add all four entries now from this four the next value it points to it actually points to this value number two and whenever we check that whether this two exist or not we can clearly see that two exist over here and we can immediately say that because we came back at a node that we have already visited before inside the hash set we can determine that there exist a cycle and in this case we will return true that okay yes there exist a cycle over here and uh that would be our solution now this solution is perfectly fine it works okay if we calculate the time and space complexity the time complexity in this case is going to be bigo of n because we are iterating over all the nodes just one one time and the space complexity in this case would be bigo of n as well because we are using this additional visited hashset uh to detect that whether there exist a cycle or not the next thing that your interviewer is going to do is he is clearly going to ask that solve this problem without using this additional uh item uh additional space and the space complexity should be bigger of one so let me show you is the most optimal solution where the space complexity would be bigo of 1 and time complexity would be bigo of N I have a short announcement I have recently created a GitHub repository uh the link is in the description and I will quickly show it to you as well so this is the repository that I was talking about and I have left it public so anyone can access it it contains list of solutions of all the lead code problems that we have solved so far uh so you can click on any problem and you can go to its solution and it will contain the Java solution for that particular problem that is acceptable at lead code our aim is to see this list growing and uh I would be posting all the solutions that I solve and uh hope it helps other fellow coders and uh our aim is to get into Fang and hopefully this can be a big stepping stone towards that direction basically what we are going to do is we are actually going to have two pointers that iterate over this given link list and we are going to have a slow pointer and a fast pointer and the aim is that at any moment this fast pointer is always intended to stay ahead of the slow pointer and if we identify that this fast pointer actually reaches back to this slow pointer we can determine that there exists a cycle let me show you how so what we are going to do is we are at this head position so we are going to first of all initialize our slow pointer and our fast pointer at these position positions so uh slow pointer would be at the first position and fast pointer will always start at the second position now we are at this position we are going to have one more condition that slow pointer will always do one jump so slow pointer will always do slow plus one so it will always go to next node but for the fast pointer we are actually going to have fast pointer do two two jumps so fast pointer is going to do fast pointer plus two nodes two node jumps and let's see that how things will turn out in this case so initially we are at these positions now this first pointer makes a makes two jumps and slow pointer makes one jump so their corresponding position change so slow pointer will reach over here and meanwhile fast pointer actually made two jumps so fast pointer will end up over here now the in the next case the slow pointer again is going to make one jump so slow pointer will reach over here and this fast pointer is going to make two jumps so fast pointer will make one jump over over here and second jump it will reach over here so in this case fast pointer will also reach at this place and slow pointer also reached at this place so over here we determine that this value at this fast is equal to value at the slow node and because we identify this condition this can only happen true if there existed a cycle somewhere and because there existed a cycle we are able to determine that okay there exist um like this fast and slow reach at the same point they met at the same node so that's why there for sure there has to be a cycle uh what happens if there does not exist a cycle so so say for an example in this case uh again let's just go back to this scenario that okay this is the list list we are given and there does not exist a cycle and let's add one more node over here we'll just uh name it number five and this is the whole link list we are given now in this case again this is the slow pointer this is the fast pointer and we are always going to have a terminat condition that either if slow reaches at the end or if fast reaches at the end at any given moment we reach to the end of the list and we find that the value of this slow or fast pointer is actually null if that is the case we can determine that uh we are able to successfully Traverse over the entire link list without detecting a cycle and that would be our final solution so in this case uh slow is here fast is here let's make one jump so again so now the slow would be here and fast would actually be here now again let's just make one more jump so in this case uh slow would be here but fast would have already crossed this portion so fast would be somewhere over here the node is null which means immediately we can determine that because we find that the fast pointer was at null value that there does not exist a cycle in this case and we can uh we will return false in this scenario so this would be the most optimal solution for this problem it is very easy and very trivial to understand as long as you get this trick and if we calculate the time and space complexity the time complexity would be bigger of n because in any case we will have to iterate over all the nodes in terms of space complexity apart from using couple of uh additional variables we are not using any more space so we can say that the space complexity is actually constant time we go of one and this would be the most optimal approach okay so first of all we are going to check that if the head is equal to null we are going to return false so this would be an edge case that we took care of now we are going to create two list nodes uh one is for slow and we are going to initialize it to the head position and second one is fast and we are going to initialize it to uh next POS uh the second position okay now we are going to run a while loop that while slow low is not equal to null or uh fast is not equal to null we are going to keep iterating over and we are going to check that if the fast. next element if that is null we can also return false immediately if that is not the case if at any point we identify that the value at fast is equal to value at slow if that is the case we can immediately say that there exists a cycle and we can return true otherwise we'll have to update the counter so slow would be slow. next so because we are incrementing slow by one value uh but for fast we are actually in incrementing fast by two values so fast would be fast. next. next and uh that's it and if at any moment we are able to get out of the loop we can always return false and uh this should be the solution let's try to run the code okay seems like our solution is working let's try to submit the code oh okay we are going to check that if fast is equal to null or fast. next equal to n okay seems like our solution is working and it's actually pretty fast it's actually uh it runs in 0 millisecond so 100% faster than all the other solution and even in terms of memory usage we are beating out most of the people because over here we are actually ending our Loop early uh by using the these both these conditions and uh again inside the GitHub I will be providing the solution to all these problems so you can go and check it out over here I will be posting this link in the description and I hope this video helps uh all the other communities that I I feel so dear for and uh not stopping till we get into Fang see you next Hello friends we are still not employed by a Fang company so let's not stop lead coding till we get there today we are going to do a linkless problem called merge two sorted list so this problem has been asked in Tech giants like Amazon Facebook Microsoft Apple Uber Google uh Bloomberg B dance which is Tik Tok and then companies like Yahoo LinkedIn indeed and Roblox and also IBM plus uh recently in news Twitter so I am paying my atmost attention I hope you also enjoy the video this is a lead code easy problem and it is also one of the most like problems on lead code uh if we understand the problem statement we are basically given the heads of two sorted link list uh list one and list two and we need to merge these two link list in one single sorted list so this is the important part that it has to be sorted and in the end we need to return the head of the merge link list okay let's try to understand this problem with an example so over here we are given two list list one and list two and we can see that both of them are increasing in ascending order and now we need to create a merge list from this so this is the merge list that has been created Even If You observe the merge list the ascending uh property is maintained so which means that the merge list is also sorted and how it is sorted it basically it has taken values from whichever the nodes that had the smaller value so in this case these first two values were one one so we can put any choose from any one right now this second Val so and now we are done with this value one and one over here now we need to take care of this 2 and three so when we compare this 2 and three we find that okay this value number two is actually smaller so that's why we add a two node over here and now we are done with this one and now we still have to compare this three with this four because remember we are not done with this three yet so we identify that this three is actually smaller so in this case we are done with this three and we add the three node over here in the our merge list now the values are four and four so again we just enter the values four and four and now we should be done with all of them and this is the new list that we have created and in the answer we need to return the head value so we would be returning this value as the part of the answer so this is the expectation of the problem let's see that what could be the potential solution so let me dra quickly draw just one more list and we'll see that what should be the approach let's see that what should be the merge list at the end so I'm denoting this as M now uh we are going to compare two values at any given moment and uh we are going to have two pointers so let's say left one and left two we are going to keep track of them so over here both the values are same so we can enter any value so we will add one over here and then again one over here because both the values are same so you can put condition to choose any one now we are done with both of them and because we are done with both of them we'll have to update the values of this L1 and L2 so we are going to update its values so now this becomes our L1 and this becomes our L2 again we do the comparison now in this case we find that okay this value is actually smaller so because this value is smaller we are done with this element essentially we will add that value to our merge list and because in the list two we found that that value was smaller we will update the list two pointer to go to its next element so we'll do a jump like this and now this becomes our list two and again we will compare list one and list two elements so in this case we find that value at list one is actually smaller so we will add it to our solution and uh again we are done with this one now so we will update the left one pointer so left one pointer would fall over over here and now again we will compare both of these values so in this case we find that okay this value is actually smaller so we'll add one more node to our merge list 4 and again update the value of list two so list two actually goes over here and this is done so this is list two and now we compare this value with this value so over here we would find that okay this five is actually smaller so now we will have to update the value five over here now because we have updated the value five over here if we do a next jump for this list one we identify that this node is actually null so the moment we identify that there exist a null node there is no point of us moving forward in this direction because we are done and essentially whatever the remaining values are still pending in the L2 they directly needs to be appended on uh this merge list why because so far all the elements we have entered they were entered based based on the some sort of relative uh comparison but once we are done with uh one Loop there is nothing for us to compare so because there is nothing for us to compare whatever is the remaining portion we can directly add over here so we uh over here we only have one node 8 so we will directly add the node 8 over here but even if we had some other nodes over here they all would be directly appended without any issues I hope this makes sense and this actually would be our final solution uh now what are what would be the tricky part in this one the tricky part in this one would be that because in this merge link list we are iterating over here so at the end we would be somewhere at the last position and remember we need to return the head node so what we what we will do is we are going to use a trick we'll create some dummy node and this dummy node would be actually as the head node we will just assign some random value whatever one two whatever this does not make any difference and the next value of this would be pointing to the merge do next and that would be the trick so at the end we will just return the next value of this dummy node and then that would be the start point of our merge list so if we calculate the time and space complexity in this case the time complexity would be Big O of n actually because uh we have we will have to iterate over all the nodes that are given in both list one and list two so actually it would be bigo of m + n where m is the total number of nodes given in list one and N is list two but in general we can write it as big of M plus n and in terms of space complexity we are only using couple of extra parameters to store the value and anyways we will have to create this merge list so we wouldn't consider that to be an additional space being used so we can say that we are actually solving this in constant time and this would be the uh most optimal solution so first of all we will create create a list node and we will just call it as dummy and uh for this dummy node actually we are going to use this dummy node to keep track of the first element inside our merge list now we will create another list node and we will call it as a merge list so just let's just call it merge and we are actually going to initialize it with dummy value and now uh we are going to run a while loop now we are going to run a while loop up until the point that when we have elements in both list one and list two so at any point we encounter that list one or list two either of them is empty we are going to uh break out of this while loop and inside the V Loop we will have to check that which one is a smaller value and suppose list one is uh smaller than list two value so in that case we will have to add it to a over merge list so now we will add uh the value to merge list but we are actually going to add it to the next element inside the merge list and you will come to know that why we are doing it so let's just do that and now we will also have to update the value of list one so this should be list one and now let's update the value of list one okay and if that is not the case which means that we will have to add the value from list two and after we break out from the loop we will actually have to uh see that which list still has values remaining because remember at any point we encounter null in any either list one or list two we break out of the loop which means that there could be still uh more elements that needs to be append to this merge list and that should be taken from uh whatever the list that is still not empty so we will just put a condition if list 1 is equal to null if that is the case we know that we will have to append the value of list two and if that is not the case which means that list two is empty and list one still has elements so we will add list one to our merge list and once that is done uh we need to return the head of this merge uh link list but the problem is that now we are actually at the end of this merge list so how can we get the head of this well actually we can get the head of this is by using this dummy node that we created because remember that dummy is actually the start value of one and dummy. next would be the value of merge. next so that that's why we actually have to create this additional node and uh in the return we are actually going to return dummy do head and uh oh sorry dummy. next and this should give us the head value so let's try to run this code okay looks like we made some mistake oh uh we are not uh we are not updating the value of merge element because at every iteration the merge node also needs to go to the next element because we are already adding a one value to this merge link list so now let's try to run the code okay seems like our solution is working as expected let's submit this and our solution is actually 100% faster than all the other Java Solutions so Hello friends we by F company so let's not stop lead coding till we get there today we are going to do merge K sorted list problem and this is one of the most asked linklist problem and uh if you just see that the number of companies that have asked this question is really huge uh there are companies like Facebook Amazon Microsoft Google Apple bite dance uh LinkedIn Bloomberg Tik Tok and uh more companies like uber Goldman Sach Lyft Twitter Yahoo wish plantier Tesla Roblox Pinterest Airbnb so these are my dream companies so that's why I'm paying my utmost attention I hope you also enjoy the video this is a lead code hard problem and it is one of the most like problems on lead code but in my opinion this should have been a medium problem and I'll tell you why now if we understand the problem statement basically we are given K distinct link list and each link list is sorted in ascending order in the answer we need to merge all all the link list that are given in one single sorted link list and then return that merge uh link list so this problem is very similar to a previous problem we did merge to uh sorted list so you can find that solution over here and if we see the example for this case uh basically we are given bunch of different link list and all of them are sorted so uh if we see this first example we are given link list like and now we need to sort all of merge all of them in one single link list and that single link list needs to be sorted so if we see the answer the answer in this case is going to be that okay the smallest values are 1 one so they will always come first so it would be 1 one then we will have 2 3 4 4 so 2 3 4 4 and then we will have five and six and this would be the answer that we need to return in this case that is the combination of all three uh link list basically in the Brute Force what we can do is uh we are given few distinct number of lists so it could be like list one list 2 list three all the way up to list K these are the list we are given in the input what we can do is whatever the number of nodes they have we can take all of those nod we can combine all the nodes we can put it in a giant list let's just name it as merge list in the merge list initially we put all the values together once and then all we need to do is if we just sort this given merge list uh then the sorted list would be our answer and basically that's the that's the whole solution this solution would work perfectly fine and we then in the end we can just return whatever the sorted list we have found uh okay what could be the issues with this problem like I I won't find too many issues because this is also a decently good enough solution if we see the time and space complexity in this case the time complexity is going to be big of n log n why n log n because initially we will have to do big of n work to iterate over all the nodes inside the given link list different link list and merge them together uh so that takes and big go of end time and plus it takes bigo of n log n time to sort the given uh list so overall we will write them as big of n log n and in terms of space complexity the space complexity in this case is going to be bigo of n because we need additional room to space to store one additional parameter uh of all the merge list before we sort it let's see that what could be another solution so in terms of the second solution uh suppose we are given three different list like this in this case k is equal to 3 because we are given three distinct values what we can do is at any point we can denote three three different pointers to each location let's name them L1 L2 L3 and what we are going to do is our aim is to find the minimum value we already know that for these three values all the values are already in ascending order so the approach that comes to mind is okay let's just create our merge list and inside the merge list at any point we are going to compare all the values between this L1 L2 and L3 and whichever is the smallest we are going to pick that one so in this case Okay the smallest value is one so we'll pick one over here and then we will update the value of L1 okay so this is already done uh L2 and L3 will still remain same so now we have these three values that we need to compare so the smallest value is two so again we'll update the L2 and uh this we are done uh so now we have these three values to compare so now again we'll add value number three and then we will be done with this one and we'll update the value of L3 so let me just do it do the whole thing and uh hope you you would be able to understand that what how how am I doing it okay so this is how we will progress and this would be our final merge list so we can simply return this one so this approach also works fine uh there is there are no issues with that if we see the time and space complexity in this one the time complexity actually becomes so suppose if we consider that all the elements in this L1 L2 and L3 the total number of nodes are given n so we can see that the time complexity is going to be Big O of n * whatever the this K is given so in this case k is three so we can do n * K so it's going to be n * K and this would be the time complexity so why n * K because remember in order for us to enter any single element we will have to do K work we will have to compare all these three elements and at any point we find the smallest element we will have to update that value so suppose if K is equal to 1,000 then we might have to compare 1,000 elements as was at once so that adds a little bit of complexity to it so is this approach good uh this approach is okay but not very good because as I mentioned that if we are given million elements as k then uh basically what we are doing is just big of n Square work while we already know that even in Brute Force we are able to solve this in big of n log n so why do we need to do n Square work okay so there is no point in doing that uh let's see that what would be the most optimal solution okay so suppose we are given three list like this and I know you are thinking that why I only put two elements in each list I'll just show you why uh basically what is our aim our aim is to find that all the nodes that should be merged and that merge merge list has to be in ascending order right we need to maintain this ascending order so one of the best thing that should come to your mind is that is there any data structure that already exist where no matter how many number of element you put inside it whenever you start taking the elements outside they should be following this ascending order property and yes there exist a predefined element or data structure that can do it and that name is actually Heap so if we maintain a Min Heap in this case uh so the if we add all the values inside the Min Heap and then we start taking values or the nodes outside of the Min Heap it is actually actually going to give us the sorted list uh where it is is the combination of all the merge elements let me show you how so let's create a priority q that will represent this Min Heap okay and now let's start adding elements one by one so first We'll add four and seven okay next element is three so the moment we need to enter three we will have the priority Q is going to fix by fix itself so now it is going to be 3 4 7 okay now we need to enter eight so eight we can enter over here now this this node we have to enter is one so again when we need to enter the one the priority Q is going to adjust itself so now the solution is going to be 1 3 and the last node we need to enter is 11 so this we have all the elements inside our priority q and now because we have this priority Q set up what we can do is now we can start pulling all the values from the priority because remember the property of priority Q is that all all the value values are entered at the back and they gets out from the front uh so now we will create new merge list now inside this new merge list all we need to do is just keep on adding all the elements that are coming out of this priority queue so sequentially we will be adding 1 3 4 7 and all those elements and this would be the final solution that we need to return return and we can simply return return this as our answer and this would be the most optimal approach like this is there are other approaches that work in the same time and space complexity but why this would be an optimal approach because your interviewer would like to hear that okay you are aware about this Min Heap concept and you can use priority Q when needed so this sounds reasonably fine if we see the time and space complexity in this case the time complexity is going to be biger of n log n y n log n because uh in order for us to enter all the values inside the priority Q it takes a log n time and uh we need to do it for all the these n elements and in terms of space complexity the space complexity is going to be bigger of n because we need to use this additional priority q and uh let's see the coding so first of all we will initialize a priority que and uh let's name it Min Heap so now we are going to run a for Loop and we are going to iterate all the lists and all the nodes and we are going to keep on adding those inside our min Heap and after adding the value to the Min Heap we will have to update the value of list as well so we'll do list is equal to list. next okay so after this Loop ends uh all the noes should be inside our uh mean Heap and now what we need to do is take all the elements out out of the Min Heap and put it inside our merge list so first of all we are going to create a dumy node uh that would act as a placeholder for so that we can call uh our head when we when we need it and this is the same trick we use in previous videos as well so you might be aware of it once this is done we will create our uh list node called merg list and for the merge we are going to uh assign the first value as dummy so that in the future we can call this dummy node to find the head of this mod list and now we simply need to run a loop that while there exist an element inside the Min Heap we will have to add all those elements to our merge list and once this is done all we need to do is just return the dummy. next and this should be our solution let's try to run the code okay seems like our solution is working as expected let's submit the code and our solution works pretty efficiently as you can see and I would be posting this solution inside the comment so you can check it out from there thank [Music] you hello friends we are still Ed by a Fang company so let's not stop lead coding till we get there today we are going to do remove nth node from an end of the list problem and this problem can be asked in many different ways and uh if we see the some of the companies that have already asked this question it's really nice uh so companies like Facebook Amazon on Microsoft Google Bloomberg Uber Apple by Dan Goldman Sach and Salesforce they all L this problem and uh they are some of my dream companies that I want to work at so that's why I'm making these videos I hope you enjoy them let's try to understand the problem statement this is a lead code medium problem and uh the title of the problem actually is self-explanatory that essentially we are given the head of a link list and we need to remove the nth node from the end of the list and then return its head so this is the whole problem if we try to understand it using an example in the example originally we are given a list called 1 2 3 4 5 and over here we are given that n is equal to 2 so we need to remove second node but remember we need to remove the second node or nth node from the end of the list so in this case this would be the first node at the end of the list and this would be the second node at the the end of the list so we will need to remove this four and once we remove this four the answer would be something like this so this is what we need to return and uh in this case we will need to return this head pointer and then automatically it will Traverse towards the entire uh link list okay so let's see that what would be the most basic solution to solve this problem suppose we are given a custom example like this and we need to return remove second node from the end of the list now in this case this would be the first node from the end of the list and this would be the second note from the end of the list so we know that we need to remove this value number five but thing is uh the we don't we are able to know it because I have drawn the picture over here and it is very evident to us but actually we don't know that what is the length of this given list so because we don't know the length what we need to do is that the answer is quite simple first we need to identify that what is the length and then we need to based on this given value n we will need to determine that what is the element that we need to remove and then it becomes easy for us to to remove the element uh so what we are going to do is we are going to use a two pass approach and inside the first pass we are just going to have a variable called n l and this L is to take care of the length of this given link list so in this case we would find that okay length is equal to six because there are six node present in this given example now once we know that there are six node present and our given n is equal to two we will need to remove the fifth node why fifth node because the node we need to remove that is going to be determined based on the formula that total length minus whatever the N is given + one why + one because we are using one index uh calculation over here that this last element this uh Sixth Element is also the first last element remember that this is the critical part that this is the first last element which means this is the second last element and because of that uh if we see over here that this L is equal to 6 this n is equal to 2 so 6 - 2 + 1 is becomes five and that's why we determine that we need to remove fifth note if we don't do this + one essentially 6 - 2 would be four and we don't need to remove fourth node because fourth node is actually third node from the end of the list so that is why I gave you this long explanation now uh in the first class we determine that okay this is the node we need to remove that this fifth node we need to remove so all we need to do is in the second node in the second iteration we are just going to iterate over this given list again till we reach the fifth node so the moment we find that okay our current node is fourth node which means that the next node is fifth node right so all we need to do is that whatever the fifth dot next is pointing So currently fifth dot next is pointing to this value number six we are going to append this value to this fourth do next so rather than over here this four pointing to this five we are going to remove this link and we are going to make this 4.26 which means that this five is Auto automatically removed from this given input list and that would be our solution but the moment you present the solution your interviewer is going to say that rather than using two pass system suppose we want to complete this whole thing in just a single pass in just a single iteration then what should be your approach and this is the critical part so let me show you that what would be the most optimal solution let's use the same example and inside the same example uh first let's try to understand couple of things over here suppose over here in this case we are told that remove n is equal to 1 so how can we determine that n is equal to one is which element we can determine that okay this is the first element from the end of the list why because the very next element of this one is actually null and this is the key point which means if we are given that n is equal to 2 so which means we need to remove the second element from the end of the list so how can we determine we can determine it by saying that okay currently if we are at this position the second node from this one so next to the next node would be a null node and if that is true we can determine that okay this is the second node from the end of the list and this is a very important property that we need to identify so basically what we are going to do is we are going to use two pointer system over here and inside the two pointer we are going to have a back pointer and a front pointer and the position of this back pointer and front pointer is determined based on whatever this n is given say if our back pointer is going to be at this position which means our front pointer needs to be two steps ahead so two steps ahead from this back position would be 1 2 so this is where our front pointer would be at the beginning right and now since we have both of these positions set up uh all we need to do is just keep iterating to the next element and we are going to iterate until we find that this F or the front element is actually at this null position so let's see that what would be the the uh different pointer situation so now our back pointer is come to this position and again our front pointer is going to come to this position because back pointer jump from here to here and front pointer jumped from here to here again we front is not at null so again we will have to do one more uh iteration so now the back pointer will come over here and the front pointer will jump to one more step and front pointer will come over here again front is not null so again our back pointer is going to take one more jump and our front pointer is also going to take one more jump so front pointer will come over here and over here we've identified that this front pointer is at null position so oh this is the critical point now this front is at null position so we have identified that okay now this back pointer is exactly uh enough spaces behind it that the whatever the next node is that needs to be removed and that is what we we are going to do so over here we identify that okay this back is at current correct position now what we need to do is currently back do next is the point that we need to remove so what we are going to do is simply we are going to uh point this current back. next so current back do next is this five value we are going to point it to whatever the back do next do next is and this would be the solution because back what would be the back do back uh next. next it would be this one so rather than this four pointing to this five we are going to break this link which means that there is no way for us to reach to this five and now four is directly connecting to six and then we need to return the solution now we need to return the head of this link list so we are going to use the same point we are going we have been using so far that initially we are going to create a dummy node and this dummy node is going to act as a placeholder and that is going to store this head value and we are going to return that in the solution and let's see that what would be the time and space complexity in this case so for the time complexity it's only going to be bigo of L where L is the given length of the link list and in terms of space complexity we are only storing couple of parameter so it would be constant time and so we are not using any additional space so first of all we are going to create a dummy node and uh inside this dumy node we are going to give it some random value we are going to create dummy. next equal to head and we are using this dummy node as a placeholder now let's create our two front and back uh list nodes okay once that is done now we will need to bring the front node n steps ahead of the back node so we are going to run a four loop after this Loop ends the front and back are at the current position so now we only need to run a while loop till the front element is not equal to null and uh all we need to do is just increment the value of front and back elements and once that is done now we are at the correct position for back to remove the next node so we are going to do back Dot next equal to next do next okay and now we have removed the node that the nth node from the end of the list so we can simply return the head of the list and this should be our solution let's try to run the code okay seems like our code is working let's try to submit the code and our code runs pretty efficiently I will be posting the solution in the comments so you can check it out from there thank [Music] you hello friends we Ed by a Fang company so let's not stop lead coding till we get there today we are going to do reorder list lead code problem and solving this one problem is actually equivalent to solving three different lead code problems and I'll show you how in this video so if we check out the list of companies that have asked this problem uh there are Tech giants like Amazon Microsoft adob Facebook Bloomberg Uber Google Yahoo Apple eBay lyt and Expedia and these are some of my dream companies so that's why I'm making these videos I hope you also enjoy the video so this is a lead code medium problem and basically we are told that we are given the head of a singly link list and we need to reorder this link list and return in a different manner so let me quickly Show You by an example that how do we want to return it so suppose we are given a link list like this that 1 2 3 4 this is a normal link list we are given and now we need to reorder it in a manner that one node we take from this left to right direction and the another node we take from this right to left Direction so in this case the first node is going to be this one this node number one and now once we have taken this node from this left to right direction the second node we are going to take is from the opposite direction so second node in this case is going to be this value number four so second node would be the value number four again since we are we have taken node from the end of the list so next node we are going to take would be this one the value number two so again we will take a node this value number two and now uh at the end we will continue in the reverse fashion and the next node we will take would be value number three so this would so this is the sequence we would need to return in this case uh after all the nodes that we have taken now let's take one more example so again in this case we will iterate we will take one node from this left to right and one node from this right to left so the first node would be node number one uh second node would be node number five then again next node would be node number two then again next node would be node number four and then again uh next node would be node number three so in this case this would be the sequence that we will need to return as the result suppose this is the link list we are given and we need to reorder this link list so what is the approach we are going to use basically we need to understand that what are the things we need well we need the all the nodes that are going from left to right and we are also need all the nodes that are coming from left to right but the pro critical part is that this is a single link list which means we don't have any way to move in the reverse order so what we are going to do is first of all we are going to create a reverse link list and then we are going to merge it with this original input and the second link list we are creating we are going to create it smartly so this is the input we are already given right so we already have our first link list that we need to create which is this one um what we are going to do for the second link list is for the second link list actually for this original given input first of all we are going to uh find what that what is the middle of the link list so in this case the middle of the link list is going to be this node number four and the sequence starting from this node to 4 to 456 this is going to be the middle of the link list right so in this case the first link list we have is and for the second link list we are going to choose it from this middle node so the second link list would be okay now we have for both of our link list first and second what we are going to do is we need all these nodes in the reverse order so we are going to uh for the second link list we are going to flip it in the reverse order so now for the second link list we are going to change it in the reverse order so the second link list we will have would be like okay okay and once this part is done for the third part we are going to merge this first and second link list so first of all let's see that what are the first and second link list we have okay so this is the first and second link list we have uh we are going to merge two link list until the point when when we get the second node to reach to this null value and how we are going to merge the list is that first we are going to take the node from this first node first link list then we will take the node from the second link list again we will take a node from the first link list again we will take a node from the second link list and we are going to keep iterating it until the second reaches null so let's see that in the action so first node would come from the first link list so this would become our first node uh second node would come from the second link list so this would become our second node again we will repeat the same process uh and in the end we would add add this value number four and then we realize that we have already reached to the null value for the second link list which means that there are no other nodes to be added in the second link list which means we would stop adding even from this first link list and we would not add the all the remaining entries and this would be our answer and we can simply return this one so this is the solution we are going to use and notice that in this solution we are actually doing three different activities so let's see that how to do each one of them first of all we need to find the middle of the link list and I have already solved this problem so you can check out check out that particular solution over here let me quickly go over the solution that I was I had already proposed so suppose I have a link list like this and if I wanted to do two partitions of it all I'm going to do is I'm going to create two pointers one pointer is slow pointer and second pointer is fast pointer for the slow pointer it is going to do one iteration uh to the next element and for the fast pointer we it is going to do two hops to the next pointer and whenever this fast pointer reaches to the end of the list this slow pointer would be at the middle position inside the given link list so let me show you how initially the fast pointer and slow pointer both would be at the same position uh then uh fast pointer would take two jumps and slow pointer would take one jump so fast pointer would reach over here and slow pointer would reach over here again both of them are going to take subsequent jumps so slow pointer would reach over here and fast pointer would reach over here now again slow pointer would take one more jump so slow pointer would reach over here but if fast pointer takes two jumps we already reach to the end of this list which means that whatever the position of the slow pointer is this is the uh part where we need to do a partition and this would be the middle of the link list next thing we need to do is that we will need to reverse the second link list so suppose we are given a link list like this so I have already solved this problem as well you can check out that solution over here and the idea is that we are going to have uh three two different pointers one pointer is previous pointer and second pointer is current pointer and at any point we are going to have the current pointer point to the previous element so which means because this is a single link list all the nodes are pointing to the next element rather than them pointing towards next element we are actually going to have uh any any single node point to its previous element and then this would become our head and then we we would have reversed the link lless so let me quickly show you how initially we would have our current pointer over here and our previous pointer over here so now right now this current do next is pointing to the next element uh so first of all we are going to create a temp variable and this in this temp variable we are going to store the value of this current. nextt so current. nextt we stored okay so temp variable is currently over over here now we are going to have this current variable which is pointing to this next element rather than pointing it to next element we are going to have it point to this previous element so now this four rather than pointing to this five it is going to point to this previous element so this would be null in this case okay and now once this is done we are going to have this previous pointer jump to the current pointer so now this previous pointer would come over here so this is the previous pointer because we have already updated the value of this value number four and then the current pointer we are going to take its value from this temp variable so current pointer would also end up over here so this would also become the current pointer once we have this uh done now in the next node we are going to repeat the same thing so first of all this temp variable we are going to jump it to the next element so this uh so this would become the temp variable again the for the current variable we are going to point it to the previous element so now this five is going to point to this node number four rather than pointing to this node number six so we are breaking up this connection and then for the temp for the current variable we are going to flip it to the temp variable so again current is going to be ending up at this position so this is where current is and this is where temp is and then we will update the value of the previous node as well so this is where the previous node is so once this is done again we will repeat the same process and then we will Point U when the previous element reaches over here to the last node we are going to return this as the head so in the answer we would have revers the original list so we would have a so we would have a link list like this and then once this is done all we need to do is now we we have two separate list we will need to merge them okay uh so for the merge of two link list you can check out that solution over here and let me quickly show you here as well we will start taking one node from each of the given list and uh first node would be node number one second node would be node number six then third node would be node number two and next node would be node number five and then we will take node number three and then we will take node number four from this list and now we realize that the second. next is actually null which means that now we don't need to take any more nodes from any other link list and we can whatever the answer is we can simply return this as our answer and this would be the final solution that we are going to use so let's see that what would be the time and space complexity in this case so for the time complexity we are actually doing three different things so first thing we are doing is that we are actually splitting the link list in two parts so that takes weig go of End by two time plus second thing we are doing is we are reversing the link list which takes big go of end time and third thing we are doing is we are merging two linklist which take big of and time so in general we can say that we are doing big of n work and uh in terms of space complexity we are actually using an additional uh link list this second link list to store the values and over here we are actually storing like half of the nodes which means that we need we will require B go of n by two additional space so generically we can write this as big of n as well and this would be the time and space complexity let's see that what would be the implementation first of all we are going to check that whether the given head is equal to null if that is the case we can uh simply return immediately and if that is not the case we will start with our implementation so first of all we are actually going to uh find the middle of the link list so let me create two list nodes for that now once we have our slow and fast list nodes we are going to run a while loop that while either fast is equal to null or fast. next equal to null we will uh move slow and fast pointer up until that point once this is done uh we will have a new link list uh starting from the low end point and we will have to reverse that link list so uh in order to reverse the link list we will need a previous node so we will create a new list node called previous and we will assign it to the value null we will also have a current node and we can initialize it to the value of slope and we will have a tempor node now uh we will run this Loop while the current is not equal to null so first of all we'll store the value of current do next into temporary variable and after that we will uh exchange the values of previous and current node so current do next will get the value of previous node and previous node will come at the current node and current node we will need to move one step forward so we will assign it to the temp node where we initially store the value of the previous current. nextt and after this second Loop runs we should have our second list the slow list that we created to be reversed and now all we need to do is merge our first list and our second list so let's create couple of list nodes and we will create a list node called First and we will assign it to the value of the head and we will also create a list node called uh Second and we will assign it to the value of the previous node we will run a loop that while second. next is not equal to null so over here we will need to uh take the values from the second node and put it behind the first node so we are going to use the temporary variable for that so first of all in the temporary variable we are going to store the value of first. next and after that for the first. next value we will take a value from the second node and for the first node we will get the value of whatever the temp value we have we had already stored and after that is done we will repeat the same process for the second node as well so first of all we will create the temp to set up as second. next and then we will have second dot next to point to the first node and in the end we will have second node point to the temp node and once that is done our code should be working as expected then where we would have updated the value of this uh original given list node in this case we don't have to return anything because the return type is void we only need to update whatever the given input is so let's try to run the code okay seems like our code is working as expected let's submit the code and our code is actually pretty efficient and it runs faster than most of the other Java submissions so which is pretty good thing to do I would be posting this in the comments so you can check it out from there also on the GitHub I have created a repository of all the questions that we have solved so far uh and uh I have made it public so anyone can access it I will be posting this link in the comments as well so you can check it out this link and it can be helpful to a lot of other people so far we have around 60 to 70 questions and uh we we are growing it by the day