给定一个已排序的链表的头 , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。head
示例 1:
输入:head = [1,1,2]
输出:[1,2]
示例 2:
输入:head = [1,1,2,3,3]
输出:[1,2,3]
提示:
- 链表中节点数目在范围 内
[0, 300]
-100 <= Node.val <= 100
- 题目数据保证链表已经按升序 排列
代码示例一:
//本解法采用双指针
class Solution {
public ListNode deleteDuplicates(ListNode head) {
//判断链表是否是空或者是一个元素
if(head == null || head.next == null){
return head;
}
//定义哨兵节点
ListNode s = new ListNode(-1,head);
//定义双指针
//s -> 1 -> 2 -> 3
// p1 p2
ListNode p1 = s.next;
ListNode p2 = s.next.next;
//当p2==null说明此时链表以遍历完
while(p2 != null){
//判断p1的值是否等于p2的值
if(p1.val == p2.val){
//相等
//改变p1的指向,并移动p2
p1.next = p2.next;
//p2 = p2.next;
}else{
//不等
//移动p1和p2
p1 = p1.next;
//p2 = p2.next;
}
//通过上面发现代码相同,就把它移出来
p2 = p2.next;
}
return s.next;
}
}
此解法比较好理解,且比较简单,只需熟练掌握双指针的基本用法就可以解决。
代码示例二:
//本题采用递归的方式进行求解
class Solution {
public ListNode deleteDuplicates(ListNode p) {
//判断链表是否为空或一
if(p == null || p.next == null){
return p;
}
//判断当前节点的值和下一个节点值是否相同
if(p.val == p.next.val){
//相同
//返回下一个节点的递归调用值
return deleteDuplicates(p.next);
}else{
//不相同
//先改变当前节点的指向
p.next = deleteDuplicates(p.next);
//返回本节点
return p;
}
}
}
运用递归求解可能会感到有点抽象,但你只要认真的多看几遍,在写几遍可能就不会那么抽象了,
在理解上可能会有点小难。