Find kth node from end of a linked list _ Applied AI Course

The Art of Traversing Linked Lists with Two Pointers

In this article, we will explore one of the most efficient methods to traverse linked lists using two pointers. This technique is particularly useful for solving problems that involve finding nodes at specific positions in a linked list.

Initially, let's consider an example where we have a linked list and we want to move our pointer P to point to the node that was initially pointing to Q. When this happens, Q will now point to the right node of P. If we continue doing this, P will move to its new position, followed by Q moving to its new position as well.

As we can see, when T is removed from the list, and cue becomes the head, there is a gap between the two pointers. This gap represents K minus 1. In this case, the gap is caused by Peas being at the initial position and Hugh being at the third position.

To find out where Q reaches, we simply follow it until it points to the last node in the list. Once Q reaches the last node, P will be K minus 1 steps behind it, which means P will reach the (n - k + 1)th node from the beginning of the list.

Now that we have a better understanding of how two pointers work, let's move on to writing pseudocode for this technique. Here is an example of the pseudocode:

**Step 1: Initialize Two Pointers**

Initialize two pointers P and Q pointing to the start of the linked list.

**Step 2: Move Q**

Move Q by k steps from its current position. This ensures that when we traverse the list, Q will point to the correct node at each step.

**Step 3: Move P and Q in Tandem**

Once Q moves, move P and Q together, one step at a time, until Q reaches the end of the linked list.

At this point, P will be pointing to the (n - k + 1)th node from the beginning of the list. This is because when Q reaches the last node, P will have moved K minus 1 steps behind it.

To confirm that this is indeed the correct solution, let's analyze its time complexity. The total time complexity of this algorithm is O(n), where n is the number of nodes in the linked list. This is because we only traverse the list once, using two pointers to move together.

The space complexity of this algorithm is also O(1), which means that we use a constant amount of space. This is because we only need two additional pointers to perform the traversal.

In conclusion, traversing linked lists with two pointers is a powerful technique that can be used to solve problems involving finding nodes at specific positions in a linked list. By using this technique, we can find the (n - k + 1)th node from the beginning of the list in O(n) time complexity and O(1) space complexity.

