首页 > 其他分享 >203. 移除链表元素

203. 移除链表元素

时间:2023-04-10 23:24:36浏览次数:64  
标签:203 val head next 链表 移除 节点

参考链接:代码随想录

题目描述:

解题思路:

由单链表的特殊性,如果删除的是头节点应该怎么操作呢?

这里就涉及如下链表操作的两种方式:

- 直接使用原来的链表进行删除操作

- 设置一个虚拟头节点进行删除操作

第一种操作:

 

移除头节点和移除其他节点的操作是不一样的,因为链表的其他节点都是通过前一个节点来移除当前节点,而头节点没有前一个节点。那么头节点应该如何移除呢,只需要将头节点向后移动一位就好,这样就从链表中移除了一个头节点。

 

 

 这样就移除了一个头节点,在单链表中移除头节点和移除其他节点的操作方式是不同的,需要单独写一段逻辑来处理头节点的情况。那么可不可以以一种统一的逻辑来移除链表的节点呢。

其实可以设置一个虚拟头节点,这样原链表的所有节点就可以按照统一的方式移除了。

依旧还是在这个链表中,移除元素1.

 

 这里来给链表添加一个虚拟头节点作为新的头节点,此时要移除这个旧头节点元素1。

在题目中,return头节点的时候,应该return dummyNode->next,这才是新的头节点。

解题过程:

 

 第一种解法:设置虚拟头节点,删除头节点不需要单独考虑

class Solution:
    def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
        dummy_head = ListNode(next=head)
        cur = dummy_head
        while(cur.next!=None):
            if(cur.next.val==val):
                cur.next = cur.next.next
            else:
                cur = cur.next
        return dummy_head.next

时间复杂度为O(n),需要遍历链表一次;空间复杂度O(1),因为是在原链表的基础上修改。

第二种解法:删除头节点时另作考虑,因为头节点没有前一个节点

class Solution:
    def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
        while(head!=None and head.val==val): # 删除值相同的头节点后,可能新的头节点也相等,用循环解决
            head = head.next
        if(head==None):
            return head
        prev = head
        while(prev.next!=None):
            if(prev.next.val==val):
                prev.next = prev.next.next
            else:
                prev = prev.next
        return head

第三种解法:递归

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

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

class Solution:
    def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
        if head is None: # 终止条件
            return head
        head.next = self.removeElements(head.next, val) # head的下一个节点只需要指向递归过的结果就好
        if head.val == val:
            return head.next
        else:
            return head

时间复杂度为O(n),递归过程中需要遍历链表一次;空间复杂度为O(n),主要取决于递归调用栈,最多不会超过n层。

 

标签:203,val,head,next,链表,移除,节点
From: https://www.cnblogs.com/lbwBH/p/17304178.html

相关文章

  • #yyds干货盘点# LeetCode程序员面试金典:合并两个有序链表
    题目:将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。  示例1:输入:l1=[1,2,4],l2=[1,3,4]输出:[1,1,2,3,4,4]示例2:输入:l1=[],l2=[]输出:[]示例3:输入:l1=[],l2=[0]输出:[0]代码实现:classSolution{publicLis......
  • 线性表之单链表
    定义初始化单链表尾插法建立单链表--正向建立单链表头插法建立单链表单链表的查找按位查找,返回第i个元素(带头结点)按值查找,找到元素值为x的点......
  • 数组、链表、跳表的基本实现和特性
    1.如何对链表加速  2.添加第一级索引  3.添加第二级索引  4.增加N级索引  5.思量及索引添加流程解释  5_1.如何找到数字8  5_2.如何找到数字9  6.跳表查询的时间复杂度分析  6_2.时间复杂度例题  ......
  • 链表专题--基础知识
    参考链接:代码随想录链表是一种通过指针串联在一起的线性结构,每个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。链表的入口节点称为链表的头节点也就是head,链表示意图如下所示:  链表的类型单链表刚才说......
  • 1019. 链表中的下一个更大节点
    题目链接:1019.链表中的下一个更大节点方法:单调栈解题思路该类问题详解:单调栈解决NextGreaterNumber一类问题代码classSolution{public:vector<int>nextLargerNodes(ListNode*head){vector<int>value;while(head!=nullptr){......
  • 链表
    1.顺序表的缺陷1.在顺序表头部中间插入数据,需要挪动数据效率低下2.容量不够时需要扩容,所以可能存在空间浪费链表可以很好的解决这些问题,下面讲解链表 2.链表概念及基本结构链表是一种逻辑上连续,物理内存空间非连续存储的线性结构typedefintSLDataType;typedefst......
  • 5、链表
    1、链表我们可以用虚拟头结点dummyHead来简化添加、删除的操作publicclassLinkedList<E>{privateclassNode{publicEe;publicNodenext;publicNode(Ee,Nodenext){this.e=e;this.next=next;......
  • 6、递归链表
    链表具有天然的递归结构,下面我们将用递归实现链表的所有操作publicclassLinkedListR<E>{privateclassNode{publicEe;publicNodenext;publicNode(Ee,Nodenext){this.e=e;this.next=next;......
  • P9203 时效「月岩笠的诅咒」 题解
    题目传送门题目大意判断每次经过以下操作其一后,\(a\)与\(b\)是否相等:将\(a\)加上\(1\),即\(a\getsa+1\);将\(b\)加上\(1\),即\(b\getsb+1\)。解题思路\(a\)和\(b\)都是每次加\(1\),所以如果它们相等,那它们的小数部分应该是相等的,所以问题就变成了判断\(a\)......
  • 线性表之静态链表实现(数组cur实现)
    main.cpp#include"StaticList.h"intmain(){StaticListSL;InitSList(SL);for(inti=0;i<5;++i){Insert(SL,'A'+i);}ShowSList(SL);DeleteSList(SL);ShowSList(SL);return0;}Stati......