文章目录
题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。
例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
注意重复的结点不保留:并不是将重复结点删除到只剩一个,而是重复结点的全部会被删除。所以
链表1->2->3->3->4->4->5不是1->2->3->4->5
思路一:采用递归的方法去解决
分为两种情况,第一种如果从第一个节点开始就发生和后面节点相同的情况,则循环跳过所有的相同节点,找到第一个不相同的节点,调用自身返回新的头结点。
第二种情况,如果相邻的节点不相同,则用当前节点指向从下一个节点调用自身方法去检查后面的链表,返回的相应节点,相当于重新构造节点,最后返回头结点。
代码如下:
package 剑指offer.删除链表中重复的结点_18;/*
作者 :XiangLin
创建时间 :13/04/2020 23:16
文件 :Offer18_02.java
IDE :IntelliJ IDEA
*/
public class Offer18_02 {
static class ListNode{
int val;
ListNode next ;
ListNode(int val,ListNode next){
this.val = val;
this.next = next;
}
}
/**
* 最简单的方法,递归,从第一个节点每个节点一样的思路
* 分为两种方式:和相邻节点相同,找到第一个与头节点不同的节点开始递归
* 和相邻节点不同,保存头节点(用它指向下一个节点,下一个节点由递归得出),从它开始再递归,寻找后面的节点
* @param phead
* @return
*/
public ListNode deleteDuplication(ListNode phead){
if (phead == null || phead.next == null){
return phead;
}
//判断相邻是否相等
if(phead.next.val == phead.val){
//找到下一个节点是否与第一个节点相同
ListNode p = phead.next;
while (p != null && p.val == phead.val){
p = p.next;
}
//改变头结点,以同样的规则进行跳跃
return deleteDuplication(p);
}else {
//相邻节点不相等,保存当前节点,从下一个节点开始是递归,相同的规则去检查
phead.next = deleteDuplication(phead.next);
return phead;
}
}
public static void main(String[] args) {
System.out.println("(不加头结点)有三个节点元素的单链表");
ListNode node3 = new ListNode(9, null);
ListNode node2 = new ListNode(2, node3);
ListNode node1 = new ListNode(2, node2);
ListNode pHead = new ListNode(-1, node1);// 头结点
System.out.println("删除之前");
printListNode(pHead);
System.out.println("删除之后");
Offer18_02 offer18_02 = new Offer18_02();
offer18_02.deleteDuplication(pHead);
printListNode(pHead);
}
/**
* 打印链表
*
* @param pHead
*/
private static void printListNode(ListNode pHead) {
ListNode p = pHead.next;
while (p != null){
System.out.print(p.val + " ");
p = p.next;
}
System.out.println();
}
}
思路二:
采用非递归实现以上思路,关键是添加一个记录断开位置结点的指针pre,以便以后面重新的连接,或者开始头节点的重新选择。通过循环去移位,依然分为两种情况,相邻节点相等和不相等,不相等则用pre记录下当前节点,并移动当前节点位置。相等的话找到第一个不相等的节点,如果pre为空,则重新设立头结点,不为空则指向当前节点。
代码如下:
package 剑指offer.删除链表中重复的结点_18;/*
作者 :XiangLin
创建时间 :24/04/2020 23:43
文件 :offer18_02.java
IDE :IntelliJ IDEA
*/
public class offer18_03 {
static class ListNode{
int val;
ListNode next;
public ListNode(int val,ListNode next){
this.val = val;
this.next = next;
}
}
/**\
* 以上思路的非递归实现
* @param pHead
* @return
*/
public ListNode deleteDuplication(ListNode pHead){
if (pHead == null || pHead.next ==null){
return pHead;
}
ListNode pre = null;
ListNode cur = pHead;
//验证cur不为空是保证连续一样时,不为空时才能进入该循环,防止一直找不到没有找到不同数字
while (cur != null && cur.next != null){
if (cur.val == cur.next.val){
int val = cur.val;
//找到与目前第一节点不同的节点
while (cur != null && cur.val == val){
cur = cur.next;
}
//头节点重复
if (pre == null){
pHead = cur;
}else {
pre.next = cur;
}
}else {
pre = cur;
cur = cur.next;
}
}
return pHead;
}
public static void main(String[] args) {
System.out.println("(不加头结点)有三个节点元素的单链表");
ListNode node3 = new ListNode(9, null);
ListNode node2 = new ListNode(2, node3);
ListNode node1 = new ListNode(2, node2);
ListNode pHead = new ListNode(-1, node1);// 头结点
System.out.println("删除之前");
printListNode(pHead);
System.out.println("删除之后");
offer18_03 offer18_03 = new offer18_03();
offer18_03.deleteDuplication(pHead);
printListNode(pHead);
}
/**
* 打印链表
*
* @param pHead
*/
private static void printListNode(ListNode pHead) {
ListNode p = pHead.next;
while (p != null){
System.out.print(p.val + " ");
p = p.next;
}
System.out.println();
}
}
所有巧合的是要么是上天注定要么是一个人偷偷的在努力。
公众号
专注于学习资源、笔记分享,欢迎关注。我们一起成长,一起学习。一直纯真着,善良着,温情地热爱生活,,如果觉得有点用的话,请不要吝啬你手中点赞的权力,谢谢我亲爱的读者朋友。
It’s never too late to start over,Even at 3 a.m. on a Saturday,It can also be a new starting point for you。Einstein said:“Time is an illusion.”
重新开始永远都不晚,就算是周六的凌晨3点,也可以成为你新的起点。爱因斯坦说了:“时间是一种幻觉”
2020年4月25日于重庆城口
好好学习,天天向上,终有所获