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

简介: 19 删除链表的倒数第 N 个结点

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

中等

相关标签

相关企业

提示

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

这段代码使用了双指针的方法,其中一个指针先走 n 步,然后两个指针一起走,直到第一个指针到达链表末尾,此时第二个指针指向的位置就是要删除的节点。

#include <stdio.h>
#include <stdlib.h>
// 链表节点的定义
struct ListNode {
    int val;
    struct ListNode *next;
};
// 删除链表倒数第n个节点的函数
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
    // 使用双指针,首先让一个指针先走n步
    struct ListNode *dummy = (struct ListNode *)malloc(sizeof(struct ListNode));
    dummy->next = head;
    struct ListNode *fast = dummy;
    struct ListNode *slow = dummy;
    // 让fast指针先走n步
    for (int i = 0; i <= n; i++) {
        fast = fast->next;
    }
    
    // 当fast指针到达链表末尾时,slow指针就在倒数第n+1个节点
    while (fast != NULL) {
        fast = fast->next;
        slow = slow->next;
    }
    // 删除倒数第n个节点
    struct ListNode *temp = slow->next;
    slow->next = slow->next->next;
    free(temp);
    return dummy->next;
}
// 创建链表节点
struct ListNode* createNode(int val) {
    struct ListNode *newNode = (struct ListNode *)malloc(sizeof(struct ListNode));
    newNode->val = val;
    newNode->next = NULL;
    return newNode;
}
// 打印链表
void printList(struct ListNode *head) {
    struct ListNode *current = head;
    while (current != NULL) {
        printf("%d -> ", current->val);
        current = current->next;
    }
    printf("NULL\n");
}
// 释放链表节点
void freeList(struct ListNode *head) {
    struct ListNode *current = head;
    while (current != NULL) {
        struct ListNode *temp = current;
        current = current->next;
        free(temp);
    }
}
int main() {
    // 创建示例链表:[1, 2, 3, 4, 5]
    struct ListNode *head = createNode(1);
    head->next = createNode(2);
    head->next->next = createNode(3);
    head->next->next->next = createNode(4);
    head->next->next->next->next = createNode(5);
    int n = 2;
    printf("原始链表:");
    printList(head);
    // 删除倒数第n个节点
    head = removeNthFromEnd(head, n);
    printf("删除倒数第%d个节点后的链表:", n);
    printList(head);
    // 释放链表内存
    freeList(head);
    return 0;
}
  1. struct ListNode 定义了链表节点的结构,包含一个整数值 val 和一个指向下一个节点的指针 next
  2. removeNthFromEnd 函数用于删除链表倒数第 n 个节点。它首先创建一个虚拟头节点 dummy,并使用两个指针 fastslow 进行遍历。
  3. createNode 函数用于创建新的链表节点,并返回指向该节点的指针。
  4. printList 函数用于打印链表。
  5. freeList 函数用于释放链表的内存。
  6. main 函数中,首先创建一个示例链表 [1, 2, 3, 4, 5],然后调用 removeNthFromEnd 删除倒数第 n 个节点,并最后打印删除节点后的链表。

在这个代码中,使用了一个虚拟头节点 dummy 的原因是为了简化删除操作的处理。如果不使用虚拟头节点,而直接使用 head,则需要特别处理删除头节点的情况,因为头节点没有前一个节点。这会导致代码中需要额外的条件判断来处理删除头节点的情况,从而增加了复杂性。

通过使用虚拟头节点 dummy,可以确保链表中的每个节点都有一个前一个节点,使得删除操作的处理更加统一和简单。此外,虚拟头节点 dummy 在遍历过程中始终位于链表的开头,不会被删除,因此不会影响最终的结果。

总的来说,使用虚拟头节点 dummy 可以简化代码逻辑,提高代码的可读性和可维护性,尤其是在处理链表的边界情况时。

 

相关文章
|
2月前
|
算法
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
71 1
|
1月前
|
存储 算法 搜索推荐
链表的中间结点
【10月更文挑战第24天】链表的中间结点是链表操作中的一个重要概念,通过快慢指针法等方法可以高效地找到它。中间结点在数据分割、平衡检测、算法应用等方面都有着重要的意义。在实际编程中,理解和掌握寻找中间结点的方法对于解决链表相关问题具有重要价值。
20 1
|
3月前
链表的中间结点
链表的中间结点
181 57
|
2月前
Leetcode第十九题(删除链表的倒数第N个节点)
LeetCode第19题要求删除链表的倒数第N个节点,可以通过快慢指针法在一次遍历中实现。
44 0
Leetcode第十九题(删除链表的倒数第N个节点)
05_删除链表的倒数第N个节点
05_删除链表的倒数第N个节点
|
2月前
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
53 0
|
2月前
【LeetCode 09】19 删除链表的倒数第 N 个结点
【LeetCode 09】19 删除链表的倒数第 N 个结点
17 0
|
4月前
|
算法
LeetCode第19题删除链表的倒数第 N 个结点
该文章介绍了 LeetCode 第 19 题删除链表的倒数第 N 个结点的解法,通过使用快慢双指针,先将快指针移动 n 步,然后快慢指针一起遍历,直到快指针到达链尾,从而找到倒数第 N 个结点的前一个结点进行删除,同时总结了快慢指针可减少链表遍历次数的特点。
LeetCode第19题删除链表的倒数第 N 个结点
|
4月前
|
Python
【Leetcode刷题Python】剑指 Offer 22. 链表中倒数第k个节点
Leetcode题目"剑指 Offer 22. 链表中倒数第k个节点"的Python解决方案,使用双指针法找到并返回链表中倒数第k个节点。
54 5
|
5月前
【数据结构OJ题】链表中倒数第k个结点
牛客题目——链表中倒数第k个结点
40 1
【数据结构OJ题】链表中倒数第k个结点