尾插法删除链表中指定元素的结点


题目描述

给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点

力扣链接


思路

将结点值不等于val的结点,逐个尾插到新链表

步骤

分析

  1. 需要创建一个头结点,来保存新链表的位置
  2. 需要创建一个循环,遍历链表,找出目标结点
  3. 循环内分为两个部分,部分一:尾插结点值非val的结点;部分二:删除结点值为val的结点

具体流程

  • 创建一个新的头指针newHead和尾指针tail
  • 开辟一个新结点,作为哨兵位的头结点,并将newhead和tail指向该结点
  • 创建一个指针cur,指向原链表的头结点head
  • 开始遍历链表,通过while循环判断当前结点cur是否为空
  • 如果当前结点cur的值不等于val,则将该结点尾插到新链表
    • 将tail结点的next指针指向cur
    • 更新tail为cur,记录新的尾结点
    • 迭代cur指向下一个结点cur->next
  • 如果当前结点的值等于val,则删除该结点
    • 创建一个del指针,指向cur,用于释放结点内存
    • 迭代cur指向下一个结点cur->next,避免结点释放后,找不到下一个结点
    • 释放del指向的结点内存
  • 遍历结束后,将新链表的尾结点tail的next指针置空,标记新链表结束,同时防止访问内存释放了的结点
  • 由于新链表的头结点是一个哨兵位,有效结点从哨兵位的next指针开始。因此,将newHead的next指针赋值newList指针
  • 然后释放哨兵位的内存
  • 返回newList指针

代码

ListNode* removeElements(ListNode* head, int val) 
{
        ListNode* newHead = nullptr;
        ListNode* tail = nullptr;
        newHead = tail = (ListNode*)malloc(sizeof(ListNode));
        newHead->next = nullptr;

       
        ListNode* cur = head;
        while(cur)
        {
             //尾插结点
            if(cur->val != val)
            {
                tail->next = cur;
                tail = cur; //更新尾结点
                cur = cur->next; //迭代当前结点
            }

            //删除等于val的结点
            else
            {
                ListNode* del = cur;
                cur = cur->next; 
                //free(del);
                delete del; //注意new申请的结点内存,不能用free释放
            }

        }

        tail->next = nullptr; //置空新链表尾结点的next指针

        ListNode* newList = newHead->next;

        free(newHead); //释放哨兵位
        return newList;
}

复杂度分析

  • 时间复杂度为O(N),N为链表结点个数,只需遍历一次链表,就可以删除结点值等于val的结点

  • 空间复杂度为O(1),函数removeElements运行过程中,只额外开辟了1个结构体指针变量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值