本文参考自《剑指offer》一书,代码采用Java语言。

更多:《剑指Offer》Java实现合集  

题目

  在一个排序的链表中,如何删除重复的结点?例如,在图3.4(a)中重复结点被删除之后,链表如图3.4(b)所示。

思路

  设置一个preNode,用于记录当前结点的前一个结点,再设置一个布尔变量needDelete,如果当前结点和后一结点的值相同(记该值为dupVal),needDelete赋值为真。

  当needDelete为真时,通过循环往后找到第一个不为dupVal的结点,把该结点设置为当前结点,并赋值给preNode.next,即相当于完成了删除操作;而当needDelete为假时,把当前结点和preNode往后移一位即可。

测试算例

  1.功能测试(重复结点位于链表头部、中部、尾部,无重复结点)

  2.特殊测试(null,所有结点均重复)

完整Java代码

    public ListNode deleteDuplication(ListNode pHead){
ListNode pre = null;
ListNode cur = pHead;
while(cur!=null){
if(cur.next!=null && cur.next.val==cur.val){
while(cur.next!=null && cur.next.val==cur.val)
cur=cur.next;
cur=cur.next;
if(pre==null)
pHead=cur;
else
pre.next=cur;
}else{
pre=cur;
cur=cur.next;
}
}
return pHead;
}

复习时写的

(含测试代码)

package _18;

/**
*
* @Description 面试题18(二):删除链表中重复的结点
*
* @author yongh
* @date 2018年9月18日 下午6:30:53
*/ // 题目:在一个排序的链表中,如何删除重复的结点?例如,在图3.4(a)中重复
// 结点被删除之后,链表如图3.4(b)所示。 public class DeleteDuplicatedNode {
class ListNode{
int val;
ListNode next = null; ListNode(int val,ListNode next) {
this.val = val;
this.next=next;
}
}
public ListNode deleteDuplication(ListNode pHead){
if(pHead==null||pHead.next==null) //空结点或者仅一个结点
return pHead;
ListNode preNode = null;
ListNode curNode = pHead; while(curNode!=null){
boolean needDelete=false;
if(curNode.next!=null && curNode.val==curNode.next.val)
needDelete=true;
if(!needDelete){ //当前结点不重复
preNode=curNode;
curNode=curNode.next;
}else{ //当前结点重复
int dupValue=curNode.val;
ListNode toBeDel = curNode;
while(toBeDel!=null&&toBeDel.val==dupValue){
//这里删除暂时不涉及前一结点操作,其实主要是找出后面第一个不重复结点
toBeDel = toBeDel.next;
}
if(preNode==null){ //说明删除的结点为头结点
pHead=toBeDel;
}else{
preNode.next=toBeDel;
}
curNode=toBeDel; //这个结点还是可能会出现重复的,所以不能=next
}
}
return pHead;
} //========测试代码======
void test(ListNode pHead) {
System.out.println("-----------");
System.out.print("The original list is: ");
ListNode curr=pHead;
if(curr!=null) {
while(curr.next!=null) {
System.out.print(curr.val+",");
curr=curr.next;
}
System.out.println(curr.val);
}else {
System.out.println();
}
pHead=deleteDuplication(pHead);
System.out.print("The result list is: ");
curr=pHead;
if(curr!=null) {
while(curr.next!=null) {
System.out.print(curr.val+",");
curr=curr.next;
}
System.out.println(curr.val);
}else {
System.out.println();
}
System.out.println("-----------");
} /**
* 重复结点位于链表头部
*/
void test1() {
ListNode p4=new ListNode(3, null);
ListNode p3=new ListNode(2, p4);
ListNode p2=new ListNode(1, p3);
ListNode p1=new ListNode(1, p2);
test(p1);
} /**
* 重复结点位于链表尾部
*/
void test2() {
ListNode p4=new ListNode(3, null);
ListNode p3=new ListNode(3, p4);
ListNode p2=new ListNode(2, p3);
ListNode p1=new ListNode(1, p2);
test(p1);
} /**
* 重复结点位于链表中部
*/
void test3() {
ListNode p4=new ListNode(3, null);
ListNode p3=new ListNode(2, p4);
ListNode p2=new ListNode(2, p3);
ListNode p1=new ListNode(1, p2);
test(p1);
} /**
* 连续出现重复结点
*/
void test4() {
ListNode p6=new ListNode(3, null);
ListNode p5=new ListNode(3, p6);
ListNode p4=new ListNode(2, p5);
ListNode p3=new ListNode(2, p4);
ListNode p2=new ListNode(1, p3);
ListNode p1=new ListNode(1, p2);
test(p1);
} /**
* 多个重复结点
*/
void test5() {
ListNode p6=new ListNode(3, null);
ListNode p5=new ListNode(3, p6);
ListNode p4=new ListNode(3, p5);
ListNode p3=new ListNode(2, p4);
ListNode p2=new ListNode(1, p3);
ListNode p1=new ListNode(1, p2);
test(p1);
} /**
* 无重复结点
*/
void test6() {
ListNode p6=new ListNode(6, null);
ListNode p5=new ListNode(5, p6);
ListNode p4=new ListNode(4, p5);
ListNode p3=new ListNode(3, p4);
ListNode p2=new ListNode(2, p3);
ListNode p1=new ListNode(1, p2);
test(p1);
} /**
* 单个结点
*/
void test7() {
ListNode p1=new ListNode(6, null);
test(p1);
} /**
* null
*/
void test8() {
ListNode p1=null;
test(p1);
} public static void main(String[] args) {
DeleteDuplicatedNode demo= new DeleteDuplicatedNode();
demo.test1();
demo.test2();
demo.test3();
demo.test4();
demo.test5();
demo.test6();
demo.test7();
demo.test8();
} }

  

