Given the head of a linked list and an integer k, return the kth node from the end of the linked list. If k is greater than the number of nodes in the list, return -1.
Examples:
Input: k = 2
Output: 8 Explanation:
The 2nd node from end is 8.
Input: k = 3
Output: 40 Explanation:
The 3rd node from the end is 40.
Input: k = 5
Output: -1 Explanation: The given linked list is 10 -> 5 -> 100 -> 5. Since 'k' is more than the number of nodes, the output is -1.
[Naive Approach] Count Nodes and Find the Required Node - O(n) Time and O(1) Space
The idea is to first count the total number of nodes in the linked list. If k is greater than the number of nodes, return -1. Otherwise, traverse the list again to reach the (count - k)th node from the beginning and return its data.
Working of Approach:
Traverse the linked list once to count the total number of nodes.
If k > count, the required node does not exist.
Otherwise, move (count - k) steps from the head.
Return the data of the current node.
C++
#include<iostream>usingnamespacestd;classNode{public:intdata;Node*next;Node(intx){data=x;next=nullptr;}};intgetKthFromLast(Node*head,intk){// Count the total number of nodesintcnt=0;Node*curr=head;while(curr!=nullptr){cnt++;curr=curr->next;}// If k is greater than the list sizeif(k>cnt)return-1;// Move to the (cnt - k)th nodecurr=head;for(inti=0;i<cnt-k;i++)curr=curr->next;returncurr->data;}intmain(){Node*head=newNode(1);head->next=newNode(2);head->next->next=newNode(3);head->next->next->next=newNode(4);head->next->next->next->next=newNode(5);head->next->next->next->next->next=newNode(6);head->next->next->next->next->next->next=newNode(7);head->next->next->next->next->next->next->next=newNode(8);head->next->next->next->next->next->next->next->next=newNode(9);intk=2;cout<<getKthFromLast(head,k);return0;}
Java
classNode{publicintdata;publicNodenext;publicNode(intx){data=x;next=null;}}publicclassGFG{// Function to get the kth node from the lastpublicstaticintgetKthFromLast(Nodehead,intk){// Count the total number of nodesintcnt=0;Nodecurr=head;while(curr!=null){cnt++;curr=curr.next;}// If k is greater than the list sizeif(k>cnt)return-1;// Move to the (cnt - k)th nodecurr=head;for(inti=0;i<cnt-k;i++)curr=curr.next;returncurr.data;}publicstaticvoidmain(String[]args){Nodehead=newNode(1);head.next=newNode(2);head.next.next=newNode(3);head.next.next.next=newNode(4);head.next.next.next.next=newNode(5);head.next.next.next.next.next=newNode(6);head.next.next.next.next.next.next=newNode(7);head.next.next.next.next.next.next.next=newNode(8);head.next.next.next.next.next.next.next.next=newNode(9);intk=2;System.out.println(getKthFromLast(head,k));}}
Python
classNode:def__init__(self,x):self.data=xself.next=None# Function to get the kth node from the lastdefgetKthFromLast(head,k):# Count the total number of nodescnt=0curr=headwhilecurrisnotNone:cnt+=1curr=curr.next# If k is greater than the list sizeifk>cnt:return-1# Move to the (cnt - k)th nodecurr=headforiinrange(cnt-k):curr=curr.nextreturncurr.dataif__name__=='__main__':head=Node(1)head.next=Node(2)head.next.next=Node(3)head.next.next.next=Node(4)head.next.next.next.next=Node(5)head.next.next.next.next.next=Node(6)head.next.next.next.next.next.next=Node(7)head.next.next.next.next.next.next.next=Node(8)head.next.next.next.next.next.next.next.next=Node(9)k=2print(getKthFromLast(head,k))
C#
publicclassNode{publicintdata;publicNodenext;publicNode(intx){data=x;next=null;}}publicclassGFG{// Function to get the kth node from the lastpublicstaticintgetKthFromLast(Nodehead,intk){// Count the total number of nodesintcnt=0;Nodecurr=head;while(curr!=null){cnt++;curr=curr.next;}// If k is greater than the list sizeif(k>cnt)return-1;// Move to the (cnt - k)th nodecurr=head;for(inti=0;i<cnt-k;i++)curr=curr.next;returncurr.data;}publicstaticvoidMain(){Nodehead=newNode(1);head.next=newNode(2);head.next.next=newNode(3);head.next.next.next=newNode(4);head.next.next.next.next=newNode(5);head.next.next.next.next.next=newNode(6);head.next.next.next.next.next.next=newNode(7);head.next.next.next.next.next.next.next=newNode(8);head.next.next.next.next.next.next.next.next=newNode(9);intk=2;System.Console.WriteLine(getKthFromLast(head,k));}}
JavaScript
classNode{constructor(x){this.data=x;this.next=null;}}// Function to get the kth node from the lastfunctiongetKthFromLast(head,k){// Count the total number of nodesletcnt=0;letcurr=head;while(curr!==null){cnt++;curr=curr.next;}// If k is greater than the list sizeif(k>cnt){return-1;}// Move to the (cnt - k)th nodecurr=head;for(leti=0;i<cnt-k;i++){curr=curr.next;}returncurr.data;}// Driver Codelethead=newNode(1);head.next=newNode(2);head.next.next=newNode(3);head.next.next.next=newNode(4);head.next.next.next.next=newNode(5);head.next.next.next.next.next=newNode(6);head.next.next.next.next.next.next=newNode(7);head.next.next.next.next.next.next.next=newNode(8);head.next.next.next.next.next.next.next.next=newNode(9);letk=2;console.log(getKthFromLast(head,k));
Output
8
[Expected Approach] Using Two Pointer Technique - O(n) Time and O(1) Space
The idea is to use two pointers with a gap of k nodes between them. First, move the fast pointer k steps ahead. Then move both pointers together until the fast pointer reaches the end. At this point, the slow pointer will be pointing to the kth node from the end.
Working of Approach:
Initialize two pointers, fast and slow, at the head.
Move fast ahead by k nodes. If it becomes nullptr before completing k steps, return -1.
Move both pointers one step at a time until fast reaches the end.
Return the data of the slow pointer.
Let us understand with an example: Input: k = 2
Move the fast pointer 2 steps ahead, so fast is at node 3 while slow remains at node 1.
Now move both pointers one step at a time until fast reaches the end of the list.
When fast becomes nullptr, slow will be at node 8.
This happens because the gap of 2 nodes between fast and slow is maintained throughout the traversal.
Hence, the 2nd node from the end is 8, so the answer is 8.
C++
#include<iostream>usingnamespacestd;classNode{public:intdata;Node*next;Node(intx){data=x;next=nullptr;}};intgetKthFromLast(Node*head,intk){// Two-pointer approach to find the kth node from the endNode*fast=head;Node*slow=head;// Move the fast pointer k steps aheadwhile(k--){if(fast==nullptr)return-1;fast=fast->next;}// Move both pointers until fast reaches the endwhile(fast!=nullptr){slow=slow->next;fast=fast->next;}// slow now points to the kth node from the endreturn(slow!=nullptr)?slow->data:-1;}intmain(){Node*head=newNode(1);head->next=newNode(2);head->next->next=newNode(3);head->next->next->next=newNode(4);head->next->next->next->next=newNode(5);head->next->next->next->next->next=newNode(6);head->next->next->next->next->next->next=newNode(7);head->next->next->next->next->next->next->next=newNode(8);head->next->next->next->next->next->next->next->next=newNode(9);intk=2;cout<<getKthFromLast(head,k);return0;}
Java
importjava.util.*;classNode{publicintdata;Nodenext;Node(intx){data=x;next=null;}}publicclassGFG{intgetKthFromLast(Nodehead,intk){// Two-pointer approach to find the kth node from// the endNodefast=head;Nodeslow=head;// Move the fast pointer k steps aheadwhile(k-->0){if(fast==null)return-1;fast=fast.next;}// Move both pointers until fast reaches the endwhile(fast!=null){slow=slow.next;fast=fast.next;}// slow now points to the kth node from the endreturn(slow!=null)?slow.data:-1;}publicstaticvoidmain(String[]args){GFGsolution=newGFG();Nodehead=newNode(1);head.next=newNode(2);head.next.next=newNode(3);head.next.next.next=newNode(4);head.next.next.next.next=newNode(5);head.next.next.next.next.next=newNode(6);head.next.next.next.next.next.next=newNode(7);head.next.next.next.next.next.next.next=newNode(8);head.next.next.next.next.next.next.next.next=newNode(9);intk=2;System.out.println(solution.getKthFromLast(head,k));}}
Python
classNode:def__init__(self,x):self.data=xself.next=NonedefgetKthFromLast(head,k):# Two-pointer approach to find the kth node from the endfast=headslow=head# Move the fast pointer k steps aheadwhilek>0:iffastisNone:return-1fast=fast.nextk-=1# Move both pointers until fast reaches the endwhilefastisnotNone:slow=slow.nextfast=fast.next# slow now points to the kth node from the endreturnslow.dataifslowisnotNoneelse-1if__name__=='__main__':head=Node(1)head.next=Node(2)head.next.next=Node(3)head.next.next.next=Node(4)head.next.next.next.next=Node(5)head.next.next.next.next.next=Node(6)head.next.next.next.next.next.next=Node(7)head.next.next.next.next.next.next.next=Node(8)head.next.next.next.next.next.next.next.next=Node(9)k=2print(getKthFromLast(head,k))
C#
usingSystem;publicclassNode{publicintdata;publicNodenext;publicNode(intx){data=x;next=null;}}publicclassGFG{publicintgetKthFromLast(Nodehead,intk){// Two-pointer approach to find the kth node from// the endNodefast=head;Nodeslow=head;// Move the fast pointer k steps aheadwhile(k-->0){if(fast==null)return-1;fast=fast.next;}// Move both pointers until fast reaches the endwhile(fast!=null){slow=slow.next;fast=fast.next;}// slow now points to the kth node from the endreturn(slow!=null)?slow.data:-1;}publicstaticvoidMain(){GFGsolution=newGFG();Nodehead=newNode(1);head.next=newNode(2);head.next.next=newNode(3);head.next.next.next=newNode(4);head.next.next.next.next=newNode(5);head.next.next.next.next.next=newNode(6);head.next.next.next.next.next.next=newNode(7);head.next.next.next.next.next.next.next=newNode(8);head.next.next.next.next.next.next.next.next=newNode(9);intk=2;Console.WriteLine(solution.getKthFromLast(head,k));}}
JavaScript
classNode{constructor(x){this.data=x;this.next=null;}}functiongetKthFromLast(head,k){// Two-pointer approach to find the kth node from the// endletfast=head;letslow=head;// Move the fast pointer k steps aheadwhile(k-->0){if(fast===null)return-1;fast=fast.next;}// Move both pointers until fast reaches the endwhile(fast!==null){slow=slow.next;fast=fast.next;}// slow now points to the kth node from the endreturnslow!==null?slow.data:-1;}// Driver Codelethead=newNode(1);head.next=newNode(2);head.next.next=newNode(3);head.next.next.next=newNode(4);head.next.next.next.next=newNode(5);head.next.next.next.next.next=newNode(6);head.next.next.next.next.next.next=newNode(7);head.next.next.next.next.next.next.next=newNode(8);head.next.next.next.next.next.next.next.next=newNode(9);letk=2;console.log(getKthFromLast(head,k));