本文参考自《剑指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. 关于windows下的虚拟机Homestead在推送代码上github 步骤

    1.ssh 秘钥登录配置 使用以下命令检查主机是否生成SSH Key: > ls -al ~/.ssh 2.如果有秘钥,那就跳过这个步骤,如果没有秘钥,则运行以下命令来生成秘钥: ssh-key ...

  2. solr学习

    入门文档 http://www.cnblogs.com/edwinchen/p/3972904.html 中文分词 https://github.com/EugenePig/ik-analyzer-s ...

  3. MRPT 安装使用

    1. 安装mrpt ( apt-get ) $ sudo apt-get install mrpt-apps libmrpt-dev 2. 下载mrpt-1.3 链接:https://github.c ...

  4. 【比赛游记】FJOI2019瞎打记

    \(\mathrm{day}\) \(-4\) 又是睡到中午才起来,这样下去省选会睡迟的. 然后下午在补 WF2019 的题目,很快就能补完的(大雾). \(\mathrm{day}\) \(-3\) ...

  5. k64 datasheet学习笔记1---概述

    1.前言 k64 datasheet描述了Freescale MCU的特性.架构和编程模型,主要是面向使用MCU的系统架构和软件应用开发人员. 2.模块划分 datasheet主要按功能对模块进行划分 ...

  6. C# 实现UDP打洞通信(一)

    最近研究了一下网络打洞的相关技术,TCP的方式据说可行性不高,各种困难,因此决定采用UDP(UDP是什么就不解释了)的方式. 原理: 我们都知道局域网内的主机想要访问外网的服务器是比较容易的,比如浏览 ...

  7. python内存数据库pydblite

    Pure-Python engine 最近由于项目开发中发现python informixDB模块对多线程的支持非常不好,当开启两个线程同时连接informix数据库的时候,数据库会报错,显示SQL ...

  8. zabbix3.0.4关于java服务端程序内存溢出的处理

    关于java服务端程序内存溢出的处理 java服务端程序内存溢出会产生jvm.log文件,此时程序会挂掉,无法正常处理业务,需要重启服务 思路: 当存在jvm.log这个文件的时候则触发clean_j ...

  9. mybatis二级缓存应用及与ehcache整合

    mybaits的二级缓存是mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,还要在具体的mapper.xml中开启二级缓存. 1.开启mybatis的二级缓存 在核心配 ...

  10. centos7 部署 docker compose

    =============================================== 2019/4/10_第1次修改                       ccb_warlock == ...