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
题目中告诉的是有序链表,而自己的代码适用于任何链表的操作,并没有使用使用到有序这个特性,猜测针对于有序应该还有一些性能上的改进,不过暂时未想到如何利用。
本文详细解析了一道关于删除有序链表中重复元素的算法题,提供了从问题理解、解决方案设计到代码实现的全过程。通过多次代码迭代,优化了算法效率,最终实现了在不破坏链表结构的前提下,有效移除所有重复节点。

177

被折叠的 条评论
为什么被折叠?



