代码训练营 Day3 | 203.移除链表元素 | 707.设计链表 | 206.反转链表

链表的类型:

单链表 : 通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)

双链表: 每一个节点有两个指针域,一个指向下一个节点,一个指向上一个节点。 双链表 既可以向前查询也可以向后查询

循环链表: 链表首尾相连

链表的存储:

数组是在内存中是连续分布的,但是链表在内存中可不是连续分布的;链表是通过指针域指针链接在内存中各个节点

性能分析:

插入/删除(时间复杂度)查询(时间复杂度)试用场景
数组O(n)O(1)数据量固定,频繁查询,较少更改
链表O(1)O(n)数据量不固定,频繁增删,较少查询

203. 移除链表元素

1. 设置一个虚拟头节点,这样可以避免遍历链表时,头节点被更改

2. 链表中是不存在完全删除一个节点的,而是让删除节点的前一个节点指向删除节点后面的一个节点,如果试用的是C++ 记得手动释放内存

3. 最后返回头节点时,return dummy_head -> next,因为真正的头节点可能被删除

# Definition for singly-linked list.
class ListNode(object):
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
class Solution(object):
    def removeElements(self, head, val):
        """
        :type head: ListNode
        :type val: int
        :rtype: ListNode
        """
        dummy_head = ListNode(next=head)
        # set a temp pointer, to help iterate the linklist
        cur = dummy_head

        # find remove element position; cur.next != None is aviod we are acees a empty Node
        while cur.next != None:
            # if we find the element we want to remove
            if cur.next.val == val:
                # remove the address, let cur point to next next
                cur.next = cur.next.next
            else:
                cur = cur.next
        
        return dummy_head.next     

707. 设计链表

  1.  使用虚拟头节点能很好的帮助实现每一个函数功能
  2. get函数: 判断index是否在valid的区域;current  = dummy_head.next 因为我们for循环出来current的下一个值才是我们获取的目标值
  3. addAtHead函数: 让新头节点指向之前的头节点,让dummy_head指向新头节点;记得linklist的size + 1因为我们添加了新的节点进入链表当中
  4. addAtTail函数:跟上面一个实现方法相同,不过我们需要先遍历到链表尾部
  5. addAtIndex函数: 这里对于index合法边界的判断要注意 index > size 即可,因为这样可以保证我们可以在链表尾部插入元素
  6. deleteAtIndex函数: 先检查index合法性,再去遍历到index位置通过操作链表节点的地址从而让需要删除节点跟前节点失去链接,达到删除的目的 

class ListNode():
    def __init__(self,val=0,next=None):
        self.val = val
        self.next = next
class MyLinkedList(object):

    def __init__(self):
        self.dummy_head = ListNode()    # create a vitrual head
        self.size = 0       # define linklist size

    def get(self, index):
        """
        :type index: int
        :rtype: int
        """
        # makesure is not empty linklist
        if index < 0 or index >= self.size:
            return -1
        
        current = self.dummy_head.next
        # iterate the linklist,find which element we want
        for _ in range(index):
            current = current.next
        
        # after the for loop we find index element, return it
        return current.val

    def addAtHead(self, val):
        """
        :type val: int
        :rtype: None
        """
        # create a new node
        newNode = ListNode(val=val)
        # temp head
        current = self.dummy_head

        # add new head
        newNode.next = current.next
        current.next = newNode
        
        # since we add a node into our linklist
        self.size += 1


    def addAtTail(self, val):
        """
        :type val: int
        :rtype: None
        """
        # creat dummy head
        current = self.dummy_head
        newNode = ListNode(val=val)

        # find the tail
        while current.next is not None:
            current = current.next
        
        # find the correct position to insert new Node
        current.next = newNode
        # add node into our linklist size += 1
        self.size += 1

    def addAtIndex(self, index, val):
        """
        :type index: int
        :type val: int
        :rtype: None
        """
        # determine the index is correct range
        if index < 0 or index > self.size:
            return 

        # create dummy head
        current = self.dummy_head
        # creat new node
        newNode = ListNode(val=val)

        # find index position
        for _ in range(index):
            current = current.next
        
        # add index element
        newNode.next = current.next
        current.next = newNode
        
        self.size += 1
        

    def deleteAtIndex(self, index):
        """
        :type index: int
        :rtype: None
        """
        # detemine index is valid range
        if index < 0 or index >= self.size:
            return

        # create dummyhead
        current = self.dummy_head

        # find the element we want to remove
        for _ in range(index):
            current = current.next
        
        # delet the node
        current.next = current.next.next

        self.size -= 1


