链表问题(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)

原文地址:https://www.cnblogs.com/Lee-yl/p/9726645.html