• 牛客网剑指offer第56题——删除链表中重复的节点


    题目:

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

    思路:

    讨论思路之前,先分析题目让我们做什么?删除重复节点,返回头节点。

    对此,我将此问题描述成两步:

    • 找到头节点
    • 构成链表
     1 /*
     2 struct ListNode {
     3     int val;
     4     struct ListNode *next;
     5     ListNode(int x) :
     6         val(x), next(NULL) {
     7     }
     8 };
     9 */
    10 class Solution {
    11 public:
    12     ListNode* deleteDuplication(ListNode* pHead)
    13     {
    14         if(pHead == nullptr)
    15             return nullptr;
    16         if(pHead->next == nullptr)
    17             return pHead;
    18         //找到第一个head
    19         ListNode*p1=pHead;
    20         ListNode*p2=pHead;
    21            while(p1 !=nullptr)
    22             {
    23                if((p1->val == p2->val))//当最坏的情况下,只有一个元素没有重复时,p1->next = null!
    24                   p1 = p1->next;
    25                 else
    26                {
    27                    p2 = p1;
    28                }
    29                 if(p2->next == nullptr || (p2->next !=nullptr && p2->val != p2->next->val))
    30                {
    31                    pHead = p2;
    32                    break;
    33                }
    34               
    35             }
    36           
    37             if(p1 == nullptr)//说明所有元素都有重复!
    38             {
    39                 pHead = nullptr;
    40                 return pHead;
    41             }
    42         ListNode*p3 = pHead;
    43         p1 = p2->next;//考虑会不会越界
    44         while(p1 != nullptr)
    45         {
    46             if(p1->next!=nullptr && p1->val == p1->next->val)
    47             {
    48             while(p1->next!=nullptr && p1->val == p1->next->val)
    49                   p1 = p1->next;
    50             p2->next = p1->next;
    51             p1 = p1->next;
    52             }
    53             else 
    54             {
    55                 p1 = p1->next;
    56                 p2=p2->next;
    57                 p3->next = p2;
    58             }
    59             p3 = p3->next;
    60         }
    61       return pHead;
    62     }
    63 };

    21行-41行的代码,先帮助我们找到head节点在哪?因为比如链表结构如:1->1->1->2->3->3->4;显然此时head 指向2;而1->1->2;此时head指向2。而1->1->1,此时head指向null;

    41行代码之前,完成了什么? 找到head节点,并让p2指向了head。下面就是正式寻找链表的过程。但我们应该注意:此时还需要第三个节点p3。p3的作用是引导构建新的不重复的链表;p1节点是当前访问的链表;p2节点为上一个不重复的节点。

    我们先看48-51行代码干了什么?

    比如head->2->3->3->3->4->4->5->6;即head指向2。此时p1指向1。显然执行完之后。p2->next指向了4。p1由原来的指向3变为指向4.也就是跳过了重复元素。下一次循环,对于4也是同样的处理。也就是执行完之后,p2-next指向了5,p1指向了5。所以48-51行代码的作用是帮助跳过重复元素。

    再看55-57行

    最开始p2 = head指向了2,然后呢p2->next指向了5.然后p2更新为p2->next,即p2指向了5。此时将p3->next赋值为p2,则完成了非重复元素的连接过程。然后p3 = p3->next。完成索引+1.

    总之:这道题还是有些繁琐的,需要仔细思考细节!

  • 相关阅读:
    c语言之指针特性
    【java异常】【redis】ERR Client sent AUTH, but no password is set
    【Tomcat】系统找不到指定的路径
    【电脑】查看主机名
    【java异常】Building workspace has encountered a problem. Error
    【MyEclipse】安装svn插件
    【oracle】drop,truncate,delete用法
    【java异常】redis.clients.jedis.exceptions.JedisConnectionException: Could not get a res
    【java】定时任务停止时间设置
    【java异常】It's likely that neither a Result Type nor a Result Map was specified
  • 原文地址:https://www.cnblogs.com/shaonianpi/p/12623002.html
Copyright © 2020-2023  润新知