9.删除链表中的重复结点

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

题目描述

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


/*

struct ListNode {

   int val;

   struct ListNode *next;

   ListNode(int x) :

       val(x), next(NULL) {

   }

};

*/

class Solution {

public:

   ListNode* deleteDuplication(ListNode* pHead)

   {

   }

};

解法:


class Solution {

public:

   ListNode* deleteDuplication(ListNode* pHead)

 {

   if( pHead == NULL ) return pHead;

   //创建3个链表结点变量

   ListNode *pre = NULL; //指向前面最晚访问过的不重复结点

   ListNode *p = pHead; //指向当前处理的结点

   ListNode *q = NULL; //指向当前处理结点后面结点

   // 其中的每个链表结点分别代表了phead的各个结点 以及改变了链表的各个指向

   while( p != NULL )

   {

      //分两种情况:

       //一种是后结点和前结点有重复

       //当前结点p,(其实是p指向当前结点),与它下一个结点p->next的val相同,说明要删掉有这个val的所有结点

       if( p->next != NULL && p->next->val == p->val )

       {

           q = p->next;

           //找到q,它指向最后一个与p val相同的结点,那p 到 q (包含) 都是要删除的

           while( q != NULL && q->next != NULL && q->next->val == p->val )

           {

               q = q->next;

           }

           //如果p指向链表中第一个元素,p -> ... -> q ->... , 要删除p到q, 将指向链表第一个元素的指针pHead指向q->next。

           if( p == pHead )

           {

               pHead = q->next;

           }

           else//如果p不指向链表中第一个元素,pre -> p ->...->q ->... ,要删除p到q,即pre->next = q->next

           {

               pre->next = q->next;

           }

           //当前处理的p要向链表尾部移动

           p = q->next;

       }

       //第二种是后结点和前结点无重复

       else//如果没有重复结点,则一直往后移动

       {

           pre = p;

           p = p->next;

       }

   }

   return pHead;//注意返回的必须是PHead,因为此时的PHead链表已经被改变了指向

}

};

解法2:递归


class Solution {

   public:

    ListNode* deleteDuplication(ListNode* pHead)

    {

       if (pHead == nullptr || pHead->next == nullptr)

       { // 只有0个或1个结点,则返回

           return pHead;

       }

       // 当前结点是重复结点

       if (pHead->val == pHead->next->val)

       {

       

           ListNode* pNode = pHead->next;

           while (pNode != nullptr && pNode->val == pHead->val)

           {

               // 跳过值与当前结点相同的全部结点,找到第一个与当前结点不同的结点

               pNode = pNode->next;

           }

           //相当于将不重复的结点放入栈中

           return deleteDuplication(pNode); // 从第一个与当前结点不同的结点(此结点不重复)开始递归;

       }

      // 当前结点不是重复结点

      else

        {

          //相当于将不重复的结点放入栈中

           pHead->next = deleteDuplication(pHead->next); // 保留当前结点,从下一个结点开始递归

           return pHead;

        }

    }

};

目录
相关文章
|
3月前
|
算法
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
81 1
|
2月前
|
存储 算法 搜索推荐
链表的中间结点
【10月更文挑战第24天】链表的中间结点是链表操作中的一个重要概念,通过快慢指针法等方法可以高效地找到它。中间结点在数据分割、平衡检测、算法应用等方面都有着重要的意义。在实际编程中,理解和掌握寻找中间结点的方法对于解决链表相关问题具有重要价值。
27 1
|
4月前
链表的中间结点
链表的中间结点
183 57
|
7月前
|
算法
数据结构和算法学习记录——线性表之双向链表(上)-结点类型定义、初始化函数、创建新结点函数、尾插函数、打印函数、尾删函数
数据结构和算法学习记录——线性表之双向链表(上)-结点类型定义、初始化函数、创建新结点函数、尾插函数、打印函数、尾删函数
59 0
|
3月前
【LeetCode 09】19 删除链表的倒数第 N 个结点
【LeetCode 09】19 删除链表的倒数第 N 个结点
21 0
|
5月前
|
算法
LeetCode第19题删除链表的倒数第 N 个结点
该文章介绍了 LeetCode 第 19 题删除链表的倒数第 N 个结点的解法,通过使用快慢双指针,先将快指针移动 n 步,然后快慢指针一起遍历,直到快指针到达链尾,从而找到倒数第 N 个结点的前一个结点进行删除,同时总结了快慢指针可减少链表遍历次数的特点。
LeetCode第19题删除链表的倒数第 N 个结点
|
6月前
【数据结构OJ题】链表中倒数第k个结点
牛客题目——链表中倒数第k个结点
42 1
【数据结构OJ题】链表中倒数第k个结点
|
5月前
【刷题记录】链表的中间结点
【刷题记录】链表的中间结点
|
6月前
【数据结构OJ题】链表的中间结点
力扣题目——链表的中间结点
32 0
【数据结构OJ题】链表的中间结点
|
7月前
|
算法
19.删除链表的倒数第N个结点
19.删除链表的倒数第N个结点

热门文章

最新文章

下一篇
开通oss服务