[LeetCode-83]-Remove Duplicates from Sorted List(删除有序list中的重复元素)

本文详细解析了一道关于删除有序链表中重复元素的算法题,提供了从问题理解、解决方案设计到代码实现的全过程。通过多次代码迭代,优化了算法效率,最终实现了在不破坏链表结构的前提下,有效移除所有重复节点。

0. 题目相关

【题目解读】
给定一个有序list,从中删除重复的元素,使得每一个元素仅出现一次。

【原题描述】原题链接
Given a sorted linked list, delete all duplicates such that each element appear only once.

Example 1:
Input: 1->1->2
Output: 1->2

Example 2:
Input: 1->1->2->3->3
Output: 1->2->3

【难度】Easy

1. Solution

此题比较简单,是一个基本的链表操作题目,画出list的结构图,手动操作一遍就大概知道每一步如何写了,在移动的过程中谨记不能断链

根据题中给定的 1->1->2->3->3这个例子,在纸上手动移动一遍,代码就出来了,剩下的就是一些边界处理问题了。
在这里插入图片描述
最终的代码为:
下面的代码经过几次迭代获得的,代码迭代过程在最后一部分可以看到。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if(head == NULL)
            return NULL;
            
        ListNode *pre = head->next;
        ListNode *pCurr = head;
        ListNode *temp = NULL;
        
        while(pre != NULL)
        {
            if(pCurr->val == pre->val)    
            {
                temp = pre->next;
                pCurr->next = temp;
                delete(pre); //程序中使用的是new,所以需要使用delete进行删除
                pre = temp;
            }else
            {
                pCurr = pre;
                pre = pre->next;
            }
        }
        return head;
    }
}; 

程序中使用的是new,所以需要使用delete进行删除。提交后的评分结果为:

在这里插入图片描述

2. 代码迭代过程

该题中难点在于两个元素相同时如何处理,下面几部分代码差异都在处理相同元素部分(元素不同就是一个便利的过程),所以下面只有处理相同元素的代码,其他部分代码都一样。

第一次提交,使用的是 1->1->2的测试用例,所以写出来的代码为:

...
if(pCurr->val == pre->val)    
{
	pCurr->next = pre->next;
	pCurr = pre->next;
	delete(pre);
	pre = pCurr->next;
}
...

这里直接报错,错误为Line 25: Char 30: runtime error: member access within null pointer of type 'struct ListNode' (solution.cpp),使用的是测试用例:[1,1,2,3,3]。

手动操作下,上面的代码在最后一个元素时有问题。

修改后的代码,第一次成功的代码为

...
if(pCurr->val == pre->val)    
{
    pCurr->next = pre->next;
    delete(pre);
    pre =  pCurr->next;
}
...

提交结果如下所示,运行速度太慢了:
在这里插入图片描述
分析上面的代码多了pre = pCurr->next;这一步遍历list的操作,可以使用temp变量记录当前指针位置,避免遍历操作。针对上面的分析结果,所以自己有了如下的改进代码

...
if(pCurr->val == pre->val)    
{
    ListNode *temp = pre->next;
    pCurr->next = temp;
    delete(pre);
    pre = temp;
}
...

提交结果如下所示,运行速度提高了,但内存使用增加了:

第二次
这里的代码,在每次while循环中,temp变量都会重新分配内存,占用了内存资源,所以自己有了上面 solution的改进代码,提交后的结果为:
在这里插入图片描述

3.other

题目中告诉的是有序链表,而自己的代码适用于任何链表的操作,并没有使用使用到有序这个特性,猜测针对于有序应该还有一些性能上的改进,不过暂时未想到如何利用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值