知识点链表
描述
删除给出链表中的重复元素(链表中元素从小到大有序),使链表中的所有元素都只出现一次
例如:
给出的链表为,返回
.
给出的链表为,返回
.
数据范围:链表长度满足 ,链表中任意节点的值满足
进阶:空间复杂度
,时间复杂度
示例1
输入:
{1,1,2}
复制返回值:
{1,2}
复制
示例2
输入:
{}
复制返回值:
{}
题解
思路:
这里提供2种解法:
- 使用set的特性,提供一个比较的仿函数,遍历一遍链表,将所有节点放入set中,然后再从set中取出所有节点即可
- 参考数组中删除重复元素的方式,比较当前节点和next节点是否相等
- 相等则将当前节点直接指向next->next
- 不等则将当前节点指向next节点
使用set的实现
struct ListNode
{
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(nullptr)
{
}
ListNode() = default;
};
class Cmp
{
public:
bool operator()(const ListNode *left, const ListNode *right)
{
return left->val < right->val;
}
};
ListNode *deleteDuplicates_1(ListNode *head)
{
std::set<ListNode *, Cmp> s;
while (head != nullptr)
{
s.insert(head);
head = head->next;
}
head = nullptr;
ListNode *tail_node = head;
while (!s.empty())
{
if (head == nullptr)
{
head = *s.begin();
tail_node = head;
}
else
{
tail_node->next = *s.begin();
tail_node = tail_node->next;
}
s.erase(s.begin());
}
if (tail_node != nullptr)
{
tail_node->next = nullptr;
}
return head;
}
使用前后指针值比较的实现
struct ListNode
{
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(nullptr)
{
}
ListNode() = default;
};
ListNode *deleteDuplicates(ListNode *head)
{
auto cur_node = head;
while (cur_node != nullptr)
{
if (cur_node->next == nullptr)
{
break;
}
if (cur_node->val == cur_node->next->val)
{
cur_node->next = cur_node->next->next;
}
else
{
cur_node = cur_node->next;
}
}
return head;
}