Lintcode 174.删除链表中倒数第n个节点

本文介绍了一种高效算法,用于删除单链表中倒数第N个节点。该方法通过双指针技巧实现,首先让前导指针移动N步,随后两个指针同步移动直至前导指针到达链表尾部。此时,另一个指针指向待删除节点的前一个节点,从而完成删除操作。

1.问题描述:给定一个链表,删除链表中倒数第n个节点,返回链表的头节点。

2.解题思路:head先走了n步,这样head和temp之间差n个节点,之后head和temp一起往后移动,当head移动到了NULL的时候,temp移动到了倒数第n+1个节点的位置,之时候改变temp->next将他指向他的下一个节点的下一个节点,这样就是把倒数第n个节点给删掉了。

3.通过的代码

/**
 * Definition of ListNode
 * class ListNode {
 * public:
 *     int val;
 *     ListNode *next;
 *     ListNode(int val) {
 *         this->val = val;
 *         this->next = NULL;
 *     }
 * }
 */
class Solution {
public:
    /**
     * @param head: The first node of linked list.
     * @param n: An integer.
     * @return: The head of linked list.
     */
    ListNode *removeNthFromEnd(ListNode *head, int n) {
        // write your code here
        ListNode *del=new ListNode(0);
        del->next=head;
        ListNode *temp=del;
        for(int i=0;i<n;i++){head=head->next;}
        while(head!=NULL){head=head->next;temp=temp->next;}
        temp->next=temp->next->next;
        return del->next;
    }
};

4.感想:自己刚开始做题的时候,通常就是看到一个题没有任何思路,自己不知道如何来解决它,然后自己就会问问别人思路是什么,在网上搜搜答案,搞懂了别人的代码的意思。这种过程就是一个逐步积累的过程,自己的思维也会扩展,比如看这个题的时候,自己有了想法,对于主要的代码,自己也知道怎么写。相比于以前自己能思考出来了,这是一种慢慢的进步。

删除链表倒数第 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 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值