链表中倒数的第N个节点如何查找

博客介绍了在单向链表中查找倒数第N个结点位置的方法。采用2个指针,前指针先偏移N个位置,后指针指向链表头部,然后前后指针同时向后偏移,当前指针指向NULL时,后指针所指即为倒数第N个节点位置,还给出了代码。

一个单向链表,查找倒数的第N个结点位置

主要思想:2个指针办法,前指针偏移N个位置,后指针指向链表头部

前后指针同时向后偏移,当前指针指向NULL,此时后指针就是倒数N个节点位置

代码如下:

/*
*@author: 赵秋然
*@date:2021年1月10日
*@description:链表倒数结点
*@param head:链表
*@param k:倒数的位置
*@return: 返回链表指针
*/

int getLength(ListNode *head)
{
    ListNode *cur = head;
    int len = 0;
    while (cur)
    {
        cur = cur->next;
        ++len;
    }

    return len;
}

ListNode *getReciprocal(ListNode *head, int k)
{
    if (head == NULL || k == 0)
    {
        return head;
    }

    int len = getLength(head);
    if (k >= len)
    {
        return head;
    }
    ListNode *cur = head, *fcur = head;
    while (k > 0)
    {
        fcur = fcur->next;
        if (fcur == NULL)
        {
            return NULL;
        }

        --k;
    }

    while (fcur)
    {
        cur = cur->next;
        fcur = fcur->next;
    }

    return cur;
}

 

在Java中,实现删除链表倒数第N个节点有两种常见的方法,分别是递归法和双指针法。 ### 递归法 递归法的思路是通过递归函数检查当前节点的下一个节点倒数第几个节点,并在满足条件时删除目标节点。 ```java class ListNode { int val; ListNode next; ListNode() {} ListNode(int val) { this.val = val; } ListNode(int val, ListNode next) { this.val = val; this.next = next; } public ListNode getNext() { return next; } public void setNext(ListNode next) { this.next = next; } } public class Solution { /** * 删除倒数第n个节点 * @param head 头结点 * @param n 倒数第n个节点 * @return 删除倒数第n个节点后的链表 */ public ListNode removeNthFromEnd(final ListNode head, final int n) { ListNode s = new ListNode(-1, head); // 头哨兵 checkAndDel(s, n); return s.getNext(); } /** * 检查当前节点的下一个节点倒数第几个节点并且删除目标节点 * @param node 当前节点 * @param n 目标 * @return 当前节点的下一个节点倒数第几个节点 */ private int checkAndDel(final ListNode node, final int n) { if (node.getNext() == null) { // 如果当前节点的下一个节点为空,说明已经到了最后一个节点返回0 return 0; } else { int num = checkAndDel(node.getNext(), n) + 1; // 当前节点的下一个节点倒数第几个节点 if (num == n) { // 如果当前节点的下一个节点倒数第n个节点,就删除当前节点的下一个节点 node.setNext(node.getNext().getNext()); } return num; // 返回当前节点的下一个节点倒数第几个节点 } } } ``` ### 双指针法 双指针法的思路是使用两个指针,一个右指针先移动N步,然后左右指针同时移动,当右指针到达链表末尾时,左指针刚好指向要删除节点的前一个节点,然后删除该节点。 ```java class ListNode { int val; ListNode next; ListNode() {} ListNode(int val) { this.val = val; } ListNode(int val, ListNode next) { this.val = val; this.next = next; } } class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { ListNode ans = new ListNode(0, head); ListNode left = ans; ListNode right = ans; while (n-- > 0) { right = right.next; } while (right.next != null) { left = left.next; right = right.next; } left.next = left.next.next; return ans.next; } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值