83 删除排序链表中的重复元素 题目描述
给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。
示例 1:
输入: 1->1->2
输出: 1->2
示例 2:
输入: 1->1->2->3->3
输出: 1->2->3
分析
这道题,如果这样想:每次只比较相邻的两个结点,如果不同则向前移动;如果相同,则将删除相邻的第二个结点。循环结束就删除了所有重复的元素。
public ListNode deleteDuplicates(ListNode head) {
if (head == null)
return null;
ListNode prev = head;
while (prev.next != null) {
if (prev.val == prev.next.val) // 相同,删除之
prev.next = prev.next.next;
else // 不同,跳过
prev = prev.next;
}
return head;
}
82 删除排序链表中的重复元素 II 题目描述
给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。
示例 1:
输入: 1->2->3->3->4->4->5
输出: 1->2->5
示例 2:
输入: 1->1->1->2->3
输出: 2->3
分析
递归版本
和前面那道题不同的地方在于,这里要删除所有重复的数字。递归版本,这道题分为两种情况,一种是删除本结点以及后面若干相同结点,另一种是不删除当前结点(当前结点和后面的结点不同),连接到后面处理过的链表,递归下去,直到结点个数只有一个的时候结束。
public ListNode deleteDuplicates(ListNode pHead) {
// 个数等于 0 和 1 ,返回pHead
if (pHead == null || pHead.next == null)
return pHead;
// 当前结点重复
if (pHead.val == pHead.next.val) {
ListNode node = pHead.next;
// 删完连续相同的结点
while (node != null && node.val == pHead.val) node = node.next;
return deleteDuplicates(node);
}
else // 当前结点不重复
pHead.next = deleteDuplicates(pHead.next);
return pHead;
}
非递归版
由于头结点也有可能被删除,所以要定义一个新结点,连接上新的链表。然后定义一个前驱指针和一个现指针,每当前驱指针指向新建结点时,现指针就从下一个位置往下遍历,遇到相同的则继续往下,遇到不同的则前驱指针指向下一个不同的元素,如果现指针判断的第一个元素就不相同,则把前驱指针向下移一位。
public ListNode deleteDuplicates(ListNode pHead) {
if (pHead == null || pHead.next == null)
return pHead;
ListNode start = new ListNode(0);
start.next = pHead;
ListNode pre = start;
while (pre.next != null) {
ListNode cur = pre.next;
while (cur.next != null && cur.next.val == cur.val) cur = cur.next;
if (cur != pre.next) pre.next = cur.next;
else pre =pre.next;
}
return pHead;
}
如果文章里有说得不对的地方请前辈多多指正~ 与君共勉~