博客
关于我
【剑指Offer】面试题18:删除链表中重复的节点
阅读量:476 次
发布时间:2019-03-06

本文共 3193 字,大约阅读时间需要 10 分钟。

在一个已经排序好的链表中,存在重复的结点,我们需要删除这些重复结点。重复的结点不予保留,返回处理后得到的链表头指针。例如,链表1→2→3→3→4→4→5,处理后应变为1→2→5。

方法思路

为了解决这个问题,我们可以使用哈希集合(HashSet)的方法,这种方法可以在O(n)的时间复杂度内解决问题,并在最坏情况下的空间复杂度为O(n),其中n是链表的长度。具体步骤如下:

  • 初始化哈希集合:用于记录已遇到的节点值。
  • 遍历链表:从链表的头节点开始,逐个比较当前节点和下一个节点的值。
  • 删除重复节点
    • 如果当前节点的值在哈希集合中存在,说明这个节点是重复的,删除它以及连续重复的节点。
    • 如果不是重复的,将节点值加入哈希集合,并继续移动指针。
  • 处理头节点重复的情况:在遍历完头节点后,可能链表的头节点已经被删除了,需要重新找到链表的新头节点。
  • 处理中间和尾节点的重复情况:继续从新头节点开始,遍历整个链表,删除所有重复的节点。
  • 代码实现

    import java.util.HashSet;public class Solution18 {    public static void main(String[] args) {        ListNode1 listNode1 = new ListNode1(1);        ListNode1 listNode2 = new ListNode1(2);        ListNode1 listNode3 = new ListNode1(3);        ListNode1 listNode4 = new ListNode1(3);        ListNode1 listNode5 = new ListNode1(4);        ListNode1 listNode6 = new ListNode1(4);        ListNode1 listNode7 = new ListNode1(5);        listNode1.next = listNode2;        listNode2.next = listNode3;        listNode3.next = listNode4;        listNode4.next = listNode5;        listNode5.next = listNode6;        listNode6.next = listNode7;        ListNode1 res = deleteDupcreationHash(listNode1);        System.out.println(res);    }    public static ListNode1 deleteDupcreationHash(ListNode1 pHead) {        if (pHead == null || pHead.next == null) {            return pHead;        }        HashSet
    hashSet = new HashSet<>(); ListNode1 pre = pHead; ListNode1 cur = pHead.next; while (cur != null) { if (pre.val == cur.val) { hashSet.add(cur.val); } pre = cur; cur = cur.next; } while (pHead != null && hashSet.contains(pHead.val)) { pHead = pHead.next; } if (pHead == null) { return null; } pre = pHead; cur = pHead.next; while (cur != null) { if (hashSet.contains(cur.val)) { pre.next = cur.next; cur = cur.next; } else { pre = cur; cur = cur.next; } } return pHead; } public static ListNode1 deleteDupcreation(ListNode1 pHead) { if (pHead == null || pHead.next == null) { return pHead; } ListNode1 head = new ListNode1(Integer.MIN_VALUE); head.next = pHead; ListNode1 pre = head; while (pre.next != null) { cur = pre.next; if (cur.next != null && cur.next.val == cur.val) { while (cur.next != null && cur.next.val == cur.val) { cur = cur.next; } pre.next = cur.next; cur = cur.next; } else { pre = cur; cur = cur.next; } } return head.next; }}class ListNode1 { int val; ListNode1 next = null; public ListNode1(int val) { this.val = val; } @Override public String toString() { return "ListNode1{" + val + ", next=" + next + '}'; }}

    代码解释

    • 初始化:创建一个HashSet来存储已遇到的节点值。
    • 遍历链表:从链表的头节点开始,逐个检查节点的值。
    • 删除重复节点:当发现当前节点的值重复时,删除后续的重复节点,并更新指针。
    • 处理头节点:在遍历中可能遇到头节点被删除的情况,重新找到链表的新头节点。
    • 处理中间和尾节点:继续从新头节点开始,确保中间和尾部的重复节点也被删除。

    这种方法高效且简洁,能够在O(n)的时间复杂度内处理问题,适用于各种规模的链表。

    转载地址:http://zufdz.baihongyu.com/

    你可能感兴趣的文章
    Nginx负载均衡
    查看>>
    Nginx负载均衡和F5的区别---系统运维工作笔记001
    查看>>
    nginx负载均衡和反相代理的配置
    查看>>
    nginx负载均衡器处理session共享的几种方法(转)
    查看>>
    nginx负载均衡的5种策略
    查看>>
    nginx负载均衡的5种策略(转载)
    查看>>
    nginx负载均衡的五种算法
    查看>>
    Nginx负载均衡(upstream)
    查看>>
    nginx转发端口时与导致websocket不生效
    查看>>
    Nginx运维与实战(二)-Https配置
    查看>>
    Nginx部署_mysql代理_redis代理_phoenix代理_xxljob代理_websocket代理_Nacos代理_内网穿透代理_多系统转发---记录021_大数据工作笔记0181
    查看>>
    Nginx配置HTTPS服务
    查看>>
    Nginx配置Https证书
    查看>>
    Nginx配置http跳转https
    查看>>
    Nginx配置ssl实现https
    查看>>
    Nginx配置TCP代理指南
    查看>>
    NGINX配置TCP连接双向SSL
    查看>>
    Nginx配置——不记录指定文件类型日志
    查看>>
    nginx配置一、二级域名、多域名对应(api接口、前端网站、后台管理网站)
    查看>>
    nginx配置中的服务器名称
    查看>>