Kth Node from the End of a Linked List

Last Updated : 28 Jul, 2026

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

1

Output: 8
Explanation:

2

The 2nd node from end is 8.

Input: k = 3

5

Output: 40
Explanation:

6

The 3rd node from the end is 40.

Input: k = 5

7

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.

Try It Yourself
redirect icon

[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>
using namespace std;

class Node
{
  public:
    int data;
    Node *next;

    Node(int x)
    {
        data = x;
        next = nullptr;
    }
};

int getKthFromLast(Node *head, int k)
{

    // Count the total number of nodes
    int cnt = 0;
    Node *curr = head;

    while (curr != nullptr)
    {
        cnt++;
        curr = curr->next;
    }

    // If k is greater than the list size
    if (k > cnt)
        return -1;

    // Move to the (cnt - k)th node
    curr = head;
    for (int i = 0; i < cnt - k; i++)
        curr = curr->next;

    return curr->data;
}

int main()
{

    Node *head = new Node(1);
    head->next = new Node(2);
    head->next->next = new Node(3);
    head->next->next->next = new Node(4);
    head->next->next->next->next = new Node(5);
    head->next->next->next->next->next = new Node(6);
    head->next->next->next->next->next->next = new Node(7);
    head->next->next->next->next->next->next->next = new Node(8);
    head->next->next->next->next->next->next->next->next = new Node(9);

    int k = 2;

    cout << getKthFromLast(head, k);

    return 0;
}
Java
class Node {
    public int data;
    public Node next;

    public Node(int x)
    {
        data = x;
        next = null;
    }
}

public class GFG {
    // Function to get the kth node from the last
    public static int getKthFromLast(Node head, int k)
    {
        // Count the total number of nodes
        int cnt = 0;
        Node curr = head;

        while (curr != null) {
            cnt++;
            curr = curr.next;
        }

        // If k is greater than the list size
        if (k > cnt)
            return -1;

        // Move to the (cnt - k)th node
        curr = head;
        for (int i = 0; i < cnt - k; i++)
            curr = curr.next;

        return curr.data;
    }

    public static void main(String[] args)
    {
        Node head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(3);
        head.next.next.next = new Node(4);
        head.next.next.next.next = new Node(5);
        head.next.next.next.next.next = new Node(6);
        head.next.next.next.next.next.next = new Node(7);
        head.next.next.next.next.next.next.next
            = new Node(8);
        head.next.next.next.next.next.next.next.next
            = new Node(9);

        int k = 2;
        System.out.println(getKthFromLast(head, k));
    }
}
Python
class Node:
    def __init__(self, x):
        self.data = x
        self.next = None

# Function to get the kth node from the last


def getKthFromLast(head, k):
    # Count the total number of nodes
    cnt = 0
    curr = head

    while curr is not None:
        cnt += 1
        curr = curr.next

    # If k is greater than the list size
    if k > cnt:
        return -1

    # Move to the (cnt - k)th node
    curr = head
    for i in range(cnt - k):
        curr = curr.next

    return curr.data


if __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 = 2
    print(getKthFromLast(head, k))
C#
public class Node {
    public int data;
    public Node next;

    public Node(int x)
    {
        data = x;
        next = null;
    }
}

public class GFG {
    // Function to get the kth node from the last
    public static int getKthFromLast(Node head, int k)
    {
        // Count the total number of nodes
        int cnt = 0;
        Node curr = head;

        while (curr != null) {
            cnt++;
            curr = curr.next;
        }

        // If k is greater than the list size
        if (k > cnt)
            return -1;

        // Move to the (cnt - k)th node
        curr = head;
        for (int i = 0; i < cnt - k; i++)
            curr = curr.next;

        return curr.data;
    }

    public static void Main()
    {
        Node head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(3);
        head.next.next.next = new Node(4);
        head.next.next.next.next = new Node(5);
        head.next.next.next.next.next = new Node(6);
        head.next.next.next.next.next.next = new Node(7);
        head.next.next.next.next.next.next.next
            = new Node(8);
        head.next.next.next.next.next.next.next.next
            = new Node(9);

        int k = 2;
        System.Console.WriteLine(getKthFromLast(head, k));
    }
}
JavaScript
class Node {
    constructor(x)
    {
        this.data = x;
        this.next = null;
    }
}

// Function to get the kth node from the last
function getKthFromLast(head, k)
{
    // Count the total number of nodes
    let cnt = 0;
    let curr = head;

    while (curr !== null) {
        cnt++;
        curr = curr.next;
    }

    // If k is greater than the list size
    if (k > cnt) {
        return -1;
    }

    // Move to the (cnt - k)th node
    curr = head;
    for (let i = 0; i < cnt - k; i++) {
        curr = curr.next;
    }

    return curr.data;
}

// Driver Code
let head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(4);
head.next.next.next.next = new Node(5);
head.next.next.next.next.next = new Node(6);
head.next.next.next.next.next.next = new Node(7);
head.next.next.next.next.next.next.next = new Node(8);
head.next.next.next.next.next.next.next.next = new Node(9);

let k = 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

1
  • 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.
12
C++
#include <iostream>
using namespace std;

class Node
{
  public:
    int data;
    Node *next;

    Node(int x)
    {
        data = x;
        next = nullptr;
    }
};

int getKthFromLast(Node *head, int k)
{

    // Two-pointer approach to find the kth node from the end
    Node *fast = head;
    Node *slow = head;

    // Move the fast pointer k steps ahead
    while (k--)
    {
        if (fast == nullptr)
            return -1;
        fast = fast->next;
    }

    // Move both pointers until fast reaches the end
    while (fast != nullptr)
    {
        slow = slow->next;
        fast = fast->next;
    }

    // slow now points to the kth node from the end
    return (slow != nullptr) ? slow->data : -1;
}

int main()
{

    Node *head = new Node(1);
    head->next = new Node(2);
    head->next->next = new Node(3);
    head->next->next->next = new Node(4);
    head->next->next->next->next = new Node(5);
    head->next->next->next->next->next = new Node(6);
    head->next->next->next->next->next->next = new Node(7);
    head->next->next->next->next->next->next->next = new Node(8);
    head->next->next->next->next->next->next->next->next = new Node(9);

    int k = 2;

    cout << getKthFromLast(head, k);

    return 0;
}
Java
import java.util.*;

class Node {
    public int data;
    Node next;

    Node(int x)
    {
        data = x;
        next = null;
    }
}

public class GFG {

    int getKthFromLast(Node head, int k)
    {

        // Two-pointer approach to find the kth node from
        // the end
        Node fast = head;
        Node slow = head;

        // Move the fast pointer k steps ahead
        while (k-- > 0) {
            if (fast == null)
                return -1;
            fast = fast.next;
        }

        // Move both pointers until fast reaches the end
        while (fast != null) {
            slow = slow.next;
            fast = fast.next;
        }

        // slow now points to the kth node from the end
        return (slow != null) ? slow.data : -1;
    }

    public static void main(String[] args)
    {
        GFG solution = new GFG();
        Node head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(3);
        head.next.next.next = new Node(4);
        head.next.next.next.next = new Node(5);
        head.next.next.next.next.next = new Node(6);
        head.next.next.next.next.next.next = new Node(7);
        head.next.next.next.next.next.next.next
            = new Node(8);
        head.next.next.next.next.next.next.next.next
            = new Node(9);

        int k = 2;

        System.out.println(
            solution.getKthFromLast(head, k));
    }
}
Python
class Node:
    def __init__(self, x):
        self.data = x
        self.next = None


def getKthFromLast(head, k):

    # Two-pointer approach to find the kth node from the end
    fast = head
    slow = head

    # Move the fast pointer k steps ahead
    while k > 0:
        if fast is None:
            return -1
        fast = fast.next
        k -= 1

    # Move both pointers until fast reaches the end
    while fast is not None:
        slow = slow.next
        fast = fast.next

    # slow now points to the kth node from the end
    return slow.data if slow is not None else -1


if __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 = 2

    print(getKthFromLast(head, k))
C#
using System;

public class Node {
    public int data;
    public Node next;

    public Node(int x)
    {
        data = x;
        next = null;
    }
}

public class GFG {
    public int getKthFromLast(Node head, int k)
    {

        // Two-pointer approach to find the kth node from
        // the end
        Node fast = head;
        Node slow = head;

        // Move the fast pointer k steps ahead
        while (k-- > 0) {
            if (fast == null)
                return -1;
            fast = fast.next;
        }

        // Move both pointers until fast reaches the end
        while (fast != null) {
            slow = slow.next;
            fast = fast.next;
        }

        // slow now points to the kth node from the end
        return (slow != null) ? slow.data : -1;
    }

    public static void Main()
    {
        GFG solution = new GFG();
        Node head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(3);
        head.next.next.next = new Node(4);
        head.next.next.next.next = new Node(5);
        head.next.next.next.next.next = new Node(6);
        head.next.next.next.next.next.next = new Node(7);
        head.next.next.next.next.next.next.next
            = new Node(8);
        head.next.next.next.next.next.next.next.next
            = new Node(9);

        int k = 2;

        Console.WriteLine(solution.getKthFromLast(head, k));
    }
}
JavaScript
class Node {
    constructor(x)
    {
        this.data = x;
        this.next = null;
    }
}

function getKthFromLast(head, k)
{

    // Two-pointer approach to find the kth node from the
    // end
    let fast = head;
    let slow = head;

    // Move the fast pointer k steps ahead
    while (k-- > 0) {
        if (fast === null)
            return -1;
        fast = fast.next;
    }

    // Move both pointers until fast reaches the end
    while (fast !== null) {
        slow = slow.next;
        fast = fast.next;
    }

    // slow now points to the kth node from the end
    return slow !== null ? slow.data : -1;
}

// Driver Code
let head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.next.next.next = new Node(4);
head.next.next.next.next = new Node(5);
head.next.next.next.next.next = new Node(6);
head.next.next.next.next.next.next = new Node(7);
head.next.next.next.next.next.next.next = new Node(8);
head.next.next.next.next.next.next.next.next = new Node(9);

let k = 2;

console.log(getKthFromLast(head, k));

Output
8
Comment