【剑指offer 18. 删除链表的节点】

剑指offer 18. 删除链表的节点

题目

给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。返回删除后的链表的头节点。

题目链接https://leetcode.cn/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/

题解

解法1:双指针

解法分析
  1. 先判断头指针是否为空,为空返回
  2. 判断头指针指向val是否为待查找值,是则返回head->next
  3. 使用p表示当前指向的节点,使用front保存当前节点p的前一个节点,为了方便后续修改勾连关系
    1. 循环直到p->val==val时修改front指向的next绕过p,指向p后面的节点
边界条件、特殊值分析、测试、注意事项
  1. 需要小心防范头指针为空的情况
复杂度分析

时间复杂度 O(n),最坏情况需要遍历扫描整个链表

空间复杂度 O(1),只使用了两个辅助变量

代码
class Solution {
public:
    ListNode* deleteNode(ListNode* head, int val) {
        if (head == NULL) return head;
        if (head->val == val) return head->next;
        ListNode* p=head;
        ListNode* front = p;
        while (p != NULL && p-> val != val) {
            front=p;
            p=p->next;
        }
        if(p==NULL){
            return head;
        }
        front->next=p->next;
        return head;
    }
};
可能存在的问题
  1. 使用双指针还是有点空间上的不必要消耗的,考虑使用单指针

解法2:单指针

解法分析
  1. 先判断头指针是否为空,为空返回
  2. 判断头指针指向val是否为待查找值,是则返回head->next
  3. 使用cur表示当前指向的节点,永远检查next指针与next指针域下的val,以此来避免多一个front指针,即cur相当于前面双指针的front指针,只不过使用front->next取代了p
边界条件、特殊值分析、测试、注意事项
  1. 需要小心防范头指针为空的情况
复杂度分析

时间复杂度 O(n),最坏情况需要遍历扫描整个链表

空间复杂度 O(1),只使用了两个辅助变量

代码
class Solution {
public:
    ListNode* deleteNode(ListNode* head, int val) {
        if (head == NULL) return head;
        if (head->val == val) return head->next;
        ListNode* cur = head;
        while (cur->next != NULL) {
            if (cur->next->val == val) {
                cur->next = cur->next->next;
                return head;
            }
            curr = cur->next;
        }
        return head;
    }
};
可能存在的问题
  1. 暂无

更多解法

  1. 使用递归
    1. 当前节点为空时退出
    2. 为待查值时向被调用函数返回next指针
  2. 使用栈
    1. 将所有值依次压栈,直到遇到待查值或者NULL
    2. 遇到待查值,则将栈中元素重新组织为链表,并将待查值->next勾连到新组成的链表后方
    3. 遇到NULL,重组栈中值为链表
  3. 使用虚拟头节点
    1. 通过使用虚拟头节点,进一步统一上述单指针解法与双指针解法中的头部需要额外判断的问题
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值