(剑指offer)面试题18:删除链表的节点

给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点

# 如果不是尾结点:o(1),把下一个节点的内容复制到需要删除的节点上覆盖原有内容,再把下一个节点删除
# 如果删除的是尾结点,需要全部遍历:o(n)复杂度,利用前一节点删除
# 平均复杂度仍然为o(1)
# 链表只有一个节点,那么删除结点后还需要把头结点设为None
class ListNode:
    def __init__(self,x):
        '''结点指针'''
        self.val=x
        self.next=None
    def __del__(self):
        '''删除结点'''
        self.val=None
        self.next=None

class Solution:
    def DeleteNode(self,pListHead,pToBeDeleted):
        # 给定头结点指针和删除结点的指针
        if not pListHead or not pToBeDeleted:
            # 判断是不是空链表
            return None
        if pToBeDeleted.next != None:
            # 要删除的不是尾结点
            pNext = pToBeDeleted.next
            pToBeDeleted.val = pNext.val
            pToBeDeleted.next = pNext.next
            pNext.__del__() # 最后把这个next结点删除
        elif pListHead == pToBeDeleted:
            # 链表只有一个节点
            pToBeDeleted.__del__() # 删除结点
            pListHead.__del__() #把头结点也设为none
        else:
            # 删除尾结点
            pNode = pListHead #从头开始查找
            # 当指针指向删除结点是停止,让该结点指针指向none,并删除要删除的节点。
            while pNode.next != pToBeDeleted:
                pNode = pNode.next
            pNode.next = None
            pToBeDeleted.__del__()

node1 = ListNode(10)
node2 = ListNode(11)
node3 = ListNode(12)
node4 = ListNode(13)

node1.next=node2
node2.next=node3
node3.next=node4

s = Solution()
# 10->11->12->13
s.DeleteNode(node1,node3)
print(node3.val)
# 10-11-12
# 删除尾结点
s.DeleteNode(node1,node3)
# 10-11
print(node3.val)
print(node2.val)
s.DeleteNode(node1,node1)
# 11
print(node1.val)

s.DeleteNode(node1,node1)
# none
print(node1.val)

题目二:删除链表中重复的节点
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

class ListNode:
    def __init__(self,x):
        self.val=x
        self.next = None

class Solution:
    def deleteDuplication(self,pHead):
        if pHead == None  or pHead.next==None:
            # 链表是空链表或者是只有一个节点的链表
            return pHead
        # 给定一个头结点在链表前
        new_head = ListNode(-1)
        new_head.next = pHead
        # 设置三个游标,pre是p前一个,nex是p下一个用来查找重复
        pre = new_head
        p = pHead
        nex = None
        while p!= None and p.next != None:
            nex = p.next
            if p.val == nex.val:
                while nex != None and nex.val == p.val:
                    nex = nex.next #一直找到和p不相同的一个位置跳出循环
                pre.next = nex
                p = nex
            else:
                # 不相同时游标向前移动
                pre = p
                p = p.next
        # return new_head.next.next.next.val

        cur = pHead
        while cur != None:
            print(cur.val,end=' ')
            cur = cur.next
        print('\n')

node1 = ListNode(1)
node2 = ListNode(2)
node3 = ListNode(3)
node4 = ListNode(3)
node5 = ListNode(4)
node6 = ListNode(4)
node7 = ListNode(5)

node1.next = node2
node2.next=node3
node3.next = node4
node4.next = node5
node5.next = node6
node6.next=node7
s = Solution()
s.deleteDuplication(node1)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值