Linked List (Singly Linked List)Find the Nth node from the end

Find the Nth node from the end

16 mins read The Jat Easy Updated 11 महीने पहले
Linked ListLinked List

Problem Statement

Given a singly linked list and an integer n. Find the nth node from the end of the linked list and return its value.

If n is greater than the length of the list, return a message indicating that the position is out of bounds.

Examples

Example 1:

Input: List 1 -> 2 -> 3 -> 4 -> 5 -> nullptr, N = 2
Output: 4

Explanation: The second node from the last is 4 while 5 is the last node.
Example 2:

Input: List 1 -> 2 -> 3 -> 4 -> 5 -> nullptr, N = 5
Output: 1

Explanation: The fifth node from the last is 1.

Different Approaches

1️⃣ Iterative Approach

Intuition:

We can solve this problem using one of the derivation of Two-Pointers technique | pattern which is Lead and Lag pointers.

The lead and lag pointer technique involves using two pointers (often referred to as the "lead" and "lag" pointers):

  1. Lead Pointer: This pointer will be moved n steps ahead in the linked list.
  2. Lag Pointer: This pointer will start from the head and will move simultaneously with the lead pointer after the lead pointer has moved n steps.
  • By moving the lead pointer n steps ahead first, the distance between the lead and lag pointers becomes n nodes.
  • When the lead pointer reaches the end of the list, the lag pointer will be exactly n nodes behind it, hence pointing to the nth node from the end.

Approach:

  1. Initialize both pointers: Start with both pointers (lead and lag) at the head of the linked list.
  2. Advance the lead pointer: Move the lead pointer n steps forward.
  3. Check out-of-bounds: If the lead pointer reaches nullptr before completing n steps, then n is larger than the number of nodes in the list.
  4. Move both pointers together: Move both pointers one step at a time until the lead pointer reaches the end of the list.
  5. Output: The lag pointer will be pointing at the nth node from the end.

Code:

#include <iostream>

struct ListNode {
    int data;
    ListNode* next;
    ListNode(int x) : data(x), next(nullptr) {}
};

// Function to find the nth node from the end of the linked list using lead and lag pointers
int findNthFromEnd(ListNode* head, int n) {
    ListNode* lead = head;  // Lead pointer
    ListNode* lag = head;   // Lag pointer

    // Step 1: Move the lead pointer n steps ahead
    for (int i = 0; i < n; ++i) {
        if (lead == nullptr) {
            std::cout << "Out of bounds" << std::endl;
            return -1; // Out of bounds
        }
        lead = lead->next;
    }

    // Step 2: Move both pointers until lead reaches the end
    while (lead != nullptr) {
        lead = lead->next;
        lag = lag->next;
    }

    // Step 3: The lag pointer is now pointing to the nth node from the end
    if (lag != nullptr) {
        return lag->data;
    } else {
        std::cout << "Out of bounds" << std::endl;
        return -1; // Out of bounds
    }
}

// Helper function to print the linked list
void printList(ListNode* head) {
    while (head != nullptr) {
        std::cout << head->data << " -> ";
        head = head->next;
    }
    std::cout << "nullptr" << std::endl;
}

int main() {
    // Create a simple linked list with initial elements
    ListNode* head = new ListNode(1);
    head->next = new ListNode(2);
    head->next->next = new ListNode(3);
    head->next->next->next = new ListNode(4);
    head->next->next->next->next = new ListNode(5);

    std::cout << "Original list: ";
    printList(head);

    // Find the 2nd node from the end
    int n = 2;
    int result = findNthFromEnd(head, n);
    if (result != -1) {
        std::cout << "The " << n << "th node from the end is: " << result << std::endl;
    }

    // Find the 5th node from the end
    n = 5;
    result = findNthFromEnd(head, n);
    if (result != -1) {
        std::cout << "The " << n << "th node from the end is: " << result << std::endl;
    }

    // Find the 6th node from the end (Out of bounds)
    n = 6;
    result = findNthFromEnd(head, n);
    if (result != -1) {
        std::cout << "The " << n << "th node from the end is: " << result << std::endl;
    }

    return 0;
}

Complexity Analysis:

  • Time Complexity: O(n)
    • The function only traverses the list once. First, it moves the lead pointer n steps ahead, and then it moves both pointers until the lead pointer reaches the end. This results in a linear time complexity relative to the number of nodes (n) in the list.
  • Space Complexity: O(1)
    • The solution uses a fixed amount of extra space (two pointers), so the space complexity is constant.
Buy Me A Coffee

Leave a comment

Your email address will not be published. Required fields are marked *

Your experience on this site will be improved by allowing cookies Cookie Policy