"WEBVTTKind: captionsLanguage: enso let's actually look at this question is a very nice question what basic singly-linked lists the question asks you to find the K through node from the end of a singly linked list so let's understand the problem imagine if I have a singly linked list like this right so each of these is my node they'll have some value in them right let's assume this is my singly linked list okay just just let's let's create a singly linked list right let's just place some values it could be any value here let's just say a b c d e f g right so let's say i have seven nodes here just for simplicity let's understand the example let's come in so this is my head or this is my start of the linker list right so let's say this is at first position second position third position fourth fifth sixth and seventh so right now how many elements do I have in the linked list let's call that as n so n equals to 7 okay let me also color-coded also let me also count it from the end so this is the first node from the end this is the second node from the end third node from the end fourth fifth sixth and seventh right so imagine imagine if so what is being asked here find the faith node from the end of a singly linked register let's assume just for simplicity that K equals to three so it's asking for us it's asking us to find the third node from the end which means it's asking us to find this node because look at this couch I'm going in the reverse order right this is the third node from the end and that's what it's asking it's got it's asking us to find the eighth note from the end okay I hope this example is clear so if K equals to three for this link enlist that node value will be e right imagine if K was equal to 5 then what happens the fifth node from the end and that would be Nord C right and also remember faith node suppose if I know the number of nodes if I know the number of nodes is seven then the third node from the end look at this what is third node from the end so if I know n right it is going to be n minus k plus 1 node from the beginning right gate node from the end is nothing but K minus one plus one throwed from the beginning look at this here M equals to five M equals to 7 K equals to three so 7 minus 3 plus 1 equals 2/5 so the third node from the end here is nothing but the fifth node from the beginning similarly if K equals to 5 if I want the fifth node from the end what does it mean from the starting it is again 7 minus 5 plus 1 which is equal to 2 so the fifth node from the end is same as second node from the beginning right it's it's same as the second node from the beginning sorry did I mess up somewhere 7 minus 5 is 2 plus 1 is 3 sorry this has to be 3 not 2 7 minus 5 plus 1 right so it has to be the third node not the second node and hence the value will be C and not B I'm sorry I just messed up the math here right and this this this is correct n minus k plus 1 throughout from the beginning so the key observation the key observation here is if you knows if you know n first of all if you know him then take the node from end gate from end is same as n minus k plus 1 load from beginning this is a key observation that we will use to build a simple algorithm for this ok so not given this fact how do you solve this let us write our first version right so let's write the first first first pseudopod we always write our code with pseudocode first so that we have a good understanding and then we'll go to the proper code okay so let's go step by step first step is I have to compute n ok find n which is the number of find n ok how do I find end I'll start with the start node how do I find this it's very simple I start with a pointer pointing to the start node and nobody has given me the number of number of nodes in my linkedlist my input when somebody gives me singly linked list the input is going to be a pointer or a reference to the first node that's all they will give me right they'll give me a pointer or reference to the first node that's all they don't tell me how many how many nodes are having a singly linked list so not to find it out what do I do I initialize a pointer P to the start and then I keep traversing this I simply traverse this one by one by one in the time I reach a node and I'll keep I'll keep a counter obviously I'll keep a counter that will start with one and I'll keep going on till the time I find a node whose next pointer points to null right so that that's how I can find em so I can find n with one traversal with one traversal of the singly linked list and how much time does it take if the singly linked list has n nodes this takes order of n time because this is a simple for loop right okay that's step one step two once I've done that okay I will just compute I'll just compute a variable called X witch's because what is my input the input will be the start and the value of K okay then I'll say X equals to n minus k plus 1 right now if this value this is important if this value is 0 or less than 0 okay look at this if I have only seven elements and if somebody asks you to find the eighth element from the end that's of course like meaningless right so first I check whether this is greater than equal to one or not okay only then only then so this check has to be performed this is like a sanity check to ensure that they have not given you a value of K that is larger than that is larger than n okay if they give you then you should you should raise an alarm and say there is an error in your input value K once you do that then you basically again traverse you basically traverse the you traverse the linked list again from start to end again till till you from start to end till the time you reach X the node right you can always do that right again you create a pointer you keep a counter once you want in this very beginning you'll give it a value of 1 then you will keep incrementing that value till the time you reach the X the node and X is nothing but n minus k plus 1 right here again here again look at this this is order of 1 obviously because this is just a simple mathematical calculation and a simple logical check now this will require one more traversal this will require one more traversal let's say you K equals to 1 let's say human what is the worst case k equals to 1 in such a a sample tremors the whole list again in this case right so when it travels the whole list the worst case time complexity of this step is going to be order of n because I start with the first node I'll have to keep reversing till the time I get n minus k plus 1 to node if K equals to 1 this whole thing X becomes n so I might have to traverse the whole whole Lincoln list again right so what is the total time complexity of this the total time complexity is order of n itself but here I am doing two traversals I am doing one traversal here and I am doing another traversal here ok so this is basically an order of n time complexity algorithm there is no additional space except a few pointers so it's only order of one space very good but here I have two traversals let's not forget that I have two traversals right I have truth to traversals of malinger list okay this is this is a fast algorithm can I perform better so the question of the next question I have in my head is the next question can that I have here is of course while the time complexity is order of n space complexity is order of n very good instead of two traversals can I find can I find the case node from end the cave node from end using a single traversal using a single traversal right because a single traversal is going to be obviously taking less time than two traversals right so can you do this okay let's think about it let's think about how to how to do it intuitively okay so let's actually go back to the same diagram that we have we will reuse this diagram right imagine if I have so here is here is the fun part here is the here is idea or the key crux of the idea here imagine if I have two pointers okay let's assume I have a pointer P that points to the start node let's assume I also have a pointer Q that is pointing here okay so what I'll do here is this okay so step by step okay logically what I will do here is first I will find n okay actually I don't even have to find them to be honest okay let's not because you are wasting one traversal there right so I will not even find n what we'll do here is I just simply initialize two pointers cute - the start node okay first I will remove because I already know the value of K I will move my cue pointer by K steps imagine K equals to 3 imagine K is K equals to 3 remember I don't know n right love in this methodology because I've not reversed and hence I don't know n okay so I do not know n I don't know it's is a question mark for me okay I know that K equals to 3 so what do I do first I will move my Q pointer by 3 steps okay so I'm starting here so this is step 1 because I am already at the first node then I'll move it to second node I will move it to third node right so I basically moved it to the cliff node from the beginning okay so when I do that what happens let me just erase this okay so what are we doing here I'm moving my cute node to the faith node from the starting you my Q pointer I'm sorry I'm moving my Q pointer to the keith node from the beginning look at this my k equals to 3 right so I've moved it to the third pointer that's a first step now now comes the fun part now comes the ingenious part here ok now comes the innovation now what I'll do here is since it has moved three positions look at the gap that I have between these two ok then this is at 1 this is at 3 okay now I will move both these step by step so the way I do it is I will comment the Q pointer once and I'll increment the P pointer once so now what happens this will get this will move and this will also move so now my P will point to this so P was initially pointing to this right so P will now point to this right and Q will point to this basically what did I do I moved my Q pointer by one step I also moved my P pointer by one step okay again I will keep repeating this ok next step what will happen my P will now move now let's see what happens now if I keep doing this my P will now move here Mike you will move here right again Q will move here P will move here ok well they just let just run it so that we understand it better ok P will move here Q will move here if we notice there is always this gap between P and Q ok it is always this gap what is this gap exactly if you notice when T was here initially andcue was here what is this gap this gap is basically K minus 1 this gap look at this Hugh is a third position peas at first position so what is that gap that gap is exactly K minus 1 okay but anyway let's keep doing it so let's say you might keep moving Cuba one step and P by one step when I do that I keep doing it till the time till the time Q reaches the last node so what happens then when Q reaches here where would P reach P would be K minus 1 steps behind it which means P will be here now how do I know that I have reached the last node if the next point resistance very simple right if the next pointer is null I know that I've reached the last node right when Q next is null because Q is pointing to this when Q next is null I know that I've reached the last node and then this happens my P will reach the K the the Keith's node from the end because look at this wait where is my where is my Q love my Q is at enter node my Q is at enter node from the beginning right my Q is a tenth Road from the beginning okay so and I know that my P pointer is K minus 1 steps behind it okay so where is my K where is my P pointer it is at n minus k plus ones from the beginning and this is what we wanted earlier also even in the even in version one even the first solution that we had to traversals right at the end of it because n minus K minus 1 is nothing but n minus k plus 1 so in this approach in this approach I have literally done only one traversal of may I have only done one traversal I have not done through presses and still I am doing very good okay so let's write the simple pseudocode for it step by step step one okay initialize two pointers P and Q pointing to the start okay step two move Q moves Q by missed cube - not by move Q 2 - K its node from beginning to care node from beginning from from begin okay from the beginning okay once you do that now move P and Q nodes P and Q nodes step-by-step in tandem step by step in tandem basically means once you move it you move the other thing also that's what in tandem basically means in English right you move them step by step in tandem till the time till Q reaches till the time Q reaches the last node the last node once this reaches the last node once this reaches automatically P reaches automatically P reaches the n minus k plus 1 to load from begin from begin which is same as which is same as H node from end which is same as Kate node from and that's it whatever P is pointing to you return that value okay and in this whole exercise I have done again the time complexity of this look at this to move this I would take order of K time right now to do all of this again I would take order of M time right again when I'm moving this Q would only move n minus K steps right so the total time complexity of this you continue to the order of n time right and space complexity is again going to be order of 1 of course I have an additional pointer Q here in addition to P but that's ok just the constant time but the beauty of this approach is I am just solving it just in one traversal right I am just doing one prover cell of course using two pointers I am using two pointers here not a single pointer but still it's just a single traversal right very simple very elegant solution again lot of linkedlist problems lot of nice linkedlist problems can be solved using two pointers and some innovative solutions like this in the next video we'll see the code snippet for it line by line and and understand how actually everything's everything works together what we have seen right now with pseudocode my suggestion is always please write pseudocode like this because then converting this into code becomes easy this is basically explaining what you are doing in English right of course once you have this you have to be careful about converting this to code but it stillso let's actually look at this question is a very nice question what basic singly-linked lists the question asks you to find the K through node from the end of a singly linked list so let's understand the problem imagine if I have a singly linked list like this right so each of these is my node they'll have some value in them right let's assume this is my singly linked list okay just just let's let's create a singly linked list right let's just place some values it could be any value here let's just say a b c d e f g right so let's say i have seven nodes here just for simplicity let's understand the example let's come in so this is my head or this is my start of the linker list right so let's say this is at first position second position third position fourth fifth sixth and seventh so right now how many elements do I have in the linked list let's call that as n so n equals to 7 okay let me also color-coded also let me also count it from the end so this is the first node from the end this is the second node from the end third node from the end fourth fifth sixth and seventh right so imagine imagine if so what is being asked here find the faith node from the end of a singly linked register let's assume just for simplicity that K equals to three so it's asking for us it's asking us to find the third node from the end which means it's asking us to find this node because look at this couch I'm going in the reverse order right this is the third node from the end and that's what it's asking it's got it's asking us to find the eighth note from the end okay I hope this example is clear so if K equals to three for this link enlist that node value will be e right imagine if K was equal to 5 then what happens the fifth node from the end and that would be Nord C right and also remember faith node suppose if I know the number of nodes if I know the number of nodes is seven then the third node from the end look at this what is third node from the end so if I know n right it is going to be n minus k plus 1 node from the beginning right gate node from the end is nothing but K minus one plus one throwed from the beginning look at this here M equals to five M equals to 7 K equals to three so 7 minus 3 plus 1 equals 2/5 so the third node from the end here is nothing but the fifth node from the beginning similarly if K equals to 5 if I want the fifth node from the end what does it mean from the starting it is again 7 minus 5 plus 1 which is equal to 2 so the fifth node from the end is same as second node from the beginning right it's it's same as the second node from the beginning sorry did I mess up somewhere 7 minus 5 is 2 plus 1 is 3 sorry this has to be 3 not 2 7 minus 5 plus 1 right so it has to be the third node not the second node and hence the value will be C and not B I'm sorry I just messed up the math here right and this this this is correct n minus k plus 1 throughout from the beginning so the key observation the key observation here is if you knows if you know n first of all if you know him then take the node from end gate from end is same as n minus k plus 1 load from beginning this is a key observation that we will use to build a simple algorithm for this ok so not given this fact how do you solve this let us write our first version right so let's write the first first first pseudopod we always write our code with pseudocode first so that we have a good understanding and then we'll go to the proper code okay so let's go step by step first step is I have to compute n ok find n which is the number of find n ok how do I find end I'll start with the start node how do I find this it's very simple I start with a pointer pointing to the start node and nobody has given me the number of number of nodes in my linkedlist my input when somebody gives me singly linked list the input is going to be a pointer or a reference to the first node that's all they will give me right they'll give me a pointer or reference to the first node that's all they don't tell me how many how many nodes are having a singly linked list so not to find it out what do I do I initialize a pointer P to the start and then I keep traversing this I simply traverse this one by one by one in the time I reach a node and I'll keep I'll keep a counter obviously I'll keep a counter that will start with one and I'll keep going on till the time I find a node whose next pointer points to null right so that that's how I can find em so I can find n with one traversal with one traversal of the singly linked list and how much time does it take if the singly linked list has n nodes this takes order of n time because this is a simple for loop right okay that's step one step two once I've done that okay I will just compute I'll just compute a variable called X witch's because what is my input the input will be the start and the value of K okay then I'll say X equals to n minus k plus 1 right now if this value this is important if this value is 0 or less than 0 okay look at this if I have only seven elements and if somebody asks you to find the eighth element from the end that's of course like meaningless right so first I check whether this is greater than equal to one or not okay only then only then so this check has to be performed this is like a sanity check to ensure that they have not given you a value of K that is larger than that is larger than n okay if they give you then you should you should raise an alarm and say there is an error in your input value K once you do that then you basically again traverse you basically traverse the you traverse the linked list again from start to end again till till you from start to end till the time you reach X the node right you can always do that right again you create a pointer you keep a counter once you want in this very beginning you'll give it a value of 1 then you will keep incrementing that value till the time you reach the X the node and X is nothing but n minus k plus 1 right here again here again look at this this is order of 1 obviously because this is just a simple mathematical calculation and a simple logical check now this will require one more traversal this will require one more traversal let's say you K equals to 1 let's say human what is the worst case k equals to 1 in such a a sample tremors the whole list again in this case right so when it travels the whole list the worst case time complexity of this step is going to be order of n because I start with the first node I'll have to keep reversing till the time I get n minus k plus 1 to node if K equals to 1 this whole thing X becomes n so I might have to traverse the whole whole Lincoln list again right so what is the total time complexity of this the total time complexity is order of n itself but here I am doing two traversals I am doing one traversal here and I am doing another traversal here ok so this is basically an order of n time complexity algorithm there is no additional space except a few pointers so it's only order of one space very good but here I have two traversals let's not forget that I have two traversals right I have truth to traversals of malinger list okay this is this is a fast algorithm can I perform better so the question of the next question I have in my head is the next question can that I have here is of course while the time complexity is order of n space complexity is order of n very good instead of two traversals can I find can I find the case node from end the cave node from end using a single traversal using a single traversal right because a single traversal is going to be obviously taking less time than two traversals right so can you do this okay let's think about it let's think about how to how to do it intuitively okay so let's actually go back to the same diagram that we have we will reuse this diagram right imagine if I have so here is here is the fun part here is the here is idea or the key crux of the idea here imagine if I have two pointers okay let's assume I have a pointer P that points to the start node let's assume I also have a pointer Q that is pointing here okay so what I'll do here is this okay so step by step okay logically what I will do here is first I will find n okay actually I don't even have to find them to be honest okay let's not because you are wasting one traversal there right so I will not even find n what we'll do here is I just simply initialize two pointers cute - the start node okay first I will remove because I already know the value of K I will move my cue pointer by K steps imagine K equals to 3 imagine K is K equals to 3 remember I don't know n right love in this methodology because I've not reversed and hence I don't know n okay so I do not know n I don't know it's is a question mark for me okay I know that K equals to 3 so what do I do first I will move my Q pointer by 3 steps okay so I'm starting here so this is step 1 because I am already at the first node then I'll move it to second node I will move it to third node right so I basically moved it to the cliff node from the beginning okay so when I do that what happens let me just erase this okay so what are we doing here I'm moving my cute node to the faith node from the starting you my Q pointer I'm sorry I'm moving my Q pointer to the keith node from the beginning look at this my k equals to 3 right so I've moved it to the third pointer that's a first step now now comes the fun part now comes the ingenious part here ok now comes the innovation now what I'll do here is since it has moved three positions look at the gap that I have between these two ok then this is at 1 this is at 3 okay now I will move both these step by step so the way I do it is I will comment the Q pointer once and I'll increment the P pointer once so now what happens this will get this will move and this will also move so now my P will point to this so P was initially pointing to this right so P will now point to this right and Q will point to this basically what did I do I moved my Q pointer by one step I also moved my P pointer by one step okay again I will keep repeating this ok next step what will happen my P will now move now let's see what happens now if I keep doing this my P will now move here Mike you will move here right again Q will move here P will move here ok well they just let just run it so that we understand it better ok P will move here Q will move here if we notice there is always this gap between P and Q ok it is always this gap what is this gap exactly if you notice when T was here initially andcue was here what is this gap this gap is basically K minus 1 this gap look at this Hugh is a third position peas at first position so what is that gap that gap is exactly K minus 1 okay but anyway let's keep doing it so let's say you might keep moving Cuba one step and P by one step when I do that I keep doing it till the time till the time Q reaches the last node so what happens then when Q reaches here where would P reach P would be K minus 1 steps behind it which means P will be here now how do I know that I have reached the last node if the next point resistance very simple right if the next pointer is null I know that I've reached the last node right when Q next is null because Q is pointing to this when Q next is null I know that I've reached the last node and then this happens my P will reach the K the the Keith's node from the end because look at this wait where is my where is my Q love my Q is at enter node my Q is at enter node from the beginning right my Q is a tenth Road from the beginning okay so and I know that my P pointer is K minus 1 steps behind it okay so where is my K where is my P pointer it is at n minus k plus ones from the beginning and this is what we wanted earlier also even in the even in version one even the first solution that we had to traversals right at the end of it because n minus K minus 1 is nothing but n minus k plus 1 so in this approach in this approach I have literally done only one traversal of may I have only done one traversal I have not done through presses and still I am doing very good okay so let's write the simple pseudocode for it step by step step one okay initialize two pointers P and Q pointing to the start okay step two move Q moves Q by missed cube - not by move Q 2 - K its node from beginning to care node from beginning from from begin okay from the beginning okay once you do that now move P and Q nodes P and Q nodes step-by-step in tandem step by step in tandem basically means once you move it you move the other thing also that's what in tandem basically means in English right you move them step by step in tandem till the time till Q reaches till the time Q reaches the last node the last node once this reaches the last node once this reaches automatically P reaches automatically P reaches the n minus k plus 1 to load from begin from begin which is same as which is same as H node from end which is same as Kate node from and that's it whatever P is pointing to you return that value okay and in this whole exercise I have done again the time complexity of this look at this to move this I would take order of K time right now to do all of this again I would take order of M time right again when I'm moving this Q would only move n minus K steps right so the total time complexity of this you continue to the order of n time right and space complexity is again going to be order of 1 of course I have an additional pointer Q here in addition to P but that's ok just the constant time but the beauty of this approach is I am just solving it just in one traversal right I am just doing one prover cell of course using two pointers I am using two pointers here not a single pointer but still it's just a single traversal right very simple very elegant solution again lot of linkedlist problems lot of nice linkedlist problems can be solved using two pointers and some innovative solutions like this in the next video we'll see the code snippet for it line by line and and understand how actually everything's everything works together what we have seen right now with pseudocode my suggestion is always please write pseudocode like this because then converting this into code becomes easy this is basically explaining what you are doing in English right of course once you have this you have to be careful about converting this to code but it still\n"