# Your MyLinkedList object will be instantiated and called as such:
# obj = MyLinkedList()
# param_1 = obj.get(index)
# obj.addAtHead(val)
# obj.addAtTail(val)
# obj.addAtIndex(index,val)
# obj.deleteAtIndex(index)

206. 反转列表(面试高频)

  1. 定义一个prev指针存储为None
  2. 创建虚拟头节点,避免在遍历的时候修改我们原始头节点
  3. 在遍历中使用temp去保存current的下一个节点地址
  4. 改变链表方向时,先让current.next 指向我们prev指针,也就是上一个节点元素
  5. 移动指针一定是要prev先走,如果current指针先移动的话会导致prev和current都指向同一个节点,从而导致失去前一个节点的地址从而无法顺利反转列表

最后返回一定是返回prev指针,因为prev指针是我们新的头节点位置(原始链表的尾部)

# Definition for singly-linked list.
class ListNode(object):
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
class Solution(object):
    def reverseList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        dummy_head = ListNode(next=head)
        current = dummy_head.next

        # create prev pointer to save the previous node
        prev = None

        # iterate the linklist
        while current:
            # save current.next node addres
            temp = current.next

            current.next = prev
            # move prev first; if we move current first, then prev will point to same node as current
            prev = current
            # move current
            current = temp
        
        # return prev, this is our new head node
        return prev

代码随想录算法训练营Day3 | Leetcode 203移除链表元素707设计链表206反转链表 void addAtIndex(int index, int val) 将一个值为 val 的节点插入到链表中下标为 index 的节点之前。在插入完成后,新节点会成为链表的第一个节点。给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回。int get(int index) 获取链表中下标为 index 的节点的值。void addAtTail(int val) 将一个值为 val 的节点追加到链表中作为链表的最后一个元素 阅读详情

相关推荐

代码随想录刷题训练营Day3--203.移除链表元素707.设计链表206.反转链表

由于一开始的代码基础链表部分花的功夫比较多,很容易就做出来了,只需要将指针指向下下一个元素(忽略下一个元素)就可以了,同时学习了虚拟头节点,删除时链表节点时使用。

一位复制者 662

代码随想录训练营Day3 LeetCode 203.移除链表元素 LeetCode707.设计链表 LeetCode206.反转链表

(一)注意事项1.定义一个dummy虚拟头结点,指向头节点之前的元素好处:便于返回链表,处理头结点2.定义个cur指针.指向 dummy当我到 cur->next->var==val,cur->next就是要删除元素:删除操作:cur->next =cur->next->next;

ly040422的博客 624

代码随想录算法训练营Day3 | 203. 移除链表元素 707. 设计链表 206.反转链表

方法一:遍历链表跳过值为val的节点,要注意头节点等于val的情况。以指示链表中的上一个节点。假设链表中的所有节点下标从。,请你反转链表,并返回反转后的链表。是指向下一个节点的指针/引用。如果是双向链表,则还需要属性。,请你删除链表中所有满足。给你一个链表的头节点。

m0_74154872的博客 353

代码算法训练营day3 | 203移除链表元素707设计链表206反转链表

链表问题很有意思,指针的指向也非常灵活,也要记得保存可能会丢失的那个值,很常见的就是cur->next。

qq_43440821的博客 967

代码随想录算法训练营Day3| LeetCode 203 移除链表元素707 设计链表206 反转链表

代码随想录算法训练营跟练第三天!!!被链表打脸!!

修炼途中的所见所闻,所思所想。 1392

代码随想录算法训练营Day3 | 203.移除链表元素 707.设计链表 206.反转链表

2. 删除head时候 tmp=head,删除cur->next,tmp=cur->next.1.需判断cur以及cur->next是否为空。

qq_24817679的博客 1860

代码随想录算法训练营Day3 | 链表203.移除链表元素707设计链表206反转链表

链表移除元素设计链表反转链表

宁愿过拟合不要欠拟合 2124

代码随想录算法训练营Day3|链表Part01|203.移除链表元素707.设计链表206.反转链表

本文总结了链表相关算法题的解题思路。203移除链表元素通过分类讨论处理头节点情况,使用双指针(pre和cur)遍历删除目标节点;707设计链表采用虚拟头节点简化操作,实现增删查等功能;206反转链表使用双指针(pre和cur)配合临时节点实现反转。关键点在于:1)虚拟头节点避免头节点特殊处理;2)双指针法遍历链表3)注意节点指针的保存与修改顺序。这些方法体现了链表与数组在双指针应用上的相似性。

m0_71282417的博客 373

