力扣-82-删除排序链表中的重复元素Ⅱ

这个删除重复不太常规的是:它不是删除多出来的剩下一个,而是比如有三个1,1重复了,那这三个1节点都不要

	ListNode* deleteDuplicates(ListNode* head) {
		if (!head) return head;// 空链表直接返回
		// 虚拟头指针避免空头问题
		ListNode* virtual_node = new ListNode();
		virtual_node->next = head;
		// 指针1用来遍历,指针2用来标记重复段的起点
		// 还需要一个指针标记重复段的前一个位置
		ListNode* ptr1 = head->next, *ptr2 = head,*ptr3 = virtual_node;

		while (ptr1){
			if (ptr1->val != ptr2->val) {
				if (ptr2->next->val!=ptr1->val)
					// 说明中间存在重复段了
					ptr3->next = ptr1;
				else ptr3 = ptr2;
				ptr2 = ptr1;
			}
			ptr1 = ptr1->next;
		}
		// 还有一种情况是遍历指针走完了,但是最后一段还是重复段没有处理
		if (ptr2->next) ptr3->next = nullptr;
		return virtual_node->next;
	}

三指针,ptr1用来遍历整个链表,ptr2用来标记重复段的起始位置,ptr3用来标记重复段的前一个位置
删除重复段的操作就是:将ptr3的next指针指向ptr1

另外需要注意的是两个情况:

  1. 原本的头节点被删除了,考虑空头的情况用虚拟头节点技巧处理
  2. 链表的最后一段是重复的,但是遍历指针ptr1跑完了,循环体不再处理,这时候就需要一个收尾处理,ptr1最后的位置应该是指向结果链表的最后一个元素
posted @ 2023-01-29 14:29  YaosGHC  阅读(27)  评论(0)    收藏  举报