The following function is trying to find the nth to last element of a singly linked list.
For example:
If the elements are
There are lots of answers here already, but they all walk the list twice (either sequentially or in parallel) or use a lot of extra storage.
You can do this while walking the list just once (plus a little bit) using constant extra space:
Node *getNthFromEnd(Node *list, int n) {
if (list == null || n<1) {
return null; //no such element
}
Node *mark1 = list, *mark2 = list, *markend = list;
int pos1 = 0, pos2 = 0, posend = 0;
while (markend!=null) {
if ((posend-pos2)>=(n-1)) {
mark1=mark2;
pos1=pos2;
mark2=markend;
pos2=posend;
}
markend=markend->next;
++posend;
}
if (posend n) {
mark1 = mark1->next;
++pos1;
}
return mark1;
}
This version uses 2 extra pointers does less than N+n traversals, where N is the length of the list and n is the argument.
If you use M extra pointers, you can get that down to N+ceil(n/(M-1)) (and you should store them in a circular buffer)