AcWing
  • 首页
  • 课程
  • 题库
  • 更多
    • 竞赛
    • 题解
    • 分享
    • 问答
    • 应用
    • 校园
  • 关闭
    历史记录
    清除记录
    猜你想搜
    AcWing热点
  • App
  • 登录/注册

1链表(删除元素相关)

作者: 作者的头像   有点丶 ,  2022-09-24 09:36:53 ,  所有人可见 ,  阅读 325


1


1.移除链表元素
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]

对于给定的链表,首先对除了头节点head 以外的节点进行删除操作,然后判断head 的节点值是否等于给定的 val。如果head 的节点值等于 val,则 head 需要被删除,因此删除操作后的头节点为 head.next;如果head 的节点值不等于val,则head 保留,因此删除操作后的头节点还是 head。上述过程是一个递归的过程。

递归的终止条件是 \textit{head}head 为空,此时直接返回 \textit{head}head。当 \textit{head}head 不为空时,递归地进行删除操作,然后判断 \textit{head}head 的节点值是否等于 \textit{val}val 并决定是否要删除 head。

代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
//递归,时间空间0(n),O(n)
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        if(head==NULL)return head;

        head->next=removeElements(head->next,val);
        if(head->val==val)
        {
            return head->next;
        }    
        else
        {
            return head;
        }

    }
};

迭代,时间空间O(n),O(1)

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode*dummy=new ListNode(-1);
        dummy->next=head;
        ListNode*cur = dummy;
        while(cur->next)
        {
            if(cur->next->val==val) //也可移除值在某一区间的,比如大于1小于5的点,改判断条件即可
            {
                ListNode*p=cur->next;
                cur->next=p->next;
                delete p;
            }
            else
            {
                cur=cur->next;
            }

        }
        return dummy->next;
    }
};
/*1.head为带头结点的链表
2.先创建工作指针指向head,利用循环判断其下一节点是否为指定节点若是则进行删除,若不是则将工作指针指向下一节点。 
ListNode*remove(ListNode*head,int val)
{
    //创工作指针
    ListNode*cur=head;
    while(cur->next)
    {
        if(cur->next==val) 
        {
            ListNode*p=cur->next;
            cur->next=p->next;
            delete(p);
        }
        else
        {
            cur=cur->next;
        }
    }

    return head; 
}*/

2.删除链表中最小值节点(最小值唯一)
O(n) O(1);
代码

算法思路:
1: 申请一个指针min,用于指向最小值节点,minPrep指针指向min的前驱结点
2: 遍历链表,当出现更小值的时候就更新min,minPrep
3: 利用minPrep对minp的删除 
class Solution {
public:
    ListNode* deleteMin(ListNode* head) {
        ListNode*dummy=new ListNode(-1);
        dummy->next=head;
        ListNode*minPre=dummy;
        ListNode*min=dummy->next;

        ListNode*curPre=dummy;
        ListNode*cur=dummy->next;

        while(cur)
        {
            if(cur->val<min->val)
            {
                min=cur;
                minPre=curPre;
            }
            curPre=cur;
            cur=cur->next;
        }
        minPre->next=min->next;
        delete min;
        return dummy->next;
    }
};

/*
head为头结点指针 
ListNode*deleteMin(ListNode*head)
{
    //工作指针和其前驱 
    ListNode*cur=head->next;
    ListNode*curPrep=head;

    //最小值节点指针和其前驱   
    ListNode*min=head->next;
    ListNode*minPrep=head;

    while(cur)
    {
        if(cur->val<min->val)
        {
            min=cur;
            minPrep=curPrep;
        }
        curPrep=cur;
        cur=cur->next;
    }
    minPrep->next=min->next;
    delete(min);
    return head;

} */

3.将最小节点移到头结点后
代码

//带头指针
ListNode*yi(ListNode*A)
{
    ListNode*cur=A->next;
    ListNode*min=A->next;
    ListNode*minPrep=A;
    ListNode*curPrep=A;

    while(cur)
    {
        if(min->val>cur->val)
        {
            min=cur;
            minPrep=curPrep;
        }
        curPrep=cur;
        cur=cur->next;
    }
    minPrep->next=minPrep->next->next;
    min->next=A->next;
    A->next=min;
    return A;
}

4.删除排序链表中的重复元素(I)
给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。
输入:head = [1,1,2]
输出:[1,2]
输入:head = [1,1,2,3,3]
输出:[1,2,3]

时间复杂度
循环了一次链表,时间复杂度为O(n)
空间复杂度
O(1)
代码:

class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
       ListNode*duyy = head;
        while(duyy!=NULL)
        {
            if(duyy->next!=NULL&&duyy->val==duyy->next->val)
            {
                duyy->next=duyy->next->next;
            }
            else
            {
                duyy=duyy->next;
            }
        }
        return head;
    }
};

手动变成带头结点的算法

class Solution {
public:
    //head是带头结点的链表 
    ListNode* deleteDuplicates(ListNode* head) {
        ListNode*duyy=head->next;
        while(duyy!=NULL)
        {
            if(duyy->next!=NULL&&duyy->val==duyy->next->val)
            {
                ListNode* q=duyy->next;
                duyy->next=q->next;
                delete q;
            }
            else
            {
                duyy=duyy->next;
            }
        }
        return head;
    }
};

0 评论

App 内打开
你确定删除吗?
1024
x

© 2018-2025 AcWing 版权所有  |  京ICP备2021015969号-2
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息