⭐算法入门⭐《链表》简单01 —— 237. 删除链表中的节点

本文详细介绍了如何在C语言中删除链表中的非尾节点,提供了基础框架代码和解题步骤。通过《光天化日学C语言》和《画解数据结构》等资源,解析了如何利用前驱节点来完成删除操作,确保时间复杂度为O(1)。此外,还分享了一个通用的删除链表节点的模板函数doDeleteNode。

🔥让天下没有难学的算法🔥

C语言免费动漫教程,和我一起打卡!
🌞《光天化日学C语言》🌞

入门级C语言真题汇总
🧡《C语言入门100例》🧡

几张动图学会一种数据结构
🌳《画解数据结构》🌳

组团学习,抱团生长
🌌《算法入门指引》🌌

竞赛选手金典图文教程
💜《夜深人静写算法》💜

一、题目

1、题目描述

  请编写一个函数,使其可以删除某个链表中给定的(非尾)结点。传入函数的唯一参数为 要被删除的结点,注意:没有给定头结点 head
  样例输入: head = [3,4,5,6], node = 4
  样例输出: [3,5,6]

2、基础框架

  • C语言 版本给出的基础框架代码如下:
void deleteNode(struct ListNode* node){
}

3、原题链接

237. 删除链表中的节点
剑指 Offer 18. 删除链表的节点
面试题 02.03. 删除中间节点

二、解题报告

1、思路分析

  由于链表 删除结点 需要知道 前驱结点 是什么,而这个问题只给了 当前结点,所以没有办法删除 当前结点
  所以,我们可以把它的 后继结点 的数据拷贝到 当前结点,并且删除它的后继结点即可。

2、时间复杂度

  • 这个问题相当于转换成删除某个结点的 后继结点,时间复杂度为 O ( 1 ) O(1) O(1)

3、代码详解

  • 首先,我们实现一个辅助函数,它的作用是在一个可重复数组中,找到一个数 v v v ,且下标最小,如果找不到,返回 − 1 -1 1;实现方法就是二分。
struct ListNode* doDeleteNode(struct ListNode* head, int val){
    struct ListNode *pre, *now;  
    if(head == NULL) {
        return NULL;                  // (1) 
    }
    if(head->val == val) {            // (2) 
        return head->next;  
    }
    pre = head, now = head->next;     // (3) 
    while(now) {
        if(now->val == val) {         // (4) 
            pre->next = now->next;    
            break;                    // (5) 
        }
        pre = now;
        now = now->next;              // (6) 
    }
    return head;                      // (7) 
}

void deleteNode(struct ListNode* node){
    int tmp = node->val;               // (8) 
    node->val = node->next->val;
    node->next->val = tmp;
    doDeleteNode(node, tmp);           // (9) 
}
  • ( 1 ) (1) (1) 空链表直接返回空即可;
  • ( 2 ) (2) (2) 等于头结点的情况,直接返回头结点的后继结点;
  • ( 3 ) (3) (3) 记录 前驱结点当前结点
  • ( 4 ) (4) (4) 找到需要删除的结点,直接让 它的前驱 指向 它的后继
  • ( 5 ) (5) (5) 由于题目要求只有一个,所以直接退出循环即可;
  • ( 6 ) (6) (6) 前驱结点当前结点 的指针都往前行进一格;
  • ( 7 ) (7) (7) 返回列表头结点;
  • ( 8 ) (8) (8) 需要 删除的结点 和 它的 后继结点 值进行交换;
  • ( 9 ) (9) (9) 删掉它的后继结点;

三、本题小知识

  文中的doDeleteNode是一个删除链表中某个结点的通用模板,其实这个问题实现可以很简单,但是其思想却是非常经典,需要有一层联想。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

英雄哪里出来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值