LeetCode.19 删除链表的倒数第N个结点

LeetCode.19 删除链表的倒数第N个结点

题目

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
示例 1:

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:

输入:head = [1], n = 1
输出:[]
示例 3:

输入:head = [1,2], n = 1
输出:[1]
提示:

链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz

思路

删除一个结点,很容易想到找到这个结点的前一个结点pre,让pre的next指向目标结点的next,那么怎样找到这个倒数第n个的pre呢,我们可以借用滑动窗口的思想,维护left和right两个指针,让left和right相差n-1个,那么就可以找到pre,就是我们的left。不明白的可以画一下试试。但是我们可能会遇到一些特殊情况,比如要删除的可能刚好是头节点,比如示例2和示例3,在维护这个n-1距离时,就已经到了链表尾部,这个时候我们可以直接返回头节点的next即可,其他情况就直接维护这个窗口使得right到达尾部,再来进行删除。切记不要忘记判断节点是否为空。否则会出错。
上代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* res=head;
        ListNode* left=res;
        ListNode* right=res;
        while(n--){
            right = right->next;
        }
        if (right == nullptr) {//要删除的是头节点
            ListNode* temp = res;
            res = res->next;
            delete temp;
            return res;
        }
        while(right != nullptr&&right->next!=nullptr){
            left=left->next;
            right=right->next;
        }
        ListNode* temp = left->next;
        if (temp != nullptr) { 
            left->next = temp->next;
            delete temp;
        }
        
        return res;
    }
};

感想

链表是真难啊,也是真烦啊。这个题稍微一想就能想出来,当然,投机取巧的还有一种办法,搞个vector<ListNode*>用这个来模拟删除,但是时间复杂度会翻倍,并且也不是这题的目的所在,实在没办法了可以这样做,像链表反转啊,k个一组链表反转都可以这样投机取巧,但是这不是题目用链表的意义,我们还是要考虑回归它的本意。想起前几天我实在写不出来反转用的就是这样的方法,我未来男朋友用5S和10S做例子告诉我虽然是常数级翻倍,在数据量很大的情况下差距也会很大,不要想着投机取巧。大家也要改变思想,我们一起加油。(放个题外话,今天和未来男朋友成功组了王者荣耀cp,他送了我好多玫瑰道具,一下干6级去了。)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值