题目:
给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。
示例 1:
输入: 1->2->3->3->4->4->5
输出: 1->2->5
示例 2:
输入: 1->1->1->2->3
输出: 2->3
分析:
因为最近一直在刷链表类型的题目,所以拿到这个题目的时候我首先想到了用双指针来做,即,快慢指针。先生成一个头节点dummy,指向head。快指针的职责就是往前遍历节点,先比较快指针指向节点与下一个节点的值,当遇到重复节点的时候继续向下遍历,而这时候慢指针原地不动,当快指针找到第一个和之前节点的值不同的节点时,判断快慢指针的位置关系。如果慢指针的下一个节点就是快指针,就让慢指针=快指针,反之的话,说明中间隔着重复节点,此时就让慢指针的next指向快指针的next。知道遍历完成。
代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if (head == null) {
return head;
}
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode fast = dummy.next;
ListNode slow = dummy;
while (fast != null) {
while (fast.next != null && fast.val == fast.next.val) {
fast = fast.next;
}
if (slow.next == fast) {
slow = fast;
}
else {
slow.next = fast.next;
}
fast = fast.next;
}
return dummy.next;
}
}
分析二:
看了大佬的解法,发现还有递归的方法, 就是由上面的解法中演变过来的,递归的三要素:终止条件,递归进行下去的条件,返回值。因为head节点是一个个往后遍历的,所以当head节点为空的时候,退出返回结果,而题目中要求重复值得节点不应该再出现在新的链表中,所以就是下面代码的return deleteDuplicates(head.next)。直接看代码吧,理解的更透彻。
代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if (head == null) {
return head;
}
if (head.next != null && head.val == head.next.val) {
while (head.next != null && head.val == head.next.val) {
head = head.next;
}
return deleteDuplicates(head.next);
} else {
head.next = deleteDuplicates(head.next);
}
return head;
}
}