开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第5天,点击查看活动详情
题目
描述
删除给出链表中的重复元素(链表中元素从小到大有序),使链表中的所有元素都只出现一次 例如: 给出的链表为1→1→2,返回1→2. 给出的链表为1→1→2→3→3,返回1→2→3.
数据范围:链表长度满足0≤n≤100,链表中任意节点的值满足∣val∣≤100
进阶:空间复杂度 O(1),时间复杂度 O(n)
示例1
输入:
{1,1,2}
返回值:
{1,2}
示例2
输入:
{}
返回值:
{}
分析
分析特殊情况
不难看出,在链表为空和链表只有一个元素时,只需要返回输入的链表头即可。
分析一般情况
由于需要删除相同的元素,那么我们就保留遇到的第一个元素即可,因为链表只能顺序访问,不能够逆序访问,如果发现后面的元素的值与它相等,那么就删除新元素,指向再下一个元素,继续判断;如果不等,说明可以继续往后遍历。
基于这样的想法,我们可以设定两个指针一个指向之前的元素pPre,初始化为头结点,pCur为当前遍历的元素,遍历链表直到pCur为空指针。
- 当pPre的元素值与pCur的元素值相等时,两者均往后移;
- 当pPre的元素值与pCur的元素值不等时,删除pCur指向的元素,并更新pCur为下一个元素,将pPre的指针执向pCur。
代码示例
如分析所述,需要注意的是,这里对节点进行删除时,需要事先分配一个临时变量存储需要释放的指针。
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
class Solution {
public:
/**
*
* @param head ListNode类
* @return ListNode类
*/
ListNode* deleteDuplicates(ListNode* head) {
// write code here
if(nullptr == head || nullptr == head->next){
return head;
}
ListNode *pPre = head;
ListNode *pCur = head->next;
while(nullptr != pCur){
if(pPre->val != pCur->val){
pPre = pCur;
pCur = pCur->next;
}else{
ListNode *pTemp = pCur;
pCur = pCur->next;
delete pTemp;
pPre->next = pCur;
}
}
return head;
}
};