1、题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。
例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
2、思路分析
方法一:非递归算法
该题目一共可以分为如下几种情况:
- 当前链表只有一个或没有节点。
- 给当前链表添加一个头结点head,使得后续所有的操作相同(cur不为空时)
head.next=pHead;
pre=head;
cur=head.next;
2.1当前节点的下一个节点不为空,且下一个节点和当前节点的值相同,则cur后移,直到不同时,删除相同的所有节点
否则,同时后移。
方法二:非递归算法——多次遍历
- 第一次遍历,挑出重复元素,放在集合中。
- 第二次遍历,删除多余元素。
方法三:递归
- 如果当前节点为重复节点,删除所有和当前节点值相同的节点,返回下一个节点
- 如果当前节点为非重复节点,直接返回下一个节点
3、代码实现
非递归:
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ListNode deleteDuplication(ListNode pHead)
{
if(pHead==null||pHead.next==null){
return pHead;
}
ListNode head=new ListNode(-1);
head.next=pHead;
ListNode pre=head;
ListNode cur=head.next;
while(cur!=null){
if(cur.next!=null&&cur.val==cur.next.val){
while(cur.next!=null&&cur.val==cur.next.val){
cur=cur.next;
}
pre.next=cur.next;
cur=cur.next;
}else{
pre=pre.next;
cur=cur.next;
}
}
return head.next;
}
}
方法二:多次便利
import java.util.*;
public class Solution {
public ListNode deleteDuplication(ListNode pHead)
{
if(pHead==null||pHead.next==null){
return pHead;
}
//1、先找出重复节点
HashSet<Integer> set=new HashSet<>();
ListNode pre=pHead;
ListNode cur=pHead.next;
while(cur!=null){
if(pre.val==cur.val){
set.add(cur.val);
}
pre=cur;
cur=cur.next;
}
//2、删除节点
//2.1、删除头结点
while(pHead!=null&& set.contains(pHead.val)){
pHead=pHead.next;
}
if(pHead==null){
return null;
}
//2.2删除中间节点
pre=pHead;
cur=pHead.next;
while(cur!=null){
if(!set.contains(cur.val)){
pre=cur;
cur=cur.next;
}else{
pre.next=cur.next;
cur=cur.next;
}
}
return pHead;
}
}
方法三:递归算法实现
public class Solution {
public ListNode deleteDuplication(ListNode pHead)
{
if(pHead==null||pHead.next==null){
return pHead;
}
//如果当前节点不是重复节点
if(pHead.val!=pHead.next.val){
pHead.next=deleteDuplication(pHead.next);
return pHead;
}else{//如果当前节点是重复节点,找到第一个不重复的节点
ListNode head=pHead;
while(head!=null&&head.val==pHead.val){
head=head.next;
}
return deleteDuplication(head);
}
}
}