CP19 删除链表的倒数第N个节点

题目描述:

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

学习过程:

最简单的就是两次循环便利链表,第一次找到长度,第二次进行删除,是OK的,主要是注意一下条件那里,最开始是认为length==1 return nullptr;提交不对后改为length==n return nullptr;继续不对后改为现在的跳过第一个head就行;因为问题是now是从1开始,所以如果删去倒数第N个就没法搞,要注意边界条件,代码如下:

补充:猛然发现这里我们自己定义的ListNode*都没有delete!!但是在return前加入delele所有自定义的指针后,发现执行出错,因为这些指针指的是链表里的元素,再和题解中的进行对比,题解中的delete的指针是new出来的,直接定义没有开辟新空间的指针是不需要delete的,C++已经全忘完了,该去复习复习了。

/**
 * 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) {
        int length=1;
        ListNode* temp_count=head;
        while(temp_count->next != nullptr)
        {
            temp_count=temp_count->next;
            length++;
        }
        

        int now=1;
        ListNode* temp_find=head;
        if(length==n)//这里的条件注意
        {
            temp_find=head->next;
            return temp_find;
        }
        while(now!=length-n)
        {
            temp_find=temp_find->next;
            now++;
        }
        ListNode* temp_delete=temp_find->next;
        temp_delete=temp_delete->next;
        temp_find->next=temp_delete;

        return head;
    }
};

学习别人:

但是这样是一种两次便利的过程,题解给出了另外两种方法:

1.栈

这里采用了stack这种数据结构,可以去学习一下用法嘎嘎,思路很好理解,官方代码如下:

补充:这里delete是因为人为在head前的定义了一个链表头,这样会避免前面我代码中删除第一个的问题,但是由于new了一块空间,因此需要delete

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummy = new ListNode(0, head);
        stack<ListNode*> stk;
        ListNode* cur = dummy;
        while (cur) {
            stk.push(cur);
            cur = cur->next;
        }
        for (int i = 0; i < n; ++i) {
            stk.pop();
        }
        ListNode* prev = stk.top();
        prev->next = prev->next->next;
        ListNode* ans = dummy->next;
        delete dummy;
        return ans;
    }
};

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/remove-nth-node-from-end-of-list/solution/shan-chu-lian-biao-de-dao-shu-di-nge-jie-dian-b-61/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2.双指针

也是一种很巧妙的思想,不需要知道总长度,

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummy = new ListNode(0, head);
        ListNode* first = head;
        ListNode* second = dummy;
        for (int i = 0; i < n; ++i) {
            first = first->next;
        }
        while (first) {
            first = first->next;
            second = second->next;
        }
        second->next = second->next->next;
        ListNode* ans = dummy->next;
        delete dummy;
        return ans;
    }
};

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/remove-nth-node-from-end-of-list/solution/shan-chu-lian-biao-de-dao-shu-di-nge-jie-dian-b-61/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值