20210605 每日一题 移除链表元素

题目

题目链接

代码

/**
 * 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) {}
 * };
 */
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {

    }
};

方法一:迭代

分析

迭代方法是解决链表问题的最简单的方法,用 t e m p temp temp 表示当前节点,题目要求删除链表中所有节点值等于特定值的节点,可以将条件转化为:
t e m p = { t e m p . n e x t i f   t e m p . v a l = s p e c i a l   v a l u e t e m p i f   t e m p . v a l ≠ s p e c i a l   v a l u e temp= \begin{cases} temp.next &if\ temp.val=special\ value\\ temp &if\ temp.val\neq special\ value \end{cases} temp={temp.nexttempif temp.val=special valueif temp.val=special value 由于链表操作当前节点容易出错,所以一般操作链表下一节点,即 t e m p . n e x t temp.next temp.next ,将上述公式转化为:
t e m p . n e x t = { t e m p . n e x t . n e x t i f   t e m p . n e x t . v a l = s p e c i a l   v a l u e t e m p . n e x t i f   t e m p . n e x t . v a l ≠ s p e c i a l   v a l u e temp.next = \begin{cases} temp.next.next &if\ temp.next.val=special\ value\\ temp.next &if\ temp.next.val\neq special\ value \end{cases} temp.next={temp.next.nexttemp.nextif temp.next.val=special valueif temp.next.val=special value t e m p . n e x t = n u l l temp.next=null temp.next=null 时,链表遍历结束。
特殊情况: 由于操作的是 t e m p . n e x t temp.next temp.next,无法实现方面对链表的头节点 h e a d head head 的删除操作,因此需要在当前头节点 h e a d head head 前连接一个虚拟头节点 v i r t u a l H e a d virtualHead virtualHead,从虚拟头节点开始遍历链表,最后返回 v i r t u a l H e a d virtualHead virtualHead

代码

/**
 * 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) {}
 * };
 */
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode* virtualHead = new ListNode(0, head);
        ListNode* temp = virtualHead;
        while(temp->next != nullptr) {
            if(temp->next->val == val) {
                temp->next = temp->next->next;
            } else {
                temp = temp->next;
            }
        }
        return virtualHead->next;
    }
};

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是链表的长度,迭代需要遍历链表每个节点。
  • 空间复杂度: O ( 1 ) O(1) O(1)

方法二:递归

分析

链表题目一般都可以用递归方法来解,先递归到达链表末端进行处理,再将处理完的链表逐级返回链表前端。可以将条件转化为:
{ r e t u r n   n o d e . n e x t i f   n o d e . v a l = s p e c i a l   v a l u e r e t u r n   n o d e i f   n o d e . v a l ≠ s p e c i a l   v a l u e \begin{cases} return\ node.next &if\ node.val=special\ value\\ return\ node &if\ node.val\neq special\ value \end{cases} {return node.nextreturn nodeif node.val=special valueif node.val=special value

代码

/**
 * 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) {}
 * };
 */
class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        if(head == nullptr) return head;
        head->next = removeElements(head->next, val);
        return head->val == val ? head->next : head;
    }
};

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是链表的长度。
  • 空间复杂度: O ( n ) O(n) O(n),空间复杂度主要取决于递归调用栈,最多不会超过 n 层。

拓展

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值