描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
官方有循环遍历和递归两种解法。
先来看递归:https://blog.nowcoder.net/n/70a35462c5ba412e9a9f9fc70a875dd4?f=comment
①如果链表头结点为空,或者只有头结点,则直接返回pHead。
②然后就是判断头结点等不等于头结点的next,也就是对pHead.val和pHead.next.val的值进行判断,如果不相等,证明头结点的值不重复(因为链表是排序的),所以保留头结点,然后对pHead.next进行递归,即保留pHead,以pHead.next为头结点的链表重新放到函数中来调用,直到去除值重复的点。
那如果头结点的值跟它的next的值重复了呢?这个时候本来应该要删除头结点,但是因为不知道有几个跟头结点值重复的结点,所以需要重新设置一个move指针,一直向后遍历寻找到与 pHead.val不相等的结点(至此前面的结点都是和头结点重复的,去掉),所以move指针这个时候指向的就是一个新的头结点了,把这个头结点代到函数中调用,直到去除所有值重复的点。
class Solution:
def deleteDuplication(self, pHead):
# write code here
if not pHead&nbs***bsp;not pHead.next:
return pHead
if pHead.val != pHead.next.val:
pHead.next = self.deleteDuplication(pHead.next)
else:
move = pHead.next
while move and pHead.val == move.val:
move = move.next
return self.deleteDuplication(move)
return pHead
时间复杂度O(N):N是链表节点数量,递归遍历一次。
空间复杂度O(N):递归调用的时候会用到了系统的栈。
再来看看循环遍历:
设置两个指针,一个是prev,一个是cur。prev初始在head位置,cur初始在pHead位置,也就是prev.next=cur,然后cur一直遍历下去,判断cur和cur.next的值是否相等,相等cur就后移一位,直到不相等时,cur相当于指向的是重复结点的最后一位(比如1,2,3,3,4,4,5,cur指向的就是第二个3),这个时候让prev.next=cur.next,等于说跳过了重复结点,cur=cur.next也后移到新的结点上,继续遍历,直到最后一个重复结点。
class Solution:
def deleteDuplication(self, pHead):
# 定义头节点指针,前指针和当前指针
p0 = ListNode(-1)
p = p0
p.next = pHead
cur = pHead
# 循环遍历
while cur and cur.next:
# 不相等,则前后指针继续遍历
if cur.val != cur.next.val:
p = p.next
cur = cur.next
else:
# 出现重复节点,即当前指针节点与下一个节点相等,则cur继续向右判断
val = cur.val
while cur and cur.val == val:
cur = cur.next
p.next = cur
return p0.next
时间复杂度O(N):需要遍历链表,N为链表长度。
空间复杂度O(1):只用到定义的指针。
这篇博客介绍了如何在排序链表中删除重复的结点,提供了递归和循环两种解法。递归方法通过比较头结点与头结点的next值来决定是否保留头结点,并递归处理后续链表;循环遍历方法使用两个指针prev和cur,遍历链表并跳过重复结点。两种方法的时间复杂度均为O(N),空间复杂度分别为O(N)和O(1)。
172万+

被折叠的 条评论
为什么被折叠?



