文章目录
- 题目
- 思路1
- 复杂度
- Code2
- 思路2
- 复杂度2
- Code2
题目
给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
示例 1:
输入:head = [1,2,3,3,4,4,5]
输出:[1,2,5]
示例 2:
输入:head = [1,1,1,2,3]
输出:[2,3]
提示:
链表中节点数目在范围 [0, 300] 内
-100 <= Node.val <= 100
题目数据保证链表已经按升序 排列
思路1
遍历两次,第一次遍历的时候声明一个set集合,存储所有出现过多次的节点,在第二次遍历的时候使用双指针,cur指针在前,pre指针在后,如果发现cur指向的节点在集合中,则将cur向后移动,否则移动pre和cur节点
最终返回事先声明的dom节点,因为head节点指向的值可能多次出现,这里我们不可以直接返回head
复杂度
时间复杂度:
遍历了两次, O ( 2 n ) O(2n) O(2n)
空间复杂度:
存储了出现两次的节点, O ( n ) O(n) O(n)
Code2
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]:s = set()if not head: return headpre,cur = ListNode(),headdom = prewhile cur.next:if cur.val == cur.next.val:s.add(cur.val)cur = cur.nextcur = headwhile cur:while cur and cur.val in s: cur = cur.nextpre.next = curif not cur: breakcur = cur.nextpre = pre.nextreturn dom.next
思路2
只声明一个指针cur,在while循环中判断cur.next和cur.next,next是否存在。如果这两个值不等,说明cur.next是不重复出现的,可以当作cur的下一个节点;
否则说明这两个数一样,则这两个数需要去除,我们这里进一个while循环,不断推进cur.next的值,知道cur.next的值得不是最开始出现的那两个相同的数,如果他是none,则此时cur.next就是none,不需要额外操作,如果他是一个数字,且后面还有节点,则继续循环
复杂度2
时间复杂度:
遍历一次: O ( n ) O(n) O(n)
空间复杂度:
没有声明额外空间: O ( 1 ) O(1) O(1)
Code2
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]:cur = dumy = ListNode(next=head)while cur.next and cur.next.next:val = cur.next.valif val == cur.next.next.val:while cur.next and cur.next.val == val:cur.next = cur.next.nextelse:cur = cur.nextreturn dumy.next