博客
关于我
【剑指Offer】面试题18:删除链表中重复的节点
阅读量:467 次
发布时间: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/

    你可能感兴趣的文章
    webpack打包less与sass
    查看>>
    [白话解析] 深入浅出熵的概念 & 决策树之ID3算法
    查看>>
    [梁山好汉说IT] 梁山好汉和抢劫银行
    查看>>
    [记录点滴] OpenResty中Redis操作总结
    查看>>
    [源码解析] 消息队列 Kombu 之 基本架构
    查看>>
    [源码分析] 消息队列 Kombu 之 启动过程
    查看>>
    [源码分析] 消息队列 Kombu 之 Consumer
    查看>>
    [源码分析] 消息队列 Kombu 之 mailbox
    查看>>
    抉择之苦
    查看>>
    wx.NET CLI wrapper for wxWidgets
    查看>>
    Silverlight for linux 和 DLR(Dynamic Language Runtime)
    查看>>
    微软网络数据包分析工具 Microsoft Network Monitor 3.2
    查看>>
    ASP.NET MVC Action Filters
    查看>>
    Windows SharePoint Services 3.0 Service Pack 2
    查看>>
    兰州大学百年校庆--风雨百年萃英路
    查看>>
    Eucalyptus企业云计算
    查看>>
    Service Broker 无法工作的问题修复
    查看>>
    Windows Server 2008 R2 Server Core
    查看>>
    WCF WebHttp Services in .NET 4
    查看>>
    Powershell中禁止执行脚本解决办法
    查看>>