• 删除链表中重复的结点——牛客剑指offer


    题目描述:

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

    解题思路:

    首先初始化一个起始指针preNode指向头结点、工作指针walkNode指向链表的第一个元素,即preNode.next=walkNode。

    迭代开始:

    while(walkNode!=null){

      如果当前工作结点的数据域walkNode.val与下一个结点的数据域walkNode.next.val相同(出现重复结点):

        preNode不移动;(指向重复结点段的前一个结点)

        walkNode移动:walkNode=walkNode.next;(此时preNode.next!=walkNode)

      否则,

        如果preNode.next==walkNode(说明未出现重复节点):

          preNode移动,walkNode移动:preNode=walkNode;walkNode=walkNode.next;

             否则,说明有重复结点,此时preNode指向重复结点段的前一个结点,walkNode指向重复结点段的最后一个重复结点

          使preNode直接指向重复结点段的下一个结点:preNode.next=walkNode.next;

          walkNode移动:walkNode=walkNode.next;

    }

    注意:因为可能会删除头结点,例如{1,1,1,2},删除了头结点1和第一个结点1,结果应为{2}。但是如果直接将函数传进来的pHead作为头结点,即初始化preNode=pHead,那么头节点永远不可能被删除,得到的结果只能为{1,2}。

    因此这里添加了一个新的头节点newhead,将pHead当一般结点处理,初始化preNode=newhead这样就可以避免出现上面的错误。

    举例:

    1->2->3->3->4->4 (加入新头结点newhead:newhead.val=0,;ewhead.next=pHead) 0->1->2->3->3->4->4

    初始化:

    preNode指向新的头结点,walkNode指向第一个结点

    preNode=newNode

    walkNode=newhead.next

    第1次迭代:

    walkNode1与其下一个结点2不相同,而且preNode0和walkNode1相邻,说明之前也没有出现过重复结点,所以把两个指针都前移

    walkNode.next.val!=walkNode.val&&pre.next==walkNode:pre=walkNode;walkNode=walkNode.next; 

    第2次迭代:

    同第一次迭代

    walkNode.next.val!=walkNode.val&&pre.next==walkNode:pre=walkNode;walkNode=walkNode.next; 

    第3次迭代:

    walkNode3与下一个结点3重复,那么此时preNode不移动,只移动walkNode

    walkNode.next.val==walkNode.val:walkNode=walkNode.next

    第4次迭代:

    walkNode3与其下一个结点4不相同,但是此时preNode和walkNode不相邻,说明preNode和walkNode中间出现了重复结点,所以把preNode直接指向walkNode的下一个结点,抛弃中间重复节点

    walkNode.next.val!=walkNode.val&&pre.next!=walkNode:pre.next=walkNode.next;walkNode=walkNode.next; 

    第5次迭代:

    walkNode4与下一个结点4重复,那么此时preNode不移动,只移动walkNode

    walkNode.next.val==walkNode.val:walkNode=walkNode.next

    第6次迭代:

    walkNode.next==null&&pre.next!=walkNode:pre.next=walkNode.next;return newNode.next;

    代码实现

     1 package struct;
     2 public class deleteList {
     3 //public class ListNode {
     4 //    int val;
     5 //    ListNode next = null;
     6 //    ListNode(int val) {
     7 //        this.val = val;
     8 //   }
     9 //}
    10     public ListNode printListFromTailToHead(ListNode pHead) {
    11         ListNode newhead=new ListNode(0);//解决删除头结点的可能,例如{1,1,1,1,2}
    12         newhead.next=pHead;
    13         ListNode pre=newhead;
    14         ListNode walkNode=newhead.next;
    15         while(walkNode!=null){
    16             if(walkNode.next!=null){
    17                 if(walkNode.next.val!=walkNode.val){
    18                     if(pre.next!=walkNode)
    19                     {
    20                         pre.next=walkNode.next;    
    21                     }
    22                     else
    23                     {
    24                         pre=walkNode;
    25                     }
    26                 }
    27             }
    28             else{                      //如果walkNode指向最后一个结点
    29                 if(pre.next!=walkNode)
    30                 {
    31                     pre.next=walkNode.next;    
    32                 }
    33                 else
    34                 {
    35                     pre=walkNode;
    36                 }
    37             }
    38             walkNode=walkNode.next;    
    39         }
    40         return newhead.next;    
    41     }
    42 }

     

  • 相关阅读:
    Linux记录-shell实现脚本监控服务器及web应用
    Hadoop记录-hadoop和hbase监控有那些比较好的工具
    Hadoop记录-Ganglia监控HDFS和HBase指标说明
    Linux记录-CPU指标介绍
    Linux记录-I/O系统监控
    Linux记录-linux系统监控命令汇总
    Hadoop记录-hadoop2.x常用端口及定义方法
    Linux记录-linux系统常用监控指标
    在IIS6上部署WebService
    《软件测试自动化之道》读书笔记 之 请求-响应测试
  • 原文地址:https://www.cnblogs.com/darlinFly/p/9328847.html
Copyright © 2020-2023  润新知