LeetCode_Medium_19. Remove Nth Node From End of List

本文介绍了一种高效算法,用于在单链表中删除倒数第N个结点,提供了两种解法:一是使用双指针法,实现一次遍历;二是通过两次遍历获取链表长度,再定位目标结点。代码示例采用C++和Java实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2019.1.30

题目描述:

Given a linked list, remove the n-th node from the end of list and return its head.

Example:

Given linked list: 1->2->3->4->5, and n = 2.

After removing the second node from the end, the linked list becomes 1->2->3->5.

Note:

Given n will always be valid.

Follow up:

Could you do this in one pass?

这题是求一个链表的倒数第N个结点,并将其删除。

解法一:

我们使用两个指针,一个fast一个slow,先放fast后移N个结点,slow处在原点,之后让fast和slow同时移动,那么等到fast移动到null的时候,slow所在位置即倒数第N个结点的位置,此时进行删除操作即可。链表的删除操作就不多言了。

C++代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* fast=head;
        while(n--)
            fast=fast->next;
        if(!fast)
            return head->next;
        ListNode* slow=head;
        while(fast->next){
            fast=fast->next;
            slow=slow->next;
        }
        slow->next=slow->next->next;
        return head;
    }
};

时间复杂度:O(n)

解法二:官方解法

遍历两次,第一次遍历求出链表的长度length,那么倒数第N个结点就是length-N+1,所以第二次遍历只要扫描到length-N+1位置删除即可。

首先我们将添加一个哑结点作为辅助,该结点位于列表头部。哑结点用来简化某些极端情况,例如列表中只含有一个结点,或需要删除列表的头部。在第一次遍历中,我们找出列表的长度 L。然后设置一个指向哑结点的指针,并移动它遍历列表,直至它到达第 (L - n)个结点那里。我们把第 (L - n)个结点的 next 指针重新链接至第 (L - n + 2)个结点,完成这个算法。

Java代码:

public ListNode removeNthFromEnd(ListNode head, int n) {
    ListNode dummy = new ListNode(0);
    dummy.next = head;
    int length  = 0;
    ListNode first = head;
    while (first != null) {
        length++;
        first = first.next;
    }
    length -= n;
    first = dummy;
    while (length > 0) {
        length--;
        first = first.next;
    }
    first.next = first.next.next;
    return dummy.next;
}

时间复杂度O(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值