自我修炼_初级算法篇_leetcode_第21题

这篇博客探讨了如何有效地从链表中删除倒数第N个节点,提供了三种不同的解决方案:遍历获取长度后再删除、双指针法以及递归法。每种方法都通过具体的示例解释了其工作原理,并给出了相应的C++代码实现。这些方法在理解和实现上各有特点,适合不同场景的应用。
摘要由CSDN通过智能技术生成

删除链表的倒数第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
 

进阶:你能尝试使用一趟扫描实现吗?

作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/xn2925/

首先就是遍历这个链表得到他的长度,然后得到删除的前一个节点删掉。

ListNode* removeNthFromEnd(ListNode* head, int n) {
    int length = 0;
    ListNode* p = head;
    while (p != nullptr)
    {
        length++;
        p = p->next;
    }
    if (length == n)
    {
        return head->next;
    }
    p = head;

    //定位到倒数第n+1的位置
    for (int i = 0; i < length - n - 1; i++)
    {
        p = p->next;
    }
    p->next = p->next->next;

    return head;
}

 

这个方法没什么新思想我们说一下官方的其他两种方法

首先是双指针求解办法

其核心思想就是,初始化两个指针,first,second,指针,让他们都指向头节点。之后在让first指针向后移n个单位,这样就会导致什么呢。我们那实例1举栗子。

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

 然后遍历first直到到底。

 看到了吗 这时候我的second指针就指向了需要删除节点的前一个节点。程序思想了解了,现在来实现.

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.com/problems/remove-nth-node-from-end-of-list/solution/shan-chu-lian-biao-de-dao-shu-di-nge-jie-dian-b-61/

我翻评论发现 一种方法:递归

递归的思想是十分难想象的所以这段代码也值得我们参考一下

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        int tr = traverse(head, n);
        if (tr == n) {
            return head->next;
        }
        return head;

    }
    int traverse(ListNode* node, int n) {
        if (node == NULL) {
            return 0;
        }
        int num = traverse(node->next, n);
        if (num == n)
            node->next = node->next->next;
        return num + 1;
    }
};

我把第一个栗子带进去 带着看一下。

 感觉有点像栈操作是吧。递归的思想不也是先进后出吗。所以今天最后一个官方的代码,就是栈操作。这个就很暴力了哈哈哈哈。使用STL容器,放进去,再把栈顶元素退出来n个,这样就get到了我们想要删除元素的前一个节点的值了,进而也得到了地址。

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.com/problems/remove-nth-node-from-end-of-list/solution/shan-chu-lian-biao-de-dao-shu-di-nge-jie-dian-b-61/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值