【单链表】返回倒数的第index个节点

本文介绍了一种在链表中查找倒数第index个节点的方法,包括三种不同的实现方式,并分析了各自的优缺点。方法1通过设置两个指针实现,通过移动其中一个指针来达到间隔index个节点的目的;方法2先求链表长度再遍历,但效率较低;方法3则是将链表倒置,操作直观但效率不如前两者。
方法 1:
1. 设置两个指针 p1, p2
2. 首先 p1 和 p2 都指向 head
3. 然后 p2 向前走 index 步,这样 p1 和 p2 之间就间隔 index 个节点
4. 然后 p1 和 p2 同时向前步进,当 p2 到达最后一个节点时,p1 就是倒数第 index 个节点了
node *fun(node * head, int index)
{
    node *ptr1,*ptr2;
    int i = 0;
    ptr1 = head;
    ptr2 = head;
    if( head == NULL || head->next == NULL )
        return ptr1;
    
    while(i<index)   //保证向后移动index个位置
    {
        ptr1 = ptr1->next;
        if(ptr1 == NULL)
            return head;
        i++;
    }

    while(ptr1->next != NULL)
    {
        ptr1 = ptr1->next;
        ptr2 = ptr2->next;
    }

    return *ptr2;
}
 
方法 2:遍历链表求出总长 count,遍历第二次,第 count-index 个节点就是倒数第 index 个节点
缺点:比方法 1 多出了求总长时的 count++(动作)。

方法 3:将链表倒置。直观,但是效率比方法 1 和方法 2 的效率低,而且需要改变链表或者新建一个逆序链表。
删除链表中倒数第 N 个节点可以通过以下两种方法实现: ### 方法一:两次遍历法 先统计链表的总节点数,再计算出要删除的节点是正数第几个,最后进行删除操作。 - 设两个指针同时指向链表的第一个节点一个指针遍历链表统计出总共有多少个节点记为 `i`,用总数减去 `N`,即可以算出要删除的节点为正数第几个节点记为 `index = i - N`,让另一个指针移动到 `index` 节点的前一个节点(如果要删除的节点不是第一个节点)。 - 最后执行删除操作,如果要删除的节点为第一个节点,则需要修改头指针,反之,则直接删除即可 [^1]。 以下是 Java 代码示例: ```java /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { int j; // 删除的是正数第 j 个结点 int k = 1; int i = 0; // 统计结点总数 if (head == null) { return head; } ListNode list1 = head; while (list1 != null) { i++; list1 = list1.next; } if (n == i) { head = head.next; return head; } if (i == 1) { return null; } j = i - n + 1; list1 = head; while (k < j - 1) { list1 = list1.next; k++; } if (n == 1) { list1.next = null; return head; } list1.next = list1.next.next; return head; } } ``` ### 方法二:快慢指针法 利用快慢指针,让 `slow` 指针指向第一个节点,让 `fast` 指针和 `slow` 间隔 `N` 个节点,即指向第 `N` 个节点。然后同时移动 `slow` 和 `fast`,每次前进一步,直到 `fast` 指针到最后一个指针,此时 `slow` 指针就是倒数第 `N` 个节点。找到第 `N` 个节点之后需要删除掉这个节点,因为是单链表,必须保留被删除节点之前的这个节点,以及被删除节点之后的那个节点,接着桥接上前后的节点 [^3]。 以下是 Python 代码示例: ```python # 定义链表节点类 class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def removeNthFromEnd(head, n): dummy = ListNode(0) dummy.next = head slow = dummy fast = dummy # 让 fast 指针先移动 n 步 for _ in range(n + 1): fast = fast.next # 同时移动 slow 和 fast 指针 while fast: slow = slow.next fast = fast.next # 删除倒数第 n 个节点 slow.next = slow.next.next return dummy.next ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值