The following function is trying to find the nth
to last element of a singly linked list.
For example:
If the elements are
Since this sounds like homework, I prefer to help you help yourself instead of giving an actual solution.
I suggest you run this code on some small sample dataset. Use your debugger to run lines step-by-step (you can set a breakpoint at the start of the function). This should give you an idea of how the code works.
You can also Console.WriteLine()
to output variables of interest.
public int nthFromLast(int n){
Node current = head;
Node reference = head;
for(int i=0;i<n;i++){
reference=reference.getNext();
}
while(reference != null){
current = current.getNext();
reference = reference.getNext();
}
return current.getData();
}
In java i will use-
public class LL {
Node head;
int linksCount;
LL(){
head = new Node();
linksCount = 0;
}
//TRAVERSE TO INDEX
public Node getNodeAt(int index){
Node temp= head;
if(index > linksCount){
System.out.println("index out of bound !");
return null;
}
for(int i=0;i<index && (temp.getNext() != null);i++){
temp = temp.getNext();
}
return temp.getNext();
}
}
To understand this problem, we should do a simple analogy with a measurement example. Let's say, you have to find the place of your arm where exactly 1 meter away from your middle finger, how would you measure? You would just grab a ruler with a 1-meter length and put the top-end of that ruler to the tip of your middle-finger and the bottom-end of the meter will be exactly 1 meter away from the top of your middle-finger.
What we do in this example will be the same, we just need a frame with n-element wide and what we have to do is put the frame to the end of the list, thus the start node of the frame will be exactly n-th element to the end of the list.
This is our list assuming we have M elements in the list, and our frame with N element wide;
HEAD -> EL(1) -> EL(2) -> ... -> EL(M-1) -> EL(M)
<-- Frame -->
However, we only need the boundaries of the frame, thus the end boundary of the frame will exactly (N-1) elements away from the start boundary of the frame. So have to only store these boundary elements. Let's call them A and B;
HEAD -> EL(1) -> EL(2) -> ... -> EL(M-1) -> EL(M)
A <- N-Element Wide-> B
The first thing we have to do is finding B, which is the end of the frame.
ListNode<T> b = head;
int count = 1;
while(count < n && b != null) {
b = b.next;
count++;
}
Now b is the n-th element of the array, and a is located on the HEAD. So our frame is set, what we will do is increment both boundary nodes step by step until b reachs to the end of the list where a will be n-th-to-the-last element;
ListNode<T> a = head;
while(b.next != null) {
a = a.next;
b = b.next;
}
return a;
To gather up everything, and with the HEAD checks, N < M (where M is the size of the list) checks and other stuff, here is the complete solution method;
public ListNode<T> findNthToLast(int n) {
if(head == null) {
return null;
} else {
ListNode<T> b = head;
int count = 1;
while(count < n && b != null) {
b = b.next;
count++;
}
if(count == n && b!=null) {
ListNode<T> a = head;
while(b.next != null) {
a = a.next;
b = b.next;
}
return a;
} else {
System.out.print("N(" + n + ") must be equal or smaller then the size of the list");
return null;
}
}
}
Here is the code using 2 pointer approach : ( source )
struct node
{
int data;
struct node *next;
}mynode;
mynode * nthNodeFrmEnd(mynode *head, int n /*pass 0 for last node*/)
{
mynode *ptr1,*ptr2;
int count;
if(!head)
{
return(NULL);
}
ptr1 = head;
ptr2 = head;
count = 0;
while(count < n)
{
count++;
if((ptr1=ptr1->next)==NULL)
{
//Length of the linked list less than n. Error.
return(NULL);
}
}
while((ptr1=ptr1->next)!=NULL)
{
ptr2=ptr2->next;
}
return(ptr2);
}
node* findNthNode (node* head, int find, int& found){
if(!head) {
found = 1;
return 0;
}
node* retval = findNthNode(head->next, find, found);
if(found==find)
retval = head;
found = found + 1;
return retval;
}
Here is C# version of finding nth child from Linklist.
public Node GetNthLast(Node head, int n)
{
Node current, nth;
current = nth = head;
int counter = 0;
while (current.next != null)
{
counter++;
if (counter % n == 0)
{
for (var i = 0; i < n - 1; i++)
{
nth = nth.next;
}
}
current = current.next;
}
var remainingCounts = counter % n;
for (var i = 0; i < remainingCounts; i++)
{
nth = nth.next;
}
return nth;
}