-----------
The original list is: ,,,
The result list is: ,
-----------
-----------
The original list is: ,,,
The result list is: ,
-----------
-----------
The original list is: ,,,
The result list is: ,
-----------
-----------
The original list is: ,,,,,
The result list is:
-----------
-----------
The original list is: ,,,,,
The result list is:
-----------
-----------
The original list is: ,,,,,
The result list is: ,,,,,
-----------
-----------
The original list is:
The result list is:
-----------
-----------
The original list is:
The result list is:
-----------

demo

收获

  1.删除多个结点时,只要把重复结点前一个结点的next指向重复结点的后一个结点;

  2.不要把重复结点一个一个删除,先定义一个布尔变量确定当前结点是否重复,然后按上一句话的方法进行删除即可。

更多:《剑指Offer》Java实现合集  

【Java】 剑指offer(18) 删除链表中重复的结点的更多相关文章

  1. 【剑指Offer】删除链表中重复的结点 解题报告(Python)

    [剑指Offer]删除链表中重复的结点 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interview ...

  2. 剑指Offer 56. 删除链表中重复的结点 (链表)

    题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...

  3. [剑指Offer] 56.删除链表中重复的结点

    题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...

  4. 【剑指offer】删除链表中重复的结点

    题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针.例如,链表1->2->3->3->4->4->5 处理后为 ...

  5. 剑指offer:删除链表中重复的结点

    题目描述: 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理 ...

  6. 剑指offer——20删除链表中重复的结点

    题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...

  7. Go语言实现:【剑指offer】删除链表中重复的结点

    该题目来源于牛客网<剑指offer>专题. 给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中没有重复出现的数字. 示例 1: 输入: 1->2->3->3- ...

  8. 【剑指offer】删除链表中重复的节点,C++实现(链表)

    0.简介       本文是牛客网<剑指offer>笔记. 1.题目 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针.例如,链表1-> ...

  9. 剑指offer56:删除链表中重复的结点,排序的链表中,删除重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

    1 题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处 ...

随机推荐

  1. ubuntu新建组合用户命令不管用

    当我们新建了组和用户的时候发现一些命令不管用了,这是什么问题呢. 一.解决方案. 通过以下命令添加组和用户,切换到新用户,发现命令不管用,只有一个$符号. groupadd 新组名 ----添加组 u ...

  2. TypeError: Only valid with DatetimeIndex, TimedeltaIndex or PeriodIndex, but got an instance of 'Index'

    这个问题说的很清楚,就是类型不对,需要转化类型,首先讲一下这个问题是在使用pandas的resample函数激发的,官方文档解释的较为清楚,如下: Convenience method for fre ...

  3. Eclipse通用设置

    分类 Eclipse分为64位.32位,安装版.免安装版 查看Eclipse版本信息 Help - About Eclipse - Installation Details

  4. HTML5实现全屏API【进入和退出全屏】

    现在主流浏览器基本上实现了全屏效果,但是不同浏览器实现不一样: [进入和退出全屏] // Webkit (works in Safari5.1 and Chrome 15)element.webkit ...

  5. win10如何获得管理员权限_百度经验

    win10如何获得管理员权限_百度经验http://jingyan.baidu.com/article/0aa223755448db88cd0d6450.html 在右下方任务栏的“搜索web和win ...

  6. Android数据存储五种方式

    1 使用SharedPreferences存储数据:常用于做本地缓存 2 文件存储数据:(1)data/data/<package name>/files目录内   (2)SDCard内 ...

  7. VMware12虚拟机中Ubuntu16.04安装CPU版本Caffe

    首先,可以自行下载VMware12进行安装,基本上都是直接点击‘下一步’直到安装完成,这里重点讲一下Ubuntu16及Caffe的安装步骤 第一步: 下载Ubuntu16.04版本的文件,这里给出链接 ...

  8. window系列

    1.关闭浏览器单个网页   ctrl+W 2.远程桌面连接  mstsc

  9. Linux下的换行符\n\r以及txt和word文档的使用

    Linux doc WINDOWS下记事本编写的文档和LINUX下VIM或者GEDIT等编写的文档的不同! 例如WINDOWS下编写的SH脚本,放到LINUX下执行可能会出错. 解决方法: 原因是:W ...

  10. Oracle 正则表达式函数-REGEXP_REPLACE

    背景 当初写oracle的一个存储过程,以前不知道sql里也有正则表达式,关于正则表达式教程很多了,这里只是记录下Oracle也有这个功能,下次再有类似需求用这个处理的确方便很多. 想起存储过程,就想 ...