美文网首页
Chapter 3链表

Chapter 3链表

作者: lililililiyan | 来源:发表于2019-06-03 23:23 被阅读0次

    单链表

    problem2 两数相加

    给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

    如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

    您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

    示例:

    输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
    输出:7 -> 0 -> 8
    原因:342 + 465 = 807
    
    # Definition for singly-linked list.
    # class ListNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution(object):
        def addTwoNumbers(self, l1, l2):
            """
            :type l1: ListNode
            :type l2: ListNode
            :rtype: ListNode
            """
            flag = 0
            p = pre = ListNode(0)
            while l1 or l2:
                if l1 is None:
                    l1 = ListNode(0)
                if l2 is None:
                    l2 = ListNode(0)
                res = (l1.val + l2.val + flag) % 10
                flag = (l1.val + l2.val +flag) // 10
                p.next = ListNode(res)
                p = p.next
                #p.next = p = ListNode(val)
                l1 = l1.next
                l2 = l2.next
                if (l1 is None) and (l2 is None) and flag:
                    p.next = ListNode(1)
            return pre.next
                            
    

    21. 合并两个有序链表

    将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

    示例:

    输入:1->2->4, 1->3->4
    输出:1->1->2->3->4->4

    用递归,比自己写的迭代简洁

    # Definition for singly-linked list.
    # class ListNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    class Solution:
        def mergeTwoLists(self, l1, l2):
            if l1 is None:
                return l2
            elif l2 is None:
                return l1
            elif l1.val < l2.val:
                l1.next = self.mergeTwoLists(l1.next, l2)
                return l1
            else:
                l2.next = self.mergeTwoLists(l1, l2.next)
                return l2
    

    83. 删除排序链表中的重复元素

    给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

    示例 1:

    输入: 1->1->2
    输出: 1->2
    示例 2:

    输入: 1->1->2->3->3
    输出: 1->2->3

    \color{red}{自己写的逻辑过于乱,虽然和别人的功能是一样的}
    ps:虽是删除但不改变原链表而是返回删除的链表

    # Definition for singly-linked list.
    # class ListNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution(object):
        def deleteDuplicates(self, head):
            """
            :type head: ListNode
            :rtype: ListNode
            """
            p = head
            if head is None or head.next is None:
                return head
            while head.next:
                if head.val == head.next.val:
                    head.next = head.next.next
                else:
                    head = head.next
                    # p = head.next
                #p.next = head
            return p
    

    \color{red}{别人的}

    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution:
        def deleteDuplicates(self, head: ListNode) -> ListNode:
            if head == None or head.next== None:
                return head        
            p = head
            while True:
                if p.val == p.next.val:
                    p.next = p.next.next
                else:
                    p = p.next
                if p.next==None:
                    break            
            return head
    
    203. 移除链表元素

    删除链表中等于给定值 val 的所有节点。

    示例:

    输入: 1->2->6->3->4->5->6, val = 6
    输出: 1->2->3->4->5
    \color{blue}{因为头结点也是可能删除的,所以相比较前题的删除节点,不能用head指针返回,而是要用另一个哑元}

    # Definition for singly-linked list.
    # class ListNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution(object):
        def removeElements(self, head, val):
            """
            :type head: ListNode
            :type val: int
            :rtype: ListNode
            """
            p = ListNode(0)
            p.next = head
            pre =p
            while p and p.next:
                if p.next.val == val:
                    p.next = p.next.next
                else:
                    p = p.next
            return pre.next
    

    237. 删除链表中的节点

    请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点。

    现有一个链表 -- head = [4,5,1,9],它可以表示为:

    image

    示例 1:

    输入: head = [4,5,1,9], node = 5
    输出: [4,1,9]
    解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.

    示例 2:

    输入: head = [4,5,1,9], node = 1
    输出: [4,5,9]
    解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.

    说明:

    • 链表至少包含两个节点。
    • 链表中所有节点的值都是唯一的。
    • 给定的节点为非末尾节点并且一定是链表中的一个有效节点。
    • 不要从你的函数中返回任何结果。

    \color{red}{因为节点没有前向的指针,所以采用先把下一节点的val值赋给该节点,然后将其的next指针后移一位来删除节点}

    # Definition for singly-linked list.
    # class ListNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution(object):
        def deleteNode(self, node):
            """
            :type node: ListNode
            :rtype: void Do not return anything, modify node in-place instead.
            """   
            node.val = node.next.val
            node.next = node.next.next
    

    \color{gray}{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
    \color{purple}{假如爱情有天意,快慢指针终会相遇(可用在循环中,慢走一步,快走两步)}
    \color{purple}{快慢指针还可用在查找链表的中间节点}

    142. 环形链表 II

    给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

    为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos-1,则在该链表中没有环。

    说明:不允许修改给定的链表。
    示例 1:
    输入:head = [3,2,0,-4], pos = 1
    输出:tail connects to node index 1
    解释:链表中有一个环,其尾部连接到第二个节点。

    image
    示例 2:
    输入:head = [1,2], pos = 0
    输出:tail connects to node index 0
    解释:链表中有一个环,其尾部连接到第一个节点。
    image
    示例 3:
    输入:head = [1], pos = -1
    输出:no cycle
    解释:链表中没有环。
    image
    进阶:
    你是否可以不用额外空间解决此题?

    \color{red}{把见过的节点丢集合里,下次再遇见就是环的开始}

    # Definition for singly-linked list.
    # class ListNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution(object):
        def detectCycle(self, head):
            """
            :type head: ListNode
            :rtype: ListNode
            """
            s = {None}
            while head not in s:
                s.add(head)
                head = head.next
            return head
    

    \color{red}{还有一个纯数学的快慢指针解法}

    设环的起始节点为 E,快慢指针从 head 出发,快指针速度为 2,设相交节点为 X,head 到 E 的距离为 H,E 到 X 的距离为 D,环的长度为 L,那么有:快指针走过的距离等于慢指针走过的距离加快指针多走的距离(多走了 n 圈的 L) 2(H + D) = H + D + nL,因此可以推出 H = nL - D,这意味着如果我们让俩个慢指针一个从 head 出发,一个从 X 出发的话,他们一定会在节点 E 相遇

    捕获.PNG
    class Solution(object):
        def detectCycle(self, head):
        slow = fast = head
        while fast and fast.next:
            fast = fast.next.next
            slow = slow.next
            if slow == fast:
            break
        else:
            return None
        while head is not slow:
            head = head.next
            slow = slow.next
        return head
    

    206. 反转链表

    反转一个单链表。
    示例:
    输入: 1->2->3->4->5->NULL
    输出: 5->4->3->2->1->NULL
    进阶:
    你可以迭代或递归地反转链表。你能否用两种方法解决这道题?

    \color{purple}{python多元赋值}

    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution:
        def reverseList(self, head):
            """
            :type head: ListNode
            :rtype: ListNode
            """
            p, rev = head, None
            while p:
                rev, rev.next, p = p, rev, p.next
            return rev
    

    \color{purple}{与上法思路一样,具体操作不同的常规解法}
    ···

    Definition for singly-linked list.

    class ListNode(object):

    def init(self, x):

    self.val = x

    self.next = None

    class Solution(object):
    def reverseList(self, head):
    """
    :type head: ListNode
    :rtype: ListNode
    """
    cur, rev = head, None
    while cur:
    p = rev
    rev = cur
    cur = cur.next
    rev.next = p
    return rev
    ···

    160. 相交链表

    编写一个程序,找到两个单链表相交的起始节点。
    注意:
    如果两个链表没有交点,返回 null.
    在返回结果后,两个链表仍须保持原有的结构。
    可假定整个链表结构中没有循环。
    程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。

    图挂了>_<
    \color{purple}{注意的是循环条件,若两单链表没有交点,两指针到末尾,都==None,结束循环,这里如果不用pA != pB的循环,会很麻烦}
    \color{blue} {这道题的代码就几行,充分说明了,把数学逻辑搞懂了,编码很容易}

    # Definition for singly-linked list.
    # class ListNode(object):
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution(object):
        def getIntersectionNode(self, headA, headB):
            """
            :type head1, head1: ListNode
            :rtype: ListNode
            """
            pA=headA
            pB=headB
            while pA!=pB:
                if pA==None:
                    pA = headB
                else:
                    pA = pA.next
                if pB==None:
                    pB = headA
                else:
                    pB = pB.next
            return pA
    

    目前的超纲知识:深拷贝,排序(算法面试卡片的链表模块)

    82. 删除排序链表中的重复元素 II

    \color{red}{虚拟头结点}

    给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 *没有重复出现 *的数字。

    示例 1:

    输入: 1->2->3->3->4->4->5
    输出: 1->2->5

    示例 2:

    输入: 1->1->1->2->3
    输出: 2->3

    \color{green}{pre指针的作用,保证了dummy指向无重复的头指针,说不清楚}

    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    
    class Solution:
        def deleteDuplicates(self, head: ListNode) -> ListNode:
            dummy = pre = ListNode(0)
            dummy.next = head
            while head and head.next:
                if head.val == head.next.val:
                    while head and head.next and head.val == head.next.val:
                        head.next = head.next.next
                    head = head.next
                    pre.next = head
                else:
                    head = head.next
                    pre = pre.next 
            return dummy.next
    

    相关文章

      网友评论

          本文标题:Chapter 3链表

          本文链接:https://www.haomeiwen.com/subject/djbqxctx.html