代码随想录算法训练营day3| 203.移除链表元素707. 设计链表206. 反转链表

分析:将后面所有的结点都想成了一个结点,其实后面是一串,所以应该接到一串结点的最后面,即head->next->next = head,这里head->next就是reversed链表结尾的结点。2、关于index超出范围的判断需要想清楚,在这个题中,因为涉及对于index的超范围的判断,因此循环不好用for,然后用index作为退出条件。3、考虑退出的规模,即一个结点都不剩,因为只要剩一个,就需要判断是否需要删除,并且将退出判断写在整个函数最前面,即“if(head == NULL)”。

weixin_40023508的博客 2105

代码随想录算法训练营Day3 | LeetCode203 移除链表元素707.设计链表206.反转链表

数组是在内存中是连续分布的,但是链表在内存中可不是连续分布的。链表是通过指针域的指针链接在内存中各个节点。所以链表中的节点在内存中不是连续分布的 ,而是散乱分布在内存中的某地址上,分配机制取决于操作系统的内存管理。链表的定义性能分析。

weixin_66774683的博客 1710

Studying-代码随想录训练营day3| 链表理论基础、203.移除链表元素707设计链表206反转链表

训练第三天,链表理论基础、203.移除链表元素707设计链表206反转链表

yachihaoteng的博客 1350

代码随想录算法训练营 day 3 |203.移除链表元素 ,707.设计链表 ,206.反转链表

如果index在[0,size)区间,对链表遍历直至index的前一个节点,然后进行插入操作。对于链表节点的next的概念及使用有了更为深刻的认识与理解。B.newNode的下一个结点指向head的下一个节点。如果index合法则遍历链表找到index的前一个结点,然后进行删除操作。有两种方法,第一种是在原链表中进行移除操作,第二种是设置一个虚拟头节点进行操作。给链表添加一个新的节点作为头结点,有利于后续节点移除的统一处理。按顺序执行A~D步骤。

m0_63601971的博客 1928

代码随想录算法训练营Day3-203.移除链表元素707.设计链表206.反转链表

def addAtIndex(self, index: int, val: int) -> None: 将一个值为 val 的节点插入到链表中下标为 index 的节点之前。如果 index 等于链表的长度,则该节点将附加到链表的末尾。链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向None(空指针的意思)示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL。

zjububbleYu的博客 921

代码随想录算法训练营day3 | 203.移除链表元素707.设计链表206.反转链表

代码随想录算法训练营day3 | 203.移除链表元素707.设计链表206.反转链表

m0_55763458的博客 1124

代码随想录算法训练营Day3 | 203 移除链表元素707 设计链表206 反转链表

203 移除链表元素 题意 删除链表中等于给定值 val 的所有节点。 示例 1: 输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5] 示例 2: 输入:head = [], val = 1 输出:[] 示例 3: 输入:head = [7,7,7,7], val = 7 输出:[] 思路 方法一:直接使用原来的链表来进行删除操作 删除节点的操作:让被删除节点的前一个节点指向后一个节点即可跳过该节点,再

pepperony3000的博客 1031

代码随想录训练营 Day3打卡 链表part01 203.移除链表元素 707.设计链表 206.反转链表

代码随想录训练营 Day3打卡 链表part01 203.移除链表元素 707.设计链表 206.反转链表

qq_42952637的博客 1128

代码随想录训练营第42期 Day3打卡 LeetCode 203.移除链表元素707.设计链表206.反转链表

代码随想录训练营第42期 Day3打卡 LeetCode 203.移除链表元素707.设计链表206.反转链表

记得要努力变强 1420

代码随想录算法训练营Day3|203.移除链表元素206.反转链表707.设计链表

1、首先,删除链表中的一个节点,为了不影响head节点,我们要定义一个curNode节点。2、但是,如果要删除的节点是头结点,如图(a)所示,对于头结点来说,需要加一个虚拟节点作为它的curNode,这样才可以和图(b)一样通过curNode.next赋值为curNode.next.next来跳过这个需要删除的节点。其实当cur为null的时候就可以停止了,因为这个时候cur为null,不需要再让cur指向pre操作了,这个时候就可以停止了,因此while循环的判断条件为while(cur!

weixin_43836337的博客 1177
上一篇: 代码训练营 Day2| 209.长度最小的子数组 |59.螺旋矩阵II
下一篇: 代码训练营 Day4 | 24. 两两交换链表中的节点 | 19.删除链表的倒数第N个节点 | 142.环形链表II
RatherDoMyMath_
博客等级 码龄7年 219粉丝 · 24原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值