本文参考自《剑指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. mipsel汇编指令学习

    MIPS汇编语言基础 MIPS的系统结构及设计理念比较先进,其指令系统经过通用处理器指令体系MIPS I.MIPS II.MIPS III.MIPS IV.MIPS V,以及嵌入式指令体系MIPS16 ...

  2. Linux 查看服务进程运行时间

    Linux  查询服务进程的 运行时间 查看运行时间 ps -eo pid,lstart,etime | grep pid ps -eo pid,lstart,etime | grep 1713 # ...

  3. Linux - 包不同安装方式

    rpm 软件包管理器 安装编译包好的二进制包 方式 rpm -ivh lynx # rpm安装 rpm -e lynx # 卸载包 rpm -e lynx --nodeps # 强制卸载 rpm -q ...

  4. JavaScript之Dom操作【删除当前节点】

    //最新更新:2017-11-25 //现在可以通过更强大而快捷的方式为所有的HTMLElement元素的Dom操作扩展新的方法[注意事项:处理HTMLElemnt元素时,此法对IE-8无效] //原 ...

  5. luogu P3304 [SDOI2013]直径

    树的直径两遍dfs救星了 至于一定在直径中的边数,可以发现这些边一定是连续的(不然你两条直径中间能有空挡?),然后,如果某个点往下有多条直径,那么这条点以下都不算入答案.所以以直径分别两端点为根,找出 ...

  6. POJ1113 Wall【凸包】

    题意: 求把城堡围起来需要的最小墙壁周长. 思路: 围墙周长为=n条平行于凸包的线段+n条圆弧的长度=凸包周长+围墙离城堡距离L为半径的圆周长. 代码: ...还是看大佬写的,自己做个记录方便日后复习 ...

  7. sun.misc.BASE64Encoder等类报错的解决方法

    一.引言: sun.misc.BASE64Encoder等类不属于JDK标准库范畴,但在JDK中包含了该类,可以直接使用.但是在eclipse中直接使用却报错.本文就介绍一下针对这样的类如何处理. 二 ...

  8. FPN 学习笔记

    通常,利用网络对物体进行检测时,浅层网络分辨率高,学到的是图片的细节特征,深层网络,分辨率低,学到的更多的是语义特征. 1).通常的CNN使用如下图中显示的网络,使用最后一层特征图进行预测 例如VGG ...

  9. 详解Jquery选择器

    1.常见的选择器 id,类,标签选择器. $("#a1") $(".myclass") $("div") 2.组合选择器 $("# ...

  10. 【转】shell编程下 特殊变量、test / [ ]判断、循环、脚本排错

    [转]shell编程下 特殊变量.test / [ ]判断.循环.脚本排错 第1章 shell中的特殊变量 1.1 $# $# 表示参数的个数 1.1.1 [示例]脚本内容 [root@znix ~] ...