Transcript for:
LeetCode Problem Solving Strategies

What is this lead code I'm seeing on the screen right now? You're goddamn right. Last night at about like 2 am, I was just like thinking to myself and kind of looking back through the years and like what I've been doing in my life, all the good and bad decisions. Classic, right? Uh that's that's not a way to get anxious at all. But more specifically, when I first got into programming and and got my first programming job as a JavaScript front-end developer, I remember at the time like I never touched lead code. And um I was looking like how to get like ready for interviews, right? And that was like one of the top things that people said is like, "Oh, get into lead code, right? It's going to come up in interviews." And I remember at the time like when I was like looking and researching through this like the vibe and the like connotation that came with lead coding was quite negative. And that might just be my like my personal experience but a lot of people that I was like reading comments on and like blog post they were saying just do it for the interview get ready for the interview but something that probably you like never touch after that. It's never going to apply to like real world projects or your applications or whatever. And a lot of people were also saying that it's really hard to get into and blah blah blah. And like in these last couple of months, I really got back into it. And I just couldn't disagree with that more. And hopefully this episode inspires people that have been putting it off to like really get back into it and and and do a couple of these every day. I genuinely think like the mentality you approach lead code problems is going to dictate how good of or bad of an experience you're going to have with it. I like to think of it as like training your brain. It's kind of like sudoku, right? It's going to keep your brain firing. It's going to build up intuition. And I remember at the time I was doing like bloody twosome problem and kept thinking like, yeah, when am I ever going to do this in a real world application, but I was clearly missing the point because it doesn't necessarily teach you the exact thing that you're going to apply to your job, but more of like decomposition like programming. If you build out an application, whatever that is, that's a bunch of little problems composed together that forms a big problem. And Elite Code does a really good job of breaking down complex problems into little ones and understanding that. And I kind of want to show you how I approach these problems as well. Now, we're going to do three simple ones here, like the two sum, contains, duplicate, and whatever. Uh, so if you solved a bunch of lead code problems, this is probably going to be a bit boring, but I appreciate you standing here. But if you've never approached these, I kind of want to show you like how I go about it and then make it actually enjoyable for you. Now, if you've never done these before, if there's like one thing that's going to put you right off lead code is to just go and try to solve a bunch of random problems. Just click through them, that's going to overwhelm you instantly. Let me tell you that. Uh because there's probably going to be different like algorithms that you need to know about or learn or different data structures that you need to like build up an intuition for and it's really difficult to do. So if there's like one resource I can like highly highly recommend to get started is on neatcode io just follow this road map and like literally start with like arrays and hashing and just stick to this and like find it's like really nicely laid out here for you. So you can click here and just go through these. And what I like to do is after I even like solve these problems here is to ask like claude or whatever to like give you similar problems so you can practice and build up more of an intuition for. So this is a fantastic resource but like really take your time with each of these and don't like go from like doing arrays to like jumping into doing trees and then whatever else, you know. Um, so okay. So how can how can you get started with this? First of all like reading these questions like don't like over complicate it. So let's let's have a look at the twosome problem. Right? Given an array of integer nums. So we have an array of numbers and an integer of target. Return indices of the two numbers such that they add up to the target. Right? You may assume that each input would have exactly one solution and you may not use the same element twice. Okay? So you got like nums here. Right? You got 2 7 11 and 15. So the target is nine. So the output should be zero and one because the index is zero, right? So that's the two and the index one is the seven. So if you add these two up together, then you get nine, right? So there we go. That's the output. And okay, so how do you approach this? And again, the way I like to think of this is more of a puzzle rather than like a programming thing. And just like put the things on the screen here, right? So we got 2, 7, 11, and then 15 like that. And then we're trying to reach nine, right? That's our like target here. So like I'm just looking in terms of like programming. I'm just looking like why I got my toolkit here in my brain. And sometimes you might not have the necessary things to do it and that's perfectly fine. And you can look at the answer and then you can go from there on. But in this case like I'm thinking well is async way going to work here. Well probably not. It's probably going to be useless or like a switch statements. It's probably not going to do me much. Uh because what I'm trying to do is essentially check two here, right? And then if two and then if I have seven here, I check seven after that. And if these two add up to nine, then bingo bongo, right? So we know in programming like how can I like go through and check each of these values? Well, hopefully you know that it's a loop, right? So you just loop through all of these, right? So I can check I here, right? I can check if I in this case the value is two, right? And then maybe I can do something like I + one like that, right? Which is going to give you the next value. So you can check this and you can check this at the same time pretty much. You could also check like three values, right? You could check I + 2, for example, if you want. Um, but you can check these, right? And then maybe you can do like a little if statement, right? You do an if and then you can do if I with i + one here equals the target, then bingo bongo, right? We we got this. Now let's say we have an example like this where we have three two and three and we're trying to get six, right? So now if we apply like the same for loop to it, it doesn't work anymore, right? I here will be like the first element for example. So that's I and then we're doing the I + one again, right? So that will be I + 1. So that doesn't work anymore, right? Uh and like for the next iteration now you're essentially just shifting these arrows over. So now I becomes two on the next iteration and I + 1 um becomes three. So again we're just checking like we're always just checking the values like this either these two, these two or these two. So it doesn't work anymore because in this case we need to check this one with potentially this one. So if if you think a little bit about it, well we can do another loop, right? So what we can do is check this value with this and then if that doesn't add up then we can check this value with this like that. And that's again just doing two loops. You have an I and a J in this case. And I actually recommend you to just copy this over into your Neovim or whatever you're using and do it here just so you can debug and actually take your time a bit. The little editor there and delete coding. I'm not a big fan of it honestly. But I'll call this C1 here. So we're doing the twosome. We have the array and we're trying to get nine, right? So let's let's do the for loop, right? So we're going to do four and then we're going to say let I we're going to start off at zero, right? And then we're going to say if I is smaller than the nums uh length, right? And then we are going to say I ++. There we go. So if you want to run a little quick test here, you can test out the nums I you make sure you want to get everything back here normal. So let's just run a little test here. uh bun run test ts right so we should get 2 7 11 and 15 all right so that's great I know a lot of people sometimes mess this up where they add equals here as well but that's why I'm saying do it here because then you can easily like catch it right if you accidentally did that and you can just quickly check and see okay well I got undefined there so I'm clearly going one over there u but there right so where we are now is here right where we can just go through two at a time uh but Having two loops is going to give you the ability to look at one but also compare it to the rest of them through each iteration. Right? So let's go here. Let's delete this. All right. So this is our first loop. We're going to say for let let's call this J. We're going to set it equal to and here like I don't want this to start at zero because if you think about it, if we start this at zero, then we're checking like the same thing twice, right? Where's the little laser? They have a laser in this thing, right? So if I do I and J at the same time, then we're checking two two right at the same time. But we want to check two and the next value. So I'm going to say I + one, right? So we're just checking the next one. And then we can do the same. We can say J is smaller than nums.length. Pretty much the same loop. J ++, right? And then here what we can do is simply check if the target triple equals to uh we want the value here, right? We don't want the actual index, but that's what we want to return. So we can say nums I right that's the first one and nums j if these are equal then I can simply return what I want to return here is in like an array form but I want to return the indices so I can say i and j and that's it right we can take this and we can give it a go so if I copy this over again you can run this in the command here in the terminal but I'll paste this here uh because I know this works and hopefully should be all There we go. Case accepted all the cases. Let's submit. And then from here on out, you're going to see that. Okay, that worked. And that was great. You can patch yourself on the back, but it didn't like it wasn't like the best, right? 34 milliseconds. Clearly, we could have done this better. And why is that? Is because we're doing two loops. And when you do two loops, then the complexity basically goes squared. Um, so how else can we approach this? Now, this is again, you might not come up with a different way or a better way, but hopefully this will set you down the rabbit hole of like, okay, how can I improve on this? And this is why in the last couple of months, I've really got into math because it gives you like a good intuition of how to approach problems. If you think of this as like a basic like equation here, right, we got the target here and we have access to one value in this case, let's say I, right? So two if we do like one loop, right? We have access to one number here uh which is I. So if if you think about that then what are we really looking for? We have the answer, we have the target, we have one. So we're just like looking for the difference really here, right? So if you kind of like draw it out like as like an equation here, right? So you have T that's like the target which we have the answer to is equal to I, right? which is our like looping thing plus D which is like the difference between the two. Okay. Now if we kind of like replace it well we know I is always going to be like whatever iteration we're in that loop in this case let's say two plus the difference we don't know the difference yet is equal to D which is the target which is nine. Okay. Well there we go. Well we got these two. So we know that you know d equals if if you remember in the math you can just take the two and bring it over to the other side and you get like 9 minus 2 right which d equals 7. Okay, cool. So, that's really cool. Now, we know that in JavaScript, well, we have a couple of different like data structures that we can use, right? We have a map for example or we have an array and looking up, you know, an element is like constant time. So, you can do it instantly. So, so let's try to apply this now uh to our code. So, we could use an array. We can also use like a map. I'm going to do a map here uh which is essentially like a key value pair. That's pretty much it. Um but again both would work just fine. So we'll create our loop. Again we'll still need to iterate once through this. Um so we'll do I smaller than nums.length. Right. There we go. And then we'll do I ++. There we go. So let me just kind of show you what this does for now. We'll just focus on the key here. So I can set and as you can see takes a key and a value. So I'll put the key as I'll put it here as a variable. This is the actual number. So that's going to be nums I. Right. So I can pass oops I. There we go. So I can pass in the number here. And I don't really care about the value here. I'm just going to look for the key. So I'll just pass in the index there for us. Let's just console log this out to see kind of what we get. So I'm going to say Smap like that. Boom. Let's go back here. Run this. And there we go. Right. So you get the key here which is going to be our number 2 7 11 and 15. So that's what we're going to focus on. We're not going to need this too much. Again, we could probably add this in an array which will work just fine. But there we go. So now that we have this, well, we can calculate the difference, right, with that little equation that we just made. So I can have the diff here, which is equal to what? Well, we got the target, right? Minus the number. Whoops, not equal to minus number. So now here we can just simply do an if statement right and if we can check if the S map has right this is a little method here that returns a boolean uh that tells you if you have a key specified in there. So if we have the difference then that means this is all true right and we have that number and the nice thing is that we can look this up in oh of one of constant time right so it's going to be really quickly we don't have to actually like iterate through all of the different values so if we have the diff here then we can simply return this so then we can return and I believe yeah we need an array here so we can do the array like that and we can just say sap and then we can say get right We want to return the two values. So we want to return uh we want to get the diff, right? And we can also return the i. And there we go. That should be it. So let's delete this now. There we go. And let's test this out and see if it works. What's wrong? Uh let's console log out here. C1. There we go. Run this. And look at that. 01. So it works, right? These two added together. We can also test out let's do C2 two sum here and let's do what was the other example we had three two and three right and we're trying to get like six so in this case like we're trying to compare like we need to get the three there and the three there but since we have the difference this is going to be super easy so change this to C2 and hopefully this will still work just fine and look at that we got zero and two and there we go so now we can take this let's copy it should just grab it like There we go. Grab this whole thing. Let's cut cut it. Let's go back here. Let's paste in here and see what we get. Let's run. And there we go. It got accepted. So, let's hit submit now. And let's see how much better this does. And look at that. Look how much better that performed compared to the two for loops, right? Because we can instantly just look up that difference in this case. And I actually highly recommend you to do this is you just like stick to one problem and like try out different methods and then like once you solve it once, go to the solution tab here and just look through and see like how other people manage to get it done or quicker and it just becomes like a fun game. Uh we're going to get do a couple more here, at least two more. But before I do that, I want to give a quick shout out to today's awesome sponsor. Let's go, Brilliant. Speaking of critical thinking and building up an intuition, Brilliant is a learning app designed to be uniquely effective for developers like us. Each lesson is filled with hands-on problem solving that lets you play with concepts, a method proven to be six times more effective than watching lecture videos. Just how we're grinding through these lead code problems, the real skill isn't memorizing solutions. is developing that pattern recognition and the ability to decompose complex problems into simple ones. And that's exactly what Brilliant focuses on. And it doesn't waste your time either. The lessons are straight to the point. They're interactive and visual, so it sticks really easily. And they have a bunch of fun ones like programming with Python, how AI actually works. And they have a new one called Programming with Functions as well that you should check out. So you get a perfect mix of like engaging challenges and daily encouragement as well to keep you motivated and on track and all of these are made by teams from Stamford and Microsoft and Google. So they're really really good. So I highly recommend you to check out Brilliant if you click the link in the description down below or visit brilliant.org/developed. You can also scan the QR code right here and you get a full free 30 days and 20% off your annual subscription. Thank you so much. Okay, here's another one that's quite a simple one, but this I wanted to showcase this as well because this is where like data structures actually help you out quite a bit and can like make you like that much more performant. Uh like for this example as well like this is a contains duplicate one, right? It's super simple. Again, you have like a nums like this. So you have Hey, I ran out of egg. There we go. So you have one, two, three, and one, right? So you're you're trying to see if this has like a duplicate. In this case, you have one one. So again, you're going to hear this like a brute force method and that's just like like kind of how we did it the first time, right? We can do the loop thing again or like do a double loop and then check i with j and see if there's a duplicate there. So if i equals 2 j then you have a duplicate but again that's going to be a bit slower. So again like kind of getting curious here and like looking out and seeing okay is there a data structure here that can help me out and in this case there is one and it's called sets right in JavaScript you can use a set which can only contain a unique value. So again it's going to be pretty simple if we just like let's take this function let's copy this over I'll paste it back here. Now the cool thing about sets is that we can use this to our advantage now knowing that it can only have a unique value. Let's call this dupes for example as a new set here. So what I can do is I can make that loop again. So let's do four. Let I equals zero. I is smaller than the nums.length. And then we're going to do I ++ right. And then I can just check if the dupes has uh the the duplicate value. So nums I right I'm checking that value. Then I can just return true. Like that's that's all there is to it. Do I need to return it? How how what's the output? Okay. It is a boolean for the output. Uh okay. Implicit semicolon. We don't really care about that. But there we go. So we're just pushing that in. Right. And then we're just doing a check again here. Right. So if it has that then we return two and then we just push all the individual values in. So dupes dot uh I believe it's the same it's not set it's add appends a new element with a specified value at the end. So okay so we we just push that in right nums I we push that value in and we are done and this needs to be an if if statement here. Sorry if uh let's just take this put that sucker in there. There we go. Right, that's it. So we should be able to try this out. Uh function sorry const t for test contains duplicate and then we'll pass in one two three one. Let's do one two three one like that. So if we console log this this should return us true. Pop that in. We get undefined. Oops. Sorry. This needs to be this needs to be an array here. One two three one. There we go. Okay, try this and it returns true. There we go. And this is going to be really efficient as well because as soon as we encounter that the dupes has a value in there, it's going to return true. So, let's copy this over. See how well it does. Let's pop it in here. Paste. There we go. Let's run this. I always like to run it first before I submit it. And as you can see, it failed. Now, even though like this was correct, uh we actually didn't return a false here. We just returned undefined because we're not returning anything if this if statement doesn't get caught. So, actually here at the end, we should go and just by default return false, right? Because if the the iteration here catches it, it'll automatically return true. So, let's just go here at the bottom and we can simply say return false. Okay, let's run that again and see how that goes. And let's see. And there we go. Now it got accepted. So let's hit submit. And it should be doing pretty well. And there we go. Not too shabby. How did these guys get two milliseconds? That That's crazy. I actually want to have a look at this after this episode. Okay, let's look at a final one here. But if you guys enjoy this, let me know down in the comments. Like I love to do stuff like this. Uh so I'll gladly make like a whole series on it. So a valid anagram. So given two strings, you got an S and T here, return true if they're an anagram and false otherwise. So basically like you should be able to like remake that word. Uh right. So if like you reorder these, it should give you anagram, right? So rat with car would not work because you have a T here and there's no way you can like reorganize these letters here to give you car, right? Uh but rack, right? If you have a big rack, then then that would work. Um, shout out to my wife. Okay, so just like thinking about this again, like don't really go like to the deep end with like programming terms, but let's do let's do car. Let's do car and uh or like tar here and rat. So let's say you have something like this rat, right? And then you have tar. Now, if we think about this, like what do we actually need to check? Um, if you think about it, like if you have a word that's like longer than this, like Taurus, that's that's not the way you spell it. But there's no way this is an anagram, right? Because there's no way you could like reorder this to get rad. Like, that would be pretty crazy. I'm not going to lie. That would impress me. Uh so like the one thing that like the first thing that you can check here is um well are are they the same length right? If they're not the same length then there's no way uh this can be true. So what you can do is like instantly return false here if they're different lengths. Okay what's the next thing we can do? Well we know a little bit about like data structures now right? It's pretty cool. We knew we know that we have a set right? So that can only contain like unique values. Okay. So that would maybe get us a little bit far, but as soon as you have something like anagram, well, we have a bunch of A's in here. So that wouldn't work any anyway, right? So set is not really good here. But map, well, that's pretty cool, right? We could kind of save the key value pair. So a can be the the key here. And then maybe we can like increment the value here. So we can do like a loop and then we can count, right? So we can check if we have an A in there. If we don't, we'll set it to zero. But then we can count and then if we have sorry we can set to one right because we have one and then we can check if there's another a in there then we can add one more and then if we have another one in this case three then a we can set this so that it has three in there right and then we can do the same for the t here as well right so you can do um you we can loop over it again right and we can count and we can add them to another map maybe and then we can check and we can say okay well then a here is also three so now if all of these keys from like this map and this map match up, that means that it's true and it's an anagram. So that's like one way you can do it. And if you want to see the code how it looks, it's something like this. Uh this is another example. There's probably like different ways you can do this, but the way I did it is a bit different is I essentially made one map and with the second loop, I basically decremented this value. So rather than doing two and then checking if they're equal, what you can do is make one and then in your second loop just check again like here. Okay, as soon as we hit the first a, let's decrement this by one and then decrement it. And if it equals zero at the end, that means that it's an anagram. So let me just show you the code quickly here. So it's something like this, right? We check the length first. So if they're not equal to each other, then it's clearly false. Let me zoom in a bit. I just don't like this little editor they got here. But here I made a little map here, right? Smap again. It has a string and a number. And then I'm doing a loop. So I'm sap set. I'm setting the character. I'm just doing a normal like for off loop here. But as you can see, I'm doing sap set. I'm setting the character. And then I'm doing a default to zero here. And then I'm adding one to it. Right? And and in my second loop here, I'm getting the character and I'm checking if it equals zero, then we return false. And then here at the end I'm just decrementing that and I'm returning true. Now another like interesting way you could solve this is essentially reorder this right. So if you have uh car for example and then you have rack right well if you reorder this. So if I move a over here right I'm going to have a a and then I'm going to reorder the c. Right. So, I'm going to have C and I'm going to have R here, right? And then if I do the same for this, right? I move A over. So, I'm going to have A and then I'm going to move the C that's going to go here, right? So, C and then the R stays in that same position. So, look at that. So, I can just essentially compare these two strings together. So, how would that look? Well, that would look like this. Uh, let me just copy this over here. Here we go. Let's copy this. Paste it. There is anagram. Okay, cool. Let's just get rid of all of this. I'm just going to console log out s.split. Right, there we go. So, let's see what this does first. Run this. Okay, car. It's still like put together. We want to separate it like by each character. So, you can just leave empty strings in there. So, run that again. See how you get car. Let's also do the other one here. um console log s.split by empty and this should be t not s actually. There we go. Right. So there we go. And now what we can do is reorder it. So if I go to the end here, uh we can do a sword. Let's do on this as well. Have a look at that. Look at that. So now they're the same. The only thing is that we need to like join them back together into a string. So that's literally the method in JavaScript you can do is join. There we go. Let's join these back together. And you you'll get a beautiful oneliner here. Here we go. ACR ACR. Now we want to join them. I think I need an empty space there. Sometimes forget how join work. There we go. ACR ACR. Cool. So now doing that you can just simply do if s split uh sort join like that right and then I can take this whole shebang let's grab it from here all the way there can yank that sucker triple equals to this but the only difference is it's not s here it's the t value then we can just simply return true and otherwise return false let's give this a go run this true there we go we can go down here const t2 is anagram let's do one that's not car rat save and we should return this as well here. Let's see. This should be false now. And there you go. Look at that. You can submit that and you are good to go. So, hope you enjoyed this episode. Hope like it gets you like excited a little bit to start doing these challenges. And I'm telling you, uh it'll like it'll make you sharper as a programmer. So, thank you so much for watching. Thank you so much for supporting this channel as always. And yeah, drop a like, drop a sub, all that good stuff. And I'll catch you in the next one. Peace.