删除排序链表中的重复元素II
题目描述:
给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。
示例 1:
输入: 1->2->3->3->4->4->5
输出: 1->2->5
示例 2:
输入: 1->1->1->2->3
输出: 2->3
问题分析:
比着之前的删除排序链表的重复元素I,来说,它不需要保留重复的所有元素,一旦发现重复,所有元素都要删除
第一种方法:双指针法(也可以说是三指针法,设置的头结点需要参与元素链接,最后还需要输出)
设置一个新的头结点,使得链表元素进行链接和输出
当前后两个指针相同时,移动下一个指针到两个元素不相同,然后使用设置的头结点进行链接,得以越过相同元素
如果两个指针不相同,就移动处理,指针跟随
第二种方法:三指针法(利用三个指针和标志位flag进行处理)
第三种方法:递归方法
第四种方法:map统计出现的次数,将出现次数为1的元素放在新的链表上面(未做)
第五种方法:将链表元素转化为数组元素进行删除操作(未做)
代码展示(已验证):
/**leetcode 82
* 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 null;
ListNode dummy = new ListNode(-1); //为链表创建一个新的头,return dummy.next 来带领整个链表
dummy.next = head;
ListNode current = head;
ListNode index = dummy;
while(current != null && current.next!= null)//index在前面,所以判断index是否为null 就行
{
if(current.val == current.next.val) //相等,将index移动向下一位
{
while(current.next!= null && current.val == current.next.val)
current = current.next;
index.next = current.next;
current = current.next;
}
else
{
index = current;
current = current.next;
}
}
return dummy.next;
第二种 :三指针法
//第二种 :三指针法(已验证)
ListNode pre = null;
ListNode current = head;
while (current != null) {
ListNode nex = current.next; //通过while循环始终让nex作为最快的指针,注意进行null的判断
boolean flag = false; //使用flag作为nex和cur的标志位
while (nex != null && current.val == nex.val) {
flag = true;
nex = nex.next;
}
//对重复元素进行处理
if (flag) {
if (pre != null) { //判断不是刚开始,进行和nex结点的连接
pre.next = nex;
}
else { //头部
head = nex;
}
current = nex;
}
//对非重复元素进行连接和跳跃
else {
pre = current;
current = current.next;
}
}
return head;//返回头指针
第三种:递归方法
//第三种:递归方法
public static ListNode deleteDuplicates(ListNode head) {
//baseCase
if (head == null || head.next == null) {
return head;
}
ListNode next = head.next;
//如果是这种情况
// 1 --> 1 --> 1 --> 2 --> 3
// head next
//1.则需要移动next直到出现与当前head.value不相等的情况(含null)
//2.并且此时的head已经不能要了,因为已经head是重复的节点
//--------------else-------------
// 1 --> 2 --> 3
// head next
//3.如果没有出现1的情况,则递归返回的节点就作为head的子节点
if (head.value == next.value) {
//1
while (next != null && head.value == next.value) {
next = next.next;
}
//2
head = deleteDuplicates(next);
} else {
//3
head.next = deleteDuplicates(next);
}
return head;
}
}
}
第四种:hashmap统计出现的次数,将出现次数为1的元素放在新的链表上面
第五种:将链表元素转化为数组元素进行删除操作
泡泡:
找到相等,链接跨越重复元素,得到新链表,返回
链表的链接在于 对 next 的使用,你需要一个头链接点进行整个后续链表的链接,这个点一般是 head 头结点,或者
跟头结点有关系的结点
链表是一个应用相当广泛的数据结构,表示方式很简单,但是应用于不同地方,表现形式可能不同,比如 图 等等