题目描述

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

思路分析

  由于是有序链表,要删除重复节点,,我们可以先设置三个指针,pre,p,next,分别指向前一个节点,当前节点,和下一个结点,遍历链表,判断当前节点和下一个结点是否相同,设置一个标记位needDel
  1. 如果没有找到,就想指针往后移动;
  2. 否则,就设置true,这时可以循环遍历往后继续搜索重复的节点(因为链表是有序的)
注意:

  1. 删除的是第一个节点的情况
  2. 传入头结点为null时,或者只有头结点

测试用例

要注意此题返回的是头指针

  1. 功能测试(重复结点位于链表头部、中部、尾部,无重复结点)
  2. 特殊测试(null,所有结点均重复)

Java代码

package com.hao.offer;
import com.hao.common.ListNode;
public class Offer18_02 { public static void main(String[] args) {
System.out.println("****功能测试***");
test1();
System.out.println("***特殊输入测试****");
test2();
System.out.println("***特殊输入测试****");
test3();
} public static ListNode deleteDuplication(ListNode pHead) {
return Solution1(pHead);
} /**
*
* 需要设置三个指针,pre pNode 和 next ;
*
* @param pHead
* @return
*/
private static ListNode Solution1(ListNode pHead) {
if (pHead == null || pHead.next == null) {// 如果链表为空,或者已有一个节点
return pHead;
}
ListNode pre = null;
ListNode pNode = pHead; // 代表当前节点
while (pNode != null) {// 从头指针开始遍历链表
boolean needDel = false;
ListNode pNext = pNode.next;
if (pNext != null && pNext.val == pNode.val) {
// 如果当前节点的下一个结点不为null 且其值和当前节点相等
needDel = true;
}
if (!needDel) {// 如果没有找到重复的元素就将指针往后移动
pre = pNode;
pNode = pNode.next;
} else { // 找到重复的元素
ListNode toBeDel = pNode;
int value = toBeDel.val;
while (toBeDel != null && toBeDel.val == value) {
// 将指针移到所有重复元素的后面
toBeDel = toBeDel.next;
}
if (pre == null) {// 删除的是第一个节点
pHead = toBeDel;
} else {
pre.next = toBeDel;
}
pNode = toBeDel;
}
} return pHead;
} /**
* 功能测试 要注意此题目没有头结点
*/
private static void test1() {//
System.out.println("有两对重复的");
ListNode node6 = new ListNode(6, null);
ListNode node5 = new ListNode(6, node6);
ListNode node4 = new ListNode(3, node5);
ListNode node3 = new ListNode(3, node4);
ListNode node2 = new ListNode(2, node3);
ListNode node1 = new ListNode(1, node2);
ListNode pHead = new ListNode(0, node1);
System.out.println("删除之前");
printListNode(pHead);
System.out.println("删除之后--->");
deleteDuplication(pHead);
printListNode(pHead);
} /**
* 特殊值输入测试
*/
private static void test2() {//
System.out.println("所有的元素都是重复的");
ListNode node6 = new ListNode(2, null);
ListNode node5 = new ListNode(1, node6);
ListNode node4 = new ListNode(1, node5);
ListNode node3 = new ListNode(1, node4);
ListNode node2 = new ListNode(1, node3);
ListNode node1 = new ListNode(1, node2);
ListNode pHead = new ListNode(1, node1);
System.out.println("删除之前");
printListNode(pHead);
System.out.println("删除之后--->");
deleteDuplication(pHead);
printListNode(pHead);
} private static void test3() {
System.out.println("只有一个节点");
ListNode pHead = new ListNode(1, null);
System.out.println("删除之前");
printListNode(pHead);
System.out.println("删除之后--->");
deleteDuplication(pHead);
printListNode(pHead);
} /**
* 打印链表 此题目没有头结点
*
* @param pHead
*/
private static void printListNode(ListNode pHead) {
ListNode p = pHead;
while (p != null) {
System.out.print(p.val + " ");
p = p.next;
}
System.out.println();
}
}

代码链接

