给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。
返回删除后的链表的头节点。
输入: head = [4,5,1,9], val = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
class Solution:
def deleteNode(self, head: ListNode, val: int) -> ListNode:
dummy = ListNode(0) # 设置伪结点
dummy.next = head
if head.val == val: return head.next # 头结点是要删除的点,直接返回
while head and head.next:
if head.next.val == val: # 找到了要删除的结点,删除
head.next = head.next.next
head = head.next
return dummy.next
val为int时解法:信息交换法
假如 head 为 4 -> 5 -> 1 -> 9,val 为 5 -> 1 -> 9,表示我们要删除结点 5,这时我们使用信息交换,把 val 改为 1 -> 9的信息就行了。
为什么呢?因为我们把待删除节点的后一个元素赋值给待删除节点,也就相当于删除了当前元素。
但是聪明的你一定会举出反例:如果 val 的值是最后一个元素 9 呢?我们无法找到 9 的后一个元素(因为没有),只能重头开始找待删除元素 9,这样的话时间复杂度再次变成了 O(N)。
这就是这道题目有意思的地方,我们发现,如果删除节点为前面的 n−1个节点,时间复杂度均为 O(1),只有删除节点为最后一个时,时间复杂度才会变成 O(n)。平均时间复杂度为: ( O ( 1 ) × ( n − 1 ) + O ( n ) ) / n = O ( 1 ) (O(1)×(n−1)+O(n))/n=O(1) (O(1)×(n−1)+O(n))/n=O(1),仍然为 O(1)。
class Solution:
def deleteNode(self, head, val):
if head is None or val is None:
return None
if val.next is not None: # 待删除节点不是尾节点
tmp = val.next
val.val = tmp.val
val.next = tmp.next
elif head == val: # 待删除节点只有一个节点,此节点为头节点
head = None
else:
cur = head # 待删除节点为尾节点
while cur.next != val:
cur = cur.next
cur.next = None
return head
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof