Problem
Given a linked list and integer n
, write an algorithm to find the nth node from the end in the linked list.
Examples
Example 1:
Input: head=[1, 2, 8, 3, 7, 0, 4], n = 3
Output : 7
Explanation: 3rd Element from the end is : 7
1->2->8->3->7->0->4
3 2 1 <- indices from end
Solution
Method 1 – Naive - Finding Number of Nodes
We can first the size len
of linked list and then loop from start to len - n
nodes. Here is the code to Find the length of the linked list.
Code
Java
public ListNode getNthNodeFromLast(ListNode head, int n) {
ListNode curr = head;
int len = size(head); // takes O(n)
// assign current to head of the list
curr = head;
// nth node from end means (len-n)th node from start (assuming n is valid)
int counter = len - n;
while (counter != 0) {
// n is greater than size (len) of the linked list
// current pointer reaches null
if (curr == null) {
return null;
}
curr = curr.next;
counter--;
}
return curr;
}
Complexity
- ⏰ Time complexity:
O(n)
wheren
is length of linked list - 🧺 Space complexity:
O(1)
Method 2 - Recursion
- Recursively traverse the linked list.
- Upon reaching the end, the base case will return 0.
- As the stack unwinds, increment the count and return it.
- When the count equals
n
, print the value.
Code
Java
class Solution {
public ListNode getNthFromEnd(ListNode head, int n) {
ListNode[] ans = ListNode[1];
helper(head, n, ans);
return ans[0];
}
private int helper(ListNode head, int n, ListNode[] ans) {
if (head == null) {
return 0;
}
int index = helper(head.next, n, ans) + 1;
if (index == n) {
ans[0] = head;
}
return index;
}
}
Complexity
- ⏰ Time complexity:
O(n)
wheren
is length of linked list - 🧺 Space complexity:
O(n)
, assuming recursion stack
Method 3 – Using Two Pointer Technique
Algo
- Initialize slow and fast pointers at the head of the list.
- Move the fast pointer forward by
n
steps. If the fast pointer reaches the end before completingn
steps, returnnull
(indicatingn
is greater than the list’s length). - Move both slow and fast pointers one step at a time, maintaining a distance of
n
nodes between them. - Continue this until the fast pointer reaches the end of the list.
- Return the slow pointer, as it will be
n
nodes from the end, which is the target node.
Code
Java
public ListNode getNthNodeFromLast(ListNode head, int n) {
ListNode slow = head, fast = head;
int i = 0;
// Traverse over list and move fast pointer n nodes ahead
while (i < n && fast != null) {
fast = fast.next;
i++;
}
if (fast == null) {
return null; // List is shorter than n nodes
}
// Now, move both pointers together until fast reaches the end
while (fast != null) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
Complexity
- ⏰ Time complexity:
O(n)
wheren
is length of linked list - 🧺 Space complexity:
O(1)
Dry Run