剑指Offer代码-Java

【Offer】[18-2] 【删除链表中重复的节点】的更多相关文章

  1. 剑指offer 面试题 删除链表中重复的节点

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

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

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

  3. php实现删除链表中重复的节点

    php实现删除链表中重复的节点 一.总结 二.php实现删除链表中重复的节点 题目描述: 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1 ...

  4. 剑指offer——面试题18.1:删除链表中重复的节点

    // 面试题18(二):删除链表中重复的结点 // 题目:在一个排序的链表中,如何删除重复的结点?例如,在图3.4(a)中重复 // 结点被删除之后,链表如图3.4(b)所示. #include &l ...

  5. 剑指offer(56)删除链表中重复的节点

    一直忘记更新了,把剑指offer更新完吧.... 题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3-&g ...

  6. python实现剑指offer删除链表中重复的节点

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

  7. 第18题:在O(1)时间删除链表结点+删除链表中重复的节点

    题目描述:题目描述在O(1)时间删除链表结点 给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点. 考查创新编程能力. 思路: 1.如果从头到尾遍历,时间O(n) 2.如果将待删 ...

  8. 剑指offer系列30-----删除链表中重复的节点

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

  9. AcWing 29. 删除链表中重复的节点

    题目地址 https://www.acwing.com/problem/content/description/27/ 来源:剑指Offer 题目描述在一个排序的链表中,存在重复的结点,请删除该链表中 ...

随机推荐

  1. L4170[CQOI2007]涂色

    #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i = a; i <= b; ...

  2. 缓存的有效期和淘汰策略【Redis和其他缓存】【刘新宇】

    缓存有效期与淘汰策略 有效期 TTL (Time to live) 设置有效期的作用: 节省空间 做到数据弱一致性,有效期失效后,可以保证数据的一致性 Redis的过期策略 过期策略通常有以下三种: ...

  3. Kafka集群模式安装(二)

    我们来安装Kafka的集群模式,三台机器: 192.168.131.128 192.168.131.130 192.168.131.131 Kafka集群需要依赖zookeeper,所以需要先安装好z ...

  4. WPF中ComboBox控件绑定键值对操作

    WPF中下拉框将键值对作为其数据源的具体操作.本实例以枚举类型以及枚举特性描述字符串生成键值对来进行. namespace ViewC { /// <summary> /// View.x ...

  5. .netcore持续集成测试篇之Xunit结合netcore内存服务器发送post请求

    系列目录 Web项目中,很多与用户数据交互的请求都是Post请求,想必大家都用过HttpClient构造过post请求,这里并不对HttpClient做详细介绍,只介绍一些常用的功能.并结合AutoF ...

  6. Markdown的最常用标记符号

    Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式. md就是markdown 如果你要把这段文字定义成标题,只需要在前面加上一个#号, ...

  7. 从原理层面掌握@ModelAttribute的使用(使用篇)【一起学Spring MVC】

    每篇一句 每个人都应该想清楚这个问题:你是祖师爷赏饭吃的,还是靠老天爷赏饭吃的 前言 上篇文章 描绘了@ModelAttribute的核心原理,这篇聚焦在场景使用上,演示@ModelAttribute ...

  8. Windows Server 2008文件服务器

    下面我们来学习Windows Server 2008文件服务器,文件服务器对于企业是相当重要的,所有的资料都保存在文件服务器上面,对于整个企业来说数据算得上是最重要的东西,下面介绍一下文件服务器的搭建 ...

  9. 上个月,我赚了2W外快。。。

    前段时间和室友一起给某个公司做了一个管理系统,每个人分2W多.这里和大家分享一下做完项目后一点点感受,想到啥就说点啥. 核心竞争力 两个月就挣了2W块,挣了我爸妈两个人一年的收入,每天还贼辛苦,披星戴 ...

  10. 如何编写高质量的 JS 函数(1) -- 敲山震虎篇

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/7lCK9cHmunvYlbm7Xi7JxQ作者:杨昆 一千个读者,有一千个哈姆雷特. 此系列文 ...