zoukankan      html  css  js  c++  java
  • 链表问题(2)-----删除

    一、题目:在单链表和双链表中删除倒数第K个节点

    分别实现两个函数,一个可以删除单链表中倒数第K个节点,另一个可以删除双链表中倒数第K个节点。

    要求:如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1)

    单链表思路:

    遍历链表,每移动一步,K-1。如果链表结束,K>0 ,则不存在倒数第K个节点。如果 K == 0,则将链表的头节点删除。如果K<0,则遍历第二遍链表。

    import copy
    class Node:
        def __init__(self,value):
            self.value = value
            self.next = None
    def delete(head,k):
        if k < 1 or not head:
            return head
        head1 = head
        while head1:      
            head1 = head1.next    
            k -= 1
        if k > 0:
            return 
        elif k == 0:
            head = head.next
        else:
            head1 = head
            k += 1
            while k != 0:
                head1 = head1.next
                k += 1
            head1.next = head1.next.next
        return head
    head = Node(1)
    head.next = Node(2)
    head.next.next = Node(3)
    head.next.next.next = Node(4)
    k = 2
    delete(head,k)
            
        

    双链表的思路:

    和单链表一样,只是在删除链表节点的地方考虑双链表的 last 指向。

    class Node:
        def __init__(self,value):
            self.value = value
            self.last = None
            self.next = None
    def delete(head,k):
        if k < 1 or not head:
            return head
        head1 = head
        while head1:      
            head1 = head1.next    
            k -= 1
        if k > 0:
            return 
        elif k == 0:
            head = head.next
            head.last = None
        else:
            head1 = head
            k += 1
            while k != 0:
                head1 = head1.next
                k += 1
            head1.next = head1.next.next
            if head1.next:
                head1.next.last = head1
        return head
    head = Node(1)
    head.next = Node(2)
    head.last = None
    head.next.next = Node(3)
    head.next.last = head
    head.next.next.next = Node(4)
    head.next.next.last = head.next
    head.next.next.next.last = head.next.next
    k = 2
    delete(head,k)

    二、题目:删除链表中间节点或者特定位置的节点

    删除中间节点的思路:

    初始:如果链表为空或者长度为1,直接返回。如果链表的长度为2,则将头结点删除。

    遍历链表,链表长度每增加2,要删除的节点就后移一个节点。

    代码:

    class Node:
        def __init__(self,value):
            self.value = value
            self.next = None
    def deleteMed(head):
        if not head or not head.next:
            return head
        if not head.next.next:
            return head.next
        pre = head
        cur = head.next.next
        while cur.next and cur.next.next:
            pre = pre.next
            cur = cur.next.next
        pre.next = pre.next.next
        return head
    head = Node(1)
    head.next = Node(2)
    head.next.next = Node(3)
    head.next.next.next = Node(4)
    deleteMed(head)

    删除特定位置 a/b 的节点的思路:

     确定链表长度n ,再 n * a/b 确定要删除节点的位置。

    代码:

    import math
    class Node:
        def __init__(self,value):
            self.value = value
            self.next = None
    def deleteMed(head,a,b):
        if not head or a < 1 or a>b:
            return head
        n = 0
        pre = head
        while pre:
            pre = pre.next
            n += 1
        m = math.ceil(n * a / b)
        if m == 1:
            head = head.next
            return head
        pre = head
        m -= 1
        while m != 1:
            pre = pre.next
            m -= 1
        pre.next = pre.next.next
        return head
    head = Node(1)
    head.next = Node(2)
    head.next.next = Node(3)
    head.next.next.next = Node(4)
    a = 2
    b = 3
    deleteMed(head,a,b)

     


    三、题目:将单链表中重复的值删除

    方法一:利用字典。时间复杂度O(N),空间复杂度O(N)

    遍历链表,如果在字典中,则将当前节点删除,如果不在就下一个。

    代码:

    def removeList(head):
        if not head:
            return None
        dic = {head:1}
        cur = head.next
        pre = head
        while cur:
            if cur not in dic:
                dic[cur] = 1
                pre = pre.next
            else:
                pre.next = cur.next
            cur = pre.next
        return head

    方法二:类似选择排序,时间复杂度O(N2),空间复杂度O(1)

    代码:

    def removeList(head):
        if not head:
            return None
        cur = head
        while cur:
            pre = cur
            next = cur.next
            while next:
                if next.value == cur.value:
                    pre.next = next.next
                else:
                    pre = pre.next
                next = next.next            
            cur = cur.next

    五、题目:给定一个节点,但不知该链表的头节点,怎么删除该节点,时间复杂度O(1)

  • 相关阅读:
    javascript类继承系列一
    Update Statistics用法
    FOR XML PATH
    SQL Server 中WITH (NOLOCK)
    ROW_NUMBER () 与 PARTITION组合拳
    sql脚本的格式
    存储过程
    动态sql
    尽量不要用select into 复制表
    杂谈
  • 原文地址:https://www.cnblogs.com/Lee-yl/p/9726645.html
Copyright © 2011-2022 走看看