首页 > 其他分享 >【代码随想录】二、链表:1、移除链表元素

【代码随想录】二、链表:1、移除链表元素

时间:2024-08-16 14:49:34浏览次数:8  
标签:结点 ListNode cur val 随想录 head next 链表 移除

部分图文参考于:代码随想录 - 203.移除链表元素

C++编程中记得要手动释放结点内存。

链表操作中,可以使用原链表来直接进行删除操作,也可以设置一个虚拟头结点再进行删除操作。

1.题目链接

203.移除链表元素

2.思路

以链表 1 4 2 4 来举例,移除元素4。
image
如果使用C,C++编程语言的话,不要忘了还要从内存中删除这两个移除的节点, 清理节点内存之后如图:

image

在单链表中移除头结点 和 移除其他节点的操作方式不一样,需要单独写一段逻辑来处理移除头结点的情况。
针对头结点和非头结点使用不同的删除方式:
1.针对头结点等于删除值,将头结点head指向下一个值不等于val的结点。
image
image
注:别忘将原头结点从内存中删掉。
image

2.针对非头结点等于删除值,使用cur指向头结点,检测cur->next所指向的结点的值是否等于val。如果相等,则将cur->next指向cur->next->next,即删除结点;不相等,则将cur继续向下一个结点移动。

/**
 * 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) {
        while (head && head->val == val) {
            ListNode* temp = head;
            head = head->next;
            delete temp;
        }
        ListNode* cur = head;
        while (cur && cur->next) {
            if (cur->next->val == val) {
                ListNode* temp = cur->next;
                cur->next = cur->next->next;
                delete temp;
            }
            else cur = cur->next;
        }
        return head;
    }
};

● 时间复杂度:O(n)
● 空间复杂度:O(1)

2.2.解法2:使用虚拟头结点

使用这种方式,不用再区分头结点和非头结点,原链表的所有节点就都可以按照统一的方式进行移除了。
来看看如何设置一个虚拟头。依然还是在这个链表中,移除元素1。
image

这里来给链表添加一个虚拟头结点为新的头结点,此时要移除这个旧头结点元素1。
return 头结点的时,return dummyNode->next;才是新的头结点。

/**
 * 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* dummyHead = new ListNode(0);
        dummyHead->next = head;
        ListNode* cur = dummyHead;
        while (cur->next) {
            if (cur->next->val == val) {
                ListNode* temp = cur->next;
                cur->next = cur->next->next;
                delete temp;
            }
            else cur = cur->next;
        }
        head = dummyHead->next;
        delete dummyHead;
        return head;
    }
};

● 时间复杂度:O(n)
● 空间复杂度:O(1)

标签:结点,ListNode,cur,val,随想录,head,next,链表,移除
From: https://www.cnblogs.com/Henfiu/p/18359103

相关文章

  • 【代码随想录】二、链表:理论基础
    原文链接:代码随想录-链表理论基础。1.什么是链表?链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。链表的入口节点称为链表的头结点也就是head。2.链表的类型2.1.......
  • 数据结构+单链表应用
    一、问题描述编写程序实现两个有序表的交和差,令L1=(x1,x2,x3,...,xn),L2=(y1,y2,y3,...,yn),它们是两个线性表,采用带头结点的单链表存储,请先实现单链表存储两个链表,再完成如下功能:(1)sort:将单链表的所有结点按照数据域进行递增排序,构造成有序单链表;(2)interSect:求两个......
  • 代码随想录 day31|| 56 合并区间,738 单调递增数字,968 监控二叉树
    56合并区间funcmerge(intervals[][]int)[][]int{ //思路先排序,然后按照后一个左区间和前一个右区间进行对比判断是否重叠,重叠扩充右区间 sort.Slice(intervals,func(i,jint)bool{ ifintervals[i][0]==intervals[j][0]{ returnintervals[i][1]<intervals[......
  • 「代码随想录算法训练营」第三十九天 | 动态规划 part12
    115.不同的子序列题目链接:https://leetcode.cn/problems/distinct-subsequences/文章讲解:https://programmercarl.com/0115.不同的子序列.html题目难度:困难视频讲解:https://www.bilibili.com/video/BV1fG4y1m75Q/题目状态:看题解思路:动态规划数组初始化创建一个二维动......
  • 代码随想录Day16
    513.找树左下角的值给定一个二叉树的根节点root,请找出该二叉树的最底层最左边节点的值。假设二叉树中至少有一个节点。示例1:输入:root=[2,1,3]输出:1示例2:输入:[1,2,3,4,null,5,6,null,null,7]输出:7提示:二叉树的节点个数的范围是[1,104]-231<=......
  • 【代码随想录】一、数组:6.前缀和
    二刷的时候发现更新了一些新的题目,尝试写了写后,发现我完全不会ACM输入输出模式。这两天在补前几天没背的八股,写得不够满意(几乎是完全誊代码了),先放着,后面再补充补充吧。1.题目:44.开发商购买土地#include<iostream>#include<vector>#include<climits>usingnamespacestd......
  • 【代码随想录】一、数组:4.滑动窗口
    1.题目1:209.长度最小的子数组1.1.解法1:暴力解法(已超时)使用两层循环,外层循环确定最小子数组开始的位置(i),内层循环确定最小子数组结束的位置(j)。在每次跳出内层循环时,sum应重置为0。当找到的子数组相加的和等于或大于目标值(target)时,算出此刻子数组的长度(j-i+1),并更新result的值......
  • 【代码随想录】一、数组:5.螺旋矩阵
    本题并不涉及到什么算法,就是模拟过程,但却十分考察对代码的掌控能力。1.题目1:59.螺旋矩阵II1.1.解法1:模拟本题的重点还是像之前的“704.二分查找”,坚持循环不变量原则,即在本题中遍历每条边时,坚持相同的原则。如下是一个示例,即n=5,我们考虑根据圈数和边数来进行遍历:由外圈到内......
  • 获取链表中间位置的两种方法方法
    方法一:我们可以计算链表节点的数量,然后遍历链表找到前半部分的尾节点。方法二:我们也可以使用快慢指针在一次遍历中找到:慢指针一次走一步,快指针一次走两步,快慢指针同时出发。当快指针移动到链表的末尾时,慢指针恰好到链表的中间。通过慢指针将链表分为两部分。慢指针:前半部......
  • 代码随想录算法训练营 | 动态规划 part01
    509.斐波那契数509.斐波那契数状态转移方程:F(0)=0,F(1)=1F(n)=F(n-1)+F(n-2),其中n>1递归,太多重复计算classSolution{public:intfib(intn){if(n==0||n==1){returnn;}returnfib(